Merge branch 'master' into optional-shadow-dom

pull/2516/head
Zephraph 7 years ago
commit dc9ca806a8

@ -1,5 +1,13 @@
# Svelte changelog
## 3.0.1
* Prevent text input cursor jumping in Safari ([#2506](https://github.com/sveltejs/svelte/issues/2506))
* Allow assignments to member expressions ([#2510](https://github.com/sveltejs/svelte/issues/2510))
* Prevent mutually dependent functions causing an infinite during hoisting ([#2542](https://github.com/sveltejs/svelte/issues/2542))
* Reuse scheduler promise instead of creating new one each time ([#2555](https://github.com/sveltejs/svelte/pull/2555))
* Various site/docs fixes
## 3.0.0
* Everything

@ -54,7 +54,7 @@ npm run test -- -g transition
## svelte.dev
The source code for https://svelte.dev, including all the documentation, lives in the [site](site) directory. The site is built with [Sapper](https://sapper.svelte.technology) To develop locally:
The source code for https://svelte.dev, including all the documentation, lives in the [site](site) directory. The site is built with [Sapper](https://sapper.svelte.technology). To develop locally:
```bash
cd site

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.0.0",
"version": "3.0.1",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",

@ -38,28 +38,21 @@ This will serve your app on [localhost:5000](http://localhost:5000) and rebuild
When you download from the REPL, you're getting a customised version of the [sveltejs/template](https://github.com/sveltejs/template) repo. You can skip messing around with zip files by using [degit](https://github.com/Rich-Harris/degit), a project scaffolding tool.
In the terminal, install degit globally (you only need to do this once):
In the terminal, you can instantly create a new project like so:
```bash
npm install -g degit
```
After that, you can instantly create a new project like so:
```bash
degit sveltejs/template my-new-project
cd my-new-project
npx degit sveltejs/template my-svelte-project
cd my-svelte-project
npm install
npm run dev
npm run dev & open http://localhost:5000
```
Once you've tinkered a bit and understood how everything fits together, you can fork [sveltejs/template](https://github.com/sveltejs/template) and start doing this instead:
```bash
degit your-name/template my-new-project
npx degit your-name/template my-new-project
```
And that's it! Do `npm run build` to create a production-ready version of your app, and check the project template's [README](https://github.com/sveltejs/template/blob/master/README.md) for instructions on how to easily deploy your app to the web with [Now](https://zeit.co/now) or [Surge](http://surge.sh/).
You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) or the [API](https://github.com/sveltejs/svelte/tree/v2#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](https://discord.gg/yy75DKs), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!
You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) (Update from 2019: with Svelte 3 the CLI was deprecated and we now use [sirv-cli](https://www.npmjs.com/package/sirv-cli) in our template. Feel free to use whatever tool you like!) or the [API](https://github.com/sveltejs/svelte/tree/v2#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](https://discord.gg/yy75DKs), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!

@ -19,7 +19,7 @@ Here, we're using [Emotion](https://emotion.sh) to generate scoped class names t
<div class="max">
<iframe
title="Aphrodite example"
src="/repl/embed?gist=ad495ff5ba9ceefe5984fe62c1f15e19"
src="/repl/embed?example=blog-svelte-css-in-js"
scrolling="no"
></iframe>
</div>
@ -27,4 +27,3 @@ Here, we're using [Emotion](https://emotion.sh) to generate scoped class names t
It's important to note that most CSS-in-JS libraries have a runtime library, and many don't support statically extracting styles out into a separate <code>.css</code> file at build time (which is essential for the best performance). You should therefore only use CSS-in-JS if it's necessary for your application!
Note that you can mix-and-match — you can still use Svelte's built-in CSS handling alongside a CSS-in-JS library.

@ -42,7 +42,7 @@ Reducing the amount of code you have to write is an explicit goal of Svelte. To
<div class="max">
<iframe
title="Simple component example"
src="/repl/embed?gist=6b573f1819d12defc441098236fb9abe"
src="/repl/embed?example=blog-write-less-code"
scrolling="no"
></iframe>
</div>
@ -161,4 +161,4 @@ In Vue, meanwhile, we have a default export with a `data` function that returns
These are just some of the ways that Svelte helps you build user interfaces with a minimum of fuss. There are plenty of others — for example, [reactive declarations](https://svelte.dev/tutorial/reactive-declarations) essentially do the work of React's `useMemo`, `useCallback` and `useEffect` without the boilerplate (or indeed the garbage collection overhead of creating inline functions and arrays on each state change).
How? By choosing a different set of constraints. Because [Svelte is a compiler](blog/frameworks-without-the-framework), we're not bound to the peculiarities of JavaScript: we can *design* a component authoring experience, rather than having to fit it around the semantics of the language. Paradoxically, this results in *more* idiomatic code — for example using variables naturally rather than via proxies or hooks — while delivering significantly more performant apps.
How? By choosing a different set of constraints. Because [Svelte is a compiler](blog/frameworks-without-the-framework), we're not bound to the peculiarities of JavaScript: we can *design* a component authoring experience, rather than having to fit it around the semantics of the language. Paradoxically, this results in *more* idiomatic code — for example using variables naturally rather than via proxies or hooks — while delivering significantly more performant apps.

@ -600,6 +600,9 @@ A `class:` directive provides a shorter way of toggling a class on an element.
<!-- Shorthand, for when name and value match -->
<div class:active>...</div>
<!-- Multiple class toggles can be included -->
<div class:active class:inactive={!active} class:isAdmin>...</div>
```
@ -934,7 +937,7 @@ Named slots allow consumers to target specific areas. They can also have fallbac
<div>
<slot name="header">No header was provided</slot>
<p>Some content between header and footer</p>
</slot name="footer"></slot>
<slot name="footer"></slot>
</div>
```

@ -0,0 +1,10 @@
<script>
import { comicSans, link } from './styles.js';
import Hero from './Hero.html';
</script>
<Hero/>
<div class={comicSans}>
<p>Did you enjoy your lunch, mom? You drank it fast enough. I know, I just call her Annabelle cause she's shaped like a…she's the belle of the ball! YOU'RE the Chiclet! Not me. Caw ca caw, caw ca caw, caw ca caw! A Colombian cartel that WON'T kidnap and kill you. You go buy a tape recorder and record yourself for a whole day. <a class={link} href="https://bluthipsum.com/">I think you'll be surprised at some of your phrasing.</a></p>
</div>

@ -0,0 +1,15 @@
<script>
import { title, comicSans, box } from './styles.js';
</script>
<div class="{title} {comicSans}">
<h1>
<div class={box}>
<div class={box}>
<div class={box}>CSS</div>
in JS
</div>
in HTML
</div>
</h1>
</div>

@ -0,0 +1,33 @@
import { css } from 'emotion/dist/emotion.umd.min.js';
const brand = '#74D900';
export const title = css`
color: ${brand};
font-size: 1em;
white-space: nowrap;
`;
export const comicSans = css`
font-family: 'Comic Sans MS';
`;
export const box = css`
position: relative;
display: inline-block;
border: 2px solid ${brand};
line-height: 1;
padding: 4px;
border-radius: 4px;
`;
export const link = css`
color: inherit;
font-weight: bold;
text-decoration: none;
border-bottom: 1px solid ${brand};
&:hover {
text-decoration: none;
background: ${brand};
}
`;

@ -0,0 +1,9 @@
<script>
let a = 1;
let b = 2;
</script>
<input type="number" bind:value={a}>
<input type="number" bind:value={b}>
<p>{a} + {b} = {a + b}</p>

@ -31,7 +31,7 @@ The `t` value is `0` at the beginning of an intro or the end of an outro, and `1
Most of the time you should return the `css` property and *not* the `tick` property, as CSS animations run off the main thread to prevent jank where possible. Svelte 'simulates' the transition and constructs a CSS animation, then lets it run.
For example the `fade` transition generates a CSS animation somewhat like this:
For example, the `fade` transition generates a CSS animation somewhat like this:
```css
0% { opacity: 0 }
@ -69,4 +69,4 @@ We can get a lot more creative though. Let's make something truly gratuitous:
</script>
```
Remember: with great power comes great responsibility.
Remember: with great power comes great responsibility.

@ -1,6 +1,4 @@
<script>
import { onMount } from 'svelte';
export let src;
export let title;
export let composer;
@ -9,10 +7,6 @@
let audio;
let paused = true;
onMount(() => {
// TODO: register the audio element
});
function stopOthers() {
// TODO: implement stopOthers
}

@ -1,10 +1,8 @@
<script context="module">
const elements = new Set();
let current;
</script>
<script>
import { onMount } from 'svelte';
export let src;
export let title;
export let composer;
@ -13,15 +11,9 @@
let audio;
let paused = true;
onMount(() => {
elements.add(audio);
return () => elements.delete(audio);
});
function stopOthers() {
elements.forEach(element => {
if (element !== audio) element.pause();
});
if (current && current !== audio) current.pause();
current = audio;
}
</script>

@ -10,21 +10,15 @@ We can do that by declaring a `<script context="module">` block. Code contained
```html
<script context="module">
const elements = new Set();
let current;
</script>
```
It's now possible for the components to 'talk' to each other without any state management:
```js
onMount(() => {
elements.add(audio);
return () => elements.delete(audio);
});
function stopOthers() {
elements.forEach(element => {
if (element !== audio) element.pause();
});
if (current && current !== audio) current.pause();
current = audio;
}
```
```

@ -2,7 +2,7 @@
title: The @debug tag
---
Occasionally it's useful to inspect a piece of data as it flows through your app.
Occasionally, it's useful to inspect a piece of data as it flows through your app.
One approach is to use `console.log(...)` inside your markup. If you want to pause execution, though, you can use the `{@debug ...}` tag with a comma-separated list of values you want to inspect:
@ -12,4 +12,4 @@ One approach is to use `console.log(...)` inside your markup. If you want to pau
<h1>Hello {user.firstname}!</h1>
```
If you now open your devtools and start interacting with the `<input>` elements, you'll trigger the debugger as the value of `user` changes.
If you now open your devtools and start interacting with the `<input>` elements, you'll trigger the debugger as the value of `user` changes.

@ -1360,6 +1360,11 @@
}
}
},
"@polka/send": {
"version": "1.0.0-next.2",
"resolved": "https://registry.npmjs.org/@polka/send/-/send-1.0.0-next.2.tgz",
"integrity": "sha512-eq8gUzykpYPuOMrnyAzsL4KunhQXZKFiNsbThAwh19PrBAz2v8mECsj3YnxjYYifbB1w1vhR74nsXQWDi80oAg=="
},
"@polka/url": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-0.5.0.tgz",
@ -1492,11 +1497,6 @@
"integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
"dev": true
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"array-map": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
@ -1621,23 +1621,6 @@
"integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=",
"dev": true
},
"body-parser": {
"version": "1.18.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
"integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
"requires": {
"bytes": "3.0.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "~1.6.3",
"iconv-lite": "0.4.23",
"on-finished": "~2.3.0",
"qs": "6.5.2",
"raw-body": "2.3.3",
"type-is": "~1.6.16"
}
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -1922,16 +1905,6 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"content-disposition": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"convert-source-map": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
@ -2097,16 +2070,6 @@
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"optional": true
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"devalue": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-1.1.0.tgz",
@ -2135,11 +2098,6 @@
"integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==",
"dev": true
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"electron-to-chromium": {
"version": "1.3.124",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.124.tgz",
@ -2152,11 +2110,6 @@
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"end-of-stream": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
@ -2200,11 +2153,6 @@
"is-symbol": "^1.0.2"
}
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@ -2241,11 +2189,6 @@
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"dev": true
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
@ -2302,43 +2245,6 @@
}
}
},
"express": {
"version": "4.16.4",
"resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
"integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
"requires": {
"accepts": "~1.3.5",
"array-flatten": "1.1.1",
"body-parser": "1.18.3",
"content-disposition": "0.5.2",
"content-type": "~1.0.4",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.1.1",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.4",
"qs": "6.5.2",
"range-parser": "~1.2.0",
"safe-buffer": "5.1.2",
"send": "0.16.2",
"serve-static": "1.13.2",
"setprototypeof": "1.1.0",
"statuses": "~1.4.0",
"type-is": "~1.6.16",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
}
},
"express-session": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.1.tgz",
@ -2476,20 +2382,6 @@
}
}
},
"finalhandler": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.2",
"statuses": "~1.4.0",
"unpipe": "~1.0.0"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -2531,11 +2423,6 @@
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
"dev": true
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
},
"fragment-cache": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@ -2545,11 +2432,6 @@
"map-cache": "^0.2.2"
}
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"fs-extra": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
@ -3373,31 +3255,12 @@
}
}
},
"http-errors": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.0",
"statuses": ">= 1.4.0 < 2"
}
},
"http-link-header": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/http-link-header/-/http-link-header-1.0.2.tgz",
"integrity": "sha512-z6YOZ8ZEnejkcCWlGZzYXNa6i+ZaTfiTg3WhlV/YvnNya3W/RbX1bMVUMTuCrg/DrtTCQxaFCkXCz4FtLpcebg==",
"dev": true
},
"iconv-lite": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
"integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"ieee754": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
@ -3443,11 +3306,6 @@
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
"dev": true
},
"ipaddr.js": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
},
"is-accessor-descriptor": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
@ -3897,11 +3755,6 @@
"resolved": "https://registry.npmjs.org/marked/-/marked-0.6.2.tgz",
"integrity": "sha512-LqxwVH3P/rqKX4EKGz7+c2G9r98WeM/SW34ybhgNGhUQNKtf1GmmSkJ6cDGJ/t6tiyae49qRkpyTw2B9HOrgUA=="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"mem": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
@ -3919,11 +3772,6 @@
"integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
"dev": true
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"merge-stream": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
@ -3933,11 +3781,6 @@
"readable-stream": "^2.0.1"
}
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@ -3962,7 +3805,8 @@
"mime": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
"dev": true
},
"mime-db": {
"version": "1.38.0",
@ -4361,14 +4205,6 @@
"integrity": "sha1-3LcCTazVDFK00wPwSALJHAV8dl8=",
"dev": true
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
@ -4565,11 +4401,6 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"path-type": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
@ -4637,6 +4468,22 @@
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==",
"dev": true
},
"polka": {
"version": "1.0.0-next.2",
"resolved": "https://registry.npmjs.org/polka/-/polka-1.0.0-next.2.tgz",
"integrity": "sha512-y82w42/8IA7bc4YwGwAmnbrXj8ZWWDGvnfwq1b0eCtFielZSSSJv7OXUIKQuc/vw5OCCM1hPIgrYsNPzbwDaJw==",
"requires": {
"@polka/url": "^1.0.0-next.1",
"trouter": "^3.0.1"
},
"dependencies": {
"@polka/url": {
"version": "1.0.0-next.1",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.1.tgz",
"integrity": "sha512-6d8YbKW4hjJMnU6ZJSDLtALWiB4J//OIPaP885ruf5U8MLZHigocDxhjgvLwbV6bGkikhllgTjD9eWioKWAQdA=="
}
}
},
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@ -4669,15 +4516,6 @@
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
"dev": true
},
"proxy-addr": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
"integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.8.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@ -4688,32 +4526,11 @@
"once": "^1.3.1"
}
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"random-bytes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
"integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
},
"range-parser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
},
"raw-body": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
"integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
"requires": {
"bytes": "3.0.0",
"http-errors": "1.6.3",
"iconv-lite": "0.4.23",
"unpipe": "1.0.0"
}
},
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@ -4805,6 +4622,11 @@
"integrity": "sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==",
"dev": true
},
"regexparam": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/regexparam/-/regexparam-1.2.1.tgz",
"integrity": "sha512-L/xx/JNXFvejDD9b4FukSh2wCyYUpxSTnLkMpcZc/ygnmaF6ETnphh+FDKZS8XBGmu2e3GoZ1why9qkTYqr1ag=="
},
"regexpu-core": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz",
@ -5029,11 +4851,6 @@
"ret": "~0.1.10"
}
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sander": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/sander/-/sander-0.6.0.tgz",
@ -5084,43 +4901,12 @@
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true
},
"send": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.6.2",
"mime": "1.4.1",
"ms": "2.0.0",
"on-finished": "~2.3.0",
"range-parser": "~1.2.0",
"statuses": "~1.4.0"
}
},
"serialize-javascript": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz",
"integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==",
"dev": true
},
"serve-static": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.2",
"send": "0.16.2"
}
},
"session-file-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/session-file-store/-/session-file-store-1.2.0.tgz",
@ -5162,11 +4948,6 @@
}
}
},
"setprototypeof": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@ -5466,11 +5247,6 @@
}
}
},
"statuses": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
},
"string-hash": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
@ -5666,13 +5442,12 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
"dev": true
},
"type-is": {
"version": "1.6.16",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
"trouter": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/trouter/-/trouter-3.0.1.tgz",
"integrity": "sha512-9IBGrlL5bW65xhWufCCf4AsZyxGVIxv7Jy+PTwNtfPHJo+8hAp4wvt/+ersAHE//0Lgjy7obPROfgasNocoYuA==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.18"
"regexparam": "^1.2.0"
}
},
"uglify-js": {
@ -5780,11 +5555,6 @@
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"unset-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",

@ -14,10 +14,10 @@
"testsrc": "mocha -r esm test/**"
},
"dependencies": {
"@polka/send": "^1.0.0-next.2",
"codemirror": "^5.44.0",
"devalue": "^1.1.0",
"do-not-zip": "^1.0.0",
"express": "^4.16.4",
"express-session": "^1.15.6",
"golden-fleece": "^1.0.9",
"limax": "^1.7.0",
@ -25,6 +25,7 @@
"node-fetch": "^2.3.0",
"passport": "^0.4.0",
"passport-github": "^1.1.0",
"polka": "^1.0.0-next.2",
"prismjs": "^1.15.0",
"session-file-store": "^1.2.0",
"shelljs": "^0.8.3",

@ -35,12 +35,21 @@
};
});
// Prevents navbar to show/hide when clicking in docs sidebar
let hash_changed = false;
function handle_hashchange() {
hash_changed = true;
}
let last_scroll = 0;
function handle_scroll() {
const scroll = window.pageYOffset;
visible = (scroll < 50 || scroll < last_scroll);
if (!hash_changed) {
visible = (scroll < 50 || scroll < last_scroll);
}
last_scroll = scroll;
hash_changed = false;
}
</script>
@ -227,7 +236,7 @@
}
</style>
<svelte:window on:scroll={handle_scroll}/>
<svelte:window on:hashchange={handle_hashchange} on:scroll={handle_scroll} />
<header class:visible="{visible || open}">
<nav>

