merge master -> leporo-master

pull/2996/head
Richard Harris 6 years ago
commit 8bff4517b5

@ -1,7 +1,3 @@
src/shared
shared.js
store.js
test/test.js
test/setup.js
**/_actual.js
**/expected.js
**/expected.js
test/*/samples/*/output.js

@ -1,44 +1,76 @@
{
"root": true,
"rules": {
"indent": [2, "tab", { "SwitchCase": 1 }],
"semi": [2, "always"],
"keyword-spacing": [2, { "before": true, "after": true }],
"space-before-blocks": [2, "always"],
"no-mixed-spaces-and-tabs": [2, "smart-tabs"],
"no-cond-assign": 0,
"no-unused-vars": 2,
"object-shorthand": [2, "always"],
"no-const-assign": 2,
"no-class-assign": 2,
"no-this-before-super": 2,
"no-var": 2,
"no-unreachable": 2,
"valid-typeof": 2,
"quote-props": [2, "as-needed"],
"one-var": [2, "never"],
"prefer-arrow-callback": 2,
"prefer-const": [2, { "destructuring": "all" }],
"arrow-spacing": 2,
"no-inner-declarations": 0
},
"env": {
"es6": true,
"browser": true,
"node": true,
"mocha": true
},
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings"
],
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module"
},
"settings": {
"import/core-modules": ["svelte"],
"svelte3/extensions": ["html"]
}
"root": true,
"rules": {
"indent": "off",
"no-unused-vars": "off",
"semi": [2, "always"],
"keyword-spacing": [2, { "before": true, "after": true }],
"space-before-blocks": [2, "always"],
"no-mixed-spaces-and-tabs": [2, "smart-tabs"],
"no-cond-assign": 0,
"object-shorthand": [2, "always"],
"no-const-assign": 2,
"no-class-assign": 2,
"no-this-before-super": 2,
"no-var": 2,
"no-unreachable": 2,
"valid-typeof": 2,
"quote-props": [2, "as-needed"],
"one-var": [2, "never"],
"prefer-arrow-callback": 2,
"prefer-const": [2, { "destructuring": "all" }],
"arrow-spacing": 2,
"no-inner-declarations": 0,
"@typescript-eslint/indent": ["error", "tab", {
"SwitchCase": 1,
"ignoredNodes": ["TemplateLiteral"]
}],
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/array-type": ["error", "array-simple"],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-member-accessibility": "off",
"@typescript-eslint/no-unused-vars": ["error", {
"argsIgnorePattern": "^_"
}],
"@typescript-eslint/no-object-literal-type-assertion": ["error", {
"allowAsParameter": true
}],
"@typescript-eslint/no-unused-vars": "off"
},
"env": {
"es6": true,
"browser": true,
"node": true,
"mocha": true
},
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module"
},
"settings": {
"import/core-modules": [
"svelte",
"svelte/internal",
"svelte/store",
"svelte/easing",
"estree"
]
},
"overrides": [
{
"files": ["*.js"],
"rules": {
"@typescript-eslint/no-var-requires": "off"
}
}
]
}

@ -1,5 +1,5 @@
[ignore]
<PROJECT_ROOT>/dist/.*
<PROJECT_ROOT>/types/.*
[include]

1
.gitattributes vendored

@ -0,0 +1 @@
*.svelte linguist-language=HTML

