Comparing version 5.0.0-next.183 to 5.0.0-next.184
@@ -5,3 +5,3 @@ { | ||
"license": "MIT", | ||
"version": "5.0.0-next.183", | ||
"version": "5.0.0-next.184", | ||
"type": "module", | ||
@@ -8,0 +8,0 @@ "types": "./types/index.d.ts", |
@@ -35,2 +35,71 @@ declare module '*.svelte' { | ||
declare namespace $state { | ||
type Primitive = string | number | boolean | null | undefined; | ||
type TypedArray = | ||
| Int8Array | ||
| Uint8Array | ||
| Uint8ClampedArray | ||
| Int16Array | ||
| Uint16Array | ||
| Int32Array | ||
| Uint32Array | ||
| Float32Array | ||
| Float64Array | ||
| BigInt64Array | ||
| BigUint64Array; | ||
/** The things that `structuredClone` can handle — https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm */ | ||
export type Cloneable = | ||
| ArrayBuffer | ||
| DataView | ||
| Date | ||
| Error | ||
| Map<any, any> | ||
| RegExp | ||
| Set<any> | ||
| TypedArray | ||
// web APIs | ||
| Blob | ||
| CryptoKey | ||
| DOMException | ||
| DOMMatrix | ||
| DOMMatrixReadOnly | ||
| DOMPoint | ||
| DOMPointReadOnly | ||
| DOMQuad | ||
| DOMRect | ||
| DOMRectReadOnly | ||
| File | ||
| FileList | ||
| FileSystemDirectoryHandle | ||
| FileSystemFileHandle | ||
| FileSystemHandle | ||
| ImageBitmap | ||
| ImageData | ||
| RTCCertificate | ||
| VideoFrame; | ||
/** Turn `SvelteDate`, `SvelteMap` and `SvelteSet` into their non-reactive counterparts. (`URL` is uncloneable.) */ | ||
type NonReactive<T> = T extends Date | ||
? Date | ||
: T extends Map<infer K, infer V> | ||
? Map<K, V> | ||
: T extends Set<infer K> | ||
? Set<K> | ||
: T; | ||
type Snapshot<T> = T extends Primitive | ||
? T | ||
: T extends Cloneable | ||
? NonReactive<T> | ||
: T extends { toJSON(): infer R } | ||
? R | ||
: T extends Array<infer U> | ||
? Array<Snapshot<U>> | ||
: T extends object | ||
? T extends { [key: string]: any } | ||
? { [K in keyof T]: Snapshot<T[K]> } | ||
: never | ||
: never; | ||
/** | ||
@@ -79,3 +148,3 @@ * Declares reactive read-only state that is shallowly immutable. | ||
*/ | ||
export function snapshot<T>(state: T): T; | ||
export function snapshot<T>(state: T): Snapshot<T>; | ||
@@ -82,0 +151,0 @@ /** |
@@ -1046,2 +1046,37 @@ import is_reference from 'is-reference'; | ||
} | ||
}, | ||
Identifier(node, { path, state }) { | ||
let i = path.length; | ||
let parent = /** @type {import('estree').Expression} */ (path[--i]); | ||
if ( | ||
Runes.includes(/** @type {Runes[number]} */ (node.name)) && | ||
is_reference(node, parent) && | ||
state.scope.get(node.name) === null && | ||
state.scope.get(node.name.slice(1)) === null | ||
) { | ||
/** @type {import('estree').Expression} */ | ||
let current = node; | ||
let name = node.name; | ||
while (parent.type === 'MemberExpression') { | ||
if (parent.computed) e.rune_invalid_computed_property(parent); | ||
name += `.${/** @type {import('estree').Identifier} */ (parent.property).name}`; | ||
current = parent; | ||
parent = /** @type {import('estree').Expression} */ (path[--i]); | ||
if (!Runes.includes(/** @type {Runes[number]} */ (name))) { | ||
if (name === '$effect.active') { | ||
e.rune_renamed(parent, '$effect.active', '$effect.tracking'); | ||
} | ||
e.rune_invalid_name(parent, name); | ||
} | ||
} | ||
if (parent.type !== 'CallExpression') { | ||
e.rune_missing_parentheses(current); | ||
} | ||
} | ||
} | ||
@@ -1157,37 +1192,2 @@ }; | ||
}, | ||
Identifier(node, { path, state }) { | ||
let i = path.length; | ||
let parent = /** @type {import('estree').Expression} */ (path[--i]); | ||
if ( | ||
Runes.includes(/** @type {Runes[number]} */ (node.name)) && | ||
is_reference(node, parent) && | ||
state.scope.get(node.name) === null && | ||
state.scope.get(node.name.slice(1)) === null | ||
) { | ||
/** @type {import('estree').Expression} */ | ||
let current = node; | ||
let name = node.name; | ||
while (parent.type === 'MemberExpression') { | ||
if (parent.computed) e.rune_invalid_computed_property(parent); | ||
name += `.${/** @type {import('estree').Identifier} */ (parent.property).name}`; | ||
current = parent; | ||
parent = /** @type {import('estree').Expression} */ (path[--i]); | ||
if (!Runes.includes(/** @type {Runes[number]} */ (name))) { | ||
if (name === '$effect.active') { | ||
e.rune_renamed(parent, '$effect.active', '$effect.tracking'); | ||
} | ||
e.rune_invalid_name(parent, name); | ||
} | ||
} | ||
if (parent.type !== 'CallExpression') { | ||
e.rune_missing_parentheses(current); | ||
} | ||
} | ||
}, | ||
LabeledStatement(node, { path }) { | ||
@@ -1373,3 +1373,4 @@ if (node.label.name !== '$' || path.at(-1)?.type !== 'Program') return; | ||
ClassDeclaration: validation_runes_js.ClassDeclaration, | ||
Identifier: validation_runes_js.Identifier, | ||
NewExpression: validation_runes_js.NewExpression | ||
}); |
import { current_component_context, flush_sync, untrack } from './internal/client/runtime.js'; | ||
import { is_array } from './internal/client/utils.js'; | ||
import { is_array } from './internal/shared/utils.js'; | ||
import { user_effect } from './internal/client/index.js'; | ||
@@ -4,0 +4,0 @@ import * as e from './internal/client/errors.js'; |
@@ -1,4 +0,3 @@ | ||
import { snapshot } from '../proxy.js'; | ||
import { snapshot } from '../../shared/clone.js'; | ||
import { inspect_effect, validate_effect } from '../reactivity/effects.js'; | ||
import { array_prototype, get_prototype_of, object_prototype } from '../utils.js'; | ||
@@ -16,45 +15,5 @@ /** | ||
inspect_effect(() => { | ||
inspector(initial ? 'init' : 'update', ...deep_snapshot(get_value())); | ||
inspector(initial ? 'init' : 'update', ...snapshot(get_value())); | ||
initial = false; | ||
}); | ||
} | ||
/** | ||
* Like `snapshot`, but recursively traverses into normal arrays/objects to find potential states in them. | ||
* @param {any} value | ||
* @param {Map<any, any>} visited | ||
* @returns {any} | ||
*/ | ||
function deep_snapshot(value, visited = new Map()) { | ||
if (typeof value === 'object' && value !== null && !visited.has(value)) { | ||
const unstated = snapshot(value); | ||
if (unstated !== value) { | ||
visited.set(value, unstated); | ||
return unstated; | ||
} | ||
const prototype = get_prototype_of(value); | ||
// Only deeply snapshot plain objects and arrays | ||
if (prototype === object_prototype || prototype === array_prototype) { | ||
let contains_unstated = false; | ||
/** @type {any} */ | ||
const nested_unstated = Array.isArray(value) ? [] : {}; | ||
for (let key in value) { | ||
const result = deep_snapshot(value[key], visited); | ||
nested_unstated[key] = result; | ||
if (result !== value[key]) { | ||
contains_unstated = true; | ||
} | ||
} | ||
visited.set(value, contains_unstated ? nested_unstated : value); | ||
} else { | ||
visited.set(value, value); | ||
} | ||
} | ||
return visited.get(value) ?? value; | ||
} |
@@ -7,3 +7,3 @@ /** @import { ProxyMetadata } from '#client' */ | ||
import { dev_current_component_function } from '../runtime.js'; | ||
import { get_prototype_of } from '../utils.js'; | ||
import { get_prototype_of } from '../../shared/utils.js'; | ||
import * as w from '../warnings.js'; | ||
@@ -10,0 +10,0 @@ |
@@ -31,3 +31,3 @@ /** @import { TemplateNode } from '#client' */ | ||
import { source, mutable_source, set } from '../../reactivity/sources.js'; | ||
import { is_array, is_frozen } from '../../utils.js'; | ||
import { is_array, is_frozen } from '../../../shared/utils.js'; | ||
import { INERT, STATE_FROZEN_SYMBOL, STATE_SYMBOL } from '../../constants.js'; | ||
@@ -34,0 +34,0 @@ import { queue_micro_task } from '../task.js'; |
@@ -23,3 +23,3 @@ import { DEV } from 'esm-env'; | ||
? /** @type {ShadowRoot} */ (root) | ||
: /** @type {Document} */ (root).head; | ||
: /** @type {Document} */ (root).head ?? /** @type {Document} */ (root.ownerDocument).head; | ||
@@ -26,0 +26,0 @@ if (!target.querySelector('#' + css.hash)) { |
import { DEV } from 'esm-env'; | ||
import { hydrating } from '../hydration.js'; | ||
import { get_descriptors, get_prototype_of } from '../../utils.js'; | ||
import { get_descriptors, get_prototype_of } from '../../../shared/utils.js'; | ||
import { | ||
@@ -5,0 +5,0 @@ AttributeAliases, |
import { teardown } from '../../../reactivity/effects.js'; | ||
import { get_descriptor } from '../../../utils.js'; | ||
import { get_descriptor } from '../../../../shared/utils.js'; | ||
@@ -4,0 +4,0 @@ /** |
import { createClassComponent } from '../../../../legacy/legacy-client.js'; | ||
import { destroy_effect, render_effect } from '../../reactivity/effects.js'; | ||
import { append } from '../template.js'; | ||
import { define_property, object_keys } from '../../utils.js'; | ||
import { define_property, object_keys } from '../../../shared/utils.js'; | ||
@@ -6,0 +6,0 @@ /** |
import { teardown } from '../../reactivity/effects.js'; | ||
import { define_property, is_array } from '../../utils.js'; | ||
import { define_property, is_array } from '../../../shared/utils.js'; | ||
import { hydrating } from '../hydration.js'; | ||
@@ -4,0 +4,0 @@ import { queue_micro_task } from '../task.js'; |
@@ -1,2 +0,2 @@ | ||
import { noop } from '../../../shared/utils.js'; | ||
import { noop, is_function } from '../../../shared/utils.js'; | ||
import { effect } from '../../reactivity/effects.js'; | ||
@@ -7,3 +7,2 @@ import { current_effect, untrack } from '../../runtime.js'; | ||
import { should_intro } from '../../render.js'; | ||
import { is_function } from '../../utils.js'; | ||
import { current_each_item } from '../blocks/each.js'; | ||
@@ -10,0 +9,0 @@ import { TRANSITION_GLOBAL, TRANSITION_IN, TRANSITION_OUT } from '../../../../constants.js'; |
import { set, source } from '../../reactivity/sources.js'; | ||
import { get } from '../../runtime.js'; | ||
import { is_array } from '../../utils.js'; | ||
import { is_array } from '../../../shared/utils.js'; | ||
@@ -5,0 +5,0 @@ /** |
@@ -266,2 +266,18 @@ /* This file is generated by scripts/process-messages/index.js. Do not edit! */ | ||
/** | ||
* The argument to `$state.frozen(...)` cannot be an object created with `$state(...)`. You should create a copy of it first, for example with `$state.snapshot` | ||
* @returns {never} | ||
*/ | ||
export function state_frozen_invalid_argument() { | ||
if (DEV) { | ||
const error = new Error(`state_frozen_invalid_argument\nThe argument to \`$state.frozen(...)\` cannot be an object created with \`$state(...)\`. You should create a copy of it first, for example with \`$state.snapshot\``); | ||
error.name = 'Svelte error'; | ||
throw error; | ||
} else { | ||
// TODO print a link to the documentation | ||
throw new Error("state_frozen_invalid_argument"); | ||
} | ||
} | ||
/** | ||
* Cannot set prototype of `$state` object | ||
@@ -268,0 +284,0 @@ * @returns {never} |
@@ -94,2 +94,3 @@ export { add_locations } from './dev/elements.js'; | ||
} from './dom/template.js'; | ||
export { freeze } from './freeze.js'; | ||
export { derived, derived_safe_equal } from './reactivity/deriveds.js'; | ||
@@ -140,3 +141,2 @@ export { | ||
unwrap, | ||
freeze, | ||
deep_read, | ||
@@ -155,3 +155,3 @@ deep_read_state, | ||
export { raf } from './timing.js'; | ||
export { proxy, snapshot, is } from './proxy.js'; | ||
export { proxy, is } from './proxy.js'; | ||
export { create_custom_element } from './dom/elements/custom-element.js'; | ||
@@ -165,2 +165,3 @@ export { | ||
} from './dom/operations.js'; | ||
export { snapshot } from '../shared/clone.js'; | ||
export { noop } from '../shared/utils.js'; | ||
@@ -167,0 +168,0 @@ export { |
@@ -7,3 +7,2 @@ import { DEV } from 'esm-env'; | ||
get_descriptor, | ||
get_descriptors, | ||
get_prototype_of, | ||
@@ -13,3 +12,3 @@ is_array, | ||
object_prototype | ||
} from './utils.js'; | ||
} from '../shared/utils.js'; | ||
import { check_ownership, widen_ownership } from './dev/ownership.js'; | ||
@@ -100,59 +99,2 @@ import { source, set } from './reactivity/sources.js'; | ||
/** | ||
* @template {import('#client').ProxyStateObject} T | ||
* @param {T} value | ||
* @param {Map<T, Record<string | symbol, any>>} already_unwrapped | ||
* @returns {Record<string | symbol, any>} | ||
*/ | ||
function unwrap(value, already_unwrapped) { | ||
if (typeof value === 'object' && value != null && STATE_SYMBOL in value) { | ||
const unwrapped = already_unwrapped.get(value); | ||
if (unwrapped !== undefined) { | ||
return unwrapped; | ||
} | ||
if (is_array(value)) { | ||
/** @type {Record<string | symbol, any>} */ | ||
const array = []; | ||
already_unwrapped.set(value, array); | ||
for (const element of value) { | ||
array.push(unwrap(element, already_unwrapped)); | ||
} | ||
return array; | ||
} else { | ||
/** @type {Record<string | symbol, any>} */ | ||
const obj = {}; | ||
const keys = Reflect.ownKeys(value); | ||
const descriptors = get_descriptors(value); | ||
already_unwrapped.set(value, obj); | ||
for (const key of keys) { | ||
if (key === STATE_SYMBOL) continue; | ||
if (descriptors[key].get) { | ||
define_property(obj, key, descriptors[key]); | ||
} else { | ||
/** @type {T} */ | ||
const property = value[key]; | ||
obj[key] = unwrap(property, already_unwrapped); | ||
} | ||
} | ||
return obj; | ||
} | ||
} | ||
return value; | ||
} | ||
/** | ||
* @template T | ||
* @param {T} value | ||
* @returns {T} | ||
*/ | ||
export function snapshot(value) { | ||
return /** @type {T} */ ( | ||
unwrap(/** @type {import('#client').ProxyStateObject} */ (value), new Map()) | ||
); | ||
} | ||
/** | ||
* @param {import('#client').Source<number>} signal | ||
@@ -159,0 +101,0 @@ * @param {1 | -1} [d] |
@@ -40,3 +40,3 @@ import { | ||
import { DEV } from 'esm-env'; | ||
import { define_property } from '../utils.js'; | ||
import { define_property } from '../../shared/utils.js'; | ||
@@ -43,0 +43,0 @@ /** |
@@ -9,3 +9,3 @@ /** @import { Source } from './types.js' */ | ||
} from '../../../constants.js'; | ||
import { get_descriptor, is_function } from '../utils.js'; | ||
import { get_descriptor, is_function } from '../../shared/utils.js'; | ||
import { mutable_source, set, source } from './sources.js'; | ||
@@ -12,0 +12,0 @@ import { derived, derived_safe_equal } from './deriveds.js'; |
@@ -18,3 +18,3 @@ import { DEV } from 'esm-env'; | ||
} from './dom/hydration.js'; | ||
import { array_from } from './utils.js'; | ||
import { array_from } from '../shared/utils.js'; | ||
import { | ||
@@ -30,3 +30,2 @@ all_registered_events, | ||
import { assign_nodes } from './dom/template.js'; | ||
import { queue_micro_task } from './dom/task.js'; | ||
@@ -33,0 +32,0 @@ /** |
import { DEV } from 'esm-env'; | ||
import { define_property, get_descriptors, get_prototype_of } from '../shared/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, | ||
@@ -31,4 +24,3 @@ effect, | ||
LEGACY_DERIVED_PROP, | ||
DISCONNECTED, | ||
STATE_FROZEN_SYMBOL | ||
DISCONNECTED | ||
} from './constants.js'; | ||
@@ -1215,31 +1207,1 @@ import { flush_tasks } from './dom/task.js'; | ||
} | ||
/** | ||
* 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) && | ||
!(STATE_FROZEN_SYMBOL in value) | ||
) { | ||
// If the object is already proxified, then snapshot the value | ||
if (STATE_SYMBOL in 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); | ||
} | ||
} | ||
return value; | ||
} |
import { untrack } from './runtime.js'; | ||
import { get_descriptor, is_array } from './utils.js'; | ||
import { get_descriptor, is_array } from '../shared/utils.js'; | ||
import * as e from './errors.js'; | ||
@@ -4,0 +4,0 @@ |
@@ -554,2 +554,4 @@ /** @import { Component, Payload, RenderOutput } from '#server' */ | ||
export { snapshot } from '../shared/clone.js'; | ||
export { | ||
@@ -556,0 +558,0 @@ add_snippet_symbol, |
@@ -9,1 +9,3 @@ export type Store<V> = { | ||
| [line: number, column: number, SourceLocation[]]; | ||
export type Snapshot<T> = ReturnType<typeof $state.snapshot<T>>; |
@@ -0,1 +1,24 @@ | ||
// 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 var is_array = Array.isArray; | ||
export var array_from = Array.from; | ||
export var object_keys = Object.keys; | ||
export var object_assign = Object.assign; | ||
export var is_frozen = Object.isFrozen; | ||
export var object_freeze = Object.freeze; | ||
export var define_property = Object.defineProperty; | ||
export var get_descriptor = Object.getOwnPropertyDescriptor; | ||
export var get_descriptors = Object.getOwnPropertyDescriptors; | ||
export var object_prototype = Object.prototype; | ||
export var array_prototype = Array.prototype; | ||
export var get_prototype_of = Object.getPrototypeOf; | ||
/** | ||
* @param {any} thing | ||
* @returns {thing is Function} | ||
*/ | ||
export function is_function(thing) { | ||
return typeof thing === 'function'; | ||
} | ||
export const noop = () => {}; | ||
@@ -2,0 +25,0 @@ |
@@ -6,3 +6,3 @@ /** @import { ComponentConstructorOptions, ComponentType, SvelteComponent, Component } from 'svelte' */ | ||
import { get } from '../internal/client/runtime.js'; | ||
import { define_property } from '../internal/client/utils.js'; | ||
import { define_property } from '../internal/shared/utils.js'; | ||
@@ -9,0 +9,0 @@ /** |
@@ -9,3 +9,3 @@ // generated during release, do not modify | ||
*/ | ||
export const VERSION = '5.0.0-next.183'; | ||
export const VERSION = '5.0.0-next.184'; | ||
export const PUBLIC_VERSION = '5'; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2136282
215
46957