@ -52,6 +52,7 @@
<a target="_blank" rel="noopener" href="http://mustlab.ru"><img src="organisations/mustlab.png" alt="Mustlab logo"></a>
<a target="_blank" rel="noopener" href="https://www.nesta.org.uk"><img src="organisations/nesta.svg" alt="Nesta logo"></a>
<a target="_blank" rel="noopener" href="https://nytimes.com"><img src="organisations/nyt.svg" alt="The New York Times logo"></a>
<a target="_blank" rel="noopener" href="https://razorpay.com"><img src="organisations/razorpay.svg" alt="Razorpay logo"></a>
<a target="_blank" rel="noopener" href="https://www.stone.co"><img src="organisations/stone.svg" alt="Stone Payments logo"></a>
<a target="_blank" rel="noopener" href="https://github.com/sveltejs/svelte/blob/master/site/src/routes/_components/WhosUsingSvelte.svelte" class="add-yourself"><span>+ your company?</span></a>
</div>

@ -1,9 +1,10 @@
import send from '@polka/send';
export function get(req, res) {
if (!req.session || !req.session.passport || !req.session.passport.user) {
res.send('null');
return;
return send(res, 200, 'null');
}
const { id, username, displayName, photo } = req.session.passport && req.session.passport.user;
res.send({ id, username, displayName, photo });
}
const { id, username, displayName, photo } = req.session.passport.user;
send(res, 200, { id, username, displayName, photo });
}