@ -3,7 +3,7 @@ Thanks for raising an issue! (For *questions*, we recommend instead using https:
To help us help you, if you've found a bug please consider the following:
* If you can demonstrate the bug using https://svelte.technology/repl, please do.
* If you can demonstrate the bug using https://svelte.dev/repl, please do.
* If that's not possible, we recommend creating a small repo that illustrates the problem.
* Make sure you include information about the browser, and which version of Svelte you're using

21
.gitignore vendored

@ -1,16 +1,17 @@
.idea
.DS_Store
.nyc_output
node_modules
*.map
/src/compile/internal-exports.ts
/compiler.js
/index.js
/internal.*
/store.js
/easing.js
/motion.*
/transition.js
/animate.js
/src/compiler/compile/internal-exports.ts
/compiler.*js
/index.*js
/internal
/store
/easing
/motion
/transition
/animate
/scratch/
/coverage/
/coverage.lcov/
@ -20,6 +21,7 @@ node_modules
/test/sourcemaps/samples/*/output.css.map
/yarn-error.log
_actual*.*
/types
/site/cypress/screenshots/
/site/__sapper__/
@ -27,5 +29,6 @@ _actual*.*
/site/.sessions
/site/static/svelte-app.json
/site/static/contributors.jpg
/site/static/workers
/site/scripts/svelte-app
/site/src/routes/_contributors.js

@ -1,7 +1,8 @@
language: node_js
node_js:
- "node"
- "8"
- "10"
- "12"
env:
global:
- BUILD_TIMEOUT=20000

@ -1,5 +1,114 @@
# Svelte changelog
## 3.5.1
* Accommodate webpack idiosyncracies
## 3.5.0
* Update package folder structure ([#2887](https://github.com/sveltejs/svelte/pull/2887))
* Support `once` modifier on component events ([#2654](https://github.com/sveltejs/svelte/issues/2654))
* Allow empty `<title>` tags ([#2980](https://github.com/sveltejs/svelte/issues/2980))
* Render textarea binding values inside element ([#2975](https://github.com/sveltejs/svelte/pull/2975))
* Fix delayed animation glitch ([#2871](https://github.com/sveltejs/svelte/issues/2871))
* Solve diamond dependencies problem with stores ([#2660](https://github.com/sveltejs/svelte/issues/2660))
* Fix missing outros inside each blocks ([#2689](https://github.com/sveltejs/svelte/issues/2689))
* Support animations without transitions ([#2908](https://github.com/sveltejs/svelte/issues/2908))
* Add missing transition events ([#2912](https://github.com/sveltejs/svelte/pull/2912))
## 3.4.4
* Publish type declaration files ([#2874](https://github.com/sveltejs/svelte/issues/2874))
* Don't trigger updates for unreferenced values ([#2865](https://github.com/sveltejs/svelte/pull/2865))
* Omit readonly bindings from SSR output ([#2339](https://github.com/sveltejs/svelte/issues/2339))
* Prevent outdated animation CSS ([#2871](https://github.com/sveltejs/svelte/issues/2871))
* Repair dynamic `{@html ...}` in head ([#2880](https://github.com/sveltejs/svelte/pull/2880))
* Don't create unknown prop warnings for internal props, or if component has `$$props` ([#2881](https://github.com/sveltejs/svelte/pull/2881))
## 3.4.3
* Add type declaration files for everything ([#2842](https://github.com/sveltejs/svelte/pull/2842))
* Prevent `svelte/store` being bundled ([#2786](https://github.com/sveltejs/svelte/issues/2786))
* Warn on unknown props in dev mode ([#2840](https://github.com/sveltejs/svelte/pull/2840))
* Treat `requestAnimationFrame` as a no-op on the server ([#2856](https://github.com/sveltejs/svelte/pull/2856))
* Add `raw` property to AST's `Text` nodes ([#2714](https://github.com/sveltejs/svelte/issues/2714))
* Add `<details bind:open>` ([#2854](https://github.com/sveltejs/svelte/issues/2854))
## 3.4.2
* Use empty string for empty data attributes ([#2804](https://github.com/sveltejs/svelte/pull/2804))
* Support `customElement: true` with no `<svelte:options>` ([#2821](https://github.com/sveltejs/svelte/issues/2821))
* Add docstrings to `svelte/store` ([#2795](https://github.com/sveltejs/svelte/pull/2795))
## 3.4.1
* Handle non-falsy non-function return values from derivers ([#2780](https://github.com/sveltejs/svelte/issues/2780))
* Allow `spring` to work server-side ([#2773](https://github.com/sveltejs/svelte/issues/2773))
## 3.4.0
* Allow custom element to be defined without a `tag` ([#2417](https://github.com/sveltejs/svelte/issues/2417))
* Fix parsing of quote marks inside attribute values ([#2715](https://github.com/sveltejs/svelte/pull/2754))
* Convert `svelte/store` to TypeScript ([#2733](https://github.com/sveltejs/svelte/pull/2733))
* Allow `debug` tags to include hoisted values ([#2764](https://github.com/sveltejs/svelte/issues/2764))
* Parse error if attribute name is missing `=` ([#1513](https://github.com/sveltejs/svelte/pull/2770))
* Allow reactive declarations to depend on mutated `const` values ([#2728](https://github.com/sveltejs/svelte/issues/2728))
## 3.3.0
* Allow multiple event listeners on a single node ([#2688](https://github.com/sveltejs/svelte/issues/2688))
* Allow derivers to return a cleanup function ([#2553](https://github.com/sveltejs/svelte/issues/2553))
* Support namespaced components (`<Foo.Bar/>`) ([#2743](https://github.com/sveltejs/svelte/pull/2743))
## 3.2.2
* Add `window` and `document` to expected globals ([#2722](https://github.com/sveltejs/svelte/pull/2722))
* Prevent hoisting of functions that depend on reactive state ([#2703](https://github.com/sveltejs/svelte/pull/2703))
* Generate correct code when slot has no changes ([#2697](https://github.com/sveltejs/svelte/issues/2697))
* Prevent `Object.prototype`-related bugs ([#2696](https://github.com/sveltejs/svelte/pull/2696))
## 3.2.1
* Use same comparison logic for `derived` as for other stores ([#2644](https://github.com/sveltejs/svelte/issues/2644))
* Invalidate dependencies of reactive declarations ([#2444](https://github.com/sveltejs/svelte/issues/2444))
* Fix instrumentation of auto-subscription self-assignments ([#2681](https://github.com/sveltejs/svelte/issues/2681))
* Warn on non-top-level or module-context statements labeled with `$:` ([#2176](https://github.com/sveltejs/svelte/issues/2176))
## 3.2.0
* Improve `spring` animations, and add `hard`/`soft` options ([#2627](https://github.com/sveltejs/svelte/pull/2627))
* Expose `parse` and `walk` functions ([#2661](https://github.com/sveltejs/svelte/issues/2661), [#2534](https://github.com/sveltejs/svelte/pull/2534))
* Support array/object rest in `each` block destructuring patterns ([#2647](https://github.com/sveltejs/svelte/issues/2647), [#2658](https://github.com/sveltejs/svelte/pull/2658))
* Use `setAttribute` to change `form` property on form elements ([#1742](https://github.com/sveltejs/svelte/issues/1742))
* Fix a11y warning when `<figcaption>` is non-direct descendant of `<figure>` ([#2582](https://github.com/sveltejs/svelte/issues/2582))
* Squelch erroneous 'empty block' warnings ([#1716](https://github.com/sveltejs/svelte/issues/1716))
* Fix IE9/10 error with `insertBefore` ([#2573](https://github.com/sveltejs/svelte/issues/2573))
* Prevent `$$scope` from being spread onto an element ([#2520](https://github.com/sveltejs/svelte/issues/2520))
* Resubscribe to stores that are assigned to in `<script>` ([#2435](https://github.com/sveltejs/svelte/issues/2435))
* Allow reactive declarations to depend on `const` variables ([#2285](https://github.com/sveltejs/svelte/issues/2285))
* Trigger store changes on UpdateExpression ([#2625](https://github.com/sveltejs/svelte/issues/2625))
* Squelch missing prop warning if variable is initialised ([#2635](https://github.com/sveltejs/svelte/issues/2635))
* Add `alert`, `confirm` and `prompt` to known globals ([#2648](https://github.com/sveltejs/svelte/issues/2648))
## 3.1.0
* Allow store subscribe functions to return an object with an `unsubscribe` method, providing native RxJS support ([#2549](https://github.com/sveltejs/svelte/issues/2549))
## 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
## 2.15.4
* IE `classList` fix ([#1868](https://github.com/sveltejs/svelte/pull/1868))
@ -312,7 +421,7 @@
## 2.0.0
*See [the blog post](https://svelte.technology/blog/version-2) for information on how to upgrade your apps*
*See [the blog post](https://svelte.dev/blog/version-2) for information on how to upgrade your apps*
* New template syntax ([#1318](https://github.com/sveltejs/svelte/issues/1318))
* Emit ES2015 code, not ES5 ([#1348](https://github.com/sveltejs/svelte/pull/1348))

@ -1,4 +1,4 @@
Copyright (c) 2016 [these people](https://github.com/sveltejs/svelte/graphs/contributors)
Copyright (c) 2016-19 [these people](https://github.com/sveltejs/svelte/graphs/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

@ -1,151 +1,33 @@
# Svelte
<p>
<a href="https://svelte.dev">
<img alt="Cybernetically enhanced web apps: Svelte" src="https://svelte-assets.surge.sh/banner.png">
</a>
The magical disappearing UI framework.
<a href="https://www.npmjs.com/package/svelte">
<img src="https://img.shields.io/npm/v/svelte.svg" alt="npm version">
</a>
* [Read the introductory blog post](https://svelte.technology/blog/frameworks-without-the-framework)
* [Read the guide](https://svelte.technology/guide)
* [Try it out](https://svelte.technology/repl)
* [Chat on Discord](https://discord.gg/yy75DKs)
<a href="https://packagephobia.now.sh/result?p=svelte">
<img src="https://packagephobia.now.sh/badge?p=svelte" alt="install size">
</a>
---
<a href="https://travis-ci.org/sveltejs/svelte">
<img src="https://api.travis-ci.org/sveltejs/svelte.svg?branch=master"
alt="build status">
</a>
## Tooling
<a href="https://github.com/sveltejs/svelte/blob/master/LICENSE">
<img src="https://img.shields.io/npm/l/svelte.svg" alt="license">
</a>
</p>
This is the Svelte compiler, which is primarily intended for authors of tooling that integrates Svelte with different build systems. If you just want to write Svelte components and use them in your app, you probably want one of those tools:
### Build Systems
## What is Svelte?
* [gulp-svelte](https://github.com/shinnn/gulp-svelte) - gulp plugin
* [metalsmith-svelte](https://github.com/shinnn/metalsmith-svelte) - Metalsmith plugin
* [system-svelte](https://github.com/CanopyTax/system-svelte)  System.js loader
* [svelte-loader](https://github.com/sveltejs/svelte-loader) Webpack loader
* [meteor-svelte](https://github.com/klaussner/meteor-svelte) Meteor build plugin
* [sveltejs-brunch](https://github.com/StarpTech/sveltejs-brunch) Brunch build plugin
* [rollup-plugin-svelte](https://github.com/rollup/rollup-plugin-svelte) Rollup plugin
* [parcel-plugin-svelte](https://github.com/DeMoorJasper/parcel-plugin-svelte) - Parcel build plugin
* [sveltify](https://github.com/tehshrike/sveltify) - Browserify transform
* [rules_svelte](https://github.com/thelgevold/rules_svelte) - Bazel Rules
Svelte is a new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient JavaScript that surgically updates the DOM.
### CSS Preprocessors
Learn more at the [Svelte website](https://svelte.dev), or stop by the [Discord chatroom](https://svelte.dev/chat).
* [Less](https://github.com/ls-age/svelte-preprocess-less)
* [modular-css](https://github.com/tivac/modular-css/tree/master/packages/svelte)
* [PostCSS](https://github.com/TehShrike/svelte-preprocess-postcss)
* [Sass](https://github.com/ls-age/svelte-preprocess-sass)
### Additional tools
* [svelte-dev-store](https://github.com/GarethOates/svelte-dev-store) - Use Redux tools to visualise Svelte store
* More to come!
## Example usage
```js
import * as svelte from 'svelte';
const { js, css, ast } = svelte.compile(source, {
// the target module format defaults to 'es' (ES2015 modules), can
// also be 'amd', 'cjs', 'umd', 'iife' or 'eval'
format: 'umd',
// the filename of the source file, used in e.g. generating sourcemaps
filename: 'MyComponent.html',
// the name of the constructor. Required for 'iife' and 'umd' output,
// but otherwise mostly useful for debugging. Defaults to 'SvelteComponent'
name: 'MyComponent',
// for 'amd' and 'umd' output, you can optionally specify an AMD module ID
amd: {
id: 'my-component'
},
// custom error/warning handlers. By default, errors will throw, and
// warnings will be printed to the console. Where applicable, the
// error/warning object will have `pos`, `loc` and `frame` properties
onerror: err => {
console.error( err.message );
},
onwarn: warning => {
console.warn( warning.message );
}
});
```
## API
The Svelte compiler exposes the following API:
* `compile(source [, options]) => { js, css, ast }` - Compile the component with the given options (see below). Returns an object containing the compiled JavaScript, a sourcemap, an AST and transformed CSS.
* `create(source [, options]) => function` - Compile the component and return the component itself.
* `preprocess(source, options) => Promise` — Preprocess a source file, e.g. to use PostCSS or CoffeeScript
* `VERSION` - The version of this copy of the Svelte compiler as a string, `'x.x.x'`.
### Compiler options
The Svelte compiler optionally takes a second argument, an object of configuration options:
| | **Values** | **Description** | **Default** |
|---|---|---|---|
| `generate` | `'dom'`, `'ssr'`, `false` | Whether to generate JavaScript code intended for use on the client (`'dom'`), or for use in server-side rendering (`'ssr'`). If `false`, component will be parsed and validated but no code will be emitted | `'dom'` |
| `dev` | `true`, `false` | Whether to enable run-time checks in the compiled component. These are helpful during development, but slow your component down. | `false` |
| `css` | `true`, `false` | Whether to include code to inject your component's styles into the DOM. | `true` |
| `hydratable` | `true`, `false` | Whether to support hydration on the compiled component. | `false` |
| `customElement` | `true`, `false`, `{ tag, props }` | Whether to compile this component to a custom element. If `tag`/`props` are passed, compiles to a custom element and overrides the values exported by the component. | `false` |
| `bind` | `boolean` | If `false`, disallows `bind:` directives | `true` |
| | | |
| `shared` | `true`, `false`, `string` | Whether to import various helpers from a shared external library. When you have a project with multiple components, this reduces the overall size of your JavaScript bundle, at the expense of having immediately-usable component. You can pass a string of the module path to use, or `true` will import from `'svelte/shared.js'`. | `false` |
| `legacy` | `true`, `false` | Ensures compatibility with very old browsers, at the cost of some extra code. | `false` |
| | | |
| `format` | `'es'`, `'amd'`, `'cjs'`, `'umd'`, `'iife'`, `'eval'` | The format to output in the compiled component.<br>`'es'` - ES6/ES2015 module, suitable for consumption by a bundler<br>`'amd'` - AMD module<br>`'cjs'` - CommonJS module<br>`'umd'` - UMD module<br>`'iife'` - IIFE-wrapped function defining a global variable, suitable for use directly in browser<br>`'eval'` - standalone function, suitable for passing to `eval()` | `'es'` for `generate: 'dom'`<br>`'cjs'` for `generate: 'ssr'` |
| `name` | `string` | The name of the constructor in the compiled component. | `'SvelteComponent'` |
| `filename` | `string` | The filename to use in sourcemaps and compiler error and warning messages. | `'SvelteComponent.html'` |
| `amd`.`id` | `string` | The AMD module ID to use for the `'amd'` and `'umd'` output formats. | `undefined` |
| `globals` | `object`, `function` | When outputting to the `'umd'`, `'iife'` or `'eval'` formats, an object or function mapping the names of imported dependencies to the names of global variables. | `{}` |
| `preserveComments` | `boolean` | Include comments in rendering. Currently, only applies to SSR rendering | `false` |
| | | |
| `onwarn` | `function` | Specify a callback for when Svelte encounters a non-fatal warning while compiling the component. Passed two arguments: the warning object, and another function that is Svelte's default onwarn handling. | (warning is logged to console) |
### Preprocessor options
`svelte.preprocess` returns a Promise that resolves to an object with a `toString` method (other properties will be added in future). It takes an options object with `markup`, `style` or `script` properties:
```js
const processed = await svelte.preprocess(source, {
markup: ({ content }) => {
// `content` is the entire component string
return { code: '...', map: {...} };
},
style: ({ content, attributes }) => {
// `content` is what's inside the <style> element, if present
// `attributes` is a map of attributes on the element
if (attributes.type !== 'text/scss') return;
return { code: '...', map: {...} };
},
script: ({ content, attributes }) => {
// `content` is what's inside the <script> element, if present
// `attributes` is a map of attributes on the element
if (attributes.type !== 'text/coffeescript') return;
return { code: '...', map: {...} };
}
});
```
The `style` and `script` preprocessors will run *after* the `markup` preprocessor. Each preprocessor can return a) nothing (in which case no transformation takes place), b) a `{ code, map }` object, or c) a Promise that resolves to a) or b). Note that sourcemaps are currently discarded, but will be used in future versions of Svelte.
## Example/starter repos
* [sveltejs/template](https://github.com/sveltejs/template) — the 'official' starter template
* [sveltejs/template-webpack](https://github.com/sveltejs/template-webpack) — using webpack for bundling
* [charpeni/svelte-example](https://github.com/charpeni/svelte-example) - Some Svelte examples with configured Rollup, Babel, ESLint, directives, Two-Way binding, and nested components
* [EmilTholin/svelte-test](https://github.com/EmilTholin/svelte-test)
* [lukechinworth/codenames](https://github.com/lukechinworth/codenames/tree/svelte)  example integration with Redux
* [khtdr/svelte-redux-shopping-cart](https://github.com/khtdr/svelte-redux-shopping-cart) Redux Shopping Cart example (with devtools and hot-reloading)
* [svelte-bazel-example](https://github.com/thelgevold/svelte-bazel-example) — Building Svelte with Bazel
## Development
@ -154,46 +36,49 @@ Pull requests are encouraged and always welcome. [Pick an issue](https://github.
To install and work on Svelte locally:
```bash
git clone git@github.com:sveltejs/svelte.git
git clone https://github.com/sveltejs/svelte.git
cd svelte
npm install
npm run dev
```
The compiler is written in [TypeScript](https://www.typescriptlang.org/), but don't let that put you off — it's basically just JavaScript with type annotations. You'll pick it up in no time. If you're using an editor other than [VSCode](https://code.visualstudio.com/) you may need to install a plugin in order to get syntax highlighting and code hints etc.
### Linking to a Live Project
To build the compiler, and all the other modules included in the package:
You can make changes locally to Svelte and test it against any Svelte project. You can also use a [default template](https://github.com/sveltejs/template) for development. Instruction on setup are found in that project repository.
```bash
npm run build
```
From your project:
To watch for changes and continually rebuild the package (this is useful if you're using [npm link](https://docs.npmjs.com/cli/link.html) to test out changes in a project locally):
```bash
cd ~/path/to/your-svelte-project
npm install ~/path/to/svelte
npm run dev
```
And you should be good to test changes locally.
The compiler is written in [TypeScript](https://www.typescriptlang.org/), but don't let that put you off — it's basically just JavaScript with type annotations. You'll pick it up in no time. If you're using an editor other than [Visual Studio Code](https://code.visualstudio.com/) you may need to install a plugin in order to get syntax highlighting and code hints etc.
To undo this and link to the official latest Svelte release, just run:
### Running Tests
```bash
npm install svelte@latest
npm run test
```
### Running Tests
To filter tests, use `-g` (aka `--grep`). For example, to only run tests involving transitions:
```bash
npm run test
npm run test -- -g transition
```
For running single tests, you can use pattern matching:
## 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.dev). To develop locally:
```bash
npm run test -- -g "includes AST in svelte.compile output"
cd site
npm install && npm run update
npm run dev
```
Alternately, you can add `solo: true` to any given `test/../_config.js` file, but **remember never to commit that setting.**
## License

@ -1,25 +0,0 @@
import { cubicOut } from './easing';
import { is_function } from './internal';
export function flip(node, animation, params) {
const style = getComputedStyle(node);
const transform = style.transform === 'none' ? '' : style.transform;
const dx = animation.from.left - animation.to.left;
const dy = animation.from.top - animation.to.top;
const d = Math.sqrt(dx * dx + dy * dy);
const {
delay = 0,
duration = d => Math.sqrt(d) * 120,
easing = cubicOut
} = params;
return {
delay,
duration: is_function(duration) ? duration(d) : duration,
easing,
css: (t, u) => `transform: ${transform} translate(${u * dx}px, ${u * dy}px);`
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

1
compiler.d.ts vendored

@ -0,0 +1 @@
export * from './types/compiler';

567
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.0.0-beta.25",
"version": "3.4.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -64,6 +64,60 @@
"integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
"dev": true
},
"@typescript-eslint/eslint-plugin": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.9.0.tgz",
"integrity": "sha512-FOgfBorxjlBGpDIw+0LaZIXRX6GEEUfzj8LXwaQIUCp+gDOvkI+1WgugJ7SmWiISqK9Vj5r8S7NDKO/LB+6X9A==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "1.9.0",
"@typescript-eslint/parser": "1.9.0",
"eslint-utils": "^1.3.1",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^2.0.1",
"requireindex": "^1.2.0",
"tsutils": "^3.7.0"
}
},
"@typescript-eslint/experimental-utils": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.9.0.tgz",
"integrity": "sha512-1s2dY9XxBwtS9IlSnRIlzqILPyeMly5tz1bfAmQ84Ul687xBBve5YsH5A5EKeIcGurYYqY2w6RkHETXIwnwV0A==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "1.9.0"
}
},
"@typescript-eslint/parser": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.9.0.tgz",
"integrity": "sha512-CWgC1XrQ34H/+LwAU7vY5xteZDkNqeAkeidEpJnJgkKu0yqQ3ZhQ7S+dI6MX4vmmM1TKRbOrKuXc6W0fIHhdbA==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "1.9.0",
"@typescript-eslint/typescript-estree": "1.9.0",
"eslint-scope": "^4.0.0",
"eslint-visitor-keys": "^1.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.9.0.tgz",
"integrity": "sha512-7Eg0TEQpCkTsEwsl1lIzd6i7L3pJLQFWesV08dS87bNz0NeSjbL78gNAP1xCKaCejkds4PhpLnZkaAjx9SU8OA==",
"dev": true,
"requires": {
"lodash.unescape": "4.0.1",
"semver": "5.5.0"
},
"dependencies": {
"semver": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
"dev": true
}
}
},
"abab": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz",
@ -148,9 +202,9 @@
}
},
"ansi-escapes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
"integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
"integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
"dev": true
},
"ansi-regex": {
@ -213,6 +267,16 @@
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
"dev": true
},
"array-includes": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
"integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.7.0"
}
},
"arrify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
@ -246,15 +310,6 @@
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true
},
"async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
"integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
"dev": true,
"requires": {
"lodash": "^4.17.11"
}
},
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
@ -493,9 +548,9 @@
}
},
"callsites": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz",
"integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
"caseless": {
@ -521,12 +576,6 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
"circular-json": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
"integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
"dev": true
},
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@ -808,6 +857,15 @@
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"dev": true,
"requires": {
"object-keys": "^1.0.12"
}
},
"define-property": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
@ -874,38 +932,14 @@
"dev": true
},
"doctrine": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
"integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
"requires": {
"esutils": "^2.0.2"
}
},
"dom-serializer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
"integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
"dev": true,
"requires": {
"domelementtype": "~1.1.1",
"entities": "~1.1.1"
},
"dependencies": {
"domelementtype": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
"dev": true
}
}
},
"domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
"dev": true
},
"domexception": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
@ -915,25 +949,6 @@
"webidl-conversions": "^4.0.2"
}
},
"domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
"dev": true,
"requires": {
"domelementtype": "1"
}
},
"domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
"dev": true,
"requires": {
"dom-serializer": "0",
"domelementtype": "1"
}
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@ -944,6 +959,12 @@
"safer-buffer": "^2.1.0"
}
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"end-of-stream": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
@ -953,12 +974,6 @@
"once": "^1.4.0"
}
},
"entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
"dev": true
},
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@ -968,6 +983,31 @@
"is-arrayish": "^0.2.1"
}
},
"es-abstract": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
"integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.0",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-keys": "^1.0.12"
}
},
"es-to-primitive": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"dev": true,
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
}
},
"es6-promise": {
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz",
@ -1011,48 +1051,61 @@
}
},
"eslint": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.12.1.tgz",
"integrity": "sha512-54NV+JkTpTu0d8+UYSA8mMKAG4XAsaOrozA9rCW7tgneg1mevcL7wIotPC+fZ0SkWwdhNqoXoxnQCTBp7UvTsg==",
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
"integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.5.3",
"ajv": "^6.9.1",
"chalk": "^2.1.0",
"cross-spawn": "^6.0.5",
"debug": "^4.0.1",
"doctrine": "^2.1.0",
"eslint-scope": "^4.0.0",
"doctrine": "^3.0.0",
"eslint-scope": "^4.0.3",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^5.0.0",
"espree": "^5.0.1",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^2.0.0",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob": "^7.1.2",
"globals": "^11.7.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"inquirer": "^6.1.0",
"js-yaml": "^3.12.0",
"inquirer": "^6.2.2",
"js-yaml": "^3.13.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.3.0",
"lodash": "^4.17.5",
"lodash": "^4.17.11",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"natural-compare": "^1.4.0",
"optionator": "^0.8.2",
"path-is-inside": "^1.0.2",
"pluralize": "^7.0.0",
"progress": "^2.0.0",
"regexpp": "^2.0.1",
"semver": "^5.5.1",
"strip-ansi": "^4.0.0",
"strip-json-comments": "^2.0.1",
"table": "^5.0.2",
"table": "^5.2.3",
"text-table": "^0.2.0"
},
"dependencies": {
"ajv": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
"integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
}
}
},
"eslint-import-resolver-node": {
@ -1083,9 +1136,9 @@
}
},
"eslint-module-utils": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz",
"integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==",
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz",
"integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==",
"dev": true,
"requires": {
"debug": "^2.6.8",
@ -1109,31 +1162,23 @@
}
}
},
"eslint-plugin-html": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-5.0.0.tgz",
"integrity": "sha512-f7p/7YQdgQUFVAX3nB4dnMQbrDeTalcA01PDhuvTLk0ZadCwM4Pb+639SRuqEf1zMkIxckLY+ckCr0hVP5zl6A==",
"dev": true,
"requires": {
"htmlparser2": "^3.10.0"
}
},
"eslint-plugin-import": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.15.0.tgz",
"integrity": "sha512-LEHqgR+RcnpGqYW7h9WMkPb/tP+ekKxWdQDztfTtZeV43IHF+X8lXU+1HOCcR4oXD24qRgEwNSxIweD5uNKGVg==",
"version": "2.17.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz",
"integrity": "sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==",
"dev": true,
"requires": {
"array-includes": "^3.0.3",
"contains-path": "^0.1.0",
"debug": "^2.6.9",
"doctrine": "1.5.0",
"eslint-import-resolver-node": "^0.3.2",
"eslint-module-utils": "^2.3.0",
"eslint-module-utils": "^2.4.0",
"has": "^1.0.3",
"lodash": "^4.17.11",
"minimatch": "^3.0.4",
"read-pkg-up": "^2.0.0",
"resolve": "^1.9.0"
"resolve": "^1.11.0"
},
"dependencies": {
"debug": {
@ -1160,13 +1205,22 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"resolve": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
"integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
}
}
},
"eslint-scope": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
"integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
@ -1186,12 +1240,12 @@
"dev": true
},
"espree": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz",
"integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
"integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
"dev": true,
"requires": {
"acorn": "^6.0.2",
"acorn": "^6.0.7",
"acorn-jsx": "^5.0.0",
"eslint-visitor-keys": "^1.0.0"
}
@ -1227,9 +1281,9 @@
"dev": true
},
"estree-walker": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.0.tgz",
"integrity": "sha512-peq1RfVAVzr3PU/jL31RaOjUKLoZJpObQWJJ+LgfcxDUifyLZ1RjPQZTl0pzj2uJ45b7A7XpyppXvxdEqzo4rw==",
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"dev": true
},
"esutils": {
@ -1363,13 +1417,12 @@
}
},
"file-entry-cache": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
"integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
"integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
"dev": true,
"requires": {
"flat-cache": "^1.2.1",
"object-assign": "^4.0.1"
"flat-cache": "^2.0.1"
}
},
"find-up": {
@ -1382,17 +1435,22 @@
}
},
"flat-cache": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
"integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
"integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
"dev": true,
"requires": {
"circular-json": "^0.3.1",
"graceful-fs": "^4.1.2",
"rimraf": "~2.6.2",
"write": "^0.2.1"
"flatted": "^2.0.0",
"rimraf": "2.6.3",
"write": "1.0.3"
}
},
"flatted": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
"integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==",
"dev": true
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@ -1520,9 +1578,9 @@
}
},
"globals": {
"version": "11.10.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz",
"integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==",
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
},
"globalyzer": {
@ -1550,12 +1608,12 @@
"dev": true
},
"handlebars": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
"integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz",
"integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==",
"dev": true,
"requires": {
"async": "^2.5.0",
"neo-async": "^2.6.0",
"optimist": "^0.6.1",
"source-map": "^0.6.1",
"uglify-js": "^3.1.4"
@ -1592,6 +1650,12 @@
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"has-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
"dev": true
},
"has-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
@ -1673,20 +1737,6 @@
"whatwg-encoding": "^1.0.1"
}
},
"htmlparser2": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz",
"integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==",
"dev": true,
"requires": {
"domelementtype": "^1.3.0",
"domhandler": "^2.3.0",
"domutils": "^1.5.1",
"entities": "^1.1.1",
"inherits": "^2.0.1",
"readable-stream": "^3.0.6"
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@ -1776,39 +1826,39 @@
"dev": true
},
"inquirer": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz",
"integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz",
"integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==",
"dev": true,
"requires": {
"ansi-escapes": "^3.0.0",
"chalk": "^2.0.0",
"ansi-escapes": "^3.2.0",
"chalk": "^2.4.2",
"cli-cursor": "^2.1.0",
"cli-width": "^2.0.0",
"external-editor": "^3.0.0",
"external-editor": "^3.0.3",
"figures": "^2.0.0",
"lodash": "^4.17.10",
"lodash": "^4.17.11",
"mute-stream": "0.0.7",
"run-async": "^2.2.0",
"rxjs": "^6.1.0",
"rxjs": "^6.4.0",
"string-width": "^2.1.0",
"strip-ansi": "^5.0.0",
"strip-ansi": "^5.1.0",
"through": "^2.3.6"
},
"dependencies": {
"ansi-regex": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz",
"integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"strip-ansi": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz",
"integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.0.0"
"ansi-regex": "^4.1.0"
}
}
}
@ -1849,6 +1899,12 @@
"builtin-modules": "^1.0.0"
}
},
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
"dev": true
},
"is-data-descriptor": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
@ -1858,6 +1914,12 @@
"kind-of": "^3.0.2"
}
},
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
"dev": true
},
"is-descriptor": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
@ -1927,12 +1989,30 @@
"@types/estree": "0.0.39"
}
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"dev": true,
"requires": {
"has": "^1.0.1"
}
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"dev": true,
"requires": {
"has-symbols": "^1.0.0"
}
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
@ -1996,9 +2076,9 @@
"dev": true
},
"js-yaml": {
"version": "3.12.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz",
"integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==",
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
@ -2166,6 +2246,12 @@
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
"dev": true
},
"lodash.unescape": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
"integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
"dev": true
},
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
@ -2448,6 +2534,12 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"neo-async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
"dev": true
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@ -2527,6 +2619,12 @@
}
}
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
},
"object-visit": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
@ -2671,9 +2769,9 @@
"dev": true
},
"parent-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz",
"integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"requires": {
"callsites": "^3.0.0"
@ -2775,12 +2873,6 @@
"find-up": "^2.1.0"
}
},
"pluralize": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
"integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
"dev": true
},
"pn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
@ -2888,17 +2980,6 @@
"read-pkg": "^2.0.0"
}
},
"readable-stream": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
"integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"regex-not": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@ -2987,6 +3068,12 @@
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
"dev": true
},
"requireindex": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
"integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
"dev": true
},
"resolve": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
@ -3440,9 +3527,9 @@
}
},
"rxjs": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz",
"integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==",
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
"integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
@ -3535,9 +3622,9 @@
"dev": true
},
"slice-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.0.0.tgz",
"integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
"integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.0",
@ -3816,15 +3903,6 @@
"strip-ansi": "^4.0.0"
}
},
"string_decoder": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
"integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@ -3888,15 +3966,55 @@
"dev": true
},
"table": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/table/-/table-5.2.1.tgz",
"integrity": "sha512-qmhNs2GEHNqY5fd2Mo+8N1r2sw/rvTAAvBZTaTx+Y7PHLypqyrxr1MdIu0pLw6Xvl/Gi4ONu/sdceP8vvUjkyA==",
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz",
"integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==",
"dev": true,
"requires": {
"ajv": "^6.6.1",
"ajv": "^6.9.1",
"lodash": "^4.17.11",
"slice-ansi": "2.0.0",
"string-width": "^2.1.1"
"slice-ansi": "^2.1.0",
"string-width": "^3.0.0"
},
"dependencies": {
"ajv": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
"integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"test-exclude": {
@ -4151,6 +4269,15 @@
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
"dev": true
},
"tsutils": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.14.0.tgz",
"integrity": "sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@ -4182,26 +4309,26 @@
"dev": true
},
"typescript": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz",
"integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==",
"version": "3.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz",
"integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==",
"dev": true
},
"uglify-js": {
"version": "3.4.9",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
"integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
"version": "3.5.12",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.12.tgz",
"integrity": "sha512-KeQesOpPiZNgVwJj8Ge3P4JYbQHUdZzpx6Fahy6eKAYRSV4zhVmLXoC+JtOeYxcHCHTve8RG1ZGdTvpeOUM26Q==",
"dev": true,
"optional": true,
"requires": {
"commander": "~2.17.1",
"commander": "~2.20.0",
"source-map": "~0.6.1"
},
"dependencies": {
"commander": {
"version": "2.17.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"dev": true,
"optional": true
}
@ -4470,9 +4597,9 @@
"dev": true
},
"write": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
"integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
"integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
"dev": true,
"requires": {
"mkdirp": "^0.5.1"

@ -1,22 +1,27 @@
{
"name": "svelte",
"version": "3.0.0-beta.28",
"description": "The magical disappearing UI framework",
"version": "3.5.1",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
"files": [
"compiler.js",
"types",
"compiler.*",
"register.js",
"index.*",
"internal.*",
"store.*",
"animate.*",
"transition.*",
"easing.*",
"motion.*",
"internal",
"store",
"animate",
"transition",
"easing",
"motion",
"svelte",
"README.md"
],
"engines": {
"node": ">= 8"
},
"types": "types/runtime",
"scripts": {
"test": "mocha --opts mocha.opts",
"test:unit": "mocha --require sucrase/register --recursive ./**/__test__.ts",
@ -25,13 +30,16 @@
"coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html",
"codecov": "codecov",
"precodecov": "npm run coverage",
"lint": "eslint src test/*.js",
"build": "rollup -c",
"build": "rollup -c && npm run tsd",
"prepare": "npm run build",
"dev": "rollup -cw",
"pretest": "npm run build",
"posttest": "agadoo src/internal/index.js",
"prepublishOnly": "export PUBLISH=true && npm run lint && npm test"
"posttest": "agadoo internal/index.mjs",
"prepublishOnly": "export PUBLISH=true && npm test && npm run create-stubs",
"create-stubs": "node scripts/create-stubs.js",
"tsd": "tsc -p . --emitDeclarationOnly",
"typecheck": "tsc -p . --noEmit",
"lint": "eslint \"{src,test}/**/*.{ts,js}\""
},
"repository": {
"type": "git",
@ -53,16 +61,17 @@
"@sveltejs/svelte-repl": "0.0.5",
"@types/mocha": "^5.2.0",
"@types/node": "^10.5.5",
"@typescript-eslint/eslint-plugin": "^1.9.0",
"@typescript-eslint/parser": "^1.9.0",
"acorn": "^6.1.1",
"acorn-dynamic-import": "^4.0.0",
"agadoo": "^1.0.1",
"c8": "^3.4.0",
"codecov": "^3.0.0",
"css-tree": "1.0.0-alpha22",
"eslint": "^5.3.0",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-import": "^2.11.0",
"estree-walker": "^0.6.0",
"eslint": "^5.16.0",
"eslint-plugin-import": "^2.17.3",
"estree-walker": "^0.6.1",
"is-reference": "^1.1.1",
"jsdom": "^12.2.0",
"kleur": "^3.0.0",
@ -83,7 +92,7 @@
"tiny-glob": "^0.2.1",
"ts-node": "^8.0.2",
"tslib": "^1.8.0",
"typescript": "^3.0.1"
"typescript": "^3.4.0"
},
"nyc": {
"include": [
@ -92,5 +101,6 @@
],
"sourceMap": true,
"instrument": true
}
},
"dependencies": {}
}

