diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3ccfae1..c620986 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -158,4 +158,4 @@ jobs:
- name: install
run: pnpm install --frozen-lockfile --offline
- name: run tests
- run: pnpm test
+ run: pnpm test:ci
diff --git a/package.json b/package.json
index 35125a2..d13654d 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"scripts": {
"release": "pnpx --no changeset publish",
"lint": "pnpm --recursive lint",
+ "test:ci": "pnpm --recursive test:ci",
"test": "pnpm --recursive test"
}
}
diff --git a/packages/svelte-hmr-spec/test/local-state-preserveLocalStateKey.spec.js b/packages/svelte-hmr-spec/test/local-state-preserveLocalStateKey.spec.js
index 0ba8c7d..21e7608 100644
--- a/packages/svelte-hmr-spec/test/local-state-preserveLocalStateKey.spec.js
+++ b/packages/svelte-hmr-spec/test/local-state-preserveLocalStateKey.spec.js
@@ -1,6 +1,9 @@
const { clickButton } = require('./helpers')
-describe('local state: preserveLocalStateKey', () => {
+const describeIf =
+ process.env.PRESERVE_LOCAL_STATE === 'false' ? describe : describe.skip
+
+describeIf('local state: preserveLocalStateKey', () => {
testHmr`
# inline annotation
diff --git a/packages/svelte-hmr-spec/test/preserveLocalState-smart.spec.js b/packages/svelte-hmr-spec/test/preserveLocalState-smart.spec.js
new file mode 100644
index 0000000..628c35d
--- /dev/null
+++ b/packages/svelte-hmr-spec/test/preserveLocalState-smart.spec.js
@@ -0,0 +1,368 @@
+const { clickButton } = require('./helpers')
+
+const describeIf =
+ process.env.PRESERVE_LOCAL_STATE === 'smart' ? describe : describe.skip
+
+describeIf('preserveLocalState: smart', () => {
+ testHmr`
+ # preserves 1 mutable
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x}
+ ::1 after: {x}
+
+
+ * * * * *
+
+ ::0::
+ before: 0
+ ${clickButton()}
+ before: 1
+ ::1::
+ after: 1
+ `
+
+ testHmr`
+ # preserves 2 mutables
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x};{y}
+ ::1 after: {x};{y}
+
+
+ * * * * *
+
+ ::0::
+ before: 0;10
+ ${clickButton()}
+ before: 1;11
+ ::1::
+ after: 1;11
+ `
+
+ testHmr`
+ # resets if @hmr:reset
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x};{y}
+ ::1 after: {x};{y}
+
+
+ * * * * *
+
+ ::0::
+ before: 0;10
+ ${clickButton()}
+ before: 1;11
+ ::1::
+ after: 0;10
+ `
+
+ testHmr`
+ # resets 1 mutable of several if init change
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x};{y}
+ ::1 after: {x};{y}
+ reactive sum = {xy}
+ sum = {x + y}
+
+
+ * * * * *
+
+ ::0::
+ before: 0;10
+ reactive sum = 10
+ sum = 10
+ ${clickButton()}
+ before: 1;11
+ reactive sum = 12
+ sum = 12
+ ::1::
+ after: 100;11
+ reactive sum = 111
+ sum = 111
+ `
+
+ testHmr`
+ # preserves props
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x}
+ ::1 after: {x}
+
+
+ * * * * *
+
+ ::0::
+ before: 0
+ ${clickButton()}
+ before: 1
+ ::1::
+ after: 1
+ `
+
+ testHmr`
+ # reset props if init changes
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x}
+ ::1 after: {x}
+
+
+ * * * * *
+
+ ::0::
+ before: 0
+ ${clickButton()}
+ before: 1
+ ::1::
+ after: 10
+ `
+
+ testHmr`
+ # reset propagates to child
+
+ --- Child.svelte ---
+
+
+
+ {foo}
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x} --
+ ::1 after: {x} --
+
+
+ * * * * *
+
+ ::0::
+ before: 0 -- foo-0
+ ${clickButton()}
+ before: 1 -- foo-1
+ ::1::
+ after: 10 -- foo-10
+ `
+
+ describe('normalization: ignore non significant spaces', () => {
+ testHmr`
+ # ignores non significant spaces before =
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x}
+ ::1 after: {x}
+
+
+ * * * * *
+
+ ::0::
+ before: 0
+ ${clickButton()}
+ before: 1
+ ::1::
+ after: 1
+ `
+
+ testHmr`
+ # ignores non significant spaces in primitive values
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x}
+ ::1 after: {x}
+
+
+ * * * * *
+
+ ::0::
+ before: 0
+ ${clickButton()}
+ before: 1
+ ::1::
+ after: 1
+ `
+
+ testHmr`
+ # ignores non significant spaces in single identifier
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x}
+ ::1 after: {x}
+
+
+ * * * * *
+
+ ::0::
+ before: 0
+ ${clickButton()}
+ before: 1
+ ::1::
+ after: 1
+ `
+
+ testHmr`
+ # ignores non significant spaces in binary expression
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x}
+ ::1 after: {x}
+
+
+ * * * * *
+
+ ::0::
+ before: 0
+ ${clickButton()}
+ before: 1
+ ::1::
+ after: 1
+ `
+
+ testHmr`
+ # ignores non significant spaces in multi members expression
+
+ --- App.svelte ---
+
+
+
+
+
+
+ ::0 before: {x}
+ ::1 after: {x}
+
+
+ * * * * *
+
+ ::0::
+ before: 0
+ ${clickButton()}
+ before: 1
+ ::1::
+ after: 1
+ `
+ })
+})
diff --git a/packages/svelte-hmr/lib/make-hot.js b/packages/svelte-hmr/lib/make-hot.js
index 53d019a..38ee33e 100644
--- a/packages/svelte-hmr/lib/make-hot.js
+++ b/packages/svelte-hmr/lib/make-hot.js
@@ -1,9 +1,11 @@
const globalName = '___SVELTE_HMR_HOT_API'
const globalAdapterName = '___SVELTE_HMR_HOT_API_PROXY_ADAPTER'
+const PRESERVE_LOCAL_STATE_SMART = 'smart'
+
const defaultHotOptions = {
// preserve all local state
- preserveLocalState: false,
+ preserveLocalState: false, // true | false | 'smart'
// escape hatchs from preservation of local state
//
@@ -309,6 +311,53 @@ const createMakeHot = ({ resolveAbsoluteImport, pkg = {} }) => ({
return [...variables]
}
+ const resolveSmartPreserveLocalState = ({ code, compiled }) => {
+ if (!compiled.ast.instance) return false
+
+ const variables = {}
+
+ const reduceDeclaration = decl => {
+ const init = decl.init
+
+ if (!init) return undefined
+
+ if ('value' in init) return init.value
+
+ if (init.type === 'Identifier') return init.name
+
+ if (init.type === 'BinaryExpression') {
+ return [
+ reduceDeclaration(init.left),
+ reduceDeclaration(init.operator),
+ reduceDeclaration(init.right),
+ ].join(' ')
+ }
+
+ return code.slice(init.start, init.end)
+ }
+
+ walk(compiled.ast.instance, {
+ enter(node) {
+ switch (node.type) {
+ case 'VariableDeclaration': {
+ if (node.kind !== 'let') return
+
+ const decl =
+ node.declarations && node.declarations[0] && node.declarations[0]
+
+ const name = decl.id && node.declarations[0].id.name
+
+ if (!name) return
+
+ variables[name] = reduceDeclaration(decl)
+ }
+ }
+ },
+ })
+
+ return variables
+ }
+
const resolvePreserveLocalState = ({
hotOptions,
originalCode,
@@ -333,6 +382,13 @@ const createMakeHot = ({ resolveAbsoluteImport, pkg = {} }) => ({
if (preserveAllLocalStateKey && hasKey(preserveAllLocalStateKey)) {
return true
}
+ // preserveLocalState
+ if (preserveLocalState === PRESERVE_LOCAL_STATE_SMART) {
+ return resolveSmartPreserveLocalState({ code: originalCode, compiled })
+ }
+ if (preserveLocalState) {
+ return true
+ }
// preserveLocalStateKey
if (preserveLocalStateKey && hasKey(preserveLocalStateKey)) {
// returns an array of variable names to preserve
diff --git a/packages/svelte-hmr/runtime/proxy.js b/packages/svelte-hmr/runtime/proxy.js
index 17ab668..f363fb2 100644
--- a/packages/svelte-hmr/runtime/proxy.js
+++ b/packages/svelte-hmr/runtime/proxy.js
@@ -251,6 +251,10 @@ class ProxyComponent {
this.$$ = comp.$$
lastProperties = copyComponentProperties(this, comp, lastProperties)
},
+ smartPreserveLocalState:
+ // TODO: use constant
+ current.hotOptions.preserveLocalState === 'smart' &&
+ current.preserveLocalState,
})
setComponent(_cmp)
} catch (err) {
diff --git a/packages/svelte-hmr/runtime/svelte-hooks.js b/packages/svelte-hmr/runtime/svelte-hooks.js
index fd4cc4b..0ef0a60 100644
--- a/packages/svelte-hmr/runtime/svelte-hooks.js
+++ b/packages/svelte-hmr/runtime/svelte-hooks.js
@@ -84,11 +84,13 @@ const get_current_component_safe = () => {
export const createProxiedComponent = (
Component,
initialOptions,
- { allowLiveBinding, onInstance, onMount, onDestroy }
+ { allowLiveBinding, onInstance, onMount, onDestroy, smartPreserveLocalState }
) => {
let cmp
let options = initialOptions
+ let lastSmartPreserveLocalState = smartPreserveLocalState
+
const isCurrent = _cmp => cmp === _cmp
const assignOptions = (target, anchor, restore, preserveLocalState) => {
@@ -109,18 +111,42 @@ export const createProxiedComponent = (
}
if (preserveLocalState && restore.state) {
+ // partial
if (Array.isArray(preserveLocalState)) {
// form ['a', 'b'] => preserve only 'a' and 'b'
props.$$inject = {}
for (const key of preserveLocalState) {
props.$$inject[key] = restore.state[key]
}
- } else {
+ }
+ // smart -- preserve only if declaration has not changed
+ else if (typeof preserveLocalState === 'object') {
+ const hasChanged = key =>
+ lastSmartPreserveLocalState[key] !== preserveLocalState[key]
+ const someInitHasChanged = Object.keys(preserveLocalState).some(
+ hasChanged
+ )
+ if (someInitHasChanged) {
+ // delete props.$$inject
+ props.$$inject = {}
+ for (const key of Object.keys(preserveLocalState)) {
+ if (hasChanged(key)) continue
+ props.$$inject[key] = restore.state[key]
+ }
+ } else {
+ props.$$inject = restore.state
+ }
+ }
+ // all
+ else {
props.$$inject = restore.state
}
} else {
delete props.$$inject
}
+
+ lastSmartPreserveLocalState = preserveLocalState
+
options = Object.assign({}, initialOptions, {
target,
anchor,
diff --git a/playground/kit-app/src/routes/index.svelte b/playground/kit-app/src/routes/index.svelte
index 5982b0a..82638e9 100644
--- a/playground/kit-app/src/routes/index.svelte
+++ b/playground/kit-app/src/routes/index.svelte
@@ -1,2 +1,12 @@
-
Welcome to SvelteKit
-Visit kit.svelte.dev to read the documentation
+
+
+{x}
+
+
diff --git a/playground/kit-app/svelte.config.js b/playground/kit-app/svelte.config.js
index 5eb051a..2c20006 100644
--- a/playground/kit-app/svelte.config.js
+++ b/playground/kit-app/svelte.config.js
@@ -9,6 +9,10 @@ const config = {
kit: {
// hydrate the element in src/app.html
target: '#svelte'
+ },
+
+ hot: {
+ preserveLocalState: 'smart'
}
};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b214e5f..8665753 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -90,6 +90,7 @@ importers:
'@rollup/plugin-node-resolve': ^13.0.4
cross-env: ^7.0.3
nollup: ^0.17.0
+ npm-run-all: ^4.1.5
rollup: '2'
rollup-plugin-hot: ^0.1.1
rollup-plugin-livereload: ^1.0.0
@@ -106,10 +107,11 @@ importers:
'@rollup/plugin-commonjs': 19.0.2_rollup@2.54.0
'@rollup/plugin-node-resolve': 13.0.4_rollup@2.54.0
nollup: 0.17.0_rollup@2.54.0
+ npm-run-all: 4.1.5
rollup: 2.54.0
rollup-plugin-hot: 0.1.1_rollup@2.54.0
rollup-plugin-livereload: 1.3.0
- rollup-plugin-svelte-hot: github.com/rixo/rollup-plugin-svelte-hot/0b9e5e34807529a7202494148675dea9603e31ff_bce53102debd41c5dac09b4d251cb2d9
+ rollup-plugin-svelte-hot: github.com/rixo/rollup-plugin-svelte-hot/5911fabc970c634f78c901e023526c81990e7474_bce53102debd41c5dac09b4d251cb2d9
rollup-plugin-terser: 5.3.1_rollup@2.54.0
svelte: 3.41.0
svelte-hmr: link:../../../packages/svelte-hmr
@@ -1879,11 +1881,37 @@ packages:
string.prototype.trimstart: 1.0.4
unbox-primitive: 1.0.0
+ /es-abstract/1.19.1:
+ resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ es-to-primitive: 1.2.1
+ function-bind: 1.1.1
+ get-intrinsic: 1.1.1
+ get-symbol-description: 1.0.0
+ has: 1.0.3
+ has-symbols: 1.0.2
+ internal-slot: 1.0.3
+ is-callable: 1.2.4
+ is-negative-zero: 2.0.1
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.1
+ is-string: 1.0.7
+ is-weakref: 1.0.1
+ object-inspect: 1.11.0
+ object-keys: 1.1.1
+ object.assign: 4.1.2
+ string.prototype.trimend: 1.0.4
+ string.prototype.trimstart: 1.0.4
+ unbox-primitive: 1.0.1
+ dev: true
+
/es-to-primitive/1.2.1:
resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
engines: {node: '>= 0.4'}
dependencies:
- is-callable: 1.2.3
+ is-callable: 1.2.4
is-date-object: 1.0.4
is-symbol: 1.0.4
@@ -2741,6 +2769,14 @@ packages:
pump: 3.0.0
dev: true
+ /get-symbol-description/1.0.0:
+ resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.1.1
+ dev: true
+
/glob-parent/5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -2846,6 +2882,12 @@ packages:
resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==}
engines: {node: '>= 0.4'}
+ /has-tostringtag/1.0.0:
+ resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.2
+
/has/1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
@@ -3006,6 +3048,15 @@ packages:
through: 2.3.8
dev: true
+ /internal-slot/1.0.3:
+ resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.1.1
+ has: 1.0.3
+ side-channel: 1.0.4
+ dev: true
+
/ipaddr.js/1.9.1:
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
engines: {node: '>= 0.10'}
@@ -3038,6 +3089,10 @@ packages:
resolution: {integrity: sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==}
engines: {node: '>= 0.4'}
+ /is-callable/1.2.4:
+ resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==}
+ engines: {node: '>= 0.4'}
+
/is-ci/2.0.0:
resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==}
hasBin: true
@@ -3132,6 +3187,18 @@ packages:
call-bind: 1.0.2
has-symbols: 1.0.2
+ /is-regex/1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: true
+
+ /is-shared-array-buffer/1.0.1:
+ resolution: {integrity: sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==}
+ dev: true
+
/is-stream/1.1.0:
resolution: {integrity: sha1-EtSj3U5o4Lec6428hBc66A2RykQ=}
engines: {node: '>=0.10.0'}
@@ -3151,6 +3218,12 @@ packages:
resolution: {integrity: sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==}
engines: {node: '>= 0.4'}
+ /is-string/1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+
/is-subdir/1.2.0:
resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==}
engines: {node: '>=4'}
@@ -3164,6 +3237,12 @@ packages:
dependencies:
has-symbols: 1.0.2
+ /is-weakref/1.0.1:
+ resolution: {integrity: sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: true
+
/is-windows/1.0.2:
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
engines: {node: '>=0.10.0'}
@@ -3220,6 +3299,10 @@ packages:
hasBin: true
dev: true
+ /json-parse-better-errors/1.0.2:
+ resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==}
+ dev: true
+
/json-parse-even-better-errors/2.3.1:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
dev: true
@@ -3325,6 +3408,16 @@ packages:
strip-bom: 3.0.0
dev: true
+ /load-json-file/4.0.0:
+ resolution: {integrity: sha1-L19Fq5HjMhYjT9U62rZo607AmTs=}
+ engines: {node: '>=4'}
+ dependencies:
+ graceful-fs: 4.2.6
+ parse-json: 4.0.0
+ pify: 3.0.0
+ strip-bom: 3.0.0
+ dev: true
+
/load-yaml-file/0.2.0:
resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==}
engines: {node: '>=6'}
@@ -3480,6 +3573,11 @@ packages:
readable-stream: 2.3.7
dev: false
+ /memorystream/0.3.1:
+ resolution: {integrity: sha1-htcJCzDORV1j+64S3aUaR93K+bI=}
+ engines: {node: '>= 0.10.0'}
+ dev: true
+
/meow/6.1.1:
resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==}
engines: {node: '>=8'}
@@ -3787,6 +3885,22 @@ packages:
which: 1.3.1
dev: true
+ /npm-run-all/4.1.5:
+ resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==}
+ engines: {node: '>= 4'}
+ hasBin: true
+ dependencies:
+ ansi-styles: 3.2.1
+ chalk: 2.4.2
+ cross-spawn: 6.0.5
+ memorystream: 0.3.1
+ minimatch: 3.0.4
+ pidtree: 0.3.1
+ read-pkg: 3.0.0
+ shell-quote: 1.7.3
+ string.prototype.padend: 3.1.3
+ dev: true
+
/npm-run-path/2.0.2:
resolution: {integrity: sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=}
engines: {node: '>=4'}
@@ -3826,6 +3940,10 @@ packages:
resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=}
engines: {node: '>=0.10.0'}
+ /object-inspect/1.11.0:
+ resolution: {integrity: sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==}
+ dev: true
+
/object-inspect/1.9.0:
resolution: {integrity: sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==}
@@ -4047,6 +4165,14 @@ packages:
error-ex: 1.3.2
dev: true
+ /parse-json/4.0.0:
+ resolution: {integrity: sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=}
+ engines: {node: '>=4'}
+ dependencies:
+ error-ex: 1.3.2
+ json-parse-better-errors: 1.0.2
+ dev: true
+
/parse-json/5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
@@ -4110,6 +4236,13 @@ packages:
pify: 2.3.0
dev: true
+ /path-type/3.0.0:
+ resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==}
+ engines: {node: '>=4'}
+ dependencies:
+ pify: 3.0.0
+ dev: true
+
/path-type/4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@@ -4141,11 +4274,22 @@ packages:
resolution: {integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==}
engines: {node: '>=8.6'}
+ /pidtree/0.3.1:
+ resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==}
+ engines: {node: '>=0.10'}
+ hasBin: true
+ dev: true
+
/pify/2.3.0:
resolution: {integrity: sha1-7RQaasBDqEnqWISY59yosVMw6Qw=}
engines: {node: '>=0.10.0'}
dev: true
+ /pify/3.0.0:
+ resolution: {integrity: sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=}
+ engines: {node: '>=4'}
+ dev: true
+
/pify/4.0.1:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
engines: {node: '>=6'}
@@ -4408,6 +4552,15 @@ packages:
path-type: 2.0.0
dev: true
+ /read-pkg/3.0.0:
+ resolution: {integrity: sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=}
+ engines: {node: '>=4'}
+ dependencies:
+ load-json-file: 4.0.0
+ normalize-package-data: 2.5.0
+ path-type: 3.0.0
+ dev: true
+
/read-pkg/5.2.0:
resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
engines: {node: '>=8'}
@@ -4785,6 +4938,18 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
+ /shell-quote/1.7.3:
+ resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==}
+ dev: true
+
+ /side-channel/1.0.4:
+ resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.1.1
+ object-inspect: 1.11.0
+ dev: true
+
/signal-exit/3.0.3:
resolution: {integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==}
dev: true
@@ -4999,6 +5164,15 @@ packages:
strip-ansi: 6.0.1
dev: true
+ /string.prototype.padend/3.1.3:
+ resolution: {integrity: sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.3
+ es-abstract: 1.19.1
+ dev: true
+
/string.prototype.trimend/1.0.4:
resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==}
dependencies:
@@ -5485,6 +5659,15 @@ packages:
has-symbols: 1.0.2
which-boxed-primitive: 1.0.2
+ /unbox-primitive/1.0.1:
+ resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==}
+ dependencies:
+ function-bind: 1.1.1
+ has-bigints: 1.0.1
+ has-symbols: 1.0.2
+ which-boxed-primitive: 1.0.2
+ dev: true
+
/unicode-length/2.0.2:
resolution: {integrity: sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==}
dependencies:
@@ -5595,7 +5778,7 @@ packages:
is-bigint: 1.0.2
is-boolean-object: 1.1.1
is-number-object: 1.0.5
- is-string: 1.0.6
+ is-string: 1.0.7
is-symbol: 1.0.4
/which-module/2.0.0:
@@ -5828,16 +6011,16 @@ packages:
zora: 3.1.9
dev: true
- github.com/rixo/rollup-plugin-svelte-hot/0b9e5e34807529a7202494148675dea9603e31ff_bce53102debd41c5dac09b4d251cb2d9:
- resolution: {tarball: https://codeload.github.com/rixo/rollup-plugin-svelte-hot/tar.gz/0b9e5e34807529a7202494148675dea9603e31ff}
- id: github.com/rixo/rollup-plugin-svelte-hot/0b9e5e34807529a7202494148675dea9603e31ff
+ github.com/rixo/rollup-plugin-svelte-hot/5911fabc970c634f78c901e023526c81990e7474_bce53102debd41c5dac09b4d251cb2d9:
+ resolution: {tarball: https://codeload.github.com/rixo/rollup-plugin-svelte-hot/tar.gz/5911fabc970c634f78c901e023526c81990e7474}
+ id: github.com/rixo/rollup-plugin-svelte-hot/5911fabc970c634f78c901e023526c81990e7474
name: rollup-plugin-svelte-hot
version: 0.14.1
peerDependencies:
nollup: '>=0.8.4'
rollup: '>=1.19.2'
svelte: '>=3.19.0'
- svelte-hmr: '>=0.14'
+ svelte-hmr: '*'
peerDependenciesMeta:
nollup:
optional: true
diff --git a/test/apps/svhs/package.json b/test/apps/svhs/package.json
index c47e2e5..f4e9f79 100644
--- a/test/apps/svhs/package.json
+++ b/test/apps/svhs/package.json
@@ -10,6 +10,7 @@
"@rollup/plugin-commonjs": "^19.0.2",
"@rollup/plugin-node-resolve": "^13.0.4",
"nollup": "^0.17.0",
+ "npm-run-all": "^4.1.5",
"rollup": "2",
"rollup-plugin-hot": "^0.1.1",
"rollup-plugin-livereload": "^1.0.0",
@@ -27,6 +28,9 @@
"dev": "cross-env MUTE_NOLLUP=0 npm run dev:nollup",
"start": "sirv public --single",
"start:dev": "sirv public --single --dev",
- "test": "pnpm svhs"
+ "test:noPreserveState": "cross-env PRESERVE_LOCAL_STATE=false pnpm svhs",
+ "test:smartPreserveState": "cross-env PRESERVE_LOCAL_STATE=smart pnpm svhs",
+ "test:ci": "run-s test:noPreserveState test:smartPreserveState",
+ "test": "run-p test:noPreserveState test:smartPreserveState"
}
}
diff --git a/test/apps/svhs/rollup.config.js b/test/apps/svhs/rollup.config.js
index e602538..dd3a1cd 100644
--- a/test/apps/svhs/rollup.config.js
+++ b/test/apps/svhs/rollup.config.js
@@ -17,7 +17,12 @@ const production = !dev
const hot = isNollup || (watch && !useLiveReload)
-const noPreserveState = !!process.env.NO_PRESERVE_STATE
+const preserveLocalState =
+ 'PRESERVE_LOCAL_STATE' in process.env
+ ? process.env.PRESERVE_LOCAL_STATE === 'false'
+ ? false
+ : process.env.PRESERVE_LOCAL_STATE
+ : null
const root = fs.realpathSync(__dirname)
@@ -52,14 +57,11 @@ export default {
},
accessors: true,
hot: hot && {
- // expose test hooks from the plugin
test,
- // optimistic will try to recover from runtime
- // errors during component init
- optimistic: true,
- // turn on to disable preservation of local component
- // state -- i.e. non exported `let` variables
- noPreserveState,
+ // optimistic: true,
+ ...(preserveLocalState != null && {
+ preserveLocalState,
+ }),
},
}),