@ -1,3 +1,4 @@
import send from '@polka/send';
import get_posts from './_posts.js';
let lookup;
@ -6,18 +7,16 @@ export function get(req, res) {
if (!lookup || process.env.NODE_ENV !== 'production') {
lookup = new Map();
get_posts().forEach(post => {
lookup.set(post.slug, JSON.stringify(post));
lookup.set(post.slug, post);
});
}
if (lookup.has(req.params.slug)) {
res.set({
'Content-Type': 'application/json',
'Cache-Control': `max-age=${5 * 60 * 1e3}` // 5 minutes
});
res.end(lookup.get(req.params.slug));
const post = lookup.get(req.params.slug);
if (post) {
res.setHeader('Cache-Control', `max-age=${5 * 60 * 1e3}`); // 5 minutes
send(res, 200, post);
} else {
res.statusCode = 404;
res.end(JSON.stringify({ message: 'not found' }));
send(res, 404, { message: 'not found' });
}
}
}

@ -1,3 +1,4 @@
import send from '@polka/send';
import get_posts from './_posts.js';
let json;
@ -16,9 +17,8 @@ export function get(req, res) {
json = JSON.stringify(posts);
}
res.set({
send(res, 200, json, {
'Content-Type': 'application/json',
'Cache-Control': `max-age=${5 * 60 * 1e3}` // 5 minutes
});
res.end(json);
}
}