@ -2,7 +2,7 @@ const fs = require('fs');
const path = require('path');
const { compile } = require('./compiler.js');
let extensions = ['.svelte', '.html'];
const extensions = ['.svelte', '.html'];
let compileOptions = {};
function capitalise(name) {
@ -25,8 +25,7 @@ function deregisterExtension(extension) {
function registerExtension(extension) {
require.extensions[extension] = function(module, filename) {
const name = path.basename(filename)
.slice(0, -path.extname(filename).length)
const name = path.parse(filename).name
.replace(/^\d/, '_$&')
.replace(/[^a-zA-Z0-9_$]/g, '');
@ -46,4 +45,4 @@ function registerExtension(extension) {
registerExtension('.svelte');
registerExtension('.html');
module.exports = register;
module.exports = register;

@ -9,36 +9,70 @@ import pkg from './package.json';
const is_publish = !!process.env.PUBLISH;
const ts_plugin = is_publish
? typescript({
include: 'src/**',
typescript: require('typescript')
})
: sucrase({
transforms: ['typescript']
});
const external = id => id.startsWith('svelte/');
export default [
/* internal.[m]js */
/* runtime */
{
input: `src/internal/index.js`,
input: `src/runtime/index.ts`,
output: [
{
file: `internal.mjs`,
file: `index.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}`
},
{
file: `internal.js`,
file: `index.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '.')}`
}
],
external: id => id.startsWith('svelte/'),
plugins: [{
generateBundle(options, bundle) {
const mod = bundle['internal.mjs'];
if (mod) {
fs.writeFileSync('src/compile/internal-exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
}
}
}]
external,
plugins: [ts_plugin]
},
...fs.readdirSync('src/runtime')
.filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory())
.map(dir => ({
input: `src/runtime/${dir}/index.ts`,
output: [
{
file: `${dir}/index.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '..')}`
},
{
file: `${dir}/index.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && `${id.replace('svelte', '..')}`
}
],
external,
plugins: [
ts_plugin,
dir === 'internal' && {
generateBundle(options, bundle) {
const mod = bundle['index.mjs'];
if (mod) {
fs.writeFileSync('src/compiler/compile/internal-exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`);
}
}
}
]
})),
/* compiler.js */
{
input: 'src/index.ts',
input: 'src/compiler/index.ts',
plugins: [
replace({
__VERSION__: pkg.version
@ -48,15 +82,7 @@ export default [
include: ['node_modules/**']
}),
json(),
is_publish
? typescript({
include: 'src/**',
exclude: 'src/internal/**',
typescript: require('typescript')
})
: sucrase({
transforms: ['typescript']
})
ts_plugin
],
output: {
file: 'compiler.js',
@ -67,34 +93,5 @@ export default [
external: is_publish
? []
: id => id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree')
},
/* motion.mjs */
{
input: `src/motion/index.js`,
output: [
{
file: `motion.mjs`,
format: 'esm',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
},
{
file: `motion.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
}
],
external: id => id.startsWith('svelte/')
},
// everything else
...['index', 'store', 'easing', 'transition', 'animate'].map(name => ({
input: `${name}.mjs`,
output: {
file: `${name}.js`,
format: 'cjs',
paths: id => id.startsWith('svelte/') && id.replace('svelte', '.')
},
external: id => id !== `${name}.mjs`
}))
}
];

@ -0,0 +1,12 @@
const fs = require('fs');
fs.readdirSync('src/runtime')
.filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory())
.forEach(dir => {
fs.writeFileSync(`${dir}/package.json`, JSON.stringify({
main: './index',
module: './index.mjs'
}, null, ' '));
fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index.d.ts';`);
});

@ -0,0 +1,9 @@
/*
!/Dockerfile
!/package.json
!/package-lock.json
!/__sapper__
/__sapper__/*
!/__sapper__/build
!/static
!/content

@ -0,0 +1,12 @@
NODE_ENV=
PORT=
BASEURL=
DATABASE_URL=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
MAPBOX_ACCESS_TOKEN=
JWT_EXP=30d
JWT_ALG=HS512
JWT_KEY=

@ -35,7 +35,7 @@
],
"plugins": ["svelte3"],
"parserOptions": {
"ecmaVersion": 8,
"ecmaVersion": 9,
"sourceType": "module"
},
"settings": {

@ -0,0 +1 @@
#!include:.dockerignore

@ -0,0 +1,19 @@
FROM mhart/alpine-node:12
# install dependencies
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --production
###
# Only copy over the Node pieces we need
# ~> Saves 35MB
###
FROM mhart/alpine-node:slim-12
WORKDIR /app
COPY --from=0 /app .
COPY . .
EXPOSE 3000
CMD ["node", "__sapper__/build"]

@ -0,0 +1,22 @@
HASH := `git rev-parse --short HEAD`
SERVICE := svelte-website
PROJECT := svelte-dev
IMAGE := gcr.io/$(PROJECT)/$(SERVICE):$(HASH)
sapper:
@echo "\n~> updating template & contributors list"
@npm run update
@echo "\n~> building Sapper app"
@npm run sapper
docker:
@echo "\n~> building docker image"
@gcloud builds submit -t $(IMAGE)
deploy: sapper docker
@echo "\n~> deploying $(SERVICE) to Cloud Run servers"
@gcloud beta run deploy $(SERVICE) --allow-unauthenticated --region us-central1 --image $(IMAGE) --memory=512Mi

@ -13,14 +13,28 @@ Start the server with `npm run dev`, and navigate to [localhost:3000](http://loc
## Using a local copy of Svelte
By default, the REPL will fetch the most recent version of Svelte from https://unpkg.com/svelte. To use the local copy of the compiler and runtime from this repo, you can navigate to [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local). To produce the proper browser-compatible UMD build, you will need to run `npm run build` with the `PUBLISH` environment variable set (to any non-empty string).
By default, the REPL will fetch the most recent version of Svelte from https://unpkg.com/svelte. When running the site locally, you can also use your local copy of Svelte.
To produce the proper browser-compatible UMD build of the compiler, you will need to run `npm run build` (or `npm run dev`) in the root of this repository with the `PUBLISH` environment variable set to any non-empty string.
Then visit the REPL at [localhost:3000/repl?version=local](http://localhost:3000/repl?version=local).
## REPL GitHub integration
In order for the REPL's GitHub integration to work properly when running locally, you will need to create a GitHub OAuth app. Set its authorization callback URL to `http://localhost:3000/auth/callback`, and in this project, create `site/.env` containing:
In order for the REPL's GitHub integration to work properly when running locally, you will need to:
- [create a GitHub OAuth app](https://github.com/settings/developers):
- set `Authorization callback URL` to `http://localhost:3000/auth/callback`;
- set `Application name` as you like, and `Homepage URL` as `http://localhost:3000/`;
- create the app and take note of `Client ID` and `Client Secret`
- in this repo, create `site/.env` containing:
```
GITHUB_CLIENT_ID=[your app's Client ID]
GITHUB_CLIENT_SECRET=[your app's Client Secret]
BASEURL=http://localhost:3000
```
```
GITHUB_CLIENT_ID=[your app's client id]
GITHUB_CLIENT_SECRET=[your app's client secret]
BASEURL=http://localhost:3000
```
## Translating the API docs
Anchors are automatically generated using headings in the documentation and by default (for the english language) they are latinised to make sure the URL is always conforming to RFC3986.
If we need to translate the API documentation to a language using unicode chars, we can setup this app to export the correct anchors by setting up `SLUG_PRESERVE_UNICODE` to `true` in `config.js`.

@ -0,0 +1,2 @@
export const SLUG_PRESERVE_UNICODE = false;
export const SLUG_SEPARATOR = '_';

@ -1,7 +1,6 @@
---
title: Frameworks without the framework: why didn't we think of this sooner?
description: You can't write serious applications in vanilla JavaScript without hitting a complexity wall. But a compiler can do it for you.
pubdate: 2016-11-26
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
@ -29,7 +28,7 @@ Given that, what if the framework *didn't actually run in the browser*? What if,
## Introducing Svelte
Svelte is a new framework that does exactly that. You write your components using HTML, CSS and JavaScript (plus a few extra bits you can [learn in under 5 minutes](/guide)), and during your build process Svelte compiles them into tiny standalone JavaScript modules. By statically analysing the component template, we can make sure that the browser does as little work as possible.
Svelte is a new framework that does exactly that. You write your components using HTML, CSS and JavaScript (plus a few extra bits you can [learn in under 5 minutes](https://v2.svelte.dev/guide)), and during your build process Svelte compiles them into tiny standalone JavaScript modules. By statically analysing the component template, we can make sure that the browser does as little work as possible.
The [Svelte implementation of TodoMVC](http://svelte-todomvc.surge.sh/) weighs 3.6kb zipped. For comparison, React plus ReactDOM *without any app code* weighs about 45kb zipped. It takes about 10x as long for the browser just to evaluate React as it does for Svelte to be up and running with an interactive TodoMVC.
@ -53,4 +52,4 @@ Finally, something I've wrestled with a great deal as an open source maintainer:
Svelte is very new. There's a lot of work still left to do creating build tool integrations, adding a server-side renderer, hot reloading, transitions, more documentation and examples, starter kits, and so on.
But you can already build rich components with it, which is why we've gone straight to a stable 1.0.0 release. [Read the guide](/guide), [try it out in the REPL](/repl), and head over to [GitHub](https://github.com/sveltejs/svelte) to help kickstart the next era of front end development.
But you can already build rich components with it, which is why we've gone straight to a stable 1.0.0 release. [Read the guide](https://v2.svelte.dev/guide), [try it out in the REPL](/repl), and head over to [GitHub](https://github.com/sveltejs/svelte) to help kickstart the next era of front end development.

@ -1,7 +1,6 @@
---
title: The easiest way to get started with Svelte
description: This'll only take a minute.
pubdate: 2017-08-07
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
@ -13,7 +12,7 @@ Because of that, getting started with it can be a little bit confusing at first.
## 1. Use the REPL
The [Svelte REPL](https://svelte.technology/repl) is the easiest way to begin. You can choose from a list of examples to get you started, and tweak them until they do what you want.
The [Svelte REPL](repl) is the easiest way to begin. You can choose from a list of examples to get you started, and tweak them until they do what you want.
<aside><p>You'll need to have <a href="https://nodejs.org/">Node.js</a> installed, and know how to use the terminal</p></aside>
@ -39,28 +38,23 @@ 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
```
This will create a new project in the `my-svelte-project` directory, install its dependencies, and start a server on 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#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](chat), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!

@ -1,7 +1,6 @@
---
title: The zen of Just Writing CSS
description: I would say this is the future, but we're already doing it.
pubdate: 2017-09-06
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
@ -29,7 +28,7 @@ The consequence of all this is the **append-only stylesheet**. There's no way of
The idea behind SFCs is simple: you write your components in an HTML file that (optionally) contains a `<style>` and `<script>` attribute describing the component's styles and behaviour. Svelte, Ractive, Vue and Polymer all follow this basic pattern.
<aside>
<p><a href="https://svelte.technology/blog/frameworks-without-the-framework">Read the introductory blog post</a> if you're new to Svelte. Or <a href="https://twitter.com/padolsey/status/899717303234908160">read</a> <a href="https://twitter.com/sveltejs/status/901818357644701696">the</a> <a href="https://twitter.com/sveltejs/status/901818106309476352">testimonials</a>.</p>
<p><a href="blog/frameworks-without-the-framework">Read the introductory blog post</a> if you're new to Svelte. Or <a href="https://twitter.com/padolsey/status/899717303234908160">read</a> <a href="https://twitter.com/sveltejs/status/901818357644701696">the</a> <a href="https://twitter.com/sveltejs/status/901818106309476352">testimonials</a>.</p>
</aside>
(For the rest of this article we'll be using Svelte, obviously. But if the idea of using a template language makes you shudder — your fears are misplaced, but that's a topic for another day — then just use Vue which lets you use JSX in your SFCs.)

@ -1,7 +1,6 @@
---
title: Sapper: Towards the ideal web app framework
description: Taking the next-plus-one step
pubdate: 2017-12-31
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
@ -29,7 +28,7 @@ Everything else flows from that breakthrough design decision. Finding the code r
But it's not perfect. As churlish as it might be to list the flaws in something *so, so good*, there are some:
* Next uses something called 'route masking' to create nice URLs (e.g. `/blog/hello-world` instead of `/post?slug=hello-world`). This undermines the guarantee about directory structure corresponding to app structure, and forces you to maintain configuration that translates between the two forms
* All your routes are assumed to be universal 'pages'. But it's very common to need routes that only render on the server, such as a 301 redirect or an [API endpoint](/api/blog/sapper-towards-the-ideal-web-app-framework) that serves the data for your pages, and Next doesn't have a great solution for this. You can add logic to your `server.js` file to handle these cases, but it feels at odds with the declarative approach taken for pages
* All your routes are assumed to be universal 'pages'. But it's very common to need routes that only render on the server, such as a 301 redirect or an [API endpoint](/blog/sapper-towards-the-ideal-web-app-framework.json) that serves the data for your pages, and Next doesn't have a great solution for this. You can add logic to your `server.js` file to handle these cases, but it feels at odds with the declarative approach taken for pages
* To use the client-side router, links can't be standard `<a>` tags. Instead, you have to use framework-specific `<Link>` components, which is impossible in the markdown content for a blog post such as this one, for example
The real problem, though, is that all that goodness comes for a price. The simplest possible Next app — a single 'hello world' page that renders some static text — involves 66kb of gzipped JavaScript. Unzipped, it's 204kb, which is a non-trivial amount of code for a mobile device to parse at a time when performance is a critical factor determining whether or not your users will stick around. And that's the *baseline*.
@ -39,7 +38,7 @@ We can do better!
## The compiler-as-framework paradigm shift
[Svelte introduced a radical idea](https://svelte.technology/blog/frameworks-without-the-framework): what if your UI framework wasn't a framework at all, but a compiler that turned your components into standalone JavaScript modules? Instead of using a library like React or Vue, which knows nothing about your app and must therefore be a one-size-fits-all solution, we can ship highly-optimised vanilla JavaScript. Just the code your app needs, and without the memory and performance overhead of solutions based on a virtual DOM.
[Svelte introduced a radical idea](blog/frameworks-without-the-framework): what if your UI framework wasn't a framework at all, but a compiler that turned your components into standalone JavaScript modules? Instead of using a library like React or Vue, which knows nothing about your app and must therefore be a one-size-fits-all solution, we can ship highly-optimised vanilla JavaScript. Just the code your app needs, and without the memory and performance overhead of solutions based on a virtual DOM.
The JavaScript world is [moving towards this model](https://tomdale.net/2017/09/compilers-are-the-new-frameworks/). [Stencil](https://stenciljs.com), a Svelte-inspired framework from the Ionic team, compiles to web components. [Glimmer](https://glimmerjs.com) *doesn't* compile to standalone JavaScript (the pros and cons of which deserve a separate blog post), but the team is doing some fascinating research around compiling templates to bytecode. (React is [getting in on the action](https://twitter.com/trueadm/status/944908776896978946), though their current research focuses on optimising your JSX app code, which is arguably more similar to the ahead-of-time optimisations that Angular, Ractive and Vue have been doing for a few years.)
@ -67,7 +66,7 @@ But size is only part of the story. Svelte apps are also extremely performant an
The biggest drawback for many developers evaluating Sapper would be 'but I like React, and I already know how to use it', which is fair.
If you're in that camp, I'd invite you to at least try alternative frameworks. You might be pleasantly surprised! The [Sapper RealWorld](https://github.com/sveltejs/realworld) implementation totals 1,201 lines of source code, compared to 2,377 for the reference implementation, because you're able to express concepts very concisely using Svelte's template syntax (which [takes all of five minutes to master](https://svelte.technology/docs#template-syntax)). You get [scoped CSS](the-zen-of-just-writing-css), with unused style removal and minification built-in, and you can use preprocessors like LESS if you want. You no longer need to use Babel. SSR is ridiculously fast, because it's just string concatenation. And we recently introduced [svelte/store](https://svelte.technology/docs#state-management), a tiny global store that synchronises state across your component hierarchy with zero boilerplate. The worst that can happen is that you'll end up feeling vindicated!
If you're in that camp, I'd invite you to at least try alternative frameworks. You might be pleasantly surprised! The [Sapper RealWorld](https://github.com/sveltejs/realworld) implementation totals 1,201 lines of source code, compared to 2,377 for the reference implementation, because you're able to express concepts very concisely using Svelte's template syntax (which [takes all of five minutes to master](https://v2.svelte.dev/guide#template-syntax)). You get [scoped CSS](blog/the-zen-of-just-writing-css), with unused style removal and minification built-in, and you can use preprocessors like LESS if you want. You no longer need to use Babel. SSR is ridiculously fast, because it's just string concatenation. And we recently introduced [svelte/store](https://v2.svelte.dev/guide#state-management), a tiny global store that synchronises state across your component hierarchy with zero boilerplate. The worst that can happen is that you'll end up feeling vindicated!
But there are trade-offs nonetheless. Some people have a pathological aversion to any form of 'template language', and maybe that applies to you. JSX proponents will clobber you with the 'it's just JavaScript' mantra, and therein lies React's greatest strength, which is that it is infinitely flexible. That flexibility comes with its own set of trade-offs, but we're not here to discuss those.
@ -82,4 +81,4 @@ I believe the next frontier of web performance is 'whole-app optimisation'. Curr
Speaking of Glimmer, the idea of compiling components to bytecode is one that we'll probably steal in 2018. A framework like Sapper could conceivably determine which compilation mode to use based on the characteristics of your app. It could even serve JavaScript for the initial route for the fastest possible startup time, then lazily serve a bytecode interpreter for subsequent routes, resulting in the optimal combination of startup size and total app size.
Mostly, though, we want the direction of Sapper to be determined by its users. If you're the kind of developer who enjoys life on the bleeding edge and would like to help shape the future of how we build web apps, please join us on [GitHub](https://github.com/sveltejs/svelte) and [Gitter](https://gitter.im/sveltejs/svelte).
Mostly, though, we want the direction of Sapper to be determined by its users. If you're the kind of developer who enjoys life on the bleeding edge and would like to help shape the future of how we build web apps, please join us on [GitHub](https://github.com/sveltejs/svelte) and [Discord](chat).

@ -1,7 +1,6 @@
---
title: Svelte v2 is out!
description: Here's what you need to know
pubdate: 2018-04-18
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
@ -13,7 +12,7 @@ Almost a year after we first started talking about version 2 on the Svelte issue
## tl;dr
Each of these items is described in more depth below. If you get stuck, ask for help in our friendly [Gitter chatroom](https://gitter.im/sveltejs/svelte).
Each of these items is described in more depth below. If you get stuck, ask for help in our friendly [Discord chatroom](chat).
- Install Svelte v2 from npm
- Upgrade your templates with [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade)
@ -86,7 +85,7 @@ If you need to support IE11 and friends, you will need to use a transpiler like
## New lifecycle hooks
In addition to `oncreate` and `ondestroy`, Svelte v2 adds two more [lifecycle hooks](docs#lifecycle-hooks) for responding to state changes:
In addition to `oncreate` and `ondestroy`, Svelte v2 adds two more [lifecycle hooks](https://v2.svelte.dev/guide#lifecycle-hooks) for responding to state changes:
```js
export default {
@ -169,7 +168,7 @@ This change might seem annoying initially, but it's the right move: among other
## event_handler.destroy
If your app has [custom event handlers](docs#custom-event-handlers), they must return an object with a `destroy` method, *not* a `teardown` method (this aligns event handlers with the component API).
If your app has [custom event handlers](https://v2.svelte.dev/guide#custom-event-handlers), they must return an object with a `destroy` method, *not* a `teardown` method (this aligns event handlers with the component API).
## No more type coercion
@ -202,4 +201,4 @@ Before, there was a `svelte.validate` method which checked your component was va
## My app is broken! Help!
Hopefully this covers everything, and the update should be easier for you than it was for us. But if you find bugs, or discover things that aren't mentioned here, swing by [Gitter](https://gitter.im/sveltejs/svelte) or raise an issue on the [tracker](https://github.com/sveltejs/svelte/issues).
Hopefully this covers everything, and the update should be easier for you than it was for us. But if you find bugs, or discover things that aren't mentioned here, swing by [Discord chatroom](chat) or raise an issue on the [tracker](https://github.com/sveltejs/svelte/issues).

@ -1,7 +1,6 @@
---
title: Using CSS-in-JS with Svelte
description: You don't need to, but you can
pubdate: 2018-12-26
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
@ -17,13 +16,14 @@ But Svelte's style handling does have some limitations. It's too difficult to sh
Here, we're using [Emotion](https://emotion.sh) to generate scoped class names that can be used across multiple components:
<iframe
title="Aphrodite example"
src="/repl/embed?gist=ad495ff5ba9ceefe5984fe62c1f15e19"
scrolling="no"
></iframe>
<div class="max">
<iframe
title="Aphrodite example"
src="/repl/embed?example=blog-svelte-css-in-js"
scrolling="no"
></iframe>
</div>
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.

@ -1,7 +1,6 @@
---
title: Virtual DOM is pure overhead
description: Let's retire the 'virtual DOM is fast' myth once and for all
pubdate: 2018-12-27
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---

@ -1,7 +1,6 @@
---
title: Svelte on The Changelog
description: Listen to the interview here
pubdate: 2019-01-31
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
@ -15,9 +14,8 @@ Earlier this month, I had the privilege of appearing on [The Changelog](https://
...and, most importantly, Svelte 3.
Unless you hang out in our [Discord server](https://discord.gg/yy75DKs) or follow [@sveltejs](https://twitter.com/sveltejs) on Twitter, you might not know that Svelte 3 is just around the corner, and it's going to be a huge release. We've rethought the developer experience from the ground up, and while it *will* be a nuisance if you need to upgrade a Svelte 2 app (more on that soon) we think you're going to love it.
Unless you hang out in our [Discord server](chat) or follow [@sveltejs](https://twitter.com/sveltejs) on Twitter, you might not know that Svelte 3 is just around the corner, and it's going to be a huge release. We've rethought the developer experience from the ground up, and while it *will* be a nuisance if you need to upgrade a Svelte 2 app (more on that soon) we think you're going to love it.
On the podcast [Adam](https://twitter.com/adamstac), [Jerod](https://twitter.com/jerodsanto) and I talk about some of the changes and why we're making them. You can listen here or on the [podcast page](https://changelog.com/podcast/332).
<audio data-theme="night" style="width: 100%" data-src="https://changelog.com/podcast/332/embed" src="https://cdn.changelog.com/uploads/podcast/332/the-changelog-332.mp3" preload="none" class="changelog-episode" controls></audio><p><a href="https://changelog.com/podcast/332">The Changelog 332: A UI framework without the framework</a> Listen on <a href="https://changelog.com/">Changelog.com</a></p><script async src="//cdn.changelog.com/embed.js"></script>

@ -0,0 +1,13 @@
---
title: Setting up your editor
description: Instructions for configuring linting and syntax highlighting
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
draft: true
---
*Coming soon* This post will walk you through setting up your editor so that recognises Svelte files:
* eslint-plugin-svelte3
* svelte-vscode
* associating .svelte files with HTML in VSCode, Sublime, Atom, etc etc etc

@ -0,0 +1,9 @@
---
title: Svelte for new developers
description: Never used Node.js or the command line? No problem
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
draft: true
---
*Coming soon* This blog post will walk you through installing Node.js and git and using Terminal.app to clone a project template and start developing with Svelte

@ -0,0 +1,164 @@
---
title: Write less code
description: The most important metric you're not paying attention to
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
All code is buggy. It stands to reason, therefore, that the more code you have to write the buggier your apps will be.
Writing more code also takes more time, leaving less time for other things like optimisation, nice-to-have features, or being outdoors instead of hunched over a laptop.
In fact it's widely acknowledged that [project development time](https://blog.codinghorror.com/diseconomies-of-scale-and-lines-of-code/) and [bug count](https://www.mayerdan.com/ruby/2012/11/11/bugs-per-line-of-code-ratio) grow *quadratically*, not linearly, with the size of a codebase. That tracks with our intuitions: a ten-line pull request will get a level of scrutiny rarely applied to a 100-line one. And once a given module becomes too big to fit on a single screen, the cognitive effort required to understand it increases significantly. We compensate by refactoring and adding comments — activities that almost always result in *more* code. It's a vicious cycle.
Yet while we obsess — rightly! — over performance numbers, bundle size and anything else we can measure, we rarely pay attention to the amount of code we're writing.
## Readability is important
I'm certainly not claiming that we should use clever tricks to scrunch our code into the most compact form possible at the expense of readability. Nor am I claiming that reducing *lines* of code is necessarily a worthwhile goal, since it encourages turning readable code like this...
```js
for (let i = 0; i <= 100; i += 1) {
if (i % 2 === 0) {
console.log(`${i} is even`);
}
}
```
...into something much harder to parse:
```js
for (let i = 0; i <= 100; i += 1) if (i % 2 === 0) console.log(`${i} is even`);
```
Instead, I'm claiming that we should favour languages and patterns that allow us to naturally write less code.
## Yes, I'm talking about Svelte
Reducing the amount of code you have to write is an explicit goal of Svelte. To illustrate, let's look at a very simple component implemented in React, Vue and Svelte. First, the Svelte version:
<div class="max">
<iframe
title="Simple component example"
src="/repl/embed?example=blog-write-less-code"
scrolling="no"
></iframe>
</div>
How would we build this in React? It would probably look something like this:
```js
import React, { useState } from 'react';
export default () => {
const [a, setA] = useState(1);
const [b, setB] = useState(2);
function handleChangeA(event) {
setA(+event.target.value);
}
function handleChangeB(event) {
setB(+event.target.value);
}
return (
<div>
<input type="number" value={a} onChange={handleChangeA}/>
<input type="number" value={b} onChange={handleChangeB}/>
<p>{a} + {b} = {a + b}</p>
</div>
);
};
```
Here's an equivalent component in Vue:
```html
<template>
<div>
<input type="number" v-model.number="a">
<input type="number" v-model.number="b">
<p>{{a}} + {{b}} = {{a + b}}</p>
</div>
</template>
<script>
export default {
data: function() {
return {
a: 1,
b: 2
};
}
};
</script>
```
<aside>
<p>I'm counting by copying the source code to the clipboard and running `pbpaste | wc -c` in my terminal</p>
</aside>
In other words, it takes 442 characters in React, and 263 characters in Vue, to achieve something that takes 145 characters in Svelte. The React version is literally three times larger!
It's unusual for the difference to be *quite* so obvious — in my experience, a React component is typically around 40% larger than its Svelte equivalent. Let's look at the features of Svelte's design that enable you to express ideas more concisely:
### Top-level elements
In Svelte, a component can have as many top-level elements as you like. In React and Vue, a component must have a single top-level element — in React's case, trying to return two top-level elements from a component function would result in syntactically invalid code. (You can use a fragment — `<>` instead of a `<div>`, but it's the same basic idea, and still results in an extra level of indentation).
In Vue, your markup must be wrapped in a `<template>` element, which I'd argue is redundant.
### Bindings
In React, we have to respond to input events ourselves:
```js
function handleChangeA(event) {
setA(+event.target.value);
}
```
This isn't just boring plumbing that takes up extra space on the screen, it's also extra surface area for bugs. Conceptually, the value of the input is bound to the value of `a` and vice versa, but that relationship isn't cleanly expressed — instead we have two tightly-coupled but physically separate chunks of code (the event handler and the `value={a}` prop). Not only that, but we have to remember to coerce the string value with the `+` operator, otherwise `2 + 2` will equal `22` instead of `4`.
Like Svelte, Vue does have a way of expressing the binding — the `v-model` attribute, though again we have to be careful to use `v-model.number` even though it's a numeric input.
### State
In Svelte, you update local component state with an assignment operator:
```js
let count = 0;
function increment() {
count += 1;
}
```
In React, we use the `useState` hook:
```js
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
```
This is much *noisier* — it expresses the exact same concept but with over 60% more characters. As you're reading the code, you have to do that much more work to understand the author's intent.
In Vue, meanwhile, we have a default export with a `data` function that returns an object literal with properties corresponding to our local state. Things like helper functions and child components can't simply be imported and used in the template, but must instead be 'registered' by attaching them to the correct part of the default export.
## Death to boilerplate
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.

@ -0,0 +1,97 @@
---
title: Svelte 3: Rethinking reactivity
description: It's finally here
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
---
After several months of being just days away, we are over the moon to announce the stable release of Svelte 3. This is a huge release representing hundreds of hours of work by many people in the Svelte community, including invaluable feedback from beta testers who have helped shape the design every step of the way.
We think you're going to love it.
## What is Svelte?
Svelte is a component framework — like React or Vue — but with an important difference. Traditional frameworks allow you to write *declarative* state-driven code, but there's a penalty: the browser must do extra work to convert those declarative structures into DOM operations, using techniques like [virtual DOM diffing](blog/virtual-dom-is-pure-overhead) that eat into your frame budget and tax the garbage collector.
Instead, Svelte runs at *build time*, converting your components into highly efficient *imperative* code that surgically updates the DOM. As a result, you're able to write ambitious applications with excellent performance characteristics.
The first version of Svelte was all about [testing a hypothesis](blog/frameworks-without-the-framework) — that a purpose-built compiler could generate rock-solid code that delivered a great user experience. The second was a small upgrade that tidied things up a bit.
Version 3 is a significant overhaul. Our focus for the last five or six months has been on delivering an outstanding *developer* experience. It's now possible to write components with [significantly less boilerplate](blog/write-less-code) than you'll find elsewhere. Try the brand new [tutorial](tutorial) and see what we mean — if you're familiar with other frameworks we think you'll be pleasantly surprised.
To make that possible we first needed to rethink the concept at the heart of modern UI frameworks: reactivity.
<div class="max">
<figure style="max-width: 960px; margin: 0 auto">
<div style="height: 0; padding: 0 0 57.1% 0; position: relative; margin: 0 auto;">
<iframe style="position: absolute; width: 100%; height: 100%; left: 0; top: 0; margin: 0;" src="https://www.youtube-nocookie.com/embed/AdNJ3fydeao" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<figcaption>'Rethinking Reactivity' from <a href="https://www.israel.yglfconf.com/">You Gotta Love Frontend Code Camp</a></figcaption>
</figure>
</div>
## Moving reactivity into the language
In old Svelte, you would tell the computer that some state had changed by calling the `this.set` method:
```js
const { count } = this.get();
this.set({
count: count + 1
});
```
That would cause the component to *react*. Speaking of which, `this.set` is almost identical to the `this.setState` method used in classical (pre-hooks) React:
```js
const { count } = this.state;
this.setState({
count: count + 1
});
```
There are some important technical differences (as I explain in the video above, React is not reactive) but conceptually it's the same thing.
<aside>
<p>In fact, Svelte 3 is basically <a href="https://twitter.com/threepointone/status/1057179801109311488">Sunil's fault</a>.</p>
</aside>
That all changed with the advent of [hooks](https://reactjs.org/docs/hooks-intro.html), which handle state in a very different fashion. Many frameworks started experimenting with their own implementations of hooks, but we quickly concluded it wasn't a direction we wanted to go in. Hooks have some intriguing properties, but they also involve some unnatural code and create unnecessary work for the garbage collector. For a framework that's used in [embedded devices](https://mobile.twitter.com/sveltejs/status/1088500539640418304) as well as animation-heavy interactives, that's no good.
So we took a step back and asked ourselves what kind of API would work for us... and realised that the best API is no API at all. We can just *use the language*. Updating some `count` value — and all the things that depend on it — should be as simple as this:
```js
count += 1;
```
Since we're a compiler, we can do that by instrumenting assignments behind the scenes:
```js
count += 1; $$invalidate('count', count);
```
Importantly, we can do all this without the overhead and complexity of using proxies or accessors. It's just a variable.
## New look
Your components aren't the only thing that's getting a facelift. Svelte itself has a completely new look and feel, thanks to the amazing design work of [Achim Vedam](https://vedam.de/) who created our new logo and website, which has moved from [svelte.technology](https://svelte.technology) to [svelte.dev](https://svelte.dev).
We've also changed our tagline, from 'The magical disappearing UI framework' to 'Cybernetically enhanced web apps'. Svelte has many aspects — outstanding performance, small bundles, accessibility, built-in style encapsulation, declarative transitions, ease of use, the fact that it's a compiler, etc — that focusing on any one of them feels like an injustice to the others. 'Cybernetically enhanced' is designed to instead evoke Svelte's overarching philosophy that our tools should work as intelligent extensions of ourselves — hopefully with a retro, William Gibson-esque twist.
## Upgrading from version 2
If you're an existing Svelte 2 user, I'm afraid there is going to be some manual upgrading involved. In the coming days we'll release a migration guide and an updated version of [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade) which will do the best it can to automate the process, but this *is* a significant change and not everything can be handled automatically.
We don't take this lightly: hopefully once you've experienced Svelte 3 you'll understand why we felt it was necessary to break with the past.
## Still to come
As grueling as this release has been, we're nowhere near finished. We have a ton of ideas for generating smarter, more compact code, and a long feature wish-list. [Sapper](https://sapper.svelte.dev), our Next.js-style app framework, is still in the middle of being updated to use Svelte 3. The [Svelte Native](https://svelte-native.technology/) community project, which allows you to write Android and iOS apps in Svelte, is making solid progress but deserves more complete support from core. We don't yet have the bounty of editor extensions, syntax highlighters, component kits, devtools and so on that other frameworks have, and we should fix that. We *really* want to add first-class TypeScript support.
But in the meantime we think Svelte 3 is the best way to build web apps yet. Take an hour to go through the [tutorial](tutorial) and we hope to convince you of the same. Either way, we'd love to see you in our [Discord chatroom](chat) and on [GitHub](https://github.com/sveltejs/svelte) — everyone is welcome, especially you.

@ -2,7 +2,7 @@
title: Before we begin
---
> Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the [Discord chatroom](https://discord.gg/yy75DKs). The [tutorial](tutorial) is more complete; start there.
> Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the [Discord chatroom](chat). The [tutorial](tutorial) is more complete; start there.
This page contains detailed API reference documentation. It's intended to be a resource for people who already have some familiarity with Svelte.

@ -36,15 +36,33 @@ Svelte uses the `export` keyword to mark a variable declaration as a *property*
export let foo;
export let bar = 'optional default value';
// you can use export { ... as ... } to have
// props whose names are reserved keywords
let clazz;
export { clazz as class };
// this property is readonly externally
export const buzz = 'buzz';
// Values that are passed in as props
// are immediately available
console.log(foo, bar);
// Function expressions can also be props
export let format = (number) => (number.toFixed(2));
// Function declarations are added as methods
// on the component, rather than props
export function greetMethod() {
alert(`I'm a <${this.constructor.name}>!`);
}
// function declarations cannot be set externally,
// but can be accessed from outside
export function instanceMethod() {
alert(foo);
// you can also use export { ... as ... } to have
// methods whose names are reserved keywords
function del() {
do_something();
}
export { del as delete };
</script>
```
@ -56,6 +74,8 @@ To change component state and trigger a re-render, just assign to a locally decl
Update expressions (`count += 1`) and property assignments (`obj.x = y`) have the same effect.
Because Svelte's reactivity is based on assignments, using array methods like `.push()` and `.splice()` won't automatically trigger updates. Options for getting around this can be found in the [tutorial](tutorial/updating-arrays-and-objects).
```html
<script>
let count = 0;
@ -72,7 +92,7 @@ Update expressions (`count += 1`) and property assignments (`obj.x = y`) have th
---
Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the `$:` label. Reactive statements run immediately before the component updates, whenever the values that they depend on have changed.
Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the `$:` [JS label syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label). Reactive statements run immediately before the component updates, whenever the values that they depend on have changed.
```html
<script>

@ -7,7 +7,7 @@ title: Template syntax
---
A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag, such as `<Widget>`, indicates a *component*.
A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag, such as `<Widget>` or `<Namespace.Widget>`, indicates a *component*.
```html
<script>
@ -351,6 +351,24 @@ If the `on:` directive is used without a value, the component will *forward* the
</button>
```
---
It's possible to have multiple event listeners for the same event:
```html
<script>
let counter = 0;
function increment() {
counter = counter + 1;
}
function track(event) {
trackEvent(event)
}
</script>
<button on:click={increment} on:click={track}>Click me!</button>
```
### Component events
@ -360,13 +378,19 @@ on:eventname={handler}
---
Components can emit events using [createEventDispatcher](docs#createeventdispatcher), or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:
Components can emit events using [createEventDispatcher](docs#createEventDispatcher), or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:
```html
<SomeComponent on:whatever={handler}/>
```
---
As with DOM events, if the `on:` directive is used without a value, the component will *forward* the event, meaning that a consumer of the component can listen for it.
```html
<SomeComponent on:whatever/>
```
### Element bindings
@ -569,12 +593,12 @@ You can bind to component props using the same mechanism.
Components also support `bind:this`, allowing you to interact with component instances programmatically.
> Note that we can do `{cart.empty}` rather than `{() => cart.empty()}`, since component methods are closures. You don't need to worry about the value of `this` when calling them.
> Note that we can't do `{cart.empty}` since `cart` is `undefined` when the button is first rendered and throws an error.
```html
<ShoppingCart bind:this={cart}/>
<button on:click={cart.empty}>
<button on:click={() => cart.empty()}>
Empty shopping cart
</button>
```
@ -600,6 +624,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>
```
@ -746,6 +773,8 @@ The `in:` and `out:` directives are not bidirectional. An in transition will con
{/if}
```
> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](docs#Client-side_component_API).
#### Transition parameters
---
@ -884,7 +913,138 @@ Local transitions only play when the block they belong to is created or destroye
### Animations
TODO i can't remember how any of this works
```sv
animate:name
```
```sv
animate:name={params}
```
```js
animation = (node: HTMLElement, { from: DOMRect, to: DOMRect } , params: any) => {
delay?: number,
duration?: number,
easing?: (t: number) => number,
css?: (t: number, u: number) => string,
tick?: (t: number, u: number) => void
}
```
```js
DOMRect {
bottom: number,
height: number,
left: number,
right: number,
top: number,
width: number,
x: number,
y:number
}
```
---
An animation is triggered when the contents of a [keyed each block](docs#Each_blocks) are re-ordered. Animations do not run when an element is removed, only when the each block's data is reordered. Animate directives must be on an element that is an *immediate* child of a keyed each block.
Animations can be used with Svelte's [built-in animation functions](docs#svelte_animate) or [custom animation functions](docs#Custom_animation_functions).
```html
<!-- When `list` is reordered the animation will run-->
{#each list as item, index (item)}
<li animate:flip>{item}</li>
{/each}
```
#### Animation Parameters
---
As with actions and transitions, animations can have parameters.
(The double `{{curlies}}` aren't a special syntax; this is an object literal inside an expression tag.)
```html
{#each list as item, index (item)}
<li animate:flip="{{ delay: 500 }}">{item}</li>
{/each}
```
#### Custom animation functions
---
Animations can use custom functions that provide the `node`, an `animation` object and any `paramaters` as arguments. The `animation` parameter is an object containing `from` and `to` properties each containing a [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect#Properties) describing the geometry of the element in its `start` and `end` positions. The `from` property is the DOMRect of the element in its starting position, the `to` property is the DOMRect of the element in its final position after the list has been reordered and the DOM updated.
If the returned object has a `css` method, Svelte will create a CSS animation that plays on the element.
The `t` argument passed to `css` is a value that goes from `0` and `1` after the `easing` function has been applied. The `u` argument is equal to `1 - t`.
The function is called repeatedly *before* the animation begins, with different `t` and `u` arguments.
```html
<script>
import { cubicOut } from 'svelte/easing';
function whizz(node, { from, to }, params) {
const dx = from.left - to.left;
const dy = from.top - to.top;
const d = Math.sqrt(dx * dx + dy * dy);
return {
delay: 0,
duration: Math.sqrt(d) * 120,
easing: cubicOut,
css: (t, u) =>
`transform: translate(${u * dx}px, ${u * dy}px) rotate(${t*360}deg);`
};
}
</script>
{#each list as item, index (item)}
<div animate:whizz>{item}</div>
{/each}
```
---
A custom animation function can also return a `tick` function, which is called *during* the animation with the same `t` and `u` arguments.
> If it's possible to use `css` instead of `tick`, do so — CSS animations can run off the main thread, preventing jank on slower devices.
```html
<script>
import { cubicOut } from 'svelte/easing';
function whizz(node, { from, to }, params) {
const dx = from.left - to.left;
const dy = from.top - to.top;
const d = Math.sqrt(dx * dx + dy * dy);
return {
delay: 0,
duration: Math.sqrt(d) * 120,
easing: cubicOut,
tick: (t, u) =>
Object.assign(node.style, {
color: t > 0.5 ? 'Pink' : 'Blue'
});
};
}
</script>
{#each list as item, index (item)}
<div animate:whizz>{item}</div>
{/each}
```
### Slots
@ -934,7 +1094,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>
```
@ -980,7 +1140,7 @@ Named slots can also expose values. The `let:` directive goes on the element wit
{/each}
</ul>
</slot name="footer"></slot>
<slot name="footer"></slot>
```
@ -1107,7 +1267,7 @@ This element makes it possible to insert elements into `document.head`. During s
---
The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](docs#compile). The possible options are:
The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](docs#svelte_compile). The possible options are:
* `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
* `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed
@ -1119,3 +1279,50 @@ The `<svelte:options>` element provides a place to specify per-component compile
```html
<svelte:options tag="my-custom-element"/>
```
### @debug
```sv
{@debug}
```
```sv
{@debug var1, var2, ..., varN}
```
---
The `{@debug ...}` tag offers an alternative to `console.log(...)`. It logs the values of specific variables whenever they change, and pauses code execution if you have devtools open.
It accepts a comma-separated list of variable names (not arbitrary expressions).
```html
<script>
let user = {
firstname: 'Ada',
lastname: 'Lovelace'
};
</script>
{@debug user}
<h1>Hello {user.firstname}!</h1>
```
---
`{@debug ...}` accepts a comma-separated list of variable names (not arbitrary expressions).
```html
<!-- Compiles -->
{@debug user}
{@debug user1, user2, user3}
<!-- WON'T compile -->
{@debug user.firstname}
{@debug myArray[0]}
{@debug !isReady}
{@debug typeof user === 'object'}
```
The `{@debug}` tag without any arguments will insert a `debugger` statement that gets triggered when *any* state changes, as opposed to the specified variables.

@ -20,7 +20,7 @@ onMount(callback: () => () => void)
The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component's initialisation (but doesn't need to live *inside* the component; it can be called from an external module).
`onMount` does not run inside a [server-side component](docs#server-side-component-api).
`onMount` does not run inside a [server-side component](docs#Server-side_component_API).
```html
<script>
@ -176,8 +176,39 @@ Retrieves the context that belongs to the closest parent component with the spec
#### `createEventDispatcher`
TODO
```js
dispatch: ((name: string, detail?: any) => void) = createEventDispatcher();
```
---
Creates an event dispatcher that can be used to dispatch [component events](docs#Component_events). Event dispatchers are functions that can take two arguments: `name` and `detail`.
Component events created with `createEventDispatcher` create a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture) and are not cancellable with `event.preventDefault()`. The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) property and can contain any type of data.
```html
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
</script>
<button on:click="{() => dispatch('notify', 'detail value')}">Fire Event</button>
```
---
Events dispatched from child components can be listened to in their parent. Any data provided when the event was dispatched is available on the `detail` property of the event object.
```html
<script>
function callbackFunction(event) {
console.log(`Notify fired! Detail: ${event.detail}`)
}
</script>
<Child on:notify="{callbackFunction}"/>
```
### `svelte/store`
@ -293,13 +324,13 @@ const time = readable(new Date(), set => {
store = derived(a, callback: (a: any) => any)
```
```js
store = derived(a, callback: (a: any, set: (value: any) => void) => void, initial_value: any)
store = derived(a, callback: (a: any, set: (value: any) => void) => void | () => void, initial_value: any)
```
```js
store = derived([a, ...b], callback: ([a: any, ...b: any[]]) => any)
```
```js
store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) => void) => void, initial_value: any)
store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) => void) => void | () => void, initial_value: any)
```
---
@ -328,6 +359,20 @@ const delayed = derived(a, ($a, set) => {
}, 'one moment...');
```
If you return a function from the callback, it will be called when a) the callback runs again, or b) the last subscriber unsubscribes:
```js
import { derived } from 'svelte/store';
const tick = derived(frequency, ($frequency, set) => {
const interval = setInterval(() => set(Date.now()), 1000 / frequency);
return () => {
clearInterval(interval);
}
}, 'one moment...');
```
---
In both cases, an array of arguments can be passed as the first argument instead of a single store.
@ -375,7 +420,7 @@ Tweened stores update their values over a fixed duration. The following options
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the tween lasts
* `easing` (`function`, default `t => t`) — an [easing function](docs#svelte-easing)
* `easing` (`function`, default `t => t`) — an [easing function](docs#svelte_easing)
* `interpolator` (`function`) — see below
`store.set` and `store.update` can accept a second `options` argument that will override the options passed in upon instantiation.
@ -455,6 +500,8 @@ A `spring` store gradually changes to its target value based on its `stiffness`
As with [`tweened`](#tweened) stores, `set` and `update` return a Promise that resolves if the spring settles. The `store.stiffness` and `store.damping` properties can be changed while the spring is in motion, and will take immediate effect.
Both `set` and `update` can take a second argument — an object with `hard` or `soft` properties. `{ hard: true }` sets the target value immediately; `{ soft: n }` preserves existing momentum for `n` seconds before settling. `{ soft: true }` is equivalent to `{ soft: 0.5 }`.
[See a full example on the spring tutorial.](tutorial/spring)
```html
@ -470,26 +517,280 @@ As with [`tweened`](#tweened) stores, `set` and `update` return a Promise that r
### `svelte/transition`
TODO
The `svelte/transition` module exports six functions: `fade`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with svelte [`transitions`](docs#Transitions).
#### `fade`
```sv
transition:fade={params}
```
```sv
in:fade={params}
```
```sv
out:fade={params}
```
---
Animates the opacity of an element from 0 to the current opacity for `in` transitions and from the current opacity to 0 for `out` transitions.
`fade` accepts the following parameters:
* fade, fly, slide, scale, draw
* crossfade...
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
You can see the `fade` transition in action in the [transition tutorial](tutorial/transition).
### `svelte/animation`
```html
<script>
import { fade } from 'svelte/transition';
</script>
TODO
{#if condition}
<div transition:fade="{{delay: 250, duration: 300}}">
fades in and out
</div>
{/if}
```
#### `fly`
```sv
transition:fly={params}
```
```sv
in:fly={params}
```
```sv
out:fly={params}
```
---
Animates the x and y positions and the opacity of an element. `in` transitions animate from an element's current (default) values to the provided values, passed as parameters. `out` transitions animate from the provided values to an element's default values.
`fly` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `x` (`number`, default 0) - the x offset to animate out to and in from
* `y` (`number`, default 0) - the y offset to animate out to and in from
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
You can see the `fly` transition in action in the [transition tutorial](tutorial/adding-parameters-to-transitions).
```html
<script>
import { fly } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
</script>
{#if condition}
<div transition:fly="{{delay: 250, duration: 300, x: 100, y: 500, opacity: 0.5, easing: quintOut}}">
flies in and out
</div>
{/if}
```
#### `slide`
```sv
transition:slide={params}
```
```sv
in:slide={params}
```
```sv
out:slide={params}
```
---
Slides an element in and out.
`slide` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
```html
<script>
import { slide } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
</script>
{#if condition}
<div transition:slide="{{delay: 250, duration: 300, easing: quintOut }}">
slides in and out
</div>
{/if}
```
#### `scale`
```sv
transition:scale={params}
```
```sv
in:scale={params}
```
```sv
out:scale={params}
```
---
Animates the opacity and scale of an element. `in` transitions animate from an element's current (default) values to the provided values, passed as parameters. `out` transitions animate from the provided values to an element's default values.
`scale` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicOut`) — an [easing function](docs#svelte_easing)
* `start` (`number`, default 0) - the scale value to animate out to and in from
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
```html
<script>
import { scale } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
</script>
{#if condition}
<div transition:scale="{{duration: 500, delay: 500, opacity: 0.5, start: 0.5, easing: quintOut}}">
scales in and out
</div>
{/if}
```
#### `draw`
```sv
transition:draw={params}
```
```sv
in:draw={params}
```
```sv
out:draw={params}
```
---
Animates the stroke of an SVG element, like a snake in a tube. `in` transitions begin with the path invisible and draw the path to the screen over time. `out` transitions start in a visible state and gradually erase the path. `draw` only works with elements that have a `getTotalLength` method, like `<path>` and `<polyline>`.
`scale` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `speed` (`number`, default undefined) - the speed of the animation, see below.
* `duration` (`number` | `function`, default 800) — milliseconds the transition lasts
* `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing)
The `speed` parameter is a means of setting the duration of the transition relative to the path's length. It is modifier that is applied to the length of the path: `duration = length / speed`. A path that is 1000 pixels with a speed of 1 will have a duration of `1000ms`, setting the speed to `0.5` will halve that duration and setting it to `2` will double it.
```html
<script>
import { draw } from 'svelte/transition';
import { quintOut } from 'svelte/easing';
</script>
<svg viewBox="0 0 5 5" xmlns="http://www.w3.org/2000/svg">
{#if condition}
<path transition:draw="{{duration: 5000, delay: 500, easing: quintOut}}"
d="M2 1 h1 v1 h1 v1 h-1 v1 h-1 v-1 h-1 v-1 h1 z"
fill="none"
stroke="cornflowerblue"
stroke-width="0.1px"
stroke-linejoin="round"
/>
{/if}
</svg>
```
<!-- Crossfade is coming soon... -->
### `svelte/animate`
The `svelte/animate` module exports one function for use with svelte [animations](docs#Animations).
#### `flip`
```sv
animate:flip={params}
```
The `flip` function calculates the start and end position of an element and animates between them, translating the `x` and `y` values. `flip` stands for [First, Last, Invert, Play](https://aerotwist.com/blog/flip-your-animations/).
`flip` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number` | `function`, default `d => Math.sqrt(d) * 120`) — see below
* `easing` (`function`, default [`cubicOut`](docs#cubicOut)) — an [easing function](docs#svelte_easing)
`duration` can be be provided as either:
- a `number`, in milliseconds.
- a function, `distance: number => duration: number`, receiving the distance the element will travel in pixels and returning the duration in milliseconds. This allows you to assign a duration that is relative to the distance travelled by each element.
---
You can see a full example on the [animations tutorial](tutorial/animate)
```html
<script>
import { flip } from 'svelte/animate';
import { quintOut } from 'svelte/easing';
let list = [1, 2, 3];
</script>
{#each list as n (n)}
<div animate:flip="{{delay: 250, duration: 250, easing: quintOut}}">
{n}
</div>
{/each}
```
* TODO this doesn't even exist yet
TODO
### `svelte/easing`
* TODO could have nice little interactive widgets showing the different functions, maybe
### `svelte/register`
TODO
To render Svelte components in Node.js without bundling, use `require('svelte/register')`. After that, you can use `require` to include any `.svelte` file.
```js
require('svelte/register');
const App = require('./App.svelte').default;
...
const { html, css, head } = App.render({ answer: 42 });
```
> The `.default` is necessary because we're converting from native JavaScript modules to the CommonJS modules recognised by Node. Note that if your component imports JavaScript modules, they will fail to load in Node and you will need to use a bundler instead.
To set compile options, or to use a custom file extension, call the `register` hook as a function:
```js
require('svelte/register')({
extensions: ['.customextension'], // defaults to ['.html', '.svelte']
preserveComments: true
});
```
### Client-side component API
@ -500,8 +801,6 @@ TODO
const component = new Component(options)
```
---
A client-side component — that is, a component compiled with `generate: 'dom'` (or the `generate` option left unspecified) is a JavaScript class.
```js
@ -532,7 +831,7 @@ Existing children of `target` are left where they are.
---
The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](docs#compile).
The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](docs#svelte_compile).
Whereas children of `target` are normally left alone, `hydrate: true` will cause any children to be removed. For that reason, the `anchor` option cannot be used alongside `hydrate: true`.
@ -573,10 +872,14 @@ component.$on(event, callback)
Causes the `callback` function to be called whenever the component dispatches an `event`.
A function is returned that will remove the event listener when called.
```js
app.$on('selected', event => {
const off = app.$on('selected', event => {
console.log(event.detail.selection);
});
off();
```
#### `$destroy`

@ -153,6 +153,30 @@ compiled: {
-->
### `svelte.parse`
```js
ast: object = svelte.parse(
source: string,
options?: {
filename?: string,
customElement?: boolean
}
)
```
---
The `parse` function parses a component, returning only its abstract syntax tree. Unlike compiling with the `generate: false` option, this will not perform any validation or other analysis of the component beyond parsing it.
```js
const svelte = require('svelte/compiler');
const ast = svelte.parse(source, { filename: 'App.svelte' });
```
### `svelte.preprocess`
```js
@ -280,6 +304,38 @@ const { code } = svelte.preprocess(source, [
```
### `svelte.walk`
```js
walk(ast: Node, {
enter(node: Node, parent: Node, prop: string, index: number)?: void,
leave(node: Node, parent: Node, prop: string, index: number)?: void
})
```
---
The `walk` function provides a way to walk to abstract syntax trees generated by the parser, using the compiler's own built-in instance of [estree-walker](https://github.com/Rich-Harris/estree-walker).
The walker takes an abstract syntax tree to walk and an object with two optional methods: `enter` and `leave`. For each node, `enter` is called (if present). Then, unless `this.skip()` is called during `enter`, each of the children are traversed, and then `leave` is called on the node.
```js
const svelte = require('svelte/compiler');
svelte.walk(ast, {
enter(node, parent, prop, index) {
do_something(node);
if (should_skip_children(node)) {
this.skip();
}
},
leave(node, parent, prop, index) {
do_something_else(node);
}
});
```
### `svelte.VERSION`
---

@ -5,7 +5,7 @@
name: 'svelte',
version: 3,
speed: 'blazing',
website: 'https://svelte.technology'
website: 'https://svelte.dev'
};
</script>

@ -1,5 +1,5 @@
<script>
import Eliza from 'elizanode';
import Eliza from 'elizabot';
import { beforeUpdate, afterUpdate } from 'svelte';
let div;

@ -1,8 +1,9 @@
<script>
import { quintOut } from 'svelte/easing';
import crossfade from './crossfade.js'; // TODO put this in svelte/transition!
import { crossfade } from 'svelte/transition';
import { flip } from 'svelte/animate';
const { send, receive } = crossfade({
const [send, receive] = crossfade({
fallback(node, params) {
const style = getComputedStyle(node);
const transform = style.transform === 'none' ? '' : style.transform;
@ -43,12 +44,6 @@
function remove(todo) {
todos = todos.filter(t => t !== todo);
}
function handleKeydown(event) {
if (event.which === 13) {
addTodo(event.target);
}
}
</script>
<style>
@ -114,7 +109,7 @@
</style>
<div class='board'>
<input class="new-todo" placeholder="what needs to be done?" on:enter={add}>
<input class="new-todo" placeholder="what needs to be done?" on:keydown="{event => event.which === 13 && add(this)}">
<div class='left'>
<h2>todo</h2>
@ -122,6 +117,7 @@
<label
in:receive="{{key: todo.id}}"
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description}
@ -136,6 +132,7 @@
<label
in:receive="{{key: todo.id}}"
out:send="{{key: todo.id}}"
animate:flip
>
<input type=checkbox bind:checked={todo.done}>
{todo.description}
@ -143,4 +140,4 @@
</label>
{/each}
</div>
</div>
</div>

@ -1,65 +0,0 @@
import { quintOut } from 'svelte/easing';
export default function crossfade({ send, receive, fallback }) {
let requested = new Map();
let provided = new Map();
function crossfade(from, node) {
const to = node.getBoundingClientRect();
const dx = from.left - to.left;
const dy = from.top - to.top;
const style = getComputedStyle(node);
const transform = style.transform === 'none' ? '' : style.transform;
return {
duration: 400,
easing: quintOut,
css: (t, u) => `
opacity: ${t};
transform: ${transform} translate(${u * dx}px,${u * dy}px);
`
};
}
return {
send(node, params) {
provided.set(params.key, {
rect: node.getBoundingClientRect()
});
return () => {
if (requested.has(params.key)) {
const { rect } = requested.get(params.key);
requested.delete(params.key);
return crossfade(rect, node);
}
// if the node is disappearing altogether
// (i.e. wasn't claimed by the other list)
// then we need to supply an outro
provided.delete(params.key);
return fallback(node, params);
};
},
receive(node, params) {
requested.set(params.key, {
rect: node.getBoundingClientRect()
});
return () => {
if (provided.has(params.key)) {
const { rect } = provided.get(params.key);
provided.delete(params.key);
return crossfade(rect, node);
}
requested.delete(params.key);
return fallback(node, params);
};
}
};
}

@ -1,9 +1,13 @@
<script>
import Modal from './Modal.svelte';
let showModal = true;
let showModal = false;
</script>
<button on:click="{() => showModal = true}">
show modal
</button>
{#if showModal}
<Modal on:close="{() => showModal = false}">
<h2 slot="header">
@ -22,8 +26,4 @@
<a href="https://www.merriam-webster.com/dictionary/modal">merriam-webster.com</a>
</Modal>
{:else}
<button on:click="{() => showModal = true}">
show modal
</button>
{/if}
{/if}

@ -1,43 +0,0 @@
<script>
import AudioPlayer from './AudioPlayer.svelte';
</script>
<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer
src="tutorial/music/strauss.mp3"
title="The Blue Danube Waltz"
composer="Johann Strauss"
performer="European Archive"
/>
<!-- https://musopen.org/music/43775-the-planets-op-32/ -->
<AudioPlayer
src="tutorial/music/holst.mp3"
title="Mars, the Bringer of War"
composer="Gustav Holst"
performer="USAF Heritage of America Band"
/>
<!-- https://musopen.org/music/8010-3-gymnopedies/ -->
<AudioPlayer
src="tutorial/music/satie.mp3"
title="Gymnopédie no. 1"
composer="Erik Satie"
performer="Prodigal Procrastinator"
/>
<!-- https://musopen.org/music/2567-symphony-no-5-in-c-minor-op-67/ -->
<AudioPlayer
src="tutorial/music/beethoven.mp3"
title="Symphony no. 5 in Cm, Op. 67 - I. Allegro con brio"
composer="Ludwig van Beethoven"
performer="European Archive"
/>
<!-- https://musopen.org/music/43683-requiem-in-d-minor-k-626/ -->
<AudioPlayer
src="tutorial/music/mozart.mp3"
title="Requiem in D minor, K. 626 - III. Sequence - Lacrymosa"
composer="Wolfgang Amadeus Mozart"
performer="Markus Staab"
/>

@ -1,46 +0,0 @@
<script context="module">
const elements = new Set();
</script>
<script>
import { onMount } from 'svelte';
export let src;
export let title;
export let composer;
export let performer;
let audio;
let paused = true;
onMount(() => {
elements.add(audio);
return () => elements.delete(audio);
});
function stopOthers() {
elements.forEach(element => {
if (element !== audio) element.pause();
});
}
</script>
<style>
article { margin: 0 0 1em 0; max-width: 800px }
h2, p { margin: 0 0 0.3em 0; }
audio { width: 100%; margin: 0.5em 0 1em 0; }
.playing { color: #ff3e00; }
</style>
<article class:playing={!paused}>
<h2>{title}</h2>
<p><strong>{composer}</strong> / performed by {performer}</p>
<audio
bind:this={audio}
bind:paused
on:play={stopOthers}
controls
{src}
></audio>
</article>

@ -1,3 +1,3 @@
{
"title": "Exports"
"title": "Named exports"
}

@ -30,10 +30,7 @@
$: selected = filteredPeople[i];
$: {
first = selected ? selected.first : '';
last = selected ? selected.last : '';
}
$: reset_inputs(selected);
function create() {
people = people.concat({ first, last });
@ -53,7 +50,8 @@
}
function reset_inputs(person) {
({ first, last } = person);
first = person ? person.first : '';
last = person ? person.last : '';
}
</script>

@ -1,11 +1,13 @@
export default function flash(element) {
element.style.transition = 'none';
element.style.color = 'rgba(255,62,0,1)';
element.style.backgroundColor = 'rgba(255,62,0,0.2)';
requestAnimationFrame(() => {
element.style.transition = 'none';
element.style.color = 'rgba(255,62,0,1)';
element.style.backgroundColor = 'rgba(255,62,0,0.2)';
setTimeout(() => {
element.style.transition = 'color 1s, background 1s';
element.style.color = '';
element.style.backgroundColor = '';
setTimeout(() => {
element.style.transition = 'color 1s, background 1s';
element.style.color = '';
element.style.backgroundColor = '';
});
});
}

@ -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>

@ -29,4 +29,4 @@ Each tutorial chapter will have a 'Show me' button that you can click if you get
## Understanding components
In Svelte, an application is composed from one or more *components*. A component is a reusable self-contained block of code that encapsulates HTML, CSS and JavaScript that belong together, written into a `.svelte` file. The 'hello world' example on the right is a simple component.
In Svelte, an application is composed from one or more *components*. A component is a reusable self-contained block of code that encapsulates HTML, CSS and JavaScript that belong together, written into a `.svelte` file. The 'hello world' example in the code editor is a simple component.

@ -3,4 +3,4 @@
let name = 'Rick Astley';
</script>
<img {src} alt="{name} dancing">
<img {src} alt="{name} dances.">

@ -16,13 +16,13 @@ That's better. But Svelte is giving us a warning:
When building web apps, it's important to make sure that they're *accessible* to the broadest possible userbase, including people with (for example) impaired vision or motion, or people without powerful hardware or good internet connections. Accessibility (shortened to a11y) isn't always easy to get right, but Svelte will help by warning you if you write inaccessible markup.
In this case, we're missing the `alt` tag that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one:
In this case, we're missing the `alt` attribute that describes the image for people using screenreaders, or people with slow or flaky internet connections that can't download the image. Let's add one:
```html
<img src={src} alt="A man dancing">
<img src={src} alt="A man dances.">
```
We can use curly braces *inside* attributes. Try changing it to `"{name} dancing"` — remember to declare a `name` variable in the `<script>` block.
We can use curly braces *inside* attributes. Try changing it to `"{name} dances."` — remember to declare a `name` variable in the `<script>` block.
## Shorthand attributes
@ -30,6 +30,6 @@ We can use curly braces *inside* attributes. Try changing it to `"{name} dancing
It's not uncommon to have an attribute where the name and value are the same, like `src={src}`. Svelte gives us a convenient shorthand for these cases:
```html
<img {src} alt="...">
<img {src} alt="A man dances.">
```

@ -12,4 +12,4 @@ In Svelte, you do this with the special `{@html ...}` tag:
<p>{@html string}</p>
```
> Svelte doesn't perform any sanitization of the data before it gets inserted into the DOM. In other words, it's critical that you manually escape HTML that comes from sources you don't trust, otherwise you risk exposing your users to XSS attacks.
> Svelte doesn't perform any sanitization of the expression inside `{@html ...}` before it gets inserted into the DOM. In other words, if you use this feature it's critical that you manually escape HTML that comes from sources you don't trust, otherwise you risk exposing your users to XSS attacks.

@ -28,4 +28,4 @@ const app = new App({
});
```
You can then interact with `app` using the [component API](docs/component-api) if you need to.
You can then interact with `app` using the [component API](docs#Client-side_component_API) if you need to.

@ -13,14 +13,20 @@ function addNumber() {
}
```
But there's a more *idiomatic* solution:
But there's a more idiomatic solution:
```js
function addNumber() {
numbers = [...numbers, numbers.length + 1;]
numbers = [...numbers, numbers.length + 1];
}
```
You can use similar patterns to replace `pop`, `shift`, `unshift` and `splice`.
> Assignments to *properties* of arrays and objects — e.g. `obj.foo += 1` or `array[i] = x` — work the same way as assignments to the values themselves.
Assignments to *properties* of arrays and objects — e.g. `obj.foo += 1` or `array[i] = x` — work the same way as assignments to the values themselves.
```js
function addNumber() {
numbers[numbers.length] = numbers.length + 1;
}
```

@ -10,9 +10,9 @@ We can easily specify default values for props:
</script>
```
If we now instantiate the component without an `answer` prop, it will fall back to the default:
If we now add a second component *without* an `answer` prop, it will fall back to the default:
```html
<Nested answer={42}/>
<Nested/>
```
```

@ -5,7 +5,7 @@
name: 'svelte',
version: 3,
speed: 'blazing',
website: 'https://svelte.technology'
website: 'https://svelte.dev'
};
</script>

@ -5,7 +5,7 @@
name: 'svelte',
version: 3,
speed: 'blazing',
website: 'https://svelte.technology'
website: 'https://svelte.dev'
};
</script>

@ -18,10 +18,10 @@ DOM event handlers can have *modifiers* that alter their behaviour. For example,
The full list of modifiers:
* `preventDefault` — calls `event.preventDefault()` before running the handler. Useful for e.g. client-side form handling
* `preventDefault` — calls `event.preventDefault()` before running the handler. Useful for client-side form handling, for example.
* `stopPropagation` — calls `event.stopPropagation()`, preventing the event reaching the next element
* `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so)
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase ([MDN docs](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture))
* `once` — remove the handler after the first time it runs
You can chain modifiers together, e.g. `on:click|once|capture={...}`.
You can chain modifiers together, e.g. `on:click|once|capture={...}`.

@ -4,7 +4,7 @@ title: Text inputs
As a general rule, data flow in Svelte is *top down* — a parent component can set props on a child component, and a component can set attributes on an element, but not the other way around.
Sometimes it's useful to break that rule. Take the case of the `<input>` element in this component — we *could* add an `on:input` event handler that set the value of `name` to `event.target.value`, but it's a bit... boilerplatey. It gets even worse with other kinds of form element, as we'll see.
Sometimes it's useful to break that rule. Take the case of the `<input>` element in this component — we *could* add an `on:input` event handler that set the value of `name` to `event.target.value`, but it's a bit... boilerplatey. It gets even worse with other form elements, as we'll see.
Instead, we can use the `bind:value` directive:
@ -12,4 +12,4 @@ Instead, we can use the `bind:value` directive:
<input bind:value={name}>
```
This means that not only will changes to the value of `name` update the input value, but changes to the input value will update `name`.
This means that not only will changes to the value of `name` update the input value, but changes to the input value will update `name`.

@ -8,8 +8,8 @@ On line 116, add `currentTime={time}`, `duration` and `paused` bindings:
```html
<video
poster="http://svelte-assets.surge.sh/caminandes-llamigos.jpg"
src="http://svelte-assets.surge.sh/caminandes-llamigos.mp4"
poster="https://svelte-assets.surge.sh/caminandes-llamigos.jpg"
src="https://svelte-assets.surge.sh/caminandes-llamigos.mp4"
on:mousemove={handleMousemove}
on:mousedown={handleMousedown}
bind:currentTime={time}
@ -31,9 +31,9 @@ The complete set of bindings for `<audio>` and `<video>` is as follows — four
* `seekable` (readonly) — ditto
* `played` (readonly) — ditto
...and three *two-way* bindings:
...and four *two-way* bindings:
* `currentTime` — the current point in the video, in seconds
* `playbackRate` — how fast to play the video, where `1` is 'normal'
* `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1
* `volume` — a value between 0 and 1

@ -2,7 +2,7 @@
title: This
---
The readonly `this` binding applies to every element (and component) and allows to you obtain a reference to rendered elements. For example, we can get a reference to a `<canvas>` element:
The readonly `this` binding applies to every element (and component) and allows you to obtain a reference to rendered elements. For example, we can get a reference to a `<canvas>` element:
```html
<canvas
@ -12,4 +12,4 @@ The readonly `this` binding applies to every element (and component) and allows
></canvas>
```
Note that the value of `canvas` will be `undefined` until the component has mounted, so we put the logic inside the `onMount` [lifecycle function](tutorials/onmount).
Note that the value of `canvas` will be `undefined` until the component has mounted, so we put the logic inside the `onMount` [lifecycle function](tutorial/onmount).

@ -1,5 +1,5 @@
<script>
import Eliza from 'elizanode';
import Eliza from 'elizabot';
import { beforeUpdate, afterUpdate } from 'svelte';
let div;

@ -1,5 +1,5 @@
<script>
import Eliza from 'elizanode';
import Eliza from 'elizabot';
import { beforeUpdate, afterUpdate } from 'svelte';
let div;

@ -39,6 +39,8 @@ It starts to get a bit boilerplatey though, especially if your component subscri
<h1>The count is {$count}</h1>
```
> Auto-subscription only works with store variables that are declared (or imported) at the top-level scope of a component.
You're not limited to using `$count` inside the markup, either — you can use it anywhere in the `<script>` as well, such as in event handlers or reactive declarations.
> Any name beginning with `$` is assumed to refer to a store value. It's effectively a reserved character — Svelte will prevent you from declaring your own variables with a `$` prefix.

@ -2,7 +2,13 @@
title: In and out
---
Instead of the `transition` directive, an element can have an `in` or an `out` directive, or both together:
Instead of the `transition` directive, an element can have an `in` or an `out` directive, or both together. Import `fade` alongside `fly`...
```js
import { fade, fly } from 'svelte/transition';
```
...then replace the `transition` directive with separate `in` and `out` directives:
```html
<p in:fly="{{ y: 200, duration: 2000 }}" out:fade>

@ -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.

@ -4,7 +4,7 @@ title: Local transitions
Ordinarily, transitions will play on elements when any container block is added or destroyed. In the example here, toggling the visibility of the entire list also applies transitions to individual list elements.
Instead, we'd like transitions to play only when individual items are added and removed — on other words, when the user drags the slider.
Instead, we'd like transitions to play only when individual items are added and removed — in other words, when the user drags the slider.
We can achieve this with a *local* transition, which only plays when the immediate parent block is added or removed:
@ -12,4 +12,4 @@ We can achieve this with a *local* transition, which only plays when the immedia
<div transition:slide|local>
{item}
</div>
```
```

@ -27,7 +27,7 @@ import { pannable } from './pannable.js';
></div>
```
Open the `pannable.js` file. Like transition functions, an action function receives a `node` and some optional parameters, and returns an action object. That object must have a `destroy` function, which is called when the element is unmounted.
Open the `pannable.js` file. Like transition functions, an action function receives a `node` and some optional parameters, and returns an action object. That object can have a `destroy` function, which is called when the element is unmounted.
We want to fire `panstart` event when the user mouses down on the element, `panmove` events (with `dx` and `dy` properties showing how far the mouse moved) when they drag it, and `panend` events when they mouse up. One possible implementation looks like this:
@ -84,4 +84,3 @@ export function pannable(node) {
Update the `pannable` function and try moving the box around.
> This implementation is for demonstration purposes — a more complete one would also consider touch events.

@ -12,7 +12,7 @@ A component can specify *fallbacks* for any slots that are left empty, by puttin
</div>
```
We can now create instances of `<Box>` eithout any children:
We can now create instances of `<Box>` without any children:
```html
<Box>
@ -21,4 +21,4 @@ We can now create instances of `<Box>` eithout any children:
</Box>
<Box/>
```
```

@ -42,6 +42,6 @@ You can rename the variable, if you want — let's call it `active` in the paren
</Hoverable>
```
You can have as many of these components you like, and the slotted props will remain local to the component where they're declared.
You can have as many of these components as you like, and the slotted props will remain local to the component where they're declared.
> Named slots can also have props; use the `let` directive on an element with a `slot="..."` attribute, instead of on the component itself.
> Named slots can also have props; use the `let` directive on an element with a `slot="..."` attribute, instead of on the component itself.

@ -1,11 +1,13 @@
export default function flash(element) {
element.style.transition = 'none';
element.style.color = 'rgba(255,62,0,1)';
element.style.backgroundColor = 'rgba(255,62,0,0.2)';
requestAnimationFrame(() => {
element.style.transition = 'none';
element.style.color = 'rgba(255,62,0,1)';
element.style.backgroundColor = 'rgba(255,62,0,0.2)';
setTimeout(() => {
element.style.transition = 'color 1s, background 1s';
element.style.color = '';
element.style.backgroundColor = '';
setTimeout(() => {
element.style.transition = 'color 1s, background 1s';
element.style.color = '';
element.style.backgroundColor = '';
});
});
}

@ -1,11 +1,13 @@
export default function flash(element) {
element.style.transition = 'none';
element.style.color = 'rgba(255,62,0,1)';
element.style.backgroundColor = 'rgba(255,62,0,0.2)';
requestAnimationFrame(() => {
element.style.transition = 'none';
element.style.color = 'rgba(255,62,0,1)';
element.style.backgroundColor = 'rgba(255,62,0,0.2)';
setTimeout(() => {
element.style.transition = 'color 1s, background 1s';
element.style.color = '';
element.style.backgroundColor = '';
setTimeout(() => {
element.style.transition = 'color 1s, background 1s';
element.style.color = '';
element.style.backgroundColor = '';
});
});
}

@ -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.

@ -6,6 +6,6 @@ You've now finished the Svelte tutorial and are ready to start building apps. Yo
To get set up in your local development environment, check out [the quickstart guide](blog/the-easiest-way-to-get-started).
If you're looking for a more expansive framework that includes routing, server-side rendering and everything else, take a look at [Sapper](https://sapper.svelte.technology).
If you're looking for a more expansive framework that includes routing, server-side rendering and everything else, take a look at [Sapper](https://sapper.svelte.dev).
Most importantly: since you're now a member of the Svelte community, you should [join our friendly Discord chatroom](https://discord.gg/yy75DKs). That's where you'll find fellow Svelte users, and it's where we plan the future of the framework.
Most importantly: since you're now a member of the Svelte community, you should [join our friendly Discord chatroom](chat). That's where you'll find fellow Svelte users, and it's where we plan the future of the framework.

@ -0,0 +1,25 @@
exports.up = DB => {
DB.sql(`
create table if not exists users (
id serial primary key,
uid character varying(255) not null unique,
name character varying(255),
username character varying(255) not null,
avatar text,
github_token character varying(255),
created_at timestamp with time zone NOT NULL DEFAULT now(),
updated_at timestamp with time zone
);
create unique index if not exists users_pkey ON users(id int4_ops);
create unique index if not exists users_uid_key ON users(uid text_ops);
`);
};
exports.down = DB => {
DB.sql(`
drop table if exists users cascade;
drop index if exists users_uid_key;
drop index if exists users_pkey;
`);
};

@ -0,0 +1,24 @@
exports.up = DB => {
DB.sql(`
create table if not exists gists (
id serial primary key,
uid uuid NOT NULL DEFAULT gen_random_uuid(),
user_id integer REFERENCES users(id) not null,
name character varying(255) not null,
files json not null,
created_at timestamp with time zone NOT NULL DEFAULT now(),
updated_at timestamp with time zone
);
create unique index if not exists gists_pkey ON gists(id int4_ops);
create index if not exists gists_user_id_key ON gists(user_id int4_ops);
`);
};
exports.down = DB => {
DB.sql(`
drop table if exists gists cascade;
drop index if exists gists_user_id_key;
drop index if exists gists_pkey;
`);
};

@ -1,17 +0,0 @@
{
"version": 1,
"name": "svelte.dev",
"alias": "svelte.dev",
"env": {
"NODE_ENV": "production",
"BASEURL": "https://svelte.dev",
"GITHUB_CLIENT_ID": "@svelte-dev-client-id",
"GITHUB_CLIENT_SECRET": "@svelte-dev-client-secret",
"MAPBOX_ACCESS_TOKEN": "@svelte-mapbox-access-token"
},
"files": [
"__sapper__/build",
"static",
"content"
]
}

3162
site/package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,62 +1,67 @@
{
"name": "svelte.technology",
"name": "svelte.dev",
"version": "1.0.0",
"description": "Docs and examples for Svelte",
"scripts": {
"dev": "sapper dev",
"sapper": "sapper build --legacy && npm run update_shimport",
"dev": "npm run copy-workers && sapper dev",
"copy-workers": "rm -rf static/workers && cp -r node_modules/@sveltejs/svelte-repl/workers static",
"migrate": "node-pg-migrate -r dotenv/config",
"sapper": "npm run copy-workers && sapper build --legacy",
"update_shimport": "cp node_modules/shimport/index.js __sapper__/build/client/shimport@0.0.14.js",
"update": "node scripts/update_template.js && node scripts/get-contributors.js",
"start": "node __sapper__/build",
"cy:run": "cypress run",
"cy:open": "cypress open",
"test": "run-p --race dev cy:run",
"deploy": "npm run stage && now alias",
"prestage": "npm run update && npm run sapper",
"stage": "now"
"testsrc": "mocha -r esm test/**",
"deploy": "make deploy"
},
"dependencies": {
"codemirror": "^5.44.0",
"compression": "^1.7.3",
"@polka/redirect": "^1.0.0-next.0",
"@polka/send": "^1.0.0-next.2",
"devalue": "^1.1.0",
"do-not-zip": "^1.0.0",
"dotenv": "^6.2.0",
"express": "^4.16.4",
"express-session": "^1.15.6",
"golden-fleece": "^1.0.9",
"httpie": "^1.1.1",
"jsonwebtoken": "^8.5.1",
"marked": "^0.6.1",
"node-fetch": "^2.3.0",
"passport": "^0.4.0",
"passport-github": "^1.1.0",
"pg": "^7.10.0",
"polka": "^1.0.0-next.2",
"prismjs": "^1.15.0",
"session-file-store": "^1.2.0",
"shelljs": "^0.8.3",
"sirv": "^0.2.2",
"yootils": "0.0.14"
"sirv": "^0.4.0",
"yootils": "0.0.15"
},
"devDependencies": {
"@babel/core": "^7.3.3",
"@babel/core": "^7.4.4",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.2.0",
"@babel/preset-env": "^7.3.1",
"@babel/runtime": "^7.3.1",
"@sveltejs/svelte-repl": "0.0.10",
"chokidar": "^2.1.2",
"@babel/plugin-transform-runtime": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@babel/runtime": "^7.4.4",
"@sindresorhus/slugify": "^0.9.1",
"@sveltejs/site-kit": "^1.0.4",
"@sveltejs/svelte-repl": "^0.1.6",
"degit": "^2.1.3",
"eslint-plugin-svelte3": "^0.4.4",
"dotenv": "^8.0.0",
"eslint-plugin-svelte3": "^1.0.0",
"esm": "^3.2.22",
"jimp": "^0.6.0",
"now": "^14.0.0",
"mocha": "^6.1.3",
"node-fetch": "^2.3.0",
"node-pg-migrate": "^3.18.1",
"npm-run-all": "^4.1.5",
"rollup": "^1.2.2",
"rollup": "^1.11.3",
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-json": "^3.1.0",
"rollup-plugin-node-resolve": "^4.0.1",
"rollup-plugin-replace": "^2.1.0",
"rollup-plugin-commonjs": "^9.3.4",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^4.2.3",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^4.0.4",
"sapper": "^0.26.0-alpha.12",
"shimport": "0.0.16",
"svelte": "^3.0.0-beta.28"
"sapper": "^0.27.1",
"shelljs": "^0.8.3",
"svelte": "^3.0.0"
},
"engines": {
"node": ">=10.0.0"
}
}

@ -53,9 +53,6 @@ export default {
module: true
})
],
// temporary, pending Rollup 1.0
experimentalCodeSplitting: true
},
server: {
@ -74,12 +71,13 @@ export default {
commonjs(),
json()
],
external: Object.keys(pkg.dependencies).concat(
require('module').builtinModules || Object.keys(process.binding('natives'))
),
// temporary, pending Rollup 1.0
experimentalCodeSplitting: true
external: [
'yootils',
'codemirror',
...Object.keys(pkg.dependencies || {}).concat(
require('module').builtinModules || Object.keys(process.binding('natives'))
)
],
},
serviceworker: {
@ -95,4 +93,4 @@ export default {
!dev && terser()
]
}
};
};

@ -1,11 +0,0 @@
const fs = require('fs');
const files = [];
for (const path of process.argv.slice(2)) {
if (!path.includes('/.')) {
files.push({ path: path.slice(19), data: fs.readFileSync(path).toString() });
}
}
fs.writeFileSync('static/svelte-app.json', JSON.stringify(files));

@ -5,15 +5,26 @@ const Jimp = require('jimp');
process.chdir(__dirname);
const base = `https://api.github.com/repos/sveltejs/svelte/contributors`;
const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = process.env;
const SIZE = 64;
async function main() {
const res = await fetch(`https://api.github.com/repos/sveltejs/svelte/stats/contributors?client_id=${process.env.GITHUB_CLIENT_ID}&client_secret=${process.env.GITHUB_CLIENT_SECRET}`);
const contributors = await res.json();
const contributors = [];
let page = 1;
while (true) {
const res = await fetch(`${base}?client_id=${GITHUB_CLIENT_ID}&client_secret=${GITHUB_CLIENT_SECRET}&per_page=100&page=${page++}`);
const list = await res.json();
if (list.length === 0) break;
contributors.push(...list);
}
const authors = contributors
.sort((a, b) => b.total - a.total)
.map(({ author }) => author);
.sort((a, b) => b.contributions - a.contributions);
const sprite = new Jimp(SIZE * authors.length, SIZE);

@ -15,7 +15,7 @@ fs.readdirSync(`content/examples`).forEach(group_dir => {
async function main() {
const browser = await puppeteer.launch({
defaultViewport: {
width: 600 * 10 / 4,
width: 400 * 10 / 4,
height: 400 + 42,
deviceScaleFactor: 2
}
@ -25,7 +25,7 @@ async function main() {
for (const slug of slugs) {
try {
const output_file = `static/examples/thumbnails/${slug}.png`;
const output_file = `static/examples/thumbnails/${slug}.jpg`;
if (fs.existsSync(output_file)) {
console.log(c.gray(`skipping ${slug}`));
continue;
@ -45,16 +45,16 @@ async function main() {
image.autocrop();
// image.scale(0.25);
if (image.bitmap.width > 300 || image.bitmap.width > 200) {
if (image.bitmap.width > 200 || image.bitmap.width > 200) {
const scale = Math.min(
300 / image.bitmap.width,
200 / image.bitmap.width,
200 / image.bitmap.height
);
image.scale(scale);
}
await image.write(output_file);
await image.quality(75).write(output_file);
} catch (err) {
console.log(c.bold().red(`failed to screenshot ${slug}`));
console.log(err);

@ -1,22 +1,25 @@
const sh = require('shelljs');
const fs = require('fs')
const fs = require('fs');
sh.cd(__dirname+'/../')
sh.cd(__dirname + '/../');
// fetch svelte app
sh.rm('-rf','scripts/svelte-app')
sh.exec('npx degit sveltejs/template#v3 scripts/svelte-app')
sh.rm('-rf','scripts/svelte-app');
sh.exec('npx degit sveltejs/template scripts/svelte-app');
// remove src (will be recreated client-side) and node_modules
sh.rm('-rf', 'scripts/svelte-app/src')
sh.rm('-rf', 'scripts/svelte-app/node_modules')
sh.rm('-rf', 'scripts/svelte-app/src');
sh.rm('-rf', 'scripts/svelte-app/node_modules');
// build svelte-app.json
const appPath = 'scripts/svelte-app'
let files = []
const appPath = 'scripts/svelte-app';
const files = [];
for (const path of sh.find(appPath).filter(p => fs.lstatSync(p).isFile()) ) {
files.push({ path: path.slice(appPath.length + 1), data: fs.readFileSync(path).toString() });
const bytes = fs.readFileSync(path);
const string = bytes.toString();
const data = bytes.compare(Buffer.from(string)) === 0 ? string : [...bytes];
files.push({ path: path.slice(appPath.length + 1), data });
}
fs.writeFileSync('static/svelte-app.json', JSON.stringify(files));

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save