chore: improve $state.frozen performance in prod (#11852)

* chore: improve $state.frozen performance in prod

* lint

* feedback
pull/11858/head
Dominic Gannaway 8 months ago committed by GitHub
parent f411f776ca
commit 5f218b5f3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
chore: improve $state.frozen performance in prod

@ -18,4 +18,5 @@ export const EFFECT_TRANSPARENT = 1 << 15;
export const LEGACY_DERIVED_PROP = 1 << 16;
export const STATE_SYMBOL = Symbol('$state');
export const STATE_FROZEN_SYMBOL = Symbol('$state.frozen');
export const LOADING_ATTR_SYMBOL = Symbol('');

@ -18,20 +18,25 @@ import {
} from './utils.js';
import { check_ownership, widen_ownership } from './dev/ownership.js';
import { mutable_source, source, set } from './reactivity/sources.js';
import { STATE_SYMBOL } from './constants.js';
import { STATE_FROZEN_SYMBOL, STATE_SYMBOL } from './constants.js';
import { UNINITIALIZED } from '../../constants.js';
import * as e from './errors.js';
/**
* @template T
* @param {T} value
* @param {T} initial_value
* @param {boolean} [immutable]
* @param {import('#client').ProxyMetadata | null} [parent]
* @param {import('#client').Source<T>} [prev] dev mode only
* @returns {import('#client').ProxyStateObject<T> | T}
*/
export function proxy(value, immutable = true, parent = null, prev) {
if (typeof value === 'object' && value != null && !is_frozen(value)) {
export function proxy(initial_value, immutable = true, parent = null, prev) {
if (typeof initial_value === 'object' && initial_value != null) {
let value = initial_value;
// If the object is frozen then snapshot the value
if (is_frozen(value) || STATE_FROZEN_SYMBOL in value) {
value = snapshot(value);
}
// If we have an existing proxy, return it...
if (STATE_SYMBOL in value) {
const metadata = /** @type {import('#client').ProxyMetadata<T>} */ (value[STATE_SYMBOL]);
@ -94,7 +99,7 @@ export function proxy(value, immutable = true, parent = null, prev) {
}
}
return value;
return initial_value;
}
/**

@ -1,5 +1,11 @@
import { DEV } from 'esm-env';
import { get_descriptors, get_prototype_of, is_frozen, object_freeze } from './utils.js';
import {
define_property,
get_descriptors,
get_prototype_of,
is_frozen,
object_freeze
} from './utils.js';
import { snapshot } from './proxy.js';
import { destroy_effect, effect, execute_effect_teardown } from './reactivity/effects.js';
import {
@ -17,7 +23,8 @@ import {
BLOCK_EFFECT,
ROOT_EFFECT,
LEGACY_DERIVED_PROP,
DISCONNECTED
DISCONNECTED,
STATE_FROZEN_SYMBOL
} from './constants.js';
import { flush_tasks } from './dom/task.js';
import { add_owner } from './dev/ownership.js';
@ -1353,19 +1360,26 @@ if (DEV) {
}
/**
* Expects a value that was wrapped with `freeze` and makes it frozen.
* Expects a value that was wrapped with `freeze` and makes it frozen in DEV.
* @template T
* @param {T} value
* @returns {Readonly<T>}
*/
export function freeze(value) {
if (typeof value === 'object' && value != null && !is_frozen(value)) {
if (typeof value === 'object' && value != null && !(STATE_FROZEN_SYMBOL in value)) {
// If the object is already proxified, then snapshot the value
if (STATE_SYMBOL in value) {
return object_freeze(snapshot(value));
if (STATE_SYMBOL in value || is_frozen(value)) {
value = snapshot(value);
}
define_property(value, STATE_FROZEN_SYMBOL, {
value: true,
writable: true,
enumerable: false
});
// Freeze the object in DEV
if (DEV) {
object_freeze(value);
}
// Otherwise freeze the object
object_freeze(value);
}
return value;
}

Loading…
Cancel
Save