@ -1,3 +1,4 @@
import send from '@polka/send';
import get_posts from '../blog/_posts.js';
const months = ',Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(',');
@ -34,9 +35,8 @@ const rss = `
`.replace(/>[^\S]+/gm, '>').replace(/[^\S]+</gm, '<').trim();
export function get(req, res) {
res.set({
send(res, 200, rss, {
'Cache-Control': `max-age=${30 * 60 * 1e3}`,
'Content-Type': 'application/rss+xml'
});
res.end(rss);
}

@ -52,7 +52,13 @@
transition: opacity 0.2s;
border-bottom: none;
padding: 0;
color: white;
color: var(--second);
}
@media (min-width: 832px) {
a {
color: white;
}
}
.section {

@ -58,7 +58,7 @@ export default function() {
renderer.link = link_renderer;
renderer.hr = (...args) => {
renderer.hr = () => {
block_open = true;
return '<div class="side-by-side"><div class="copy">';
@ -94,7 +94,7 @@ export default function() {
lang
);
let html = `<div class='${className}'>${prefix}<pre class='language-${plang}'><code>${highlighted}</code></pre></div>`;
const html = `<div class='${className}'>${prefix}<pre class='language-${plang}'><code>${highlighted}</code></pre></div>`;
if (block_open) {
block_open = false;

@ -1,15 +1,12 @@
import send from '@polka/send';
import get_sections from './_sections.js';
let json;
export function get(req, res) {
if (!json || process.env.NODE_ENV !== 'production') {
json = JSON.stringify(get_sections());
json = get_sections();
}
res.set({
'Content-Type': 'application/json'
});
res.end(json);
}
send(res, 200, json);
}

@ -96,16 +96,16 @@
}
aside.open {
width: calc(100vw - 1.6rem);
height: calc(100vh - var(--nav-h) - 7rem);
width: calc(100vw - 3rem);
height: calc(100vh - var(--nav-h));
}
aside.open::before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: calc(100vh - var(--nav-h) - 10.8rem);
width: 100%;
width: calc(100% - 2rem);
height: 2em;
background: linear-gradient(to top, rgba(255,255,255,0) 0%, rgba(255,255,255,0.7) 50%, rgba(255,255,255,1) 100%);
pointer-events: none;
@ -117,7 +117,7 @@
position: absolute;
left: 0;
bottom: 1.9em;
width: 100%;
width: calc(100% - 2rem);
height: 2em;
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,0.7) 50%, rgba(255,255,255,1) 100%);
pointer-events: none;
@ -127,9 +127,9 @@
position: absolute;
font-family: var(--font);
overflow-y: auto;
width: calc(100vw - 4.8rem);
height: calc(100vh - var(--nav-h) - 10.8rem);
padding: 2em 1.6rem 2em 3.2rem;
width: 100%;
height: 100%;
padding: 4em 1.6rem 2em 3.2rem;
bottom: 2em;
}

@ -1,3 +1,4 @@
import send from '@polka/send';
import { get_example } from './_examples.js';
const cache = new Map();
@ -6,20 +7,17 @@ export function get(req, res) {
const { slug } = req.params;
try {
if (!cache.has(slug) || process.env.NODE_ENV !== 'production') {
cache.set(slug, JSON.stringify(get_example(slug)));
}
let example = cache.get(slug);
res.writeHead(200, {
'Content-Type': 'application/json'
});
if (!example || process.env.NODE_ENV !== 'production') {
example = get_example(slug);
cache.set(slug, example);
}
res.end(cache.get(slug));
send(res, 200, example);
} catch (err) {
res.writeHead(404, {
'Content-Type': 'application/json'
send(res, 404, {
error: 'not found'
});
res.end(JSON.stringify({ error: 'not found' }));
}
}

@ -1,6 +1,7 @@
<script>
export let sections = [];
export let active_section = null;
export let isLoading = false;
</script>
<style>
@ -50,6 +51,12 @@
color: white;
}
a.active.loading {
background: rgba(255, 255, 255, 0.1) calc(100% - 3rem) 50% no-repeat url(/icons/loading.svg);
background-size: 1em 1em;
color: white;
}
.thumbnail {
background-color: white;
object-fit: contain;
@ -73,6 +80,7 @@
href="examples#{example.slug}"
class="row"
class:active="{example.slug === active_section}"
class:loading="{isLoading}"
>
<img
class="thumbnail"

@ -1,5 +1,4 @@
import fs from 'fs';
import path from 'path';
let lookup;
const titles = new Map();
@ -48,4 +47,4 @@ export function get_example(slug) {
});
return { title, files };
}
}

