From 550cecf3114286ae9e3fc54efdd2c54b9d858884 Mon Sep 17 00:00:00 2001 From: gtmnayan <50981692+gtm-nayan@users.noreply.github.com> Date: Mon, 20 Nov 2023 15:24:43 +0545 Subject: [PATCH] chore: shave off more bytes (#9540) * shavings * dro unused max safe int * get rid of array_ref and object_ref * extract STATUS_MASK * fix test * revert is_controlled change * more run_all --- .../svelte/src/internal/client/reconciler.js | 3 +- packages/svelte/src/internal/client/render.js | 7 +- .../svelte/src/internal/client/runtime.js | 79 ++++++++++--------- .../svelte/src/internal/client/transitions.js | 11 +-- packages/svelte/src/internal/client/utils.js | 13 ++- packages/svelte/src/internal/common.js | 7 ++ packages/svelte/tests/hydration/test.ts | 2 +- 7 files changed, 64 insertions(+), 58 deletions(-) diff --git a/packages/svelte/src/internal/client/reconciler.js b/packages/svelte/src/internal/client/reconciler.js index 0dbe9eef11..a5fcff6873 100644 --- a/packages/svelte/src/internal/client/reconciler.js +++ b/packages/svelte/src/internal/client/reconciler.js @@ -341,8 +341,7 @@ export function reconcile_tracked_array( insert_each_item_block(block, dom, is_controlled, null); } } else { - var should_update_block = - (flags & EACH_ITEM_REACTIVE) !== 0 || (flags & EACH_INDEX_REACTIVE) !== 0; + var should_update_block = (flags & (EACH_ITEM_REACTIVE | EACH_INDEX_REACTIVE)) !== 0; var start = 0; /** @type {null | Text | Element | Comment} */ diff --git a/packages/svelte/src/internal/client/render.js b/packages/svelte/src/internal/client/render.js index 8e85e43886..d992199d8d 100644 --- a/packages/svelte/src/internal/client/render.js +++ b/packages/svelte/src/internal/client/render.js @@ -2256,8 +2256,8 @@ function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, re ); push_destroy_fn(each, () => { const flags = block.f; - const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0; const anchor_node = block.a; + const is_controlled = (flags & EACH_IS_CONTROLLED) !== 0; let fallback = current_fallback; while (fallback !== null) { const dom = fallback.d; @@ -3081,7 +3081,10 @@ export function mount(component, options) { if (options.recover !== false && hydration_fragment !== null) { // eslint-disable-next-line no-console console.error( - 'Hydration failed because the initial UI does not match what was rendered on the server.', + 'ERR_SVELTE_HYDRATION_MISMATCH' + + (DEV + ? ': Hydration failed because the initial UI does not match what was rendered on the server.' + : ''), error ); remove(hydration_fragment); diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index fdde5f3d6a..a082adda2e 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -1,5 +1,6 @@ +import { DEV } from 'esm-env'; import { subscribe_to_store } from '../../store/utils.js'; -import { EMPTY_FUNC } from '../common.js'; +import { EMPTY_FUNC, run_all } from '../common.js'; import { unwrap } from './render.js'; import { is_array } from './utils.js'; @@ -21,7 +22,6 @@ const IS_EFFECT = EFFECT | PRE_EFFECT | RENDER_EFFECT | SYNC_EFFECT; const FLUSH_MICROTASK = 0; const FLUSH_SYNC = 1; -const MAX_SAFE_INT = Number.MAX_SAFE_INTEGER; export const UNINITIALIZED = Symbol(); @@ -457,8 +457,11 @@ function flush_queued_effects(effects) { if (length > 0) { if (flush_count > 100) { throw new Error( - 'Maximum update depth exceeded. This can happen when a reactive block or effect ' + - 'repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops.' + 'ERR_SVELTE_TOO_MANY_UPDATES' + + (DEV + ? ': Maximum update depth exceeded. This can happen when a reactive block or effect ' + + 'repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops.' + : '') ); } flush_count++; @@ -524,9 +527,7 @@ function process_task() { is_task_queued = false; const tasks = current_queued_tasks.slice(); current_queued_tasks = []; - for (let i = 0; i < tasks.length; i++) { - tasks[i](); - } + run_all(tasks); } /** @@ -968,9 +969,12 @@ export function set_signal_value(signal, value) { (current_consumer.f & DERIVED) !== 0 ) { throw new Error( - "Unsafe mutations during Svelte's render or derived phase are not permitted in runes mode. " + - 'This can lead to unexpected errors and possibly cause infinite loops.\n\nIf this mutation is not meant ' + - 'to be reactive do not use the "$state" rune for that declaration.' + 'ERR_SVELTE_UNSAFE_MUTATION' + + (DEV + ? ": Unsafe mutations during Svelte's render or derived phase are not permitted in runes mode. " + + 'This can lead to unexpected errors and possibly cause infinite loops.\n\nIf this mutation is not meant ' + + 'to be reactive do not use the "$state" rune for that declaration.' + : '') ); } if ( @@ -1005,10 +1009,10 @@ export function set_signal_value(signal, value) { if (current_effect === null && current_queued_pre_and_render_effects.length === 0) { const update_callbacks = component_context?.u; if (update_callbacks != null) { - update_callbacks.b.forEach(/** @param {any} c */ (c) => c()); + run_all(update_callbacks.b); const managed = managed_effect(() => { destroy_signal(managed); - update_callbacks.a.forEach(/** @param {any} c */ (c) => c()); + run_all(update_callbacks.a); }); } } @@ -1026,21 +1030,20 @@ export function destroy_signal(signal) { const flags = signal.f; destroy_references(signal); remove_consumer(signal, 0, true); - signal.i = null; - signal.r = null; - signal.y = null; - signal.x = null; - signal.b = null; - signal.v = /** @type {V} */ (null); - signal.d = null; - signal.c = null; + signal.i = + signal.r = + signal.y = + signal.x = + signal.b = + // @ts-expect-error - this is fine, since we're assigning to null to clear out a destroyed signal + signal.v = + signal.d = + signal.c = + null; set_signal_status(signal, DESTROYED); if (destroy !== null) { if (is_array(destroy)) { - let i; - for (i = 0; i < destroy.length; i++) { - destroy[i](); - } + run_all(destroy); } else { destroy(); } @@ -1146,7 +1149,10 @@ function internal_create_effect(type, init, sync, block, schedule) { */ export function user_effect(init) { if (current_effect === null) { - throw new Error('The Svelte $effect rune can only be used during component initialisation.'); + throw new Error( + 'ERR_SVELTE_ORPHAN_EFFECT' + + (DEV ? ': The Svelte $effect rune can only be used during component initialisation.' : '') + ); } const apply_component_effect_heuristics = current_effect.f & RENDER_EFFECT && @@ -1203,7 +1209,10 @@ export function managed_pre_effect(init, sync) { export function pre_effect(init) { if (current_effect === null) { throw new Error( - 'The Svelte $effect.pre rune can only be used during component initialisation.' + 'ERR_SVELTE_ORPHAN_EFFECT' + + (DEV + ? ': The Svelte $effect.pre rune can only be used during component initialisation.' + : '') ); } const sync = current_effect !== null && (current_effect.f & RENDER_EFFECT) !== 0; @@ -1273,6 +1282,7 @@ export function push_destroy_fn(signal, destroy_fn) { } } +const STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN); /** * @template V * @param {import('./types.js').Signal} signal @@ -1280,17 +1290,7 @@ export function push_destroy_fn(signal, destroy_fn) { * @returns {void} */ export function set_signal_status(signal, status) { - const flags = signal.f; - if ((flags & status) === 0) { - if ((flags & MAYBE_DIRTY) !== 0) { - signal.f ^= MAYBE_DIRTY; - } else if ((flags & CLEAN) !== 0) { - signal.f ^= CLEAN; - } else if ((flags & DIRTY) !== 0) { - signal.f ^= DIRTY; - } - signal.f ^= status; - } + signal.f = (signal.f & STATUS_MASK) | status; } /** @@ -1484,7 +1484,10 @@ export function safe_equal(a, b) { export function get_or_init_context_map() { const component_context = current_component_context; if (component_context === null) { - throw new Error('Context can only be used during component initialisation.'); + throw new Error( + 'ERR_SVELTE_ORPHAN_CONTEXT' + + (DEV ? 'Context can only be used during component initialisation.' : '') + ); } let context_map = component_context.c; if (context_map === null) { diff --git a/packages/svelte/src/internal/client/transitions.js b/packages/svelte/src/internal/client/transitions.js index cfad871279..8b2666a713 100644 --- a/packages/svelte/src/internal/client/transitions.js +++ b/packages/svelte/src/internal/client/transitions.js @@ -1,4 +1,5 @@ import { EACH_IS_ANIMATED, EACH_IS_CONTROLLED } from '../../constants.js'; +import { run_all } from '../common.js'; import { AWAIT_BLOCK, DYNAMIC_COMPONENT_BLOCK, @@ -322,9 +323,7 @@ function create_transition(dom, init, direction, effect) { const is_outro = curr_direction === 'out'; /** @type {Animation | TickAnimation} */ (animation).pause(); if (is_outro) { - for (const sub of subs) { - sub(); - } + run_all(subs); subs = []; } dispatch_event(dom, is_outro ? 'outroend' : 'introend'); @@ -378,9 +377,7 @@ function create_transition(dom, init, direction, effect) { }, // cleanup x() { - for (const sub of subs) { - sub(); - } + run_all(subs); subs = []; }, r: direction, @@ -554,7 +551,7 @@ export function trigger_transitions(transitions, target_direction, from) { destroy_signal(e); const e2 = managed_effect(() => { destroy_signal(e2); - outros.forEach(/** @param {any} o */ (o) => o()); + run_all(outros); }); }, false); } diff --git a/packages/svelte/src/internal/client/utils.js b/packages/svelte/src/internal/client/utils.js index 45a79d9dce..6e43daefd6 100644 --- a/packages/svelte/src/internal/client/utils.js +++ b/packages/svelte/src/internal/client/utils.js @@ -1,10 +1,7 @@ // Store the references to globals in case someone tries to monkey patch these, causing the below // to de-opt (this occurs often when using popular extensions). -export const object_ref = Object; -export const array_ref = Array; - -export const is_array = array_ref.isArray; -export const array_from = array_ref.from; -export const define_property = object_ref.defineProperty; -export const get_descriptor = object_ref.getOwnPropertyDescriptor; -export const get_descriptors = object_ref.getOwnPropertyDescriptors; +export var is_array = Array.isArray; +export var array_from = Array.from; +export var define_property = Object.defineProperty; +export var get_descriptor = Object.getOwnPropertyDescriptor; +export var get_descriptors = Object.getOwnPropertyDescriptors; diff --git a/packages/svelte/src/internal/common.js b/packages/svelte/src/internal/common.js index ced62972f5..03fc1df070 100644 --- a/packages/svelte/src/internal/common.js +++ b/packages/svelte/src/internal/common.js @@ -16,3 +16,10 @@ export function is_promise(value) { typeof (/** @type {any} */ (value).then) === 'function' ); } + +/** @param {Array<() => void>} arr */ +export function run_all(arr) { + for (var i = 0; i < arr.length; i++) { + arr[i](); + } +} diff --git a/packages/svelte/tests/hydration/test.ts b/packages/svelte/tests/hydration/test.ts index 9dfffa3bfd..d10612ef9b 100644 --- a/packages/svelte/tests/hydration/test.ts +++ b/packages/svelte/tests/hydration/test.ts @@ -71,7 +71,7 @@ const { test, run } = suite(async (config, cwd) => { const error = console.error; let got_hydration_error = false; console.error = (message: any) => { - if (typeof message === 'string' && message.startsWith('Hydration failed')) { + if (typeof message === 'string' && message.startsWith('ERR_SVELTE_HYDRATION_MISMATCH')) { got_hydration_error = true; if (!config.expect_hydration_error) { error(message);