From e5cbcf190c786019de587e97a582b0205ec25110 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 24 Aug 2024 16:51:14 -0400 Subject: [PATCH] WIP --- .../svelte/src/internal/client/dev/hmr.js | 2 +- .../src/internal/client/dom/blocks/await.js | 4 ++-- .../src/internal/client/dom/blocks/each.js | 4 ++-- .../src/internal/client/dom/legacy/misc.js | 2 +- packages/svelte/src/internal/client/index.js | 2 +- packages/svelte/src/internal/client/proxy.js | 4 ++-- .../src/internal/client/reactivity/props.js | 5 ++++- .../src/internal/client/reactivity/sources.js | 19 ++++++++++++++++++- .../svelte/src/internal/client/runtime.js | 2 +- packages/svelte/src/reactivity/date.js | 2 +- packages/svelte/src/reactivity/map.js | 12 ++++++------ .../src/reactivity/url-search-params.js | 2 +- packages/svelte/src/reactivity/url.js | 16 ++++++++-------- packages/svelte/src/store/index-client.js | 2 +- 14 files changed, 49 insertions(+), 29 deletions(-) diff --git a/packages/svelte/src/internal/client/dev/hmr.js b/packages/svelte/src/internal/client/dev/hmr.js index ee5e08c0b1..4b6c5f5b76 100644 --- a/packages/svelte/src/internal/client/dev/hmr.js +++ b/packages/svelte/src/internal/client/dev/hmr.js @@ -71,7 +71,7 @@ export function hmr(original, get_source) { // The `get_source` parameter reads `wrapper[HMR].source`, but in the `accept` // function we always replace it with `previous[HMR].source`, which in practice // means we only ever update the original - source: source(original) + source: source(original, null) }; return wrapper; diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index 5477176660..40669f5b47 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -53,8 +53,8 @@ export function await_block(node, get_input, pending_fn, then_fn, catch_fn) { var catch_effect; var input_source = runes - ? source(/** @type {V} */ (undefined)) - : mutable_source(/** @type {V} */ (undefined)); + ? source(/** @type {V} */ (undefined), null) + : mutable_source(/** @type {V} */ (undefined), null); var error_source = runes ? source(undefined) : mutable_source(undefined); var resolved = false; diff --git a/packages/svelte/src/internal/client/dom/blocks/each.js b/packages/svelte/src/internal/client/dom/blocks/each.js index 7b27773a54..cd61ef1075 100644 --- a/packages/svelte/src/internal/client/dom/blocks/each.js +++ b/packages/svelte/src/internal/client/dom/blocks/each.js @@ -469,8 +469,8 @@ function create_item(anchor, state, prev, next, value, key, index, render_fn, fl var reactive = (flags & EACH_ITEM_REACTIVE) !== 0; var mutable = (flags & EACH_ITEM_IMMUTABLE) === 0; - var v = reactive ? (mutable ? mutable_source(value) : source(value)) : value; - var i = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index); + var v = reactive ? (mutable ? mutable_source(value) : source(value, null)) : value; + var i = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index, null); /** @type {EachItem} */ var item = { diff --git a/packages/svelte/src/internal/client/dom/legacy/misc.js b/packages/svelte/src/internal/client/dom/legacy/misc.js index 82362e17c4..667f51fc93 100644 --- a/packages/svelte/src/internal/client/dom/legacy/misc.js +++ b/packages/svelte/src/internal/client/dom/legacy/misc.js @@ -8,7 +8,7 @@ import { is_array } from '../../../shared/utils.js'; * @param {() => any} fn */ export function reactive_import(fn) { - var s = source(0); + var s = source(0, null); return function () { if (arguments.length === 1) { diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index a29c197192..5c88897ca8 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -105,7 +105,7 @@ export { user_effect, user_pre_effect } from './reactivity/effects.js'; -export { mutable_source, mutate, source, set } from './reactivity/sources.js'; +export { mutable_source, mutate, source, set, state } from './reactivity/sources.js'; export { prop, rest_props, diff --git a/packages/svelte/src/internal/client/proxy.js b/packages/svelte/src/internal/client/proxy.js index 03ebf16432..ad932af070 100644 --- a/packages/svelte/src/internal/client/proxy.js +++ b/packages/svelte/src/internal/client/proxy.js @@ -80,7 +80,7 @@ export function proxy(value, parent = null, prev) { var s = sources.get(prop); if (s === undefined) { - s = source(descriptor.value); + s = source(descriptor.value, null); sources.set(prop, s); } else { set(s, proxy(descriptor.value, metadata)); @@ -193,7 +193,7 @@ export function proxy(value, parent = null, prev) { // object property before writing to that property. if (s === undefined) { if (!has || get_descriptor(target, prop)?.writable) { - s = source(undefined); + s = source(undefined, null); set(s, proxy(value, metadata)); sources.set(prop, s); } diff --git a/packages/svelte/src/internal/client/reactivity/props.js b/packages/svelte/src/internal/client/reactivity/props.js index fa2ea6dd7c..c125ebe317 100644 --- a/packages/svelte/src/internal/client/reactivity/props.js +++ b/packages/svelte/src/internal/client/reactivity/props.js @@ -150,7 +150,10 @@ const legacy_rest_props_handler = { * @returns {Record} */ export function legacy_rest_props(props, exclude) { - return new Proxy({ props, exclude, special: {}, version: source(0) }, legacy_rest_props_handler); + return new Proxy( + { props, exclude, special: {}, version: source(0, null) }, + legacy_rest_props_handler + ); } /** diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index 4b3750ac99..90de029a65 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -58,6 +58,15 @@ export function source(v, owner = current_reaction) { return source; } +/** + * @template V + * @param {V} v + * @returns {Source} + */ +export function state(v) { + return source(v); +} + /** * @template V * @param {V} initial_value @@ -65,10 +74,18 @@ export function source(v, owner = current_reaction) { * @returns {Source} */ /*#__NO_SIDE_EFFECTS__*/ -export function mutable_source(initial_value, owner) { +export function mutable_source(initial_value, owner = current_reaction) { const s = source(initial_value, owner); s.equals = safe_equals; + if (owner !== null && (owner.f & DERIVED) !== 0) { + if (derived_sources === null) { + set_derived_sources([s]); + } else { + derived_sources.push(s); + } + } + // bind the signal to the component context, in case we need to // track updates to trigger beforeUpdate/afterUpdate callbacks if (current_component_context !== null && current_component_context.l !== null) { diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index de6476b71f..57bc7686da 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -1001,7 +1001,7 @@ export function push(props, runes = false, fn) { s: null, u: null, r1: [], - r2: source(false) + r2: source(false, null) }; } diff --git a/packages/svelte/src/reactivity/date.js b/packages/svelte/src/reactivity/date.js index a1fb73c5f5..24a8ce4dbe 100644 --- a/packages/svelte/src/reactivity/date.js +++ b/packages/svelte/src/reactivity/date.js @@ -6,7 +6,7 @@ import { get } from '../internal/client/runtime.js'; var inited = false; export class SvelteDate extends Date { - #time = source(super.getTime()); + #time = source(super.getTime(), null); /** @type {Map>} */ #deriveds = new Map(); diff --git a/packages/svelte/src/reactivity/map.js b/packages/svelte/src/reactivity/map.js index c732806cd0..302823f0fc 100644 --- a/packages/svelte/src/reactivity/map.js +++ b/packages/svelte/src/reactivity/map.js @@ -12,8 +12,8 @@ import { increment } from './utils.js'; export class SvelteMap extends Map { /** @type {Map>} */ #sources = new Map(); - #version = source(0); - #size = source(0); + #version = source(0, null); + #size = source(0, null); /** * @param {Iterable | null | undefined} [value] @@ -40,7 +40,7 @@ export class SvelteMap extends Map { if (s === undefined) { var ret = super.get(key); if (ret !== undefined) { - s = source(0); + s = source(0, null); sources.set(key, s); } else { // We should always track the version in case @@ -71,7 +71,7 @@ export class SvelteMap extends Map { if (s === undefined) { var ret = super.get(key); if (ret !== undefined) { - s = source(0); + s = source(0, null); sources.set(key, s); } else { // We should always track the version in case @@ -96,7 +96,7 @@ export class SvelteMap extends Map { var res = super.set(key, value); if (s === undefined) { - sources.set(key, source(0)); + sources.set(key, source(0, null)); set(this.#size, super.size); increment(this.#version); } else if (prev_res !== value) { @@ -144,7 +144,7 @@ export class SvelteMap extends Map { if (this.#size.v !== sources.size) { for (var key of super.keys()) { if (!sources.has(key)) { - sources.set(key, source(0)); + sources.set(key, source(0, null)); } } } diff --git a/packages/svelte/src/reactivity/url-search-params.js b/packages/svelte/src/reactivity/url-search-params.js index 13f6971996..28ac9defd6 100644 --- a/packages/svelte/src/reactivity/url-search-params.js +++ b/packages/svelte/src/reactivity/url-search-params.js @@ -6,7 +6,7 @@ import { increment } from './utils.js'; export const REPLACE = Symbol(); export class SvelteURLSearchParams extends URLSearchParams { - #version = source(0); + #version = source(0, null); #url = get_current_url(); #updating = false; diff --git a/packages/svelte/src/reactivity/url.js b/packages/svelte/src/reactivity/url.js index 5d003be021..6fd829982e 100644 --- a/packages/svelte/src/reactivity/url.js +++ b/packages/svelte/src/reactivity/url.js @@ -11,14 +11,14 @@ export function get_current_url() { } export class SvelteURL extends URL { - #protocol = source(super.protocol); - #username = source(super.username); - #password = source(super.password); - #hostname = source(super.hostname); - #port = source(super.port); - #pathname = source(super.pathname); - #hash = source(super.hash); - #search = source(super.search); + #protocol = source(super.protocol, null); + #username = source(super.username, null); + #password = source(super.password, null); + #hostname = source(super.hostname, null); + #port = source(super.port, null); + #pathname = source(super.pathname, null); + #hash = source(super.hash, null); + #search = source(super.search, null); #searchParams; /** diff --git a/packages/svelte/src/store/index-client.js b/packages/svelte/src/store/index-client.js index b612124e3c..de38438b72 100644 --- a/packages/svelte/src/store/index-client.js +++ b/packages/svelte/src/store/index-client.js @@ -106,7 +106,7 @@ export function toStore(get, set) { */ export function fromStore(store) { let value = /** @type {V} */ (undefined); - let version = source(0); + let version = source(0, null); let subscribers = 0; let unsubscribe = noop;