@ -1,3 +1,4 @@
import send from '@polka/send';
import { get_examples } from './_examples.js';
let cached;
@ -5,19 +6,13 @@ let cached;
export function get(req, res) {
try {
if (!cached || process.env.NODE_ENV !== 'production') {
cached = JSON.stringify(get_examples());
cached = get_examples().filter(section => section.title);
}
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(cached);
send(res, 200, cached);
} catch (e) {
res.writeHead(e.status || 500, {
'Content-Type': 'application/json'
send(res, e.status || 500, {
message: e.message
});
res.end(JSON.stringify({ message: e.message }));
}
}
}

@ -21,7 +21,7 @@
import ScreenToggle from '../../components/ScreenToggle.svelte';
import {
mapbox_setup, // needed for context API example
mapbox_setup, // see site/content/examples/15-context/00-context-api
rollupUrl,
svelteUrl
} from '../../config';
@ -36,32 +36,47 @@
let width;
let offset = 1;
let repl;
let isLoading = false;
let cache = {};
$: title = title_by_slug[active_slug] || '';
$: first_slug = sections[0].examples[0].slug;
$: if (repl) {
fetch(`examples/${active_slug}.json`)
.then(async response => {
if (response.ok) {
const data = await response.json();
repl.set({
components: process_example(data.files)
});
}
});
}
$: mobile = width < 768; // note: same as per media query below
$: replOrientation = (mobile || width > 1080) ? 'columns' : 'rows';
$: if (repl && active_slug) {
if (active_slug in cache) {
repl.set({ components: cache[active_slug] });
offset = 1;
} else {
isLoading = true;
fetch(`examples/${active_slug}.json`)
.then(async response => {
if (response.ok) {
const {files} = await response.json();
return process_example(files);
}
})
.then(components => {
cache[active_slug] = components;
repl.set({components});
offset = 1;
isLoading = false;
})
.catch(function(error) {
isLoading = false;
});
}
}
onMount(() => {
const onhashchange = () => {
active_slug = getFragment();
offset = 1;
};
window.addEventListener('hashchange', onhashchange, false);
if (getFragment()) {
active_slug = getFragment();
const fragment = getFragment();
if (fragment) {
active_slug = fragment;
} else {
active_slug = first_slug;
goto(`examples#${active_slug}`);
@ -82,17 +97,21 @@
</svelte:head>
<div class='examples-container' bind:clientWidth={width}>
<div class="viewport offset-{offset}">
<TableOfContents {sections} active_section={active_slug} />
<Repl
bind:this={repl}
{svelteUrl}
{rollupUrl}
orientation={mobile ? 'columns' : 'rows'}
fixed={mobile}
relaxed
injectedJS={mapbox_setup}
/>
<div
class="viewport offset-{offset}"
>
<TableOfContents {sections} active_section={active_slug} {isLoading} />
<div class="toc" class:loading={isLoading}>
<Repl
bind:this={repl}
{svelteUrl}
{rollupUrl}
orientation={replOrientation}
fixed={mobile}
relaxed
injectedJS={mapbox_setup}
/>
</div>
</div>
{#if mobile}
<ScreenToggle bind:offset labels={['index', 'input', 'output']}/>
@ -117,6 +136,10 @@
grid-auto-rows: 100%;
}
.toc.loading {
opacity: 0.6;
}
.offset-1 { transform: translate(-33.333%, 0); }
.offset-2 { transform: translate(-66.666%, 0); }

@ -1,5 +1,6 @@
import fetch from 'node-fetch';
import { body } from './_utils.js';
import send from '@polka/send';
export async function get(req, res) {
const { id } = req.params;
@ -14,22 +15,18 @@ export async function get(req, res) {
headers
});
res.writeHead(r.status, {
'Content-Type': 'application/json'
});
const result = await r.json();
if (r.status === 200) {
res.end(JSON.stringify({
send(res, 200, {
id: result.id,
description: result.description,
owner: result.owner,
html_url: result.html_url,
files: result.files
}));
});
} else {
res.end(JSON.stringify(result));
send(res, r.status, result);
}
}
@ -37,11 +34,7 @@ export async function patch(req, res) {
const user = req.session && req.session.passport && req.session.passport.user;
if (!user) {
res.writeHead(403, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({ error: 'unauthorized' }));
return;
return send(res, 403, { error: 'unauthorized' });
}
try {
@ -58,24 +51,16 @@ export async function patch(req, res) {
})
});
res.writeHead(r.status, {
'Content-Type': 'application/json'
});
if (r.status === 200) {
res.end(JSON.stringify({
ok: true
}));
send(res, 200, { ok: true });
} else {
res.end(await r.text());
send(res, r.status, await r.text(), {
'Content-Type': 'application/json'
});
}
} catch (err) {
res.writeHead(500, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
send(res, 500, {
error: err.message
}));
});
}
}
}

