diff --git a/.gitignore b/.gitignore index 228136cbc8..ee1daa2c03 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,6 @@ node_modules /transition /animate /scratch/ -/coverage/ -/coverage.lcov /test/*/samples/_ /yarn-error.log _actual*.* diff --git a/CHANGELOG.md b/CHANGELOG.md index 39dc47b387..1dd186cfcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,37 @@ # Svelte changelog +## 3.46.4 + +* Avoid `maximum call stack size exceeded` errors on large components ([#4694](https://github.com/sveltejs/svelte/issues/4694)) +* Preserve leading space with `preserveWhitespace: true` ([#4731](https://github.com/sveltejs/svelte/issues/4731)) +* Preserve leading space in `
` tags ([#6437](https://github.com/sveltejs/svelte/issues/6437))
+* Improve error message when trying to use `style:` directives on inline components ([#7177](https://github.com/sveltejs/svelte/issues/7177))
+* Add `FormData` as a known global ([#7199](https://github.com/sveltejs/svelte/pull/7199))
+* Mark `css`/`instance`/`module` AST properties as optional in types ([#7204](https://github.com/sveltejs/svelte/pull/7204))
+
+## 3.46.3
+
+* Ignore whitespace in `{#each}` blocks when containing elements with `animate:` ([#5477](https://github.com/sveltejs/svelte/pull/5477))
+* Throw compiler error when variable in `context="instance"` collides with import in `context="module"` ([#7090](https://github.com/sveltejs/svelte/issues/7090))
+* Fix compiler crash when `{@const}` contains arrow functions ([#7134](https://github.com/sveltejs/svelte/issues/7134))
+
+## 3.46.2
+
+* Export `FlipParams` interface from `svelte/animate` ([#7103](https://github.com/sveltejs/svelte/issues/7103))
+* Fix `style:` directive reactivity inside `{#each}` block ([#7136](https://github.com/sveltejs/svelte/issues/7136))
+
+## 3.46.1
+
+* Handle `style:kebab-case` directives ([#7122](https://github.com/sveltejs/svelte/issues/7122))
+* Improve AST produced for `style:` directives ([#7127](https://github.com/sveltejs/svelte/pull/7127))
+
+## 3.46.0
+
+* Implement `{@const}` tag ([RFC #33](https://github.com/sveltejs/rfcs/pull/33), [#6413](https://github.com/sveltejs/svelte/pull/6413))
+* Implement `style:` directive ([RFC #42](https://github.com/sveltejs/rfcs/pull/42), [#5923](https://github.com/sveltejs/svelte/pull/5923))
+* Fix style manager conflicts when using multiple Svelte instances ([#7026](https://github.com/sveltejs/svelte/issues/7026))
+* Fix hydration when using `{@html}` ([#7115](https://github.com/sveltejs/svelte/issues/7115))
+
## 3.45.0
* Fix non-boolean attribute rendering in SSR to render truthy values as-is ([#6121](https://github.com/sveltejs/svelte/issues/6121))
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000000..65d86fe76a
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,3 @@
+This repository is governed by the Svelte Code of Conduct.
+
+https://github.com/sveltejs/community/blob/main/CODE_OF_CONDUCT.md
diff --git a/package-lock.json b/package-lock.json
index c0f623415d..e9b672d689 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,11 @@
{
"name": "svelte",
- "version": "3.45.0",
+ "version": "3.46.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "svelte",
- "version": "3.45.0",
+ "version": "3.46.4",
"license": "MIT",
"devDependencies": {
"@ampproject/remapping": "^0.3.0",
@@ -24,9 +23,7 @@
"@typescript-eslint/parser": "^4.31.2",
"acorn": "^8.4.1",
"agadoo": "^1.1.0",
- "c8": "^5.0.1",
- "code-red": "^0.2.4",
- "codecov": "^3.5.0",
+ "code-red": "^0.2.5",
"css-tree": "^1.1.2",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.24.2",
@@ -97,12 +94,6 @@
"node": ">=6.9.0"
}
},
- "node_modules/@bcoe/v8-coverage": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.1.tgz",
- "integrity": "sha512-KioOCsSvSvXx6xUNLiJz+P+VMb7NRcePjoefOr74Y5P6lEKsiOn35eZyZzgpK4XCNJdXTDR7+zykj0lwxRvZ2g==",
- "dev": true
- },
"node_modules/@eslint/eslintrc": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
@@ -329,33 +320,12 @@
"resolved": "git+ssh://git@github.com/sveltejs/eslint-config.git#31fd4faeea88990069502460b023698b1c9c2d13",
"dev": true
},
- "node_modules/@tootallnate/once": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz",
- "integrity": "sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==",
- "dev": true,
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/@types/estree": {
"version": "0.0.50",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
"integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
"dev": true
},
- "node_modules/@types/is-windows": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@types/is-windows/-/is-windows-0.2.0.tgz",
- "integrity": "sha1-byTuSHMdMRaOpRBhDW3RXl/Jxv8=",
- "dev": true
- },
- "node_modules/@types/istanbul-lib-coverage": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
- "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==",
- "dev": true
- },
"node_modules/@types/json-schema": {
"version": "7.0.9",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
@@ -767,15 +737,6 @@
"sprintf-js": "~1.0.2"
}
},
- "node_modules/argv": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
- "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
- "dev": true,
- "engines": {
- "node": ">=0.6.10"
- }
- },
"node_modules/array-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
@@ -960,32 +921,6 @@
"node": ">=6"
}
},
- "node_modules/c8": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/c8/-/c8-5.0.1.tgz",
- "integrity": "sha512-63V/XrzqX2wgByuJyafJYuaudvxxmGrm/acqRJpvbtKvRUj6h/85EFrVweQ14j1F7wRASp0W9zyZqj8fnWI+4Q==",
- "dev": true,
- "dependencies": {
- "@bcoe/v8-coverage": "^0.2.1",
- "find-up": "^3.0.0",
- "foreground-child": "^1.5.6",
- "furi": "^1.3.0",
- "istanbul-lib-coverage": "^2.0.1",
- "istanbul-lib-report": "^2.0.1",
- "istanbul-reports": "^2.2.4",
- "rimraf": "^2.6.2",
- "test-exclude": "^5.0.0",
- "v8-to-istanbul": "^3.1.3",
- "yargs": "^13.1.0",
- "yargs-parser": "^10.1.0"
- },
- "bin": {
- "c8": "bin/c8.js"
- },
- "engines": {
- "node": ">=10.12.0"
- }
- },
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@@ -1082,9 +1017,9 @@
}
},
"node_modules/code-red": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.2.4.tgz",
- "integrity": "sha512-tAJQiZviSyB2KUhz+rocKFzCHPkVooX2aFrdpfWDRvxWJaBQTYFJ/Z2TcWqbjXj5oJJBlqd2GxBXdtAhOXySVQ==",
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.2.5.tgz",
+ "integrity": "sha512-x+uQyJLNS1v0+74eXqM7FMPoM1fU/fN3tdexGWtCuVjCfxADt1TuuEGIGlFyCC2vhgINDctDb/rgSn8/ZDfJsQ==",
"dev": true,
"dependencies": {
"@types/estree": "^0.0.50",
@@ -1095,25 +1030,6 @@
"sourcemap-codec": "^1.4.8"
}
},
- "node_modules/codecov": {
- "version": "3.6.5",
- "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.6.5.tgz",
- "integrity": "sha512-v48WuDMUug6JXwmmfsMzhCHRnhUf8O3duqXvltaYJKrO1OekZWpB/eH6iIoaxMl8Qli0+u3OxptdsBOYiD7VAQ==",
- "dev": true,
- "dependencies": {
- "argv": "0.0.2",
- "ignore-walk": "3.0.3",
- "js-yaml": "3.13.1",
- "teeny-request": "6.0.1",
- "urlgrey": "0.4.4"
- },
- "bin": {
- "codecov": "bin/codecov"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
"node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -1171,31 +1087,12 @@
"typedarray": "^0.0.6"
}
},
- "node_modules/convert-source-map": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
- "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
- "dev": true,
- "dependencies": {
- "safe-buffer": "~5.1.1"
- }
- },
"node_modules/core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
- "node_modules/cross-spawn": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
- "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
- "dev": true,
- "dependencies": {
- "lru-cache": "^4.0.1",
- "which": "^1.2.9"
- }
- },
"node_modules/css-tree": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz",
@@ -2362,16 +2259,6 @@
"integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
"dev": true
},
- "node_modules/foreground-child": {
- "version": "1.5.6",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz",
- "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=",
- "dev": true,
- "dependencies": {
- "cross-spawn": "^4",
- "signal-exit": "^3.0.0"
- }
- },
"node_modules/forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@@ -2428,16 +2315,6 @@
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
- "node_modules/furi": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/furi/-/furi-1.3.0.tgz",
- "integrity": "sha512-TYoXEeRLKHXNWcCBP0VH1psPktQ9G8Y0GfZwMXCvwVbhbfNx7JItKWhB5mMBYufNjqxEHq+Ivd1nLtr5vQyVoQ==",
- "dev": true,
- "dependencies": {
- "@types/is-windows": "^0.2.0",
- "is-windows": "^1.0.2"
- }
- },
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -2692,38 +2569,6 @@
"whatwg-encoding": "^1.0.1"
}
},
- "node_modules/html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
- },
- "node_modules/http-proxy-agent": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
- "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
- "dev": true,
- "dependencies": {
- "@tootallnate/once": "1",
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/http-proxy-agent/node_modules/agent-base": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz",
- "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==",
- "dev": true,
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
"node_modules/http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -2773,15 +2618,6 @@
"node": ">= 4"
}
},
- "node_modules/ignore-walk": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
- "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
- "dev": true,
- "dependencies": {
- "minimatch": "^3.0.4"
- }
- },
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -3078,15 +2914,6 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true
},
- "node_modules/is-windows": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
- "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -3105,41 +2932,6 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
"dev": true
},
- "node_modules/istanbul-lib-coverage": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
- "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/istanbul-lib-report": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
- "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
- "dev": true,
- "dependencies": {
- "istanbul-lib-coverage": "^2.0.5",
- "make-dir": "^2.1.0",
- "supports-color": "^6.1.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/istanbul-reports": {
- "version": "2.2.7",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz",
- "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==",
- "dev": true,
- "dependencies": {
- "html-escaper": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -3384,16 +3176,6 @@
"node": ">=8"
}
},
- "node_modules/lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
- "dev": true,
- "dependencies": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
"node_modules/magic-string": {
"version": "0.25.3",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz",
@@ -3403,19 +3185,6 @@
"sourcemap-codec": "^1.4.4"
}
},
- "node_modules/make-dir": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
- "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
- "dev": true,
- "dependencies": {
- "pify": "^4.0.1",
- "semver": "^5.6.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/mdn-data": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
@@ -3656,15 +3425,6 @@
"semver": "^5.7.0"
}
},
- "node_modules/node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
- "dev": true,
- "engines": {
- "node": "4.x || >=6.0.0"
- }
- },
"node_modules/node-modules-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
@@ -3955,15 +3715,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/pify": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/pirates": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
@@ -4152,12 +3903,6 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
- "node_modules/pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
- },
"node_modules/psl": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz",
@@ -4256,19 +4001,6 @@
"node": ">=4"
}
},
- "node_modules/read-pkg-up": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
- "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
- "dev": true,
- "dependencies": {
- "find-up": "^3.0.0",
- "read-pkg": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
@@ -4585,12 +4317,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/signal-exit": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
- "dev": true
- },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -4760,15 +4486,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/stream-events": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz",
- "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==",
- "dev": true,
- "dependencies": {
- "stubs": "^3.0.0"
- }
- },
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -4838,12 +4555,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/stubs": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
- "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=",
- "dev": true
- },
"node_modules/sucrase": {
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.16.0.tgz",
@@ -4882,18 +4593,6 @@
"node": "*"
}
},
- "node_modules/supports-color": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
- "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/svelte": {
"version": "3.43.0",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.43.0.tgz",
@@ -5005,34 +4704,6 @@
"node": ">=8"
}
},
- "node_modules/teeny-request": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz",
- "integrity": "sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g==",
- "dev": true,
- "dependencies": {
- "http-proxy-agent": "^4.0.0",
- "https-proxy-agent": "^4.0.0",
- "node-fetch": "^2.2.0",
- "stream-events": "^1.0.5",
- "uuid": "^3.3.2"
- }
- },
- "node_modules/test-exclude": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
- "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3",
- "minimatch": "^3.0.4",
- "read-pkg-up": "^4.0.0",
- "require-main-filename": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -5235,12 +4906,6 @@
"punycode": "^2.1.0"
}
},
- "node_modules/urlgrey": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz",
- "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=",
- "dev": true
- },
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -5262,20 +4927,6 @@
"integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
"dev": true
},
- "node_modules/v8-to-istanbul": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-3.2.3.tgz",
- "integrity": "sha512-B8d/oxMtc/x0TYXr9b+Ywu5KexA/on4QMQ9M1kTYnoGZzKdo8LLk9ySlWePdDOtr2G0/2Injgcp3sOR9gU+3vQ==",
- "dev": true,
- "dependencies": {
- "@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^1.6.0",
- "source-map": "^0.7.3"
- },
- "engines": {
- "node": ">=10.10.0"
- }
- },
"node_modules/validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -5491,12 +5142,6 @@
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
"dev": true
},
- "node_modules/yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
- "dev": true
- },
"node_modules/yargs": {
"version": "13.3.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
@@ -5515,24 +5160,6 @@
"yargs-parser": "^13.1.2"
}
},
- "node_modules/yargs-parser": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
- "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
- "dev": true,
- "dependencies": {
- "camelcase": "^4.1.0"
- }
- },
- "node_modules/yargs-parser/node_modules/camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/yargs-unparser": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
@@ -5605,12 +5232,6 @@
"js-tokens": "^4.0.0"
}
},
- "@bcoe/v8-coverage": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.1.tgz",
- "integrity": "sha512-KioOCsSvSvXx6xUNLiJz+P+VMb7NRcePjoefOr74Y5P6lEKsiOn35eZyZzgpK4XCNJdXTDR7+zykj0lwxRvZ2g==",
- "dev": true
- },
"@eslint/eslintrc": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
@@ -5807,30 +5428,12 @@
"dev": true,
"from": "@sveltejs/eslint-config@github:sveltejs/eslint-config#v5.8.0"
},
- "@tootallnate/once": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz",
- "integrity": "sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==",
- "dev": true
- },
"@types/estree": {
"version": "0.0.50",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
"integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
"dev": true
},
- "@types/is-windows": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@types/is-windows/-/is-windows-0.2.0.tgz",
- "integrity": "sha1-byTuSHMdMRaOpRBhDW3RXl/Jxv8=",
- "dev": true
- },
- "@types/istanbul-lib-coverage": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
- "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==",
- "dev": true
- },
"@types/json-schema": {
"version": "7.0.9",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
@@ -6121,12 +5724,6 @@
"sprintf-js": "~1.0.2"
}
},
- "argv": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
- "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
- "dev": true
- },
"array-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
@@ -6278,26 +5875,6 @@
"integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==",
"dev": true
},
- "c8": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/c8/-/c8-5.0.1.tgz",
- "integrity": "sha512-63V/XrzqX2wgByuJyafJYuaudvxxmGrm/acqRJpvbtKvRUj6h/85EFrVweQ14j1F7wRASp0W9zyZqj8fnWI+4Q==",
- "dev": true,
- "requires": {
- "@bcoe/v8-coverage": "^0.2.1",
- "find-up": "^3.0.0",
- "foreground-child": "^1.5.6",
- "furi": "^1.3.0",
- "istanbul-lib-coverage": "^2.0.1",
- "istanbul-lib-report": "^2.0.1",
- "istanbul-reports": "^2.2.4",
- "rimraf": "^2.6.2",
- "test-exclude": "^5.0.0",
- "v8-to-istanbul": "^3.1.3",
- "yargs": "^13.1.0",
- "yargs-parser": "^10.1.0"
- }
- },
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@@ -6376,9 +5953,9 @@
}
},
"code-red": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.2.4.tgz",
- "integrity": "sha512-tAJQiZviSyB2KUhz+rocKFzCHPkVooX2aFrdpfWDRvxWJaBQTYFJ/Z2TcWqbjXj5oJJBlqd2GxBXdtAhOXySVQ==",
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/code-red/-/code-red-0.2.5.tgz",
+ "integrity": "sha512-x+uQyJLNS1v0+74eXqM7FMPoM1fU/fN3tdexGWtCuVjCfxADt1TuuEGIGlFyCC2vhgINDctDb/rgSn8/ZDfJsQ==",
"dev": true,
"requires": {
"@types/estree": "^0.0.50",
@@ -6389,19 +5966,6 @@
"sourcemap-codec": "^1.4.8"
}
},
- "codecov": {
- "version": "3.6.5",
- "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.6.5.tgz",
- "integrity": "sha512-v48WuDMUug6JXwmmfsMzhCHRnhUf8O3duqXvltaYJKrO1OekZWpB/eH6iIoaxMl8Qli0+u3OxptdsBOYiD7VAQ==",
- "dev": true,
- "requires": {
- "argv": "0.0.2",
- "ignore-walk": "3.0.3",
- "js-yaml": "3.13.1",
- "teeny-request": "6.0.1",
- "urlgrey": "0.4.4"
- }
- },
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -6450,31 +6014,12 @@
"typedarray": "^0.0.6"
}
},
- "convert-source-map": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
- "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.1"
- }
- },
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
- "cross-spawn": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
- "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
- "dev": true,
- "requires": {
- "lru-cache": "^4.0.1",
- "which": "^1.2.9"
- }
- },
"css-tree": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz",
@@ -7391,16 +6936,6 @@
"integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
"dev": true
},
- "foreground-child": {
- "version": "1.5.6",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz",
- "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=",
- "dev": true,
- "requires": {
- "cross-spawn": "^4",
- "signal-exit": "^3.0.0"
- }
- },
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@@ -7443,16 +6978,6 @@
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
- "furi": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/furi/-/furi-1.3.0.tgz",
- "integrity": "sha512-TYoXEeRLKHXNWcCBP0VH1psPktQ9G8Y0GfZwMXCvwVbhbfNx7JItKWhB5mMBYufNjqxEHq+Ivd1nLtr5vQyVoQ==",
- "dev": true,
- "requires": {
- "@types/is-windows": "^0.2.0",
- "is-windows": "^1.0.2"
- }
- },
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -7640,34 +7165,6 @@
"whatwg-encoding": "^1.0.1"
}
},
- "html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
- },
- "http-proxy-agent": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
- "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
- "dev": true,
- "requires": {
- "@tootallnate/once": "1",
- "agent-base": "6",
- "debug": "4"
- },
- "dependencies": {
- "agent-base": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz",
- "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==",
- "dev": true,
- "requires": {
- "debug": "4"
- }
- }
- }
- },
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -7704,15 +7201,6 @@
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
- "ignore-walk": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
- "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
- "dev": true,
- "requires": {
- "minimatch": "^3.0.4"
- }
- },
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -7914,12 +7402,6 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
"dev": true
},
- "is-windows": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
- "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
- "dev": true
- },
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -7938,32 +7420,6 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
"dev": true
},
- "istanbul-lib-coverage": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
- "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
- "dev": true
- },
- "istanbul-lib-report": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
- "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
- "dev": true,
- "requires": {
- "istanbul-lib-coverage": "^2.0.5",
- "make-dir": "^2.1.0",
- "supports-color": "^6.1.0"
- }
- },
- "istanbul-reports": {
- "version": "2.2.7",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz",
- "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==",
- "dev": true,
- "requires": {
- "html-escaper": "^2.0.0"
- }
- },
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -8176,16 +7632,6 @@
"chalk": "^2.4.2"
}
},
- "lru-cache": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
- "dev": true,
- "requires": {
- "pseudomap": "^1.0.2",
- "yallist": "^2.1.2"
- }
- },
"magic-string": {
"version": "0.25.3",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz",
@@ -8195,16 +7641,6 @@
"sourcemap-codec": "^1.4.4"
}
},
- "make-dir": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
- "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
- "dev": true,
- "requires": {
- "pify": "^4.0.1",
- "semver": "^5.6.0"
- }
- },
"mdn-data": {
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
@@ -8399,12 +7835,6 @@
"semver": "^5.7.0"
}
},
- "node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
- "dev": true
- },
"node-modules-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
@@ -8628,12 +8058,6 @@
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
"dev": true
},
- "pify": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true
- },
"pirates": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
@@ -8781,12 +8205,6 @@
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true
},
- "pseudomap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
- "dev": true
- },
"psl": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz",
@@ -8857,16 +8275,6 @@
"path-type": "^3.0.0"
}
},
- "read-pkg-up": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
- "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
- "dev": true,
- "requires": {
- "find-up": "^3.0.0",
- "read-pkg": "^3.0.0"
- }
- },
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
@@ -9119,12 +8527,6 @@
"object-inspect": "^1.9.0"
}
},
- "signal-exit": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
- "dev": true
- },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -9265,15 +8667,6 @@
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
"dev": true
},
- "stream-events": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz",
- "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==",
- "dev": true,
- "requires": {
- "stubs": "^3.0.0"
- }
- },
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -9325,12 +8718,6 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
- "stubs": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
- "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=",
- "dev": true
- },
"sucrase": {
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.16.0.tgz",
@@ -9361,15 +8748,6 @@
}
}
},
- "supports-color": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
- "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- },
"svelte": {
"version": "3.43.0",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.43.0.tgz",
@@ -9461,31 +8839,6 @@
}
}
},
- "teeny-request": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz",
- "integrity": "sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g==",
- "dev": true,
- "requires": {
- "http-proxy-agent": "^4.0.0",
- "https-proxy-agent": "^4.0.0",
- "node-fetch": "^2.2.0",
- "stream-events": "^1.0.5",
- "uuid": "^3.3.2"
- }
- },
- "test-exclude": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
- "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==",
- "dev": true,
- "requires": {
- "glob": "^7.1.3",
- "minimatch": "^3.0.4",
- "read-pkg-up": "^4.0.0",
- "require-main-filename": "^2.0.0"
- }
- },
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -9653,12 +9006,6 @@
"punycode": "^2.1.0"
}
},
- "urlgrey": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz",
- "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=",
- "dev": true
- },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -9677,17 +9024,6 @@
"integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
"dev": true
},
- "v8-to-istanbul": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-3.2.3.tgz",
- "integrity": "sha512-B8d/oxMtc/x0TYXr9b+Ywu5KexA/on4QMQ9M1kTYnoGZzKdo8LLk9ySlWePdDOtr2G0/2Injgcp3sOR9gU+3vQ==",
- "dev": true,
- "requires": {
- "@types/istanbul-lib-coverage": "^2.0.1",
- "convert-source-map": "^1.6.0",
- "source-map": "^0.7.3"
- }
- },
"validate-npm-package-license": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -9878,12 +9214,6 @@
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
"dev": true
},
- "yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
- "dev": true
- },
"yargs": {
"version": "13.3.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
@@ -9914,23 +9244,6 @@
}
}
},
- "yargs-parser": {
- "version": "10.1.0",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
- "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
- "dev": true,
- "requires": {
- "camelcase": "^4.1.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true
- }
- }
- },
"yargs-unparser": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
diff --git a/package.json b/package.json
index 7d36c10971..2ca79c5fa8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "svelte",
- "version": "3.45.0",
+ "version": "3.46.4",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@@ -86,10 +86,6 @@
"test": "mocha --exit",
"test:unit": "mocha --require sucrase/register --recursive src/**/__test__.ts --exit",
"quicktest": "mocha",
- "precoverage": "c8 mocha",
- "coverage": "c8 report --reporter=text-lcov > coverage.lcov && c8 report --reporter=html",
- "codecov": "codecov",
- "precodecov": "npm run coverage",
"build": "rollup -c && npm run tsd",
"prepare": "npm run build",
"dev": "rollup -cw",
@@ -131,9 +127,7 @@
"@typescript-eslint/parser": "^4.31.2",
"acorn": "^8.4.1",
"agadoo": "^1.1.0",
- "c8": "^5.0.1",
- "code-red": "^0.2.4",
- "codecov": "^3.5.0",
+ "code-red": "^0.2.5",
"css-tree": "^1.1.2",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.24.2",
diff --git a/site/content/blog/2022-01-13-accelerating-sveltes-development.md b/site/content/blog/2022-01-13-accelerating-sveltes-development.md
new file mode 100644
index 0000000000..7860c2acbc
--- /dev/null
+++ b/site/content/blog/2022-01-13-accelerating-sveltes-development.md
@@ -0,0 +1,67 @@
+---
+title: "Accelerating Svelte's Development"
+description: "Scaling the team, building partnerships, and growing the community"
+author: Ben McCann
+authorURL: https://www.benmccann.com/
+---
+
+[Svelte](/) is a frontend framework for building fast reactive web apps with less code. If you’re new here, [check out the tutorial](/tutorial) or [examples](/examples) to get a feel for it.
+
+Svelte was [launched 5 years ago](https://news.ycombinator.com/item?id=13069841) and has [come a long way in the time since](https://www.youtube.com/watch?v=YeY5M29-WcY). In 2021, as usage more than doubled, it was voted the [most loved](https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-web-frameworks) framework with the [most satisfied](https://2020.stateofjs.com/en-US/technologies/front-end-frameworks/) developers in a pair of surveys. Alongside high-profile companies like The New York Times, Apple, Spotify, Square, Rakuten, Bloomberg, Reuters, Ikea, Brave, and countless others, Svelte is used to power everything from hobby projects to embedded systems interfaces.
+
+To help developers build fully-featured applications with Svelte without worrying about the hard parts, we’ve been developing the [SvelteKit](https://kit.svelte.dev/) application framework. We’re moving quickly towards a [stable 1.0 release](https://github.com/sveltejs/kit/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0) with the help of early adopters who have already downloaded SvelteKit almost one million times.
+
+## Scaling the team
+
+Rich Harris, Svelte’s creator, has [joined Vercel to work on Svelte full-time](https://vercel.com/blog/vercel-welcomes-rich-harris-creator-of-svelte). We’re incredibly excited to have Rich’s level of involvement in Svelte increase even more and have him steward Svelte into the future.
+
+Svelte has been made possible by the work of a large, dedicated community. Svelte has added numerous core maintainers over the course of the pandemic, including three this past week. In alphabetical order:
+- [benmccann](https://github.com/benmccann) - primary maintainer of SvelteKit for much of 2021
+- [bluwy](https://github.com/bluwy) - major contributor across SvelteKit, vite-plugin-svelte, and Vite
+- [dominikg](https://github.com/dominikg) - creator of vite-plugin-svelte
+- [dummdidumm](https://github.com/dummdidumm) - maintainer of language-tools, which includes the VS Code extension and `svelte-check`
+- [ehrencrona](https://github.com/ehrencrona) - contributor to SvelteKit and uses Svelte at work
+- [geoffrich](https://github.com/geoffrich) - has driven efforts to improve the accessibility of the Svelte site and documentation
+- [GrygrFlzr](https://github.com/GrygrFlzr) - holds a unique status as a maintainer of both SvelteKit and Vite
+- [Halfnelson](https://github.com/Halfnelson) - creator of svelte-native
+- [ignatiusmb](https://github.com/ignatiusmb) - regular SvelteKit contributor especially to TypeScript support
+- [jasonlyu123](https://github.com/jasonlyu123) - maintainer of language-tools, which includes the VS Code extension and `svelte-check`
+- [kaisermann](https://github.com/kaisermann) - creator of svelte-preprocess
+- [RedHatter](https://github.com/RedHatter) - creator of Svelte Devtools
+- [rixo](https://github.com/rixo) - creator of svelte-hmr
+
+Svelte began accepting donations via [OpenCollective](https://opencollective.com/svelte) last year and has now had over $60,000 donated to-date with [Cohere](https://cohere.ai/) giving $10,000 just today. We hope that these funds will allow existing maintainers to spend more time on Svelte or that the funds could otherwise support Svelte on a part-time or contract basis, which we will continue to investigate.
+
+## Partnerships
+
+Multiple major cloud vendors are stepping up to make deploying SvelteKit applications anywhere a seamless experience. As a result of Rich’s new job, SvelteKit will soon run on [Vercel Edge Functions](https://vercel.com/features/edge-functions). Netlify has made [big contributions](https://github.com/sveltejs/kit/pull/2113) to the SvelteKit Netlify adapter and also [updated](https://github.com/dependents/node-precinct/pull/88) their zip-it-and-ship-it tool to better support SvelteKit. The recent [Cloudflare Pages launch](https://blog.cloudflare.com/cloudflare-pages-goes-full-stack/) featured SvelteKit as a day one partner via a [new adapter](https://github.com/sveltejs/kit/tree/master/packages/adapter-cloudflare) written by Svelte maintainers [pngwn](https://twitter.com/evilpingwin) and [lukeed](https://twitter.com/lukeed05), the latter of whom joined Cloudflare in 2021. [Begin](https://begin.com) created a [SvelteKit adapter](https://github.com/architect/sveltekit-adapter) for [Architect](https://arc.codes) apps. And community members have [contributed adapters](https://sveltesociety.dev/components#adapters) for environments such as Firebase and Deno, showcasing SvelteKit’s ability to run wherever JavaScript does.
+
+We’ve also been working closely with the [Vite](https://vitejs.dev) team to iron out SSR issues uncovered by SvelteKit users. Vite is the build tool that makes the SvelteKit developer experience possible, and thanks to hard work from a contributor base that includes representatives of multiple frameworks, recent releases have solved almost all the issues we’ve been tracking as SvelteKit 1.0 release blockers.
+
+## A growing community
+
+[SvelteSociety](https://sveltesociety.dev/) just hosted the [4th Svelte Summit](https://sveltesummit.com/) — [read a summary here](https://svelte.dev/blog/whats-new-in-svelte-december-2021#what-happened-at-svelte-summit) — and Kevin Åberg Kultalahti is [going full-time to lead SvelteSociety](https://twitter.com/kevmodrome/status/1463151477174714373). In addition to hosting Svelte Summit, Kevin and SvelteSociety host and manage the [Svelte Radio podcast](https://www.svelteradio.com/), the [SvelteSociety YouTube channel](https://www.youtube.com/SvelteSociety), and the [Svelte subreddit](https://www.reddit.com/r/sveltejs). SvelteSociety has become the home of all things related to the Svelte community, with the sveltejs/community and sveltejs/integrations repos being retired in favor of [sveltesociety.dev](https://sveltesociety.dev/), which has been redesigned and rebuilt in SvelteKit. In October [Brittney Postma](https://github.com/brittneypostma), [Willow aka GHOST](https://ghostdev.xyz), [Steph Dietz](https://github.com/StephDietz), and [Gen Ashley](https://twitter.com/coderinheels) founded [Svelte Sirens](https://sveltesirens.dev/), a group for women & non-binary community members and their allies.
+
+Hundreds of developers join the Svelte Discord every week to chat about Svelte. You may have noticed that, as of recently, some members of the server have purple names. These are people with the ambassadors role, which was created to recognise some of the community’s most valued members and help manage the demands of a rapidly growing community. Svelte ambassadors are people who are well known for their helpfulness and contributions and for upholding Svelte’s reputation as a friendly, welcoming community, and we’re deeply grateful for their involvement. The initial ambassadors in alphabetical order are:
+- [babichjacob](https://github.com/babichjacob)
+- [brady fractal](https://github.com/FractalHQ)
+- [brittney postma](https://github.com/brittneypostma)
+- [d3sandoval](https://github.com/d3sandoval)
+- [geoffrich](https://github.com/geoffrich)
+- [kev](https://github.com/kevmodrome)
+- [puru](https://github.com/PuruVJ)
+- [rainlife](https://github.com/stephane-vanraes)
+- [rmunn](https://github.com/rmunn)
+- [stolinski](https://github.com/stolinski)
+- [swyx](https://github.com/sw-yx)
+- [theo](https://github.com/theo-steiner)
+
+We’re also testing out [GitHub discussions on SvelteKit](https://github.com/sveltejs/kit/discussions) and may bring this to other repos in the Svelte organization if feedback is positive.
+
+## Things to watch
+
+SvelteKit is continuing to progress towards 1.0 and, in just the past week, we have added major features like [improved client-only rendering](https://github.com/sveltejs/kit/pull/2804), [routing hooks](https://github.com/sveltejs/kit/pull/3293), and [the ability to pass data from child components to layouts](https://github.com/sveltejs/kit/pull/3252) (e.g. to support easier management of `` tags). We're currently working on a number of other high priority items such as discussing API designs for features like streaming and file uploads and contributing to the upcoming Vite 2.8 release.
+
+While a lot of effort has been going into SvelteKit recently, we continue to progress the entire ecosystem. [Svelte 3.46.0](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md#3460) was one of our biggest releases in awhile with two major new features added: [constants in markup](https://github.com/sveltejs/rfcs/blob/master/text/0007-markup-constants.md) and [style directives](https://github.com/sveltejs/rfcs/blob/master/text/0008-style-directives.md).
+
+Svelte and SvelteKit’s trajectories have been accelerated by the numerous investments above and there will be many more updates to come — subscribe to the [blog](/blog) via [RSS](https://svelte.dev/blog/rss.xml) or check monthly to be the first to get them.
diff --git a/site/content/blog/2022-02-01-whats-new-in-svelte-february-2022.md b/site/content/blog/2022-02-01-whats-new-in-svelte-february-2022.md
new file mode 100644
index 0000000000..990295bb89
--- /dev/null
+++ b/site/content/blog/2022-02-01-whats-new-in-svelte-february-2022.md
@@ -0,0 +1,106 @@
+---
+title: "What's new in Svelte: February 2022"
+description: "Rapid-fire releases across Svelte, SvelteKit and the community"
+author: Daniel Sandoval
+authorURL: https://desandoval.net
+---
+
+Happy February, everyone! Over the last month or so, we've seen Svelte and SvelteKit [develop at rapid speed](accelerating-sveltes-development), new community rules across the [Reddit](https://www.reddit.com/r/sveltejs/comments/s9n8ou/new_rules/), [GitHub](https://github.com/sveltejs/community/blob/main/CODE_OF_CONDUCT.md) and [Discord](https://discord.com/channels/457912077277855764/831611707667382303/935264550436102315), and quite a few amazing apps, tutorials and libraries.
+
+Let's take a look...
+
+## Highlights from the Svelte changelog
+- **3.45.0** brought a [new a11y warning `a11y-no-redundant-roles`](https://svelte.dev/docs#accessibility-warnings-a11y-no-redundant-roles), destructuring and caching fixes
+- **3.46.0** added the much requested [`{@const}` tag](https://svelte.dev/docs#template-syntax-const) and [`style:` directive](https://svelte.dev/docs#template-syntax-element-directives-style-property)
+- Check out **3.46.1 - 3.46.3** for fixes to the `{@const}` tag and `style:` directive, along with a number of fixes to animations
+- [AST output is now available in the Svelte REPL](https://svelte.dev/repl/hello-world)
+
+## What's new in SvelteKit
+- `inlineStyleThreshold` allows you to specify where inline stylesheets are inserted into the page ([Docs](https://kit.svelte.dev/docs#configuration-inlinestylethreshold), [#2620](https://github.com/sveltejs/kit/pull/2620))
+- `beforeNavigate`/`afterNavigate` lifecycle functions lets you add functionality before or after a page navigation ([Docs](https://kit.svelte.dev/docs#modules-$app-navigation), [#3293](https://github.com/sveltejs/kit/pull/3293))
+- Platform context can now be passed from adapters ([Docs](https://kit.svelte.dev/docs#adapters-supported-environments-platform-specific-context), [#3429](https://github.com/sveltejs/kit/pull/3429))
+- Hooks now have an `ssr` parameter in `resolve` to make it easier to skip SSR, when needed ([Docs](https://kit.svelte.dev/docs#hooks-handle), [#2804](https://github.com/sveltejs/kit/pull/2804))
+- `$page.stuff` provides a mechanism for pages to pass data 'upward' to layouts ([Docs](https://kit.svelte.dev/docs#loading-input-stuff), [#3252](https://github.com/sveltejs/kit/pull/3252))
+- Fallthrough routes let you specify where to route when an route can't be loaded ([Docs](https://kit.svelte.dev/docs#routing-advanced-fallthrough-routes), [#3217](https://github.com/sveltejs/kit/pull/3217))
+
+**New configs**
+- Content Security Policy (CSP) is now supported for increased security when using inline javascript or stylesheets ([Docs](https://kit.svelte.dev/docs#configuration-csp), [#3499](https://github.com/sveltejs/kit/pull/3499))
+- `kit.routes` config allows you to customise public/private modules during build ([Docs](https://kit.svelte.dev/docs#configuration-routes), [#3576](https://github.com/sveltejs/kit/pull/3576))
+- `prerender.createIndexFiles` config lets you prerender index.html files as their subfolder's name ([Docs](https://kit.svelte.dev/docs#configuration-prerender), [#2632](https://github.com/sveltejs/kit/pull/2632))
+- HTTP methods can now be overridden using `kit.methodOverride` ([Docs](https://kit.svelte.dev/docs#routing-endpoints-http-method-overrides), [#2989](https://github.com/sveltejs/kit/pull/2989))
+
+**Config changes**
+- `config.kit.hydrate` and `config.kit.router` are now nested under `config.kit.browser` ([Docs](https://kit.svelte.dev/docs#configuration-browser), [3578](https://github.com/sveltejs/kit/pull/3578))
+
+**Breaking change**
+- use `Request` and `Response` objects in endpoints and hooks ([#3384](https://github.com/sveltejs/kit/pull/3384))
+
+
+---
+
+## Community Showcase
+
+**Apps & Sites**
+- [timb(re)](https://paullj.github.io/timb) is a live music programming environment
+- [Music for Programming](https://musicforprogramming.net/latest/) is a series of mixes intended for listening while `${task}` to focus the brain and inspire the mind
+- [Team Tale](https://teamtale.app/) allows two authors to write the same story in a tag-team sort of fashion
+- [Puzzlez](https://www.puzzlez.io/) is an online place to play Sudoku and Wordle
+- [Closed Caption Creator](https://www.closedcaptioncreator.com/) makes it easy to add subtitles to your video on Windows, Mac and Google Chrome
+- [SC3Lab](https://sc3-lab.netlify.app/) is a code generator for experimenting with svelte-cubed and three.js
+- [Donkeytype](https://github.com/0ql/Donkeytype) is a minimalistic and lightweight typingtest inspired by Monkeytype.
+- [Above](https://above.silas.pro/) is a visual routine timer built for the ADHD/autistic mind
+- [base.report](https://base.report/) is a modern research platform for serious investors
+- [String](https://string.kampsy.xyz/) turns your Phone into a secure portable audio recorder, making it easy to capture and share personal notes, family moments, classroom lectures, and more
+- [The Raytracer Challenge REPL](https://github.com/jakobwesthoff/the_raytracer_challenge_repl) provides a live editor interface to configure a raytraced scene and render it live in any modern browser
+- [awesome-svelte-kit](https://github.com/janosh/awesome-svelte-kit) is a list of awesome examples of SvelteKit in the wild
+- [Map Projection Explorer](https://www.geo-projections.com/) lets you explore different map projections and explains their differences
+- [Rubiks](https://github.com/MeharGaur/rubiks) is a Rubik's Cube simulator
+- [Pianisto](https://pianisto.net/) is a working piano made with SVG, ToneJS and a lot of patience
+
+Want to work on a SvelteKit site with others, [try contributing to the Svelte Society site](https://github.com/svelte-society/sveltesociety-2021/issues)!
+
+
+**Learning and Listening**
+
+_To Read_
+- [Accelerating Svelte's Development](https://svelte.dev/blog/accelerating-sveltes-development) by Ben McCann
+- [Storybook for Vite](https://storybook.js.org/blog/storybook-for-vite/)
+- [Let's learn SvelteKit by building a static Markdown blog from scratch](https://joshcollinsworth.com/blog/build-static-sveltekit-markdown-blog) by Josh Collinsworth
+- [Building an iOS app with Svelte, Capacitor and Firebase](https://harryherskowitz.com/2022/01/05/tapedrop-app.html) by Harry Herskowitz
+- [Mutating Query Params in SvelteKit Without Page Reloads or Navigations](https://dev.to/mohamadharith/mutating-query-params-in-sveltekit-without-page-reloads-or-navigations-2i2b) and [Workaround for Bubbling Custom Events in Svelte](https://dev.to/mohamadharith/workaround-for-bubbling-custom-events-in-svelte-3khk) by Mohamad Harith
+- [How to build a full stack serverless application with Svelte and GraphQL](https://dev.to/shadid12/how-to-build-a-full-stack-serverless-application-with-svelte-graphql-and-fauna-5427) by Shadid Haque
+- [How to Deploy SvelteKit Apps to Github Pages](https://sveltesaas.com/articles/sveltekit-github-pages-guide/)
+- [Creating a dApp with SvelteKit](https://anthonyriley.org/2021/12/31/creating-a-dapp-with-sveltekit/) by Anthony Riley
+- [Comparing Svelte Reactivity Options](https://opendirective.net/2022/01/06/comparing-svelte-reactivity-options/) by Steve Lee
+
+_To Watch_
+- [Integrating Storybook with SvelteKit](https://www.youtube.com/watch?v=Kc1ULlfyUcw) and [Integrating FaunaDB with Svelte](https://www.youtube.com/watch?v=zaoLZc76uZM) by the Svelte Sirens
+- [SvelteKit Crash Course Tutorial](https://www.youtube.com/watch?v=9OlLxkaeVvw&list=PL4cUxeGkcC9hpM9ARM59Ve3jqcb54dqiP) by The Net Ninja
+- [Svelte for Beginners](https://www.youtube.com/watch?v=BrkrOjknC_E&list=PLA9WiRZ-IS_ylnMYxIFCsZN6xVVSvLuHk) by Joy of Code
+- [SvelteKit For Beginners | Movie App Tutorial](https://www.youtube.com/watch?v=ydR_M0fw9Xc) by Dev Ed
+- [SvelteKit $app/stores](https://www.youtube.com/watch?v=gBPhr1xbgaQ) by lihautan
+- [Sveltekit - Get All Routes/Pages](https://www.youtube.com/watch?v=Y_NE2R3HuOU) by WebJeda
+
+_To Listen To_
+- [New Year, New Svelte!?](https://share.transistor.fm/s/36212cdc) from Svelte Radio
+- [So much Sveltey goodness (featuring Rich Harris)](https://changelog.com/jsparty/205) from JS Party
+- [The Other Side of Tech: A Documentarian Perspective (with Stefan Kingham)](https://codingcat.dev/podcast/2-4-the-other-side-of-tech-a-documentarian-perspective) from Purrfect.dev
+
+**Libraries, Tools & Components**
+- [threlte](https://github.com/grischaerbe/threlte) is a three.js component library for Svelte
+- [svelte-formify](https://github.com/nodify-at/svelte-formify) is a library to manage and validate forms that uses decorators to define validations
+- [gQuery](https://github.com/leveluptuts/gQuery) is a GraphQL Fetcher & Cache for Svelte Kit
+- [Unlock-protocol](https://github.com/novum-insights/sveltekit-unlock-firebase) is an integration to help login with MetaMask, Firebase, and paywall customers
+- [AgnosticUI](https://github.com/AgnosticUI/agnosticui) is a set of UI primitives that start their lives in clean HTML and CSS
+- [Vitebook](https://github.com/vitebook/vitebook) is a fast and lightweight alternative to Storybook that's powered by Vite
+- [SwyxKit](https://swyxkit.netlify.app/) is an opinionated blog starter for SvelteKit + Tailwind + Netlify. Refreshed for 2022!
+- [svelte-themes](https://github.com/beynar/svelte-themes) is an abstraction for themes in your SvelteKit app
+- [svelte-transition](https://www.npmjs.com/package/svelte-transition) is a Svelte component to make using CSS class based transitions easier - ideally suited for use with TailwindCSS
+- [Svelte Inview](https://www.npmjs.com/package/svelte-inview) is a Svelte action that monitors an element enters or leaves the viewport/parent element
+- [svelte-inline-compile](https://github.com/DockYard/svelte-inline-compile) is a babel transform that allows for a much more pleasant experience when testing svelte components using Jest and `@testing-library/svelte`
+- [@feltcoop/svelte-mutable-store](https://github.com/feltcoop/svelte-mutable-store) is a Svelte store for mutable values with an `immutable` compiler option
+- [headless-svelte-ui](https://www.npmjs.com/package/@bojalelabs/headless-svelte-ui) is a group of headless components that can be used in building Svelte Apps.
+
+Did we miss something? Need help bringing your next idea to life in Svelte? Join us on [Reddit](https://www.reddit.com/r/sveltejs/) or [Discord](https://discord.com/invite/yy75DKs).
+
+See ya next month!
diff --git a/site/content/docs/01-component-format.md b/site/content/docs/01-component-format.md
index d1751320c0..1c64094002 100644
--- a/site/content/docs/01-component-format.md
+++ b/site/content/docs/01-component-format.md
@@ -57,7 +57,7 @@ In development mode (see the [compiler options](/docs#compile-time-svelte-compil
If you export a `const`, `class` or `function`, it is readonly from outside the component. Function *expressions* are valid props, however.
-Readonly props can be accessed as properties on the element, tied to the component using [`bind:this` syntax](/docs#template-syntax-element-directives-bind-element).
+Readonly props can be accessed as properties on the element, tied to the component using [`bind:this` syntax](/docs#template-syntax-component-directives-bind-this).
```sv
+
+{#each boxes as box}
+ {@const area = box.width * box.height}
+ {box.width} * {box.height} = {area}
+{/each}
+```
+
+`{@const}` is only allowed as direct child of `{#each}`, `{:then}`, `{:catch}`, ` ` or ` `.
+
### Element directives
@@ -1670,6 +1693,7 @@ All except `scrollX` and `scrollY` are readonly.
```
+> Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. However, if the scrolling behaviour is desired, call `scrollTo()` in `onMount()`.
### ``
@@ -1734,7 +1758,7 @@ The `` element provides a place to specify per-component compile
### ``
-The `` element allows you to place content in a [named slot](/docs#template-syntax-slot-slot-name) without wrapping it in a container DOM element. This keeps the flow layout of your document intact.
+The `` element allows you to place content in a [named slot](/docs#template-syntax-slot-slot-name-name) without wrapping it in a container DOM element. This keeps the flow layout of your document intact.
```sv
diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md
index 54228f5c2a..636a98834d 100644
--- a/site/content/docs/03-run-time.md
+++ b/site/content/docs/03-run-time.md
@@ -226,7 +226,7 @@ dispatch: ((name: string, detail?: any) => void) = createEventDispatcher();
---
-Creates an event dispatcher that can be used to dispatch [component events](/docs#template-syntax-component-directives-on-component-event). Event dispatchers are functions that can take two arguments: `name` and `detail`.
+Creates an event dispatcher that can be used to dispatch [component events](/docs#template-syntax-component-directives-on-eventname). 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.
diff --git a/site/content/docs/04-compile-time.md b/site/content/docs/04-compile-time.md
index 6ba5dabacc..1ee41eeb93 100644
--- a/site/content/docs/04-compile-time.md
+++ b/site/content/docs/04-compile-time.md
@@ -178,7 +178,7 @@ ast: object = svelte.parse(
---
-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.
+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. Note that the returned AST is not considered public API, so breaking changes could occur at any point in time.
```js
diff --git a/site/content/docs/05-accessibility-warnings.md b/site/content/docs/05-accessibility-warnings.md
index 149603dcf9..b39b06f9ff 100644
--- a/site/content/docs/05-accessibility-warnings.md
+++ b/site/content/docs/05-accessibility-warnings.md
@@ -213,6 +213,20 @@ Enforce that `on:mouseover` and `on:mouseout` are accompanied by `on:focus` and
---
+### `a11y-no-redundant-roles`
+
+Some HTML elements have default ARIA roles. Giving these elements an ARIA role that is already set by the browser [has no effect](https://www.w3.org/TR/using-aria/#aria-does-nothing) and is redundant.
+
+```sv
+
+
+
+
+
+```
+
+---
+
### `a11y-positive-tabindex`
Avoid positive `tabindex` property values. This will move elements out of the expected tab order, creating a confusing experience for keyboard users.
diff --git a/site/content/examples/07-stores/00-writable-stores/App.svelte b/site/content/examples/07-stores/00-writable-stores/App.svelte
index ee542f789d..61e55401a5 100644
--- a/site/content/examples/07-stores/00-writable-stores/App.svelte
+++ b/site/content/examples/07-stores/00-writable-stores/App.svelte
@@ -4,14 +4,14 @@
import Decrementer from './Decrementer.svelte';
import Resetter from './Resetter.svelte';
- let count_value;
+ let countValue;
const unsubscribe = count.subscribe(value => {
- count_value = value;
+ countValue = value;
});
-The count is {count_value}
+The count is {countValue}
diff --git a/site/content/examples/17-special-elements/03-svelte-window-bindings/App.svelte b/site/content/examples/17-special-elements/03-svelte-window-bindings/App.svelte
index 28831a6d31..15c2aa0ebc 100644
--- a/site/content/examples/17-special-elements/03-svelte-window-bindings/App.svelte
+++ b/site/content/examples/17-special-elements/03-svelte-window-bindings/App.svelte
@@ -7,7 +7,7 @@
- {#each [0, 1, 2, 3, 4, 5, 6, 7, 8] as layer}
+ {#each layers as layer}
\ No newline at end of file
+
diff --git a/site/content/faq/450-how-do-i-document-my-components.md b/site/content/faq/450-how-do-i-document-my-components.md
index 78177abd54..4574d02961 100644
--- a/site/content/faq/450-how-do-i-document-my-components.md
+++ b/site/content/faq/450-how-do-i-document-my-components.md
@@ -4,7 +4,7 @@ question: How do I document my components?
In editors which use the Svelte Language Server you can document Components, functions and exports using specially formatted comments.
-````svelte
+````sv
-The count is {count_value}
+The count is {countValue}
diff --git a/site/content/tutorial/08-stores/01-writable-stores/app-b/App.svelte b/site/content/tutorial/08-stores/01-writable-stores/app-b/App.svelte
index c77563e354..57bbde1c1e 100644
--- a/site/content/tutorial/08-stores/01-writable-stores/app-b/App.svelte
+++ b/site/content/tutorial/08-stores/01-writable-stores/app-b/App.svelte
@@ -4,14 +4,14 @@
import Decrementer from './Decrementer.svelte';
import Resetter from './Resetter.svelte';
- let count_value;
+ let countValue;
count.subscribe(value => {
- count_value = value;
+ countValue = value;
});
-The count is {count_value}
+The count is {countValue}
diff --git a/site/content/tutorial/08-stores/01-writable-stores/text.md b/site/content/tutorial/08-stores/01-writable-stores/text.md
index 247ef86e8d..dc7081f46a 100644
--- a/site/content/tutorial/08-stores/01-writable-stores/text.md
+++ b/site/content/tutorial/08-stores/01-writable-stores/text.md
@@ -4,7 +4,7 @@ title: Writable stores
Not all application state belongs inside your application's component hierarchy. Sometimes, you'll have values that need to be accessed by multiple unrelated components, or by a regular JavaScript module.
-In Svelte, we do this with *stores*. A store is simply an object with a `subscribe` method that allows interested parties to be notified whenever the store value changes. In `App.svelte`, `count` is a store, and we're setting `count_value` in the `count.subscribe` callback.
+In Svelte, we do this with *stores*. A store is simply an object with a `subscribe` method that allows interested parties to be notified whenever the store value changes. In `App.svelte`, `count` is a store, and we're setting `countValue` in the `count.subscribe` callback.
Click the `stores.js` tab to see the definition of `count`. It's a *writable* store, which means it has `set` and `update` methods in addition to `subscribe`.
diff --git a/site/content/tutorial/08-stores/02-auto-subscriptions/app-a/App.svelte b/site/content/tutorial/08-stores/02-auto-subscriptions/app-a/App.svelte
index f2a4023f25..481b3070dc 100644
--- a/site/content/tutorial/08-stores/02-auto-subscriptions/app-a/App.svelte
+++ b/site/content/tutorial/08-stores/02-auto-subscriptions/app-a/App.svelte
@@ -4,14 +4,14 @@
import Decrementer from './Decrementer.svelte';
import Resetter from './Resetter.svelte';
- let count_value;
+ let countValue;
count.subscribe(value => {
- count_value = value;
+ countValue = value;
});
-The count is {count_value}
+The count is {countValue}
diff --git a/site/content/tutorial/08-stores/02-auto-subscriptions/text.md b/site/content/tutorial/08-stores/02-auto-subscriptions/text.md
index fc7967f658..2bed4a67d1 100644
--- a/site/content/tutorial/08-stores/02-auto-subscriptions/text.md
+++ b/site/content/tutorial/08-stores/02-auto-subscriptions/text.md
@@ -8,7 +8,7 @@ Start by declaring `unsubscribe` in `App.svelte`:
```js
const unsubscribe = count.subscribe(value => {
- count_value = value;
+ countValue = value;
});
```
> Calling a `subscribe` method returns an `unsubscribe` function.
@@ -23,16 +23,16 @@ You now declared `unsubscribe`, but it still needs to be called, for example thr
import Decrementer from './Decrementer.svelte';
import Resetter from './Resetter.svelte';
- let count_value;
+ let countValue;
const unsubscribe = count.subscribe(value => {
- count_value = value;
+ countValue = value;
});
onDestroy(unsubscribe);
-The count is {count_value}
+The count is {countValue}
```
It starts to get a bit boilerplatey though, especially if your component subscribes to multiple stores. Instead, Svelte has a trick up its sleeve — you can reference a store value by prefixing the store name with `$`:
diff --git a/site/content/tutorial/15-context/01-context-api/app-a/mapbox.js b/site/content/tutorial/15-context/01-context-api/app-a/mapbox.js
index 55b4200038..9c5cec430c 100644
--- a/site/content/tutorial/15-context/01-context-api/app-a/mapbox.js
+++ b/site/content/tutorial/15-context/01-context-api/app-a/mapbox.js
@@ -3,6 +3,6 @@ import mapbox from 'mapbox-gl';
// https://docs.mapbox.com/help/glossary/access-token/
mapbox.accessToken = MAPBOX_ACCESS_TOKEN;
-const key = {};
+const key = Symbol();
export { mapbox, key };
\ No newline at end of file
diff --git a/site/content/tutorial/15-context/01-context-api/app-b/mapbox.js b/site/content/tutorial/15-context/01-context-api/app-b/mapbox.js
index 55b4200038..9c5cec430c 100644
--- a/site/content/tutorial/15-context/01-context-api/app-b/mapbox.js
+++ b/site/content/tutorial/15-context/01-context-api/app-b/mapbox.js
@@ -3,6 +3,6 @@ import mapbox from 'mapbox-gl';
// https://docs.mapbox.com/help/glossary/access-token/
mapbox.accessToken = MAPBOX_ACCESS_TOKEN;
-const key = {};
+const key = Symbol();
export { mapbox, key };
\ No newline at end of file
diff --git a/site/content/tutorial/15-context/01-context-api/text.md b/site/content/tutorial/15-context/01-context-api/text.md
index efb6157652..e1f095c494 100644
--- a/site/content/tutorial/15-context/01-context-api/text.md
+++ b/site/content/tutorial/15-context/01-context-api/text.md
@@ -40,10 +40,10 @@ The markers can now add themselves to the map.
In `mapbox.js` you'll see this line:
```js
-const key = {};
+const key = Symbol();
```
-We can use anything as a key — we could do `setContext('mapbox', ...)` for example. The downside of using a string is that different component libraries might accidentally use the same one; using an object literal means the keys are guaranteed not to conflict in any circumstance (since an object only has referential equality to itself, i.e. `{} !== {}` whereas `"x" === "x"`), even when you have multiple different contexts operating across many component layers.
+Technically, we can use any value as a key — we could do `setContext('mapbox', ...)` for example. The downside of using a string is that different component libraries might accidentally use the same one; using [symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol), on the other hand, means that the keys are guaranteed not to conflict in any circumstance, even when you have multiple different contexts operating across many component layers, since a symbol is essentially a unique identifier.
## Contexts vs. stores
diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts
index 0347a28743..5f7d4b9758 100644
--- a/src/compiler/compile/Component.ts
+++ b/src/compiler/compile/Component.ts
@@ -191,27 +191,33 @@ export default class Component {
this.stylesheet.warn_on_unused_selectors(this);
}
- add_var(variable: Var, add_to_lookup = true) {
+ add_var(node: Node, variable: Var, add_to_lookup = true) {
this.vars.push(variable);
if (add_to_lookup) {
+ if (this.var_lookup.has(variable.name)) {
+ const exists_var = this.var_lookup.get(variable.name);
+ if (exists_var.module && exists_var.imported) {
+ this.error(node as any, compiler_errors.illegal_variable_declaration);
+ }
+ }
this.var_lookup.set(variable.name, variable);
}
}
- add_reference(name: string) {
+ add_reference(node: Node, name: string) {
const variable = this.var_lookup.get(name);
if (variable) {
variable.referenced = true;
} else if (is_reserved_keyword(name)) {
- this.add_var({
+ this.add_var(node, {
name,
injected: true,
referenced: true
});
} else if (name[0] === '$') {
- this.add_var({
+ this.add_var(node, {
name,
injected: true,
referenced: true,
@@ -228,7 +234,7 @@ export default class Component {
}
} else {
if (this.compile_options.varsReport === 'full') {
- this.add_var({ name, referenced: true }, false);
+ this.add_var(node, { name, referenced: true }, false);
}
this.used_names.add(name);
@@ -599,12 +605,14 @@ export default class Component {
}
const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let');
+ const imported = node.type.startsWith('Import');
- this.add_var({
+ this.add_var(node, {
name,
module: true,
hoistable: true,
- writable
+ writable,
+ imported
});
});
@@ -612,7 +620,7 @@ export default class Component {
if (name[0] === '$') {
return this.error(node as any, compiler_errors.illegal_subscription);
} else {
- this.add_var({
+ this.add_var(node, {
name,
global: true,
hoistable: true
@@ -674,7 +682,7 @@ export default class Component {
const writable = node.type === 'VariableDeclaration' && (node.kind === 'var' || node.kind === 'let');
const imported = node.type.startsWith('Import');
- this.add_var({
+ this.add_var(node, {
name,
initialised: instance_scope.initialised_declarations.has(name),
writable,
@@ -697,7 +705,7 @@ export default class Component {
const node = globals.get(name);
if (this.injected_reactive_declaration_vars.has(name)) {
- this.add_var({
+ this.add_var(node, {
name,
injected: true,
writable: true,
@@ -705,7 +713,7 @@ export default class Component {
initialised: true
});
} else if (is_reserved_keyword(name)) {
- this.add_var({
+ this.add_var(node, {
name,
injected: true
});
@@ -714,14 +722,14 @@ export default class Component {
return this.error(node as any, compiler_errors.illegal_global(name));
}
- this.add_var({
+ this.add_var(node, {
name,
injected: true,
mutated: true,
writable: true
});
- this.add_reference(name.slice(1));
+ this.add_reference(node, name.slice(1));
const variable = this.var_lookup.get(name.slice(1));
if (variable) {
@@ -729,7 +737,7 @@ export default class Component {
variable.referenced_from_script = true;
}
} else {
- this.add_var({
+ this.add_var(node, {
name,
global: true,
hoistable: true
diff --git a/src/compiler/compile/compiler_errors.ts b/src/compiler/compile/compiler_errors.ts
index 463f6b27cf..a04780e375 100644
--- a/src/compiler/compile/compiler_errors.ts
+++ b/src/compiler/compile/compiler_errors.ts
@@ -40,6 +40,10 @@ export default {
code: 'invalid-binding',
message: 'Cannot bind to a variable declared with {#await ... then} or {:catch} blocks'
},
+ invalid_binding_const: {
+ code: 'invalid-binding',
+ message: 'Cannot bind to a variable declared with {@const ...}'
+ },
invalid_binding_writibale: {
code: 'invalid-binding',
message: 'Cannot bind to a variable which is not writable'
@@ -186,6 +190,10 @@ export default {
code: 'illegal-global',
message: `${name} is an illegal variable name`
}),
+ illegal_variable_declaration: {
+ code: 'illegal-variable-declaration',
+ message: 'Cannot declare same variable name which is imported inside
+
+before
+
+
+{#each content as c}
+ {@html c}
+{/each}
+after
diff --git a/test/js/samples/debug-ssr-foo/expected.js b/test/js/samples/debug-ssr-foo/expected.js
index 40531f18c0..a57060d528 100644
--- a/test/js/samples/debug-ssr-foo/expected.js
+++ b/test/js/samples/debug-ssr-foo/expected.js
@@ -7,8 +7,10 @@ const Component = create_ssr_component(($$result, $$props, $$bindings, slots) =>
if ($$props.things === void 0 && $$bindings.things && things !== void 0) $$bindings.things(things);
if ($$props.foo === void 0 && $$bindings.foo && foo !== void 0) $$bindings.foo(foo);
- return `${each(things, thing => `${escape(thing.name)}
- ${debug(null, 7, 2, { foo })}`)}
+ return `${each(things, thing => {
+ return `${escape(thing.name)}
+ ${debug(null, 7, 2, { foo })}`;
+ })}
foo: ${escape(foo)}
`;
});
diff --git a/test/parser/samples/attribute-style-directive-shorthand/output.json b/test/parser/samples/attribute-style-directive-shorthand/output.json
index d4e81b6e4b..ac658408e6 100644
--- a/test/parser/samples/attribute-style-directive-shorthand/output.json
+++ b/test/parser/samples/attribute-style-directive-shorthand/output.json
@@ -13,19 +13,13 @@
{
"start": 5,
"end": 16,
- "type": "Style",
+ "type": "StyleDirective",
"name": "color",
- "modifiers": [],
- "expression": {
- "start": 11,
- "end": 16,
- "name": "color",
- "type": "Identifier"
- }
+ "value": true
}
],
"children": []
}
]
}
-}
+}
\ No newline at end of file
diff --git a/test/parser/samples/attribute-style-directive-string/input.svelte b/test/parser/samples/attribute-style-directive-string/input.svelte
index b2eb6bfef8..dd8ec8dc94 100644
--- a/test/parser/samples/attribute-style-directive-string/input.svelte
+++ b/test/parser/samples/attribute-style-directive-string/input.svelte
@@ -1 +1,7 @@
-
\ No newline at end of file
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/parser/samples/attribute-style-directive-string/output.json b/test/parser/samples/attribute-style-directive-string/output.json
index 4cf2bd30c2..e81e7be3c9 100644
--- a/test/parser/samples/attribute-style-directive-string/output.json
+++ b/test/parser/samples/attribute-style-directive-string/output.json
@@ -1,7 +1,7 @@
{
"html": {
"start": 0,
- "end": 29,
+ "end": 252,
"type": "Fragment",
"children": [
{
@@ -13,23 +13,339 @@
{
"start": 5,
"end": 22,
- "type": "Style",
+ "type": "StyleDirective",
"name": "color",
- "modifiers": [],
- "expression": {
- "type": "TemplateLiteral",
- "expressions": [],
- "quasis": [
- {
- "type": "TemplateElement",
- "value": {
- "raw": "red",
- "cooked": null
+ "value": [
+ {
+ "start": 18,
+ "end": 21,
+ "type": "Text",
+ "raw": "red",
+ "data": "red"
+ }
+ ]
+ }
+ ],
+ "children": []
+ },
+ {
+ "start": 29,
+ "end": 30,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ },
+ {
+ "start": 30,
+ "end": 59,
+ "type": "Element",
+ "name": "div",
+ "attributes": [
+ {
+ "start": 35,
+ "end": 52,
+ "type": "StyleDirective",
+ "name": "color",
+ "value": [
+ {
+ "start": 48,
+ "end": 51,
+ "type": "Text",
+ "raw": "red",
+ "data": "red"
+ }
+ ]
+ }
+ ],
+ "children": []
+ },
+ {
+ "start": 59,
+ "end": 60,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ },
+ {
+ "start": 60,
+ "end": 87,
+ "type": "Element",
+ "name": "div",
+ "attributes": [
+ {
+ "start": 65,
+ "end": 80,
+ "type": "StyleDirective",
+ "name": "color",
+ "value": [
+ {
+ "start": 77,
+ "end": 80,
+ "type": "Text",
+ "raw": "red",
+ "data": "red"
+ }
+ ]
+ }
+ ],
+ "children": []
+ },
+ {
+ "start": 87,
+ "end": 88,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ },
+ {
+ "start": 88,
+ "end": 127,
+ "type": "Element",
+ "name": "div",
+ "attributes": [
+ {
+ "start": 93,
+ "end": 120,
+ "type": "StyleDirective",
+ "name": "color",
+ "value": [
+ {
+ "start": 106,
+ "end": 109,
+ "type": "Text",
+ "raw": "red",
+ "data": "red"
+ },
+ {
+ "start": 109,
+ "end": 119,
+ "type": "MustacheTag",
+ "expression": {
+ "type": "Identifier",
+ "start": 110,
+ "end": 118,
+ "loc": {
+ "start": {
+ "line": 4,
+ "column": 22
+ },
+ "end": {
+ "line": 4,
+ "column": 30
+ }
+ },
+ "name": "variable"
+ }
+ }
+ ]
+ }
+ ],
+ "children": []
+ },
+ {
+ "start": 127,
+ "end": 128,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ },
+ {
+ "start": 128,
+ "end": 167,
+ "type": "Element",
+ "name": "div",
+ "attributes": [
+ {
+ "start": 133,
+ "end": 160,
+ "type": "StyleDirective",
+ "name": "color",
+ "value": [
+ {
+ "start": 146,
+ "end": 149,
+ "type": "Text",
+ "raw": "red",
+ "data": "red"
+ },
+ {
+ "start": 149,
+ "end": 159,
+ "type": "MustacheTag",
+ "expression": {
+ "type": "Identifier",
+ "start": 150,
+ "end": 158,
+ "loc": {
+ "start": {
+ "line": 5,
+ "column": 22
+ },
+ "end": {
+ "line": 5,
+ "column": 30
+ }
+ },
+ "name": "variable"
+ }
+ }
+ ]
+ }
+ ],
+ "children": []
+ },
+ {
+ "start": 167,
+ "end": 168,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ },
+ {
+ "start": 168,
+ "end": 205,
+ "type": "Element",
+ "name": "div",
+ "attributes": [
+ {
+ "start": 173,
+ "end": 198,
+ "type": "StyleDirective",
+ "name": "color",
+ "value": [
+ {
+ "start": 185,
+ "end": 188,
+ "type": "Text",
+ "raw": "red",
+ "data": "red"
+ },
+ {
+ "start": 188,
+ "end": 198,
+ "type": "MustacheTag",
+ "expression": {
+ "type": "Identifier",
+ "start": 189,
+ "end": 197,
+ "loc": {
+ "start": {
+ "line": 6,
+ "column": 21
+ },
+ "end": {
+ "line": 6,
+ "column": 29
+ }
+ },
+ "name": "variable"
+ }
+ }
+ ]
+ }
+ ],
+ "children": []
+ },
+ {
+ "start": 205,
+ "end": 206,
+ "type": "Text",
+ "raw": "\n",
+ "data": "\n"
+ },
+ {
+ "start": 206,
+ "end": 252,
+ "type": "Element",
+ "name": "div",
+ "attributes": [
+ {
+ "start": 211,
+ "end": 245,
+ "type": "StyleDirective",
+ "name": "color",
+ "value": [
+ {
+ "start": 223,
+ "end": 245,
+ "type": "MustacheTag",
+ "expression": {
+ "type": "TemplateLiteral",
+ "start": 224,
+ "end": 244,
+ "loc": {
+ "start": {
+ "line": 7,
+ "column": 18
+ },
+ "end": {
+ "line": 7,
+ "column": 38
+ }
},
- "tail": true
+ "expressions": [
+ {
+ "type": "Identifier",
+ "start": 235,
+ "end": 242,
+ "loc": {
+ "start": {
+ "line": 7,
+ "column": 29
+ },
+ "end": {
+ "line": 7,
+ "column": 36
+ }
+ },
+ "name": "literal"
+ }
+ ],
+ "quasis": [
+ {
+ "type": "TemplateElement",
+ "start": 225,
+ "end": 233,
+ "loc": {
+ "start": {
+ "line": 7,
+ "column": 19
+ },
+ "end": {
+ "line": 7,
+ "column": 27
+ }
+ },
+ "value": {
+ "raw": "template",
+ "cooked": "template"
+ },
+ "tail": false
+ },
+ {
+ "type": "TemplateElement",
+ "start": 243,
+ "end": 243,
+ "loc": {
+ "start": {
+ "line": 7,
+ "column": 37
+ },
+ "end": {
+ "line": 7,
+ "column": 37
+ }
+ },
+ "value": {
+ "raw": "",
+ "cooked": ""
+ },
+ "tail": true
+ }
+ ]
}
- ]
- }
+ }
+ ]
}
],
"children": []
diff --git a/test/parser/samples/attribute-style-directive/output.json b/test/parser/samples/attribute-style-directive/output.json
index 36906045ce..f36ce6b01e 100644
--- a/test/parser/samples/attribute-style-directive/output.json
+++ b/test/parser/samples/attribute-style-directive/output.json
@@ -13,25 +13,31 @@
{
"start": 5,
"end": 26,
- "type": "Style",
+ "type": "StyleDirective",
"name": "color",
- "modifiers": [],
- "expression": {
- "type": "Identifier",
- "start": 18,
- "end": 25,
- "loc": {
- "start": {
- "line": 1,
- "column": 18
- },
- "end": {
- "line": 1,
- "column": 25
+ "value": [
+ {
+ "start": 17,
+ "end": 26,
+ "type": "MustacheTag",
+ "expression": {
+ "type": "Identifier",
+ "start": 18,
+ "end": 25,
+ "loc": {
+ "start": {
+ "line": 1,
+ "column": 18
+ },
+ "end": {
+ "line": 1,
+ "column": 25
+ }
+ },
+ "name": "myColor"
}
- },
- "name": "myColor"
- }
+ }
+ ]
}
],
"children": []
diff --git a/test/runtime/index.ts b/test/runtime/index.ts
index 4fc3880208..f3c962f1d9 100644
--- a/test/runtime/index.ts
+++ b/test/runtime/index.ts
@@ -245,7 +245,7 @@ describe('runtime', () => {
.catch(err => {
// print a clickable link to open the directory
err.stack += `\n\ncmd-click: ${path.relative(process.cwd(), cwd)}/main.svelte`;
- done();
+ done(err);
throw err;
})
.then(() => {
diff --git a/test/runtime/samples/const-tag-await-then-destructuring/_config.js b/test/runtime/samples/const-tag-await-then-destructuring/_config.js
new file mode 100644
index 0000000000..cb40e7c456
--- /dev/null
+++ b/test/runtime/samples/const-tag-await-then-destructuring/_config.js
@@ -0,0 +1,19 @@
+export default {
+ html: '12 120 70, 30+4=34',
+ async test({ component, target, assert }) {
+ component.promise1 = Promise.resolve({width: 5, height: 6});
+ component.promise2 = Promise.reject({width: 6, height: 7});
+
+ await Promise.resolve();
+ assert.htmlEqual(target.innerHTML, `
+ 30 300 110, 50+6=56
+ 42 420 130, 60+7=67
+ `);
+
+ component.constant = 20;
+ assert.htmlEqual(target.innerHTML, `
+ 30 600 220, 100+6=106
+ 42 840 260, 120+7=127
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-await-then-destructuring/main.svelte b/test/runtime/samples/const-tag-await-then-destructuring/main.svelte
new file mode 100644
index 0000000000..ab450822c6
--- /dev/null
+++ b/test/runtime/samples/const-tag-await-then-destructuring/main.svelte
@@ -0,0 +1,23 @@
+
+
+{#await promise1 then { width, height }}
+ {@const {area, volume} = calculate(width, height, constant)}
+ {@const perimeter = (width + height) * constant}
+ {@const [_width, _height, sum] = [width * constant, height, width * constant + height]}
+ {area} {volume} {perimeter}, {_width}+{_height}={sum}
+{/await}
+
+{#await promise2 catch { width, height }}
+ {@const {area, volume} = calculate(width, height, constant)}
+ {@const perimeter = (width + height) * constant}
+ {@const [_width, _height, sum] = [width * constant, height, width * constant + height]}
+ {area} {volume} {perimeter}, {_width}+{_height}={sum}
+{/await}
\ No newline at end of file
diff --git a/test/runtime/samples/const-tag-await-then/_config.js b/test/runtime/samples/const-tag-await-then/_config.js
new file mode 100644
index 0000000000..cb40e7c456
--- /dev/null
+++ b/test/runtime/samples/const-tag-await-then/_config.js
@@ -0,0 +1,19 @@
+export default {
+ html: '12 120 70, 30+4=34',
+ async test({ component, target, assert }) {
+ component.promise1 = Promise.resolve({width: 5, height: 6});
+ component.promise2 = Promise.reject({width: 6, height: 7});
+
+ await Promise.resolve();
+ assert.htmlEqual(target.innerHTML, `
+ 30 300 110, 50+6=56
+ 42 420 130, 60+7=67
+ `);
+
+ component.constant = 20;
+ assert.htmlEqual(target.innerHTML, `
+ 30 600 220, 100+6=106
+ 42 840 260, 120+7=127
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-await-then/main.svelte b/test/runtime/samples/const-tag-await-then/main.svelte
new file mode 100644
index 0000000000..f8eed87115
--- /dev/null
+++ b/test/runtime/samples/const-tag-await-then/main.svelte
@@ -0,0 +1,23 @@
+
+
+{#await promise1 then box}
+ {@const {area, volume} = calculate(box.width, box.height, constant)}
+ {@const perimeter = (box.width + box.height) * constant}
+ {@const [width, height, sum] = [box.width * constant, box.height, box.width * constant + box.height]}
+ {area} {volume} {perimeter}, {width}+{height}={sum}
+{/await}
+
+{#await promise2 catch box}
+ {@const {area, volume} = calculate(box.width, box.height, constant)}
+ {@const perimeter = (box.width + box.height) * constant}
+ {@const [width, height, sum] = [box.width * constant, box.height, box.width * constant + box.height]}
+ {area} {volume} {perimeter}, {width}+{height}={sum}
+{/await}
\ No newline at end of file
diff --git a/test/runtime/samples/const-tag-component/Component.svelte b/test/runtime/samples/const-tag-component/Component.svelte
new file mode 100644
index 0000000000..68ba82f245
--- /dev/null
+++ b/test/runtime/samples/const-tag-component/Component.svelte
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/const-tag-component/_config.js b/test/runtime/samples/const-tag-component/_config.js
new file mode 100644
index 0000000000..66399a06fa
--- /dev/null
+++ b/test/runtime/samples/const-tag-component/_config.js
@@ -0,0 +1,46 @@
+export default {
+ html: `
+ 12 120 70, 30+4=34
+ 12 120 70, 30+4=34
+ 12 120 70, 30+4=34
+
+ 12 120 70, 30+4=34
+
+
+ 12 120 70, 30+4=34
+
+ 12 120 70, 30+4=34
+ 12 120 70, 30+4=34
+ `,
+ async test({ component, target, assert }) {
+ component.constant = 20;
+ assert.htmlEqual(target.innerHTML, `
+ 12 240 140, 60+4=64
+ 12 240 140, 60+4=64
+ 12 240 140, 60+4=64
+
+ 12 240 140, 60+4=64
+
+
+ 12 240 140, 60+4=64
+
+ 12 240 140, 60+4=64
+ 12 240 140, 60+4=64
+ `);
+
+ component.box = {width: 5, height: 6};
+ assert.htmlEqual(target.innerHTML, `
+ 30 600 220, 100+6=106
+ 30 600 220, 100+6=106
+ 30 600 220, 100+6=106
+
+ 30 600 220, 100+6=106
+
+
+ 30 600 220, 100+6=106
+
+ 30 600 220, 100+6=106
+ 30 600 220, 100+6=106
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-component/main.svelte b/test/runtime/samples/const-tag-component/main.svelte
new file mode 100644
index 0000000000..1854c3fba9
--- /dev/null
+++ b/test/runtime/samples/const-tag-component/main.svelte
@@ -0,0 +1,60 @@
+
+
+
+
+ {@const {area, volume} = calculate(box.width, box.height, constant)}
+ {@const perimeter = (box.width + box.height) * constant}
+ {@const [width, height, sum] = [box.width * constant, box.height, box.width * constant + box.height]}
+ {area} {volume} {perimeter}, {width}+{height}={sum}
+
+
+
+ {@const {area, volume} = calculate(width, height, constant)}
+ {@const perimeter = (width + height) * constant}
+ {@const [_width, _height, sum] = [width * constant, height, width * constant + height]}
+ {area} {volume} {perimeter}, {_width}+{_height}={sum}
+
+
+
+ {@const {area, volume} = calculate(width, height, constant)}
+ {@const perimeter = (width + height) * constant}
+ {@const [_width, _height, sum] = [width * constant, height, width * constant + height]}
+ {area} {volume} {perimeter}, {_width}+{_height}={sum}
+
+
+
+
+
+ {@const {area, volume} = calculate(box.width, box.height, constant)}
+ {@const perimeter = (box.width + box.height) * constant}
+ {@const [width, height, sum] = [box.width * constant, box.height, box.width * constant + box.height]}
+ {area} {volume} {perimeter}, {width}+{height}={sum}
+
+
+
+ {@const {area, volume} = calculate(width, height, constant)}
+ {@const perimeter = (width + height) * constant}
+ {@const [_width, _height, sum] = [width * constant, height, width * constant + height]}
+ {area} {volume} {perimeter}, {_width}+{_height}={sum}
+
+
+ {@const {area, volume} = calculate(box.width, box.height, constant)}
+ {@const perimeter = (box.width + box.height) * constant}
+ {@const [width, height, sum] = [box.width * constant, box.height, box.width * constant + box.height]}
+ {area} {volume} {perimeter}, {width}+{height}={sum}
+
+
+
+ {@const {area, volume} = calculate(width, height, constant)}
+ {@const perimeter = (width + height) * constant}
+ {@const [_width, _height, sum] = [width * constant, height, width * constant + height]}
+ {area} {volume} {perimeter}, {_width}+{_height}={sum}
+
diff --git a/test/runtime/samples/const-tag-dependencies/_config.js b/test/runtime/samples/const-tag-dependencies/_config.js
new file mode 100644
index 0000000000..5cbb2da587
--- /dev/null
+++ b/test/runtime/samples/const-tag-dependencies/_config.js
@@ -0,0 +1,12 @@
+export default {
+ html: `
+ 7
+ `,
+ async test({ component, target, assert }) {
+ component.a = 5;
+
+ assert.htmlEqual(target.innerHTML, `
+ 9
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-dependencies/main.svelte b/test/runtime/samples/const-tag-dependencies/main.svelte
new file mode 100644
index 0000000000..cce3b0c1f7
--- /dev/null
+++ b/test/runtime/samples/const-tag-dependencies/main.svelte
@@ -0,0 +1,10 @@
+
+
+{#each [value] as n}
+ {@const ab = a + b}
+ {ab}
+{/each}
\ No newline at end of file
diff --git a/test/runtime/samples/const-tag-each-arrow/_config.js b/test/runtime/samples/const-tag-each-arrow/_config.js
new file mode 100644
index 0000000000..8e8036b851
--- /dev/null
+++ b/test/runtime/samples/const-tag-each-arrow/_config.js
@@ -0,0 +1,47 @@
+export default {
+ html: `
+ #FF0000
+ #00FF00
+ #0000FF
+ `,
+ async test({ component, target, assert }) {
+ component.constant = 20;
+
+ assert.htmlEqual(target.innerHTML, `
+ #FF0000
+ #00FF00
+ #0000FF
+ `);
+
+ component.tags = [
+ {
+ name: 'Red',
+ color: '#FF0000'
+ },
+ {
+ name: 'Green',
+ color: '#00FF00'
+ },
+ {
+ name: 'Blue',
+ color: '#0000FF'
+ },
+ {
+ name: 'Black',
+ color: '#000000'
+ },
+ {
+ name: 'White',
+ color: '#FFFFFF'
+ }
+ ];
+
+ assert.htmlEqual(target.innerHTML, `
+ #FF0000
+ #00FF00
+ #0000FF
+ #000000
+ #FFFFFF
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-each-arrow/main.svelte b/test/runtime/samples/const-tag-each-arrow/main.svelte
new file mode 100644
index 0000000000..7292a7d485
--- /dev/null
+++ b/test/runtime/samples/const-tag-each-arrow/main.svelte
@@ -0,0 +1,21 @@
+
+
+{#each tags as tag}
+ {@const tagColor = tags.find(t => t.name === tag.name).color}
+ {tagColor}
+{/each}
diff --git a/test/runtime/samples/const-tag-each-destructure/_config.js b/test/runtime/samples/const-tag-each-destructure/_config.js
new file mode 100644
index 0000000000..00f8b31540
--- /dev/null
+++ b/test/runtime/samples/const-tag-each-destructure/_config.js
@@ -0,0 +1,30 @@
+export default {
+ html: `
+ 12 120 70, 30+4=34
+ 35 350 120, 50+7=57
+ 48 480 140, 60+8=68
+ `,
+ async test({ component, target, assert }) {
+ component.constant = 20;
+
+ assert.htmlEqual(target.innerHTML, `
+ 12 240 140, 60+4=64
+ 35 700 240, 100+7=107
+ 48 960 280, 120+8=128
+ `);
+
+ component.boxes = [
+ {width: 3, height: 4},
+ {width: 4, height: 5},
+ {width: 5, height: 6},
+ {width: 6, height: 7}
+ ];
+
+ assert.htmlEqual(target.innerHTML, `
+ 12 240 140, 60+4=64
+ 20 400 180, 80+5=85
+ 30 600 220, 100+6=106
+ 42 840 260, 120+7=127
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-each-destructure/main.svelte b/test/runtime/samples/const-tag-each-destructure/main.svelte
new file mode 100644
index 0000000000..7f0391d5e6
--- /dev/null
+++ b/test/runtime/samples/const-tag-each-destructure/main.svelte
@@ -0,0 +1,19 @@
+
+
+{#each boxes as { width, height }}
+ {@const {area, volume} = calculate(width, height, constant)}
+ {@const perimeter = (width + height) * constant}
+ {@const [_width, _height, sum] = [width * constant, height, width * constant + height]}
+ {area} {volume} {perimeter}, {_width}+{_height}={sum}
+{/each}
\ No newline at end of file
diff --git a/test/runtime/samples/const-tag-each/_config.js b/test/runtime/samples/const-tag-each/_config.js
new file mode 100644
index 0000000000..00f8b31540
--- /dev/null
+++ b/test/runtime/samples/const-tag-each/_config.js
@@ -0,0 +1,30 @@
+export default {
+ html: `
+ 12 120 70, 30+4=34
+ 35 350 120, 50+7=57
+ 48 480 140, 60+8=68
+ `,
+ async test({ component, target, assert }) {
+ component.constant = 20;
+
+ assert.htmlEqual(target.innerHTML, `
+ 12 240 140, 60+4=64
+ 35 700 240, 100+7=107
+ 48 960 280, 120+8=128
+ `);
+
+ component.boxes = [
+ {width: 3, height: 4},
+ {width: 4, height: 5},
+ {width: 5, height: 6},
+ {width: 6, height: 7}
+ ];
+
+ assert.htmlEqual(target.innerHTML, `
+ 12 240 140, 60+4=64
+ 20 400 180, 80+5=85
+ 30 600 220, 100+6=106
+ 42 840 260, 120+7=127
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-each/main.svelte b/test/runtime/samples/const-tag-each/main.svelte
new file mode 100644
index 0000000000..004f81cd83
--- /dev/null
+++ b/test/runtime/samples/const-tag-each/main.svelte
@@ -0,0 +1,19 @@
+
+
+{#each boxes as box}
+ {@const {area, volume} = calculate(box.width, box.height, constant)}
+ {@const perimeter = (box.width + box.height) * constant}
+ {@const [width, height, sum] = [box.width * constant, box.height, box.width * constant + box.height]}
+ {area} {volume} {perimeter}, {width}+{height}={sum}
+{/each}
\ No newline at end of file
diff --git a/test/runtime/samples/const-tag-hoisting/_config.js b/test/runtime/samples/const-tag-hoisting/_config.js
new file mode 100644
index 0000000000..f8f4a5c85e
--- /dev/null
+++ b/test/runtime/samples/const-tag-hoisting/_config.js
@@ -0,0 +1,12 @@
+export default {
+ html: `
+ 4 ^ 4 = 256
+ `,
+ async test({ component, target, assert }) {
+ component.value = 3;
+
+ assert.htmlEqual(target.innerHTML, `
+ 3 ^ 4 = 81
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-hoisting/main.svelte b/test/runtime/samples/const-tag-hoisting/main.svelte
new file mode 100644
index 0000000000..49fce93274
--- /dev/null
+++ b/test/runtime/samples/const-tag-hoisting/main.svelte
@@ -0,0 +1,11 @@
+
+
+{#each [value] as n}
+ {n} ^ 4 = {hypercubed}
+
+ {@const squared = n * n}
+ {@const cubed = squared * n}
+ {@const hypercubed = cubed * n}
+{/each}
\ No newline at end of file
diff --git a/test/runtime/samples/const-tag-ordering/_config.js b/test/runtime/samples/const-tag-ordering/_config.js
new file mode 100644
index 0000000000..f8f4a5c85e
--- /dev/null
+++ b/test/runtime/samples/const-tag-ordering/_config.js
@@ -0,0 +1,12 @@
+export default {
+ html: `
+ 4 ^ 4 = 256
+ `,
+ async test({ component, target, assert }) {
+ component.value = 3;
+
+ assert.htmlEqual(target.innerHTML, `
+ 3 ^ 4 = 81
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-ordering/main.svelte b/test/runtime/samples/const-tag-ordering/main.svelte
new file mode 100644
index 0000000000..49fce93274
--- /dev/null
+++ b/test/runtime/samples/const-tag-ordering/main.svelte
@@ -0,0 +1,11 @@
+
+
+{#each [value] as n}
+ {n} ^ 4 = {hypercubed}
+
+ {@const squared = n * n}
+ {@const cubed = squared * n}
+ {@const hypercubed = cubed * n}
+{/each}
\ No newline at end of file
diff --git a/test/runtime/samples/const-tag-shadow/_config.js b/test/runtime/samples/const-tag-shadow/_config.js
new file mode 100644
index 0000000000..312235f113
--- /dev/null
+++ b/test/runtime/samples/const-tag-shadow/_config.js
@@ -0,0 +1,43 @@
+export default {
+ html: `
+ 7
+ 11
+ 15
+ 7
+ 19
+ 23
+ 27
+ 19
+ `,
+ async test({ component, target, assert }) {
+ component.numbers = [
+ {
+ a: 4,
+ b: 5,
+ children: [
+ { a: 6, b: 7 },
+ { a: 8, b: 9 }
+ ]
+ },
+ {
+ a: 10,
+ b: 11,
+ children: [
+ { a: 12, b: 13 },
+ { a: 14, b: 15 }
+ ]
+ }
+ ];
+
+ assert.htmlEqual(target.innerHTML, `
+ 9
+ 13
+ 17
+ 9
+ 21
+ 25
+ 29
+ 21
+ `);
+ }
+};
diff --git a/test/runtime/samples/const-tag-shadow/main.svelte b/test/runtime/samples/const-tag-shadow/main.svelte
new file mode 100644
index 0000000000..725121c733
--- /dev/null
+++ b/test/runtime/samples/const-tag-shadow/main.svelte
@@ -0,0 +1,31 @@
+
+
+{#each numbers as {a, b, children}}
+ {@const ab = a + b}
+ {ab}
+ {#each children as {a, b}}
+ {@const ab = a + b}
+ {ab}
+ {/each}
+ {ab}
+{/each}
\ No newline at end of file
diff --git a/test/runtime/samples/inline-style-directive-shorthand/_config.js b/test/runtime/samples/inline-style-directive-shorthand/_config.js
index 64043e5269..352d4a139c 100644
--- a/test/runtime/samples/inline-style-directive-shorthand/_config.js
+++ b/test/runtime/samples/inline-style-directive-shorthand/_config.js
@@ -1,18 +1,25 @@
export default {
html: `
+
`,
test({ assert, component, target, window }) {
- const p = target.querySelector('p');
+ const [p1, p2] = target.querySelectorAll('p');
- let styles = window.getComputedStyle(p);
- assert.equal(styles.color, 'red');
+ assert.equal(window.getComputedStyle(p1).color, 'red');
+ assert.equal(window.getComputedStyle(p2).color, 'red');
component.color = 'blue';
- assert.htmlEqual(target.innerHTML, '');
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+ `
+ );
- styles = window.getComputedStyle(p);
- assert.equal(styles.color, 'blue');
+ assert.equal(window.getComputedStyle(p1).color, 'blue');
+ assert.equal(window.getComputedStyle(p2).color, 'blue');
}
};
diff --git a/test/runtime/samples/inline-style-directive-shorthand/main.svelte b/test/runtime/samples/inline-style-directive-shorthand/main.svelte
index 65bbff910b..2b5f8e3db7 100644
--- a/test/runtime/samples/inline-style-directive-shorthand/main.svelte
+++ b/test/runtime/samples/inline-style-directive-shorthand/main.svelte
@@ -3,3 +3,7 @@
+
+{#each [1] as _}
+
+{/each}
diff --git a/test/runtime/samples/inline-style-directive-string-variable-kebab-case/_config.js b/test/runtime/samples/inline-style-directive-string-variable-kebab-case/_config.js
new file mode 100644
index 0000000000..3bd6d38ea5
--- /dev/null
+++ b/test/runtime/samples/inline-style-directive-string-variable-kebab-case/_config.js
@@ -0,0 +1,18 @@
+export default {
+ html: `
+
+ `,
+
+ test({ assert, target, window }) {
+ const div = target.querySelector('div');
+ const styles = window.getComputedStyle(div);
+
+ assert.equal(styles['background-image'], 'url(https://raw.githubusercontent.com/sveltejs/branding/master/svelte-vertical.png)');
+ assert.equal(styles.getPropertyValue('--css-variable'), 'rgba(0, 0, 0, 1)');
+
+ assert.htmlEqual(
+ target.innerHTML,
+ ''
+ );
+ }
+};
diff --git a/test/runtime/samples/inline-style-directive-string-variable-kebab-case/main.svelte b/test/runtime/samples/inline-style-directive-string-variable-kebab-case/main.svelte
new file mode 100644
index 0000000000..dbfba08d64
--- /dev/null
+++ b/test/runtime/samples/inline-style-directive-string-variable-kebab-case/main.svelte
@@ -0,0 +1,11 @@
+
+
+
diff --git a/test/runtime/samples/pre-tag/_config.js b/test/runtime/samples/pre-tag/_config.js
new file mode 100644
index 0000000000..a2e8feb118
--- /dev/null
+++ b/test/runtime/samples/pre-tag/_config.js
@@ -0,0 +1,57 @@
+export default {
+ test({ assert, target }) {
+ // Test for tag
+ const elementPre = target.querySelector('#pre');
+ // Test for non tag
+ const elementDiv = target.querySelector('#div');
+ // Test for tag in non tag
+ const elementDivWithPre = target.querySelector('#div-with-pre');
+
+ // There is a slight difference in innerHTML because there is a difference in HTML optimization (in jsdom)
+ // depending on how the innerHTML is set.
+ // (There is no difference in the display.)
+ // Reassign innerHTML to add the same optimizations to innerHTML.
+
+ // eslint-disable-next-line no-self-assign
+ elementPre.innerHTML = elementPre.innerHTML;
+ // eslint-disable-next-line no-self-assign
+ elementDiv.innerHTML = elementDiv.innerHTML;
+ // eslint-disable-next-line no-self-assign
+ elementDivWithPre.innerHTML = elementDivWithPre.innerHTML;
+
+ assert.equal(
+ elementPre.innerHTML,
+ `
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+`
+ );
+ assert.equal(
+ elementDiv.innerHTML,
+ `A
+ B
+ C
+ D
+ E
+ F`
+ );
+ assert.equal(
+ elementDivWithPre.innerHTML,
+ ` A
+ B
+
+ C
+ D
+
+ E
+ F
+ `
+ );
+ }
+};
diff --git a/test/runtime/samples/pre-tag/main.svelte b/test/runtime/samples/pre-tag/main.svelte
new file mode 100644
index 0000000000..ef603b9883
--- /dev/null
+++ b/test/runtime/samples/pre-tag/main.svelte
@@ -0,0 +1,34 @@
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
diff --git a/test/runtime/samples/preserve-whitespaces/_config.js b/test/runtime/samples/preserve-whitespaces/_config.js
new file mode 100644
index 0000000000..e0c621a18b
--- /dev/null
+++ b/test/runtime/samples/preserve-whitespaces/_config.js
@@ -0,0 +1,66 @@
+export default {
+ compileOptions: {
+ preserveWhitespace: true
+ },
+ test({ assert, target }) {
+ // Test for tag
+ const elementPre = target.querySelector('#pre');
+ // Test for non tag
+ const elementDiv = target.querySelector('#div');
+ // Test for tag in non tag
+ const elementDivWithPre = target.querySelector('#div-with-pre');
+
+ // There is a slight difference in innerHTML because there is a difference in HTML optimization (in jsdom)
+ // depending on how the innerHTML is set.
+ // (There is no difference in the display.)
+ // Reassign innerHTML to add the same optimizations to innerHTML.
+
+ // eslint-disable-next-line no-self-assign
+ elementPre.innerHTML = elementPre.innerHTML;
+ // eslint-disable-next-line no-self-assign
+ elementDiv.innerHTML = elementDiv.innerHTML;
+ // eslint-disable-next-line no-self-assign
+ elementDivWithPre.innerHTML = elementDivWithPre.innerHTML;
+
+ assert.equal(
+ elementPre.innerHTML,
+ `
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+`
+ );
+ assert.equal(
+ elementDiv.innerHTML,
+ `
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+`
+ );
+ assert.equal(
+ elementDivWithPre.innerHTML,
+ `
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+`
+ );
+ }
+};
diff --git a/test/runtime/samples/preserve-whitespaces/main.svelte b/test/runtime/samples/preserve-whitespaces/main.svelte
new file mode 100644
index 0000000000..ef603b9883
--- /dev/null
+++ b/test/runtime/samples/preserve-whitespaces/main.svelte
@@ -0,0 +1,34 @@
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
diff --git a/test/server-side-rendering/index.ts b/test/server-side-rendering/index.ts
index f4175c73a6..f5773e37b6 100644
--- a/test/server-side-rendering/index.ts
+++ b/test/server-side-rendering/index.ts
@@ -83,9 +83,13 @@ describe('ssr', () => {
if (css.code) fs.writeFileSync(`${dir}/_actual.css`, css.code);
try {
- (compileOptions.preserveComments
- ? assert.htmlEqualWithComments
- : assert.htmlEqual)(html, expectedHtml);
+ if (config.withoutNormalizeHtml) {
+ assert.strictEqual(html.trim(), expectedHtml.trim().replace(/\r\n/g, '\n'));
+ } else {
+ (compileOptions.preserveComments
+ ? assert.htmlEqualWithComments
+ : assert.htmlEqual)(html, expectedHtml);
+ }
} catch (error) {
if (shouldUpdateExpected()) {
fs.writeFileSync(`${dir}/_expected.html`, html);
@@ -128,13 +132,13 @@ describe('ssr', () => {
}
if (show) showOutput(dir, { generate: 'ssr', format: 'cjs' });
+ done();
} catch (err) {
showOutput(dir, { generate: 'ssr', format: 'cjs' });
err.stack += `\n\ncmd-click: ${path.relative(process.cwd(), dir)}/main.svelte`;
- throw err;
+ done(err);
} finally {
set_current_component(null);
- done();
}
});
});
diff --git a/test/server-side-rendering/samples/pre-tag/_config.js b/test/server-side-rendering/samples/pre-tag/_config.js
new file mode 100644
index 0000000000..39b31839f5
--- /dev/null
+++ b/test/server-side-rendering/samples/pre-tag/_config.js
@@ -0,0 +1,3 @@
+export default {
+ withoutNormalizeHtml: true
+};
diff --git a/test/server-side-rendering/samples/pre-tag/_expected.html b/test/server-side-rendering/samples/pre-tag/_expected.html
new file mode 100644
index 0000000000..7f88acdff4
--- /dev/null
+++ b/test/server-side-rendering/samples/pre-tag/_expected.html
@@ -0,0 +1,30 @@
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+A
+ B
+ C
+ D
+
+ E
+ F
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
diff --git a/test/server-side-rendering/samples/pre-tag/main.svelte b/test/server-side-rendering/samples/pre-tag/main.svelte
new file mode 100644
index 0000000000..fb240817f7
--- /dev/null
+++ b/test/server-side-rendering/samples/pre-tag/main.svelte
@@ -0,0 +1,34 @@
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
diff --git a/test/server-side-rendering/samples/preserve-whitespaces/_config.js b/test/server-side-rendering/samples/preserve-whitespaces/_config.js
new file mode 100644
index 0000000000..41eb78446c
--- /dev/null
+++ b/test/server-side-rendering/samples/preserve-whitespaces/_config.js
@@ -0,0 +1,6 @@
+export default {
+ withoutNormalizeHtml: true,
+ compileOptions: {
+ preserveWhitespace: true
+ }
+};
diff --git a/test/server-side-rendering/samples/preserve-whitespaces/_expected.html b/test/server-side-rendering/samples/preserve-whitespaces/_expected.html
new file mode 100644
index 0000000000..fb240817f7
--- /dev/null
+++ b/test/server-side-rendering/samples/preserve-whitespaces/_expected.html
@@ -0,0 +1,34 @@
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
diff --git a/test/server-side-rendering/samples/preserve-whitespaces/main.svelte b/test/server-side-rendering/samples/preserve-whitespaces/main.svelte
new file mode 100644
index 0000000000..fb240817f7
--- /dev/null
+++ b/test/server-side-rendering/samples/preserve-whitespaces/main.svelte
@@ -0,0 +1,34 @@
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
+
+
+ A
+ B
+
+ C
+ D
+
+ E
+ F
+
+
diff --git a/test/validator/samples/animation-each-with-const/errors.json b/test/validator/samples/animation-each-with-const/errors.json
new file mode 100644
index 0000000000..0637a088a0
--- /dev/null
+++ b/test/validator/samples/animation-each-with-const/errors.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/test/validator/samples/animation-each-with-const/input.svelte b/test/validator/samples/animation-each-with-const/input.svelte
new file mode 100644
index 0000000000..1e236de76f
--- /dev/null
+++ b/test/validator/samples/animation-each-with-const/input.svelte
@@ -0,0 +1,10 @@
+
+
+
+ {#each [] as n (n)}
+ {@const a = n}
+
+ {/each}
+
diff --git a/test/validator/samples/animation-each-with-whitespace/errors.json b/test/validator/samples/animation-each-with-whitespace/errors.json
new file mode 100644
index 0000000000..0637a088a0
--- /dev/null
+++ b/test/validator/samples/animation-each-with-whitespace/errors.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/test/validator/samples/animation-each-with-whitespace/input.svelte b/test/validator/samples/animation-each-with-whitespace/input.svelte
new file mode 100644
index 0000000000..3e063716ab
--- /dev/null
+++ b/test/validator/samples/animation-each-with-whitespace/input.svelte
@@ -0,0 +1,7 @@
+
+
+
+ {#each [] as n (n)} {/each}
+
diff --git a/test/validator/samples/component-invalid-style-directive/errors.json b/test/validator/samples/component-invalid-style-directive/errors.json
new file mode 100644
index 0000000000..087f0db651
--- /dev/null
+++ b/test/validator/samples/component-invalid-style-directive/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-component-style-directive",
+ "message": "Style directives cannot be used on components",
+ "start": { "line": 7, "column": 19, "character": 97 },
+ "end": { "line": 7, "column": 36, "character": 114 },
+ "pos": 97
+ }
+]
diff --git a/test/validator/samples/component-invalid-style-directive/input.svelte b/test/validator/samples/component-invalid-style-directive/input.svelte
new file mode 100644
index 0000000000..975621088f
--- /dev/null
+++ b/test/validator/samples/component-invalid-style-directive/input.svelte
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/test/validator/samples/const-tag-conflict-1/errors.json b/test/validator/samples/const-tag-conflict-1/errors.json
new file mode 100644
index 0000000000..59c72eccaf
--- /dev/null
+++ b/test/validator/samples/const-tag-conflict-1/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-const-declaration",
+ "message": "'a' has already been declared",
+ "start": { "line": 7, "column": 2, "character": 84 },
+ "end": { "line": 7, "column": 19, "character": 101 },
+ "pos": 84
+ }
+]
diff --git a/test/validator/samples/const-tag-conflict-1/input.svelte b/test/validator/samples/const-tag-conflict-1/input.svelte
new file mode 100644
index 0000000000..6633eeacdf
--- /dev/null
+++ b/test/validator/samples/const-tag-conflict-1/input.svelte
@@ -0,0 +1,8 @@
+
+
+{#each array as item}
+ {@const a = item}
+ {@const a = item}
+{/each}
\ No newline at end of file
diff --git a/test/validator/samples/const-tag-conflict-2/errors.json b/test/validator/samples/const-tag-conflict-2/errors.json
new file mode 100644
index 0000000000..11e2535091
--- /dev/null
+++ b/test/validator/samples/const-tag-conflict-2/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-const-declaration",
+ "message": "'item' has already been declared",
+ "start": { "line": 6, "column": 2, "character": 64 },
+ "end": { "line": 6, "column": 21, "character": 83 },
+ "pos": 64
+ }
+]
diff --git a/test/validator/samples/const-tag-conflict-2/input.svelte b/test/validator/samples/const-tag-conflict-2/input.svelte
new file mode 100644
index 0000000000..2be7207691
--- /dev/null
+++ b/test/validator/samples/const-tag-conflict-2/input.svelte
@@ -0,0 +1,7 @@
+
+
+{#each array as item}
+ {@const item = 123}
+{/each}
\ No newline at end of file
diff --git a/test/validator/samples/const-tag-cyclical/errors.json b/test/validator/samples/const-tag-cyclical/errors.json
new file mode 100644
index 0000000000..1436747798
--- /dev/null
+++ b/test/validator/samples/const-tag-cyclical/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "cyclical-const-tags",
+ "message": "Cyclical dependency detected: b → c → b",
+ "start": { "line": 6, "column": 2, "character": 61 },
+ "end": { "line": 6, "column": 20, "character": 79 },
+ "pos": 61
+ }
+]
diff --git a/test/validator/samples/const-tag-cyclical/input.svelte b/test/validator/samples/const-tag-cyclical/input.svelte
new file mode 100644
index 0000000000..2f694be808
--- /dev/null
+++ b/test/validator/samples/const-tag-cyclical/input.svelte
@@ -0,0 +1,8 @@
+
+
+{#each array as a}
+ {@const b = a + c}
+ {@const c = b + a}
+{/each}
\ No newline at end of file
diff --git a/test/validator/samples/const-tag-out-of-scope/input.svelte b/test/validator/samples/const-tag-out-of-scope/input.svelte
new file mode 100644
index 0000000000..d1c2723e22
--- /dev/null
+++ b/test/validator/samples/const-tag-out-of-scope/input.svelte
@@ -0,0 +1,10 @@
+
+
+{#each array as a}
+ {@const b = a + 1}
+
+{/each}
+
+{b}
\ No newline at end of file
diff --git a/test/validator/samples/const-tag-out-of-scope/warnings.json b/test/validator/samples/const-tag-out-of-scope/warnings.json
new file mode 100644
index 0000000000..c85b417fe4
--- /dev/null
+++ b/test/validator/samples/const-tag-out-of-scope/warnings.json
@@ -0,0 +1,17 @@
+[
+ {
+ "code": "missing-declaration",
+ "message": "'b' is not defined",
+ "pos": 100,
+ "start": {
+ "character": 100,
+ "column": 1,
+ "line": 10
+ },
+ "end": {
+ "character": 101,
+ "column": 2,
+ "line": 10
+ }
+ }
+]
diff --git a/test/validator/samples/const-tag-placement-1/errors.json b/test/validator/samples/const-tag-placement-1/errors.json
new file mode 100644
index 0000000000..52de84e2be
--- /dev/null
+++ b/test/validator/samples/const-tag-placement-1/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-const-placement",
+ "message": "{@const} must be the immediate child of {#each}, {:then}, {:catch}, or ",
+ "start": { "line": 5, "column": 0, "character": 36 },
+ "end": { "line": 5, "column": 18, "character": 54 },
+ "pos": 36
+ }
+]
diff --git a/test/validator/samples/const-tag-placement-1/input.svelte b/test/validator/samples/const-tag-placement-1/input.svelte
new file mode 100644
index 0000000000..14ea3085e7
--- /dev/null
+++ b/test/validator/samples/const-tag-placement-1/input.svelte
@@ -0,0 +1,5 @@
+
+
+{@const b = a + 1}
\ No newline at end of file
diff --git a/test/validator/samples/const-tag-placement-2/errors.json b/test/validator/samples/const-tag-placement-2/errors.json
new file mode 100644
index 0000000000..005b3ff8b7
--- /dev/null
+++ b/test/validator/samples/const-tag-placement-2/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-const-placement",
+ "message": "{@const} must be the immediate child of {#each}, {:then}, {:catch}, or ",
+ "start": { "line": 6, "column": 2, "character": 46 },
+ "end": { "line": 6, "column": 20, "character": 64 },
+ "pos": 46
+ }
+]
diff --git a/test/validator/samples/const-tag-placement-2/input.svelte b/test/validator/samples/const-tag-placement-2/input.svelte
new file mode 100644
index 0000000000..a843f9d58f
--- /dev/null
+++ b/test/validator/samples/const-tag-placement-2/input.svelte
@@ -0,0 +1,7 @@
+
+
+{#if a}
+ {@const b = a + 1}
+{/if}
\ No newline at end of file
diff --git a/test/validator/samples/const-tag-placement-3/errors.json b/test/validator/samples/const-tag-placement-3/errors.json
new file mode 100644
index 0000000000..cc0ba4d74d
--- /dev/null
+++ b/test/validator/samples/const-tag-placement-3/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-const-placement",
+ "message": "{@const} must be the immediate child of {#each}, {:then}, {:catch}, or ",
+ "start": { "line": 7, "column": 4, "character": 63 },
+ "end": { "line": 7, "column": 18, "character": 77 },
+ "pos": 63
+ }
+]
diff --git a/test/validator/samples/const-tag-placement-3/input.svelte b/test/validator/samples/const-tag-placement-3/input.svelte
new file mode 100644
index 0000000000..2519482a98
--- /dev/null
+++ b/test/validator/samples/const-tag-placement-3/input.svelte
@@ -0,0 +1,9 @@
+
+
+{#each a as i}
+
+ {@const b = i}
+
+{/each}
\ No newline at end of file
diff --git a/test/validator/samples/const-tag-readonly-1/errors.json b/test/validator/samples/const-tag-readonly-1/errors.json
new file mode 100644
index 0000000000..ed60c529fd
--- /dev/null
+++ b/test/validator/samples/const-tag-readonly-1/errors.json
@@ -0,0 +1,9 @@
+[
+ {
+ "code": "invalid-const-update",
+ "message": "'b' is declared using {@const ...} and is read-only",
+ "start": { "line": 7, "column": 26, "character": 106 },
+ "end": { "line": 7, "column": 30, "character": 110 },
+ "pos": 106
+ }
+]
diff --git a/test/validator/samples/const-tag-readonly-1/input.svelte b/test/validator/samples/const-tag-readonly-1/input.svelte
new file mode 100644
index 0000000000..b5a37c8608
--- /dev/null
+++ b/test/validator/samples/const-tag-readonly-1/input.svelte
@@ -0,0 +1,8 @@
+
+
+{#each array as a}
+ {@const b = a + 1}
+