From ba47076ffdf09a22642d8396205ec8c94c826a7e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 28 Jan 2025 16:06:56 -0500 Subject: [PATCH 1/2] move more code --- packages/svelte/src/index-client.js | 35 +++++++++ .../svelte/src/internal/client/context.js | 5 ++ .../src/internal/client/dom/blocks/await.js | 3 +- .../src/internal/client/dom/blocks/key.js | 2 +- .../client/dom/elements/bindings/input.js | 3 +- packages/svelte/src/internal/client/index.js | 4 +- .../src/internal/client/reactivity/props.js | 11 +-- .../src/internal/client/reactivity/sources.js | 32 +++++++- .../svelte/src/internal/client/runtime.js | 73 +------------------ packages/svelte/tests/signals/test.ts | 10 +-- 10 files changed, 86 insertions(+), 92 deletions(-) diff --git a/packages/svelte/src/index-client.js b/packages/svelte/src/index-client.js index bd2b353395c6..ca29d5bfbe3c 100644 --- a/packages/svelte/src/index-client.js +++ b/packages/svelte/src/index-client.js @@ -8,6 +8,41 @@ import * as e from './internal/client/errors.js'; import { lifecycle_outside_component } from './internal/shared/errors.js'; import { legacy_mode_flag } from './internal/flags/index.js'; import { component_context } from './internal/client/context.js'; +import { DEV } from 'esm-env'; + +if (DEV) { + /** + * @param {string} rune + */ + function throw_rune_error(rune) { + if (!(rune in globalThis)) { + // TODO if people start adjusting the "this can contain runes" config through v-p-s more, adjust this message + /** @type {any} */ + let value; // let's hope noone modifies this global, but belts and braces + Object.defineProperty(globalThis, rune, { + configurable: true, + // eslint-disable-next-line getter-return + get: () => { + if (value !== undefined) { + return value; + } + + e.rune_outside_svelte(rune); + }, + set: (v) => { + value = v; + } + }); + } + } + + throw_rune_error('$state'); + throw_rune_error('$effect'); + throw_rune_error('$derived'); + throw_rune_error('$inspect'); + throw_rune_error('$props'); + throw_rune_error('$bindable'); +} /** * The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM. diff --git a/packages/svelte/src/internal/client/context.js b/packages/svelte/src/internal/client/context.js index 1d7f0747cd72..e1088edf308d 100644 --- a/packages/svelte/src/internal/client/context.js +++ b/packages/svelte/src/internal/client/context.js @@ -185,6 +185,11 @@ export function pop(component) { return component || /** @type {T} */ ({}); } +/** @returns {boolean} */ +export function is_runes() { + return !legacy_mode_flag || (component_context !== null && component_context.l === null); +} + /** * @param {string} name * @returns {Map} diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index 633a6e5bab87..34af401c030f 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -3,7 +3,8 @@ import { DEV } from 'esm-env'; import { is_promise } from '../../../shared/utils.js'; import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js'; import { internal_set, mutable_source, source } from '../../reactivity/sources.js'; -import { flush_sync, is_runes, set_active_effect, set_active_reaction } from '../../runtime.js'; +import { flush_sync, set_active_effect, set_active_reaction } from '../../runtime.js'; +import { is_runes } from '../../context.js'; import { hydrate_next, hydrate_node, hydrating } from '../hydration.js'; import { queue_micro_task } from '../task.js'; import { UNINITIALIZED } from '../../../../constants.js'; diff --git a/packages/svelte/src/internal/client/dom/blocks/key.js b/packages/svelte/src/internal/client/dom/blocks/key.js index 4a8b7b94fcc8..a69716354819 100644 --- a/packages/svelte/src/internal/client/dom/blocks/key.js +++ b/packages/svelte/src/internal/client/dom/blocks/key.js @@ -2,7 +2,7 @@ import { UNINITIALIZED } from '../../../../constants.js'; import { block, branch, pause_effect } from '../../reactivity/effects.js'; import { not_equal, safe_not_equal } from '../../reactivity/equality.js'; -import { is_runes } from '../../runtime.js'; +import { is_runes } from '../../context.js'; import { hydrate_next, hydrate_node, hydrating } from '../hydration.js'; /** diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/input.js b/packages/svelte/src/internal/client/dom/elements/bindings/input.js index 3ea1a24d7edc..f1992007ed7d 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/input.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/input.js @@ -5,7 +5,8 @@ import * as e from '../../../errors.js'; import { is } from '../../../proxy.js'; import { queue_micro_task } from '../../task.js'; import { hydrating } from '../../hydration.js'; -import { is_runes, untrack } from '../../../runtime.js'; +import { untrack } from '../../../runtime.js'; +import { is_runes } from '../../../context.js'; /** * @param {HTMLInputElement} input diff --git a/packages/svelte/src/internal/client/index.js b/packages/svelte/src/internal/client/index.js index 877f3c59ee55..3f3b29b029dd 100644 --- a/packages/svelte/src/internal/client/index.js +++ b/packages/svelte/src/internal/client/index.js @@ -110,7 +110,7 @@ export { user_effect, user_pre_effect } from './reactivity/effects.js'; -export { mutable_state, mutate, set, state } from './reactivity/sources.js'; +export { mutable_state, mutate, set, state, update, update_pre } from './reactivity/sources.js'; export { prop, rest_props, @@ -139,8 +139,6 @@ export { flush_sync, tick, untrack, - update, - update_pre, exclude_from_object, deep_read, deep_read_state diff --git a/packages/svelte/src/internal/client/reactivity/props.js b/packages/svelte/src/internal/client/reactivity/props.js index 3e5a0258c744..d157642d5d35 100644 --- a/packages/svelte/src/internal/client/reactivity/props.js +++ b/packages/svelte/src/internal/client/reactivity/props.js @@ -8,16 +8,9 @@ import { PROPS_IS_UPDATED } from '../../../constants.js'; import { get_descriptor, is_function } from '../../shared/utils.js'; -import { mutable_source, set, source } from './sources.js'; +import { mutable_source, set, source, update } from './sources.js'; import { derived, derived_safe_equal } from './deriveds.js'; -import { - active_effect, - get, - captured_signals, - set_active_effect, - untrack, - update -} from '../runtime.js'; +import { active_effect, get, captured_signals, set_active_effect, untrack } from '../runtime.js'; import { safe_equals } from './equality.js'; import * as e from '../errors.js'; import { diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index b3e66a333625..ded0ca05846b 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -5,7 +5,6 @@ import { active_effect, untracked_writes, get, - is_runes, schedule_effect, set_untracked_writes, set_signal_status, @@ -34,7 +33,7 @@ import { import * as e from '../errors.js'; import { legacy_mode_flag, tracing_mode_flag } from '../../flags/index.js'; import { get_stack } from '../dev/tracing.js'; -import { component_context } from '../context.js'; +import { component_context, is_runes } from '../context.js'; export let inspect_effects = new Set(); @@ -226,6 +225,35 @@ export function internal_set(source, value) { return value; } +/** + * @template {number | bigint} T + * @param {Source} source + * @param {1 | -1} [d] + * @returns {T} + */ +export function update(source, d = 1) { + var value = get(source); + var result = d === 1 ? value++ : value--; + + set(source, value); + + // @ts-expect-error + return result; +} + +/** + * @template {number | bigint} T + * @param {Source} source + * @param {1 | -1} [d] + * @returns {T} + */ +export function update_pre(source, d = 1) { + var value = get(source); + + // @ts-expect-error + return set(source, d === 1 ? ++value : --value); +} + /** * @param {Value} signal * @param {number} status should be DIRTY or MAYBE_DIRTY diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 859925186f59..831b536c8d3f 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -27,15 +27,16 @@ import { BOUNDARY_EFFECT } from './constants.js'; import { flush_tasks } from './dom/task.js'; -import { internal_set, set } from './reactivity/sources.js'; +import { internal_set } from './reactivity/sources.js'; import { destroy_derived, execute_derived, update_derived } from './reactivity/deriveds.js'; import * as e from './errors.js'; import { FILENAME } from '../../constants.js'; -import { legacy_mode_flag, tracing_mode_flag } from '../flags/index.js'; +import { tracing_mode_flag } from '../flags/index.js'; import { tracing_expressions, get_stack } from './dev/tracing.js'; import { component_context, dev_current_component_function, + is_runes, set_component_context, set_dev_current_component_function } from './context.js'; @@ -157,11 +158,6 @@ export function increment_write_version() { return ++write_version; } -/** @returns {boolean} */ -export function is_runes() { - return !legacy_mode_flag || (component_context !== null && component_context.l === null); -} - /** * Determines whether a derived or effect is dirty. * If it is MAYBE_DIRTY, will set the status to CLEAN @@ -1091,35 +1087,6 @@ export function set_signal_status(signal, status) { signal.f = (signal.f & STATUS_MASK) | status; } -/** - * @template {number | bigint} T - * @param {Value} signal - * @param {1 | -1} [d] - * @returns {T} - */ -export function update(signal, d = 1) { - var value = get(signal); - var result = d === 1 ? value++ : value--; - - set(signal, value); - - // @ts-expect-error - return result; -} - -/** - * @template {number | bigint} T - * @param {Value} signal - * @param {1 | -1} [d] - * @returns {T} - */ -export function update_pre(signal, d = 1) { - var value = get(signal); - - // @ts-expect-error - return set(signal, d === 1 ? ++value : --value); -} - /** * @param {Record} obj * @param {string[]} keys @@ -1211,37 +1178,3 @@ export function deep_read(value, visited = new Set()) { } } } - -if (DEV) { - /** - * @param {string} rune - */ - function throw_rune_error(rune) { - if (!(rune in globalThis)) { - // TODO if people start adjusting the "this can contain runes" config through v-p-s more, adjust this message - /** @type {any} */ - let value; // let's hope noone modifies this global, but belts and braces - Object.defineProperty(globalThis, rune, { - configurable: true, - // eslint-disable-next-line getter-return - get: () => { - if (value !== undefined) { - return value; - } - - e.rune_outside_svelte(rune); - }, - set: (v) => { - value = v; - } - }); - } - } - - throw_rune_error('$state'); - throw_rune_error('$effect'); - throw_rune_error('$derived'); - throw_rune_error('$inspect'); - throw_rune_error('$props'); - throw_rune_error('$bindable'); -} diff --git a/packages/svelte/tests/signals/test.ts b/packages/svelte/tests/signals/test.ts index aa1dbf31328c..d5fe93e41ad2 100644 --- a/packages/svelte/tests/signals/test.ts +++ b/packages/svelte/tests/signals/test.ts @@ -8,7 +8,7 @@ import { render_effect, user_effect } from '../../src/internal/client/reactivity/effects'; -import { state, set } from '../../src/internal/client/reactivity/sources'; +import { state, set, update, update_pre } from '../../src/internal/client/reactivity/sources'; import type { Derived, Value } from '../../src/internal/client/types'; import { proxy } from '../../src/internal/client/proxy'; import { derived } from '../../src/internal/client/reactivity/deriveds'; @@ -875,14 +875,14 @@ describe('signals', () => { return () => { const count = state(0n); - assert.doesNotThrow(() => $.update(count)); + assert.doesNotThrow(() => update(count)); assert.equal($.get(count), 1n); - assert.doesNotThrow(() => $.update(count, -1)); + assert.doesNotThrow(() => update(count, -1)); assert.equal($.get(count), 0n); - assert.doesNotThrow(() => $.update_pre(count)); + assert.doesNotThrow(() => update_pre(count)); assert.equal($.get(count), 1n); - assert.doesNotThrow(() => $.update_pre(count, -1)); + assert.doesNotThrow(() => update_pre(count, -1)); assert.equal($.get(count), 0n); }; }); From 86de89711b4c3c77aa251bdd77a39af1bde977b3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 29 Jan 2025 08:05:45 -0500 Subject: [PATCH 2/2] lint --- packages/svelte/src/internal/client/dom/blocks/await.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/svelte/src/internal/client/dom/blocks/await.js b/packages/svelte/src/internal/client/dom/blocks/await.js index 34af401c030f..c8c7c1c0ea77 100644 --- a/packages/svelte/src/internal/client/dom/blocks/await.js +++ b/packages/svelte/src/internal/client/dom/blocks/await.js @@ -4,12 +4,12 @@ import { is_promise } from '../../../shared/utils.js'; import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js'; import { internal_set, mutable_source, source } from '../../reactivity/sources.js'; import { flush_sync, set_active_effect, set_active_reaction } from '../../runtime.js'; -import { is_runes } from '../../context.js'; import { hydrate_next, hydrate_node, hydrating } from '../hydration.js'; import { queue_micro_task } from '../task.js'; import { UNINITIALIZED } from '../../../../constants.js'; import { component_context, + is_runes, set_component_context, set_dev_current_component_function } from '../../context.js';