@ -1,15 +1,12 @@
import fetch from 'node-fetch';
import { body } from './_utils.js';
import send from '@polka/send';
export async function post(req, res) {
const user = req.session.passport && req.session.passport.user;
if (!user) {
res.writeHead(403, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({ error: 'unauthorized' }));
return;
return send(res, 403, { error: 'unauthorized' });
}
try {
@ -45,26 +42,18 @@ export async function post(req, res) {
})
});
res.writeHead(r.status, {
'Content-Type': 'application/json'
});
const gist = await r.json();
res.end(JSON.stringify({
send(res, r.status, {
id: gist.id,
description: gist.description,
owner: gist.owner,
html_url: gist.html_url,
files: gist.files
}));
} catch (err) {
res.writeHead(500, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
} catch (err) {
send(res, 500, {
error: err.message
}));
});
}
}

@ -2,6 +2,7 @@ import * as fs from 'fs';
import * as path from 'path';
import marked from 'marked';
import PrismJS from 'prismjs';
import send from '@polka/send';
import { extract_frontmatter, extract_metadata, langs, link_renderer } from '../../../utils/markdown';
const cache = new Map();
@ -94,20 +95,15 @@ function get_tutorial(slug) {
export function get(req, res) {
const { slug } = req.params;
if (!cache.has(slug) || process.env.NODE_ENV !== 'production') {
cache.set(slug, JSON.stringify(get_tutorial(slug)));
let tut = cache.get(slug);
if (!tut || process.env.NODE_ENV !== 'production') {
tut = get_tutorial(slug);
cache.set(slug, tut);
}
const json = cache.get(slug);
res.set({
'Content-Type': 'application/json'
});
if (json) {
res.end(json);
if (tut) {
send(res, 200, tut);
} else {
res.statusCode = 404;
res.end(JSON.stringify({ message: 'not found' }));
send(res, 404, { message: 'not found' });
}
}
}

@ -1,4 +1,5 @@
import * as fs from 'fs';
import send from '@polka/send';
import { extract_frontmatter } from '../../utils/markdown';
let json;
@ -41,7 +42,7 @@ function get_sections() {
throw new Error(`Error building tutorial ${dir}/${tutorial}: ${err.message}`);
}
})
}
};
});
return sections;
@ -50,21 +51,13 @@ function get_sections() {
export function get(req, res) {
try {
if (!json || process.env.NODE_ENV !== 'production') {
json = JSON.stringify(get_sections());
json = get_sections();
}
res.set({
'Content-Type': 'application/json'
});
res.end(json);
send(res, 200, json);
} catch (err) {
res.writeHead(500, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
send(res, 500, {
message: err.message
}));
});
}
}

@ -1,14 +1,14 @@
import 'dotenv/config';
import sirv from 'sirv';
import express from 'express';
import polka from 'polka';
import devalue from 'devalue';
import session from 'express-session';
import passport from 'passport';
import { Strategy } from 'passport-github';
import sessionFileStore from 'session-file-store';
import devalue from 'devalue';
import * as sapper from '@sapper/server';
const app = express();
const app = polka();
if (process.env.GITHUB_CLIENT_ID) {
const FileStore = sessionFileStore(session);
@ -66,7 +66,8 @@ if (process.env.GITHUB_CLIENT_ID) {
.get('/auth/callback', passport.authenticate('github', { failureRedirect: '/auth/error' }), (req, res) => {
const { id, username, displayName, photo } = req.session.passport && req.session.passport.user;
res.set({ 'Content-Type': 'text/html; charset=utf-8' });
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.end(`
<script>
window.opener.postMessage({

@ -76,7 +76,7 @@ self.addEventListener('fetch', event => {
const response = await fetch(event.request);
cache.put(event.request, response.clone());
return response;
} catch(err) {
} catch (err) {
const response = await cache.match(event.request);
if (response) return response;

@ -13,7 +13,7 @@ export function keyEvent(code) {
node.removeEventListener('keydown', handleKeydown);
}
};
}
};
}
export const enter = keyEvent(13);
export const enter = keyEvent(13);

@ -49,13 +49,13 @@ export function link_renderer (href, title, text) {
let target_attr = '';
let title_attr = '';
if(href.startsWith("http")) {
if (href.startsWith("http")) {
target_attr = ' target="_blank"';
}
if(title !== null) {
if (title !== null) {
title_attr = ` title="${title}"`;
}
return `<a href="${href}"${target_attr}${title_attr}>${text}</a>`;
};
}

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" viewBox="0 0 24 24">
<circle id="spinner" cx="12" cy="12" r="8" fill="none" stroke="white" stroke-width="3" stroke-dasharray="50.2 50" />
<animate href="#spinner" attributeName="stroke-dashoffset" values="52;0;52" dur="5s" repeatCount="indefinite" />
<animateTransform href="#spinner" attributeName="transform" type="rotate" values="0 12 12;360 12 12;0 12 12" dur="9s" repeatCount="indefinite"/>
</svg>

After

Width:  |  Height:  |  Size: 519 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="316" height="67" fill="#072654" viewBox="0 0 1896 401"><path fill="#3395FF" d="M122.63 105.7l-15.75 57.97 90.15-58.3-58.96 219.98 59.88.05L285.05.48"/><path d="M25.6 232.92L.8 325.4h122.73l50.22-188.13L25.6 232.92m426.32-81.42c-3 11.15-8.78 19.34-17.4 24.57-8.6 5.22-20.67 7.84-36.25 7.84h-49.5l17.38-64.8h49.5c15.56 0 26.25 2.6 32.05 7.9 5.8 5.3 7.2 13.4 4.22 24.6m51.25-1.4c6.3-23.4 3.7-41.4-7.82-54-11.5-12.5-31.68-18.8-60.48-18.8H324.4l-66.5 248.1h53.67l26.8-100h35.2c7.9 0 14.12 1.3 18.66 3.8 4.55 2.6 7.22 7.1 8.04 13.6l9.58 82.6h57.5l-9.32-77c-1.9-17.2-9.77-27.3-23.6-30.3 17.63-5.1 32.4-13.6 44.3-25.4a92.6 92.6 0 0 0 24.44-42.5m130.46 86.4c-4.5 16.8-11.4 29.5-20.73 38.4-9.34 8.9-20.5 13.3-33.52 13.3-13.26 0-22.25-4.3-27-13-4.76-8.7-4.92-21.3-.5-37.8 4.42-16.5 11.47-29.4 21.17-38.7 9.7-9.3 21.04-13.95 34.06-13.95 13 0 21.9 4.5 26.4 13.43 4.6 8.97 4.7 21.8.2 38.5zm23.52-87.8l-6.72 25.1c-2.9-9-8.53-16.2-16.85-21.6-8.34-5.3-18.66-8-30.97-8-15.1 0-29.6 3.9-43.5 11.7-13.9 7.8-26.1 18.8-36.5 33-10.4 14.2-18 30.3-22.9 48.4-4.8 18.2-5.8 34.1-2.9 47.9 3 13.9 9.3 24.5 19 31.9 9.8 7.5 22.3 11.2 37.6 11.2a82.4 82.4 0 0 0 35.2-7.7 82.11 82.11 0 0 0 28.4-21.2l-7 26.16h51.9L709.3 149h-52zm238.65 0H744.87l-10.55 39.4h87.82l-116.1 100.3-9.92 37h155.8l10.55-39.4h-94.1l117.88-101.8m142.4 52c-4.67 17.4-11.6 30.48-20.75 39-9.15 8.6-20.23 12.9-33.24 12.9-27.2 0-36.14-17.3-26.86-51.9 4.6-17.2 11.56-30.13 20.86-38.84 9.3-8.74 20.57-13.1 33.82-13.1 13 0 21.78 4.33 26.3 13.05 4.52 8.7 4.48 21.67-.13 38.87m30.38-80.83c-11.95-7.44-27.2-11.16-45.8-11.16-18.83 0-36.26 3.7-52.3 11.1a113.09 113.09 0 0 0-41 32.06c-11.3 13.9-19.43 30.2-24.42 48.8-4.9 18.53-5.5 34.8-1.7 48.73 3.8 13.9 11.8 24.6 23.8 32 12.1 7.46 27.5 11.17 46.4 11.17 18.6 0 35.9-3.74 51.8-11.18 15.9-7.48 29.5-18.1 40.8-32.1 11.3-13.94 19.4-30.2 24.4-48.8 5-18.6 5.6-34.84 1.8-48.8-3.8-13.9-11.7-24.6-23.6-32.05m185.1 40.8l13.3-48.1c-4.5-2.3-10.4-3.5-17.8-3.5-11.9 0-23.3 2.94-34.3 8.9-9.46 5.06-17.5 12.2-24.3 21.14l6.9-25.9-15.07.06h-37l-47.7 176.7h52.63l24.75-92.37c3.6-13.43 10.08-24 19.43-31.5 9.3-7.53 20.9-11.3 34.9-11.3 8.6 0 16.6 1.97 24.2 5.9m146.5 41.1c-4.5 16.5-11.3 29.1-20.6 37.8-9.3 8.74-20.5 13.1-33.5 13.1s-21.9-4.4-26.6-13.2c-4.8-8.85-4.9-21.6-.4-38.36 4.5-16.75 11.4-29.6 20.9-38.5 9.5-8.97 20.7-13.45 33.7-13.45 12.8 0 21.4 4.6 26 13.9 4.6 9.3 4.7 22.2.28 38.7m36.8-81.4c-9.75-7.8-22.2-11.7-37.3-11.7-13.23 0-25.84 3-37.8 9.06-11.95 6.05-21.65 14.3-29.1 24.74l.18-1.2 8.83-28.1h-51.4l-13.1 48.9-.4 1.7-54 201.44h52.7l27.2-101.4c2.7 9.02 8.2 16.1 16.6 21.22 8.4 5.1 18.77 7.63 31.1 7.63 15.3 0 29.9-3.7 43.75-11.1 13.9-7.42 25.9-18.1 36.1-31.9 10.2-13.8 17.77-29.8 22.6-47.9 4.9-18.13 5.9-34.3 3.1-48.45-2.85-14.17-9.16-25.14-18.9-32.9m174.65 80.65c-4.5 16.7-11.4 29.5-20.7 38.3-9.3 8.86-20.5 13.27-33.5 13.27-13.3 0-22.3-4.3-27-13-4.8-8.7-4.9-21.3-.5-37.8 4.4-16.5 11.42-29.4 21.12-38.7 9.7-9.3 21.05-13.94 34.07-13.94 13 0 21.8 4.5 26.4 13.4 4.6 8.93 4.63 21.76.15 38.5zm23.5-87.85l-6.73 25.1c-2.9-9.05-8.5-16.25-16.8-21.6-8.4-5.34-18.7-8-31-8-15.1 0-29.68 3.9-43.6 11.7-13.9 7.8-26.1 18.74-36.5 32.9-10.4 14.16-18 30.3-22.9 48.4-4.85 18.17-5.8 34.1-2.9 47.96 2.93 13.8 9.24 24.46 19 31.9 9.74 7.4 22.3 11.14 37.6 11.14 12.3 0 24.05-2.56 35.2-7.7a82.3 82.3 0 0 0 28.33-21.23l-7 26.18h51.9l47.38-176.7h-51.9zm269.87.06l.03-.05h-31.9c-1.02 0-1.92.05-2.85.07h-16.55l-8.5 11.8-2.1 2.8-.9 1.4-67.25 93.68-13.9-109.7h-55.08l27.9 166.7-61.6 85.3h54.9l14.9-21.13c.42-.62.8-1.14 1.3-1.8l17.4-24.7.5-.7 77.93-110.5 65.7-93 .1-.06h-.03z"/></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -1002,9 +1002,11 @@ export default class Component {
if (walking.has(other_declaration)) {
hoistable = false;
} else if (other_declaration.type === 'ExportNamedDeclaration' && walking.has(other_declaration.declaration)) {
hoistable = false;
} else if (!is_hoistable(other_declaration)) {
hoistable = false;
}
}
}
else {

@ -111,7 +111,7 @@ export default class BindingWrapper {
let update_conditions: string[] = this.needs_lock ? [`!${lock}`] : [];
const dependency_array = [...this.node.expression.dependencies]
const dependency_array = [...this.node.expression.dependencies];
if (dependency_array.length === 1) {
update_conditions.push(`changed.${dependency_array[0]}`)
@ -121,6 +121,14 @@ export default class BindingWrapper {
)
}
if (parent.node.name === 'input') {
const type = parent.node.get_static_attribute_value('type');
if (type === null || type === "" || type === "text") {
update_conditions.push(`(${parent.var}.${this.node.name} !== ${this.snippet})`)
}
}
// model to view
let update_dom = get_dom_updater(parent, this);

@ -106,7 +106,7 @@ export function extract_names(param: Node) {
export function extract_identifiers(param: Node) {
const nodes: Node[] = [];
extractors[param.type](nodes, param);
extractors[param.type] && extractors[param.type](nodes, param);
return nodes;
}

@ -4,21 +4,22 @@ import { set_current_component } from './lifecycle.js';
export const dirty_components = [];
export const intros = { enabled: false };
let update_promise;
const resolved_promise = Promise.resolve();
let update_scheduled = false;
const binding_callbacks = [];
const render_callbacks = [];
const flush_callbacks = [];
export function schedule_update() {
if (!update_promise) {
update_promise = Promise.resolve();
update_promise.then(flush);
if (!update_scheduled) {
update_scheduled = true;
resolved_promise.then(flush);
}
}
export function tick() {
schedule_update();
return update_promise;
return resolved_promise;
}
export function add_binding_callback(fn) {
@ -65,7 +66,7 @@ export function flush() {
flush_callbacks.pop()();
}
update_promise = null;
update_scheduled = false;
}
function update($$) {
@ -77,4 +78,4 @@ function update($$) {
$$.after_render.forEach(add_render_callback);
}
}
}

@ -31,7 +31,7 @@ export default {
const select = target.querySelector('select');
const options = [...target.querySelectorAll('option')];
assert.deepEqual(options, select.options);
assert.deepEqual(options, [...select.options]);
assert.equal(component.selected, 'one');
const change = new window.Event('change');

@ -0,0 +1,3 @@
export default {
html: 'Compile plz'
}

@ -0,0 +1,11 @@
<script>
export function one () {
two()
}
export function two () {
return one()
}
</script>
Compile plz

@ -0,0 +1,3 @@
export default {
html: `{"bar":42}`
};

@ -0,0 +1,7 @@
<script>
let foo = {};
let bar = 42;
$: foo.bar = bar;
</script>
{JSON.stringify(foo)}

@ -11,8 +11,8 @@
}
</script>
{#each [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as number}
{#each [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as number}
{#if threshold >= number}
<div transition:foo>{number}</div>
{/if}
{/each}
{/each}

Loading…
Cancel
Save