Skip to content

Commit 697bf6b

Browse files
Rich-Harristrueadm
authored andcommitted
breaking: use structuredClone inside $state.snapshot (#12413)
* move cloning logic into new file, use structuredClone, add tests * changeset * breaking * tweak * use same cloning approach between server and client * get types mostly working * fix type error that popped up * cheeky hack * we no longer need deep_snapshot * shallow copy state when freezing * throw if argument is a state proxy * docs * regenerate
1 parent fe97f21 commit 697bf6b

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

documentation/docs/03-runes/01-state.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,7 @@ person = {
9090

9191
This can improve performance with large arrays and objects that you weren't planning to mutate anyway, since it avoids the cost of making them reactive. Note that frozen state can _contain_ reactive state (for example, a frozen array of reactive objects).
9292

93-
In development mode, the argument to `$state.frozen` will be shallowly frozen with `Object.freeze()`, to make it obvious if you accidentally mutate it.
94-
95-
> Objects and arrays passed to `$state.frozen` will have a `Symbol` property added to them to signal to Svelte that they are frozen. If you don't want this, pass in a clone of the object or array instead. The argument cannot be an existing state proxy created with `$state(...)`.
93+
> Objects and arrays passed to `$state.frozen` will be shallowly frozen using `Object.freeze()`. If you don't want this, pass in a clone of the object or array instead. The argument cannot be an existing state proxy created with `$state(...)`.
9694
9795
## `$state.snapshot`
9896

packages/svelte/src/internal/client/errors.js

+16
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,22 @@ export function snippet_missing_mount() {
294294
}
295295
}
296296

297+
/**
298+
* 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`
299+
* @returns {never}
300+
*/
301+
export function state_frozen_invalid_argument() {
302+
if (DEV) {
303+
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\``);
304+
305+
error.name = 'Svelte error';
306+
throw error;
307+
} else {
308+
// TODO print a link to the documentation
309+
throw new Error("state_frozen_invalid_argument");
310+
}
311+
}
312+
297313
/**
298314
* Cannot set prototype of `$state` object
299315
* @returns {never}

packages/svelte/src/internal/shared/types.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ export type Snapshot<T> = ReturnType<typeof $state.snapshot<T>>;
1212
export type Getters<T> = {
1313
[K in keyof T]: () => T[K];
1414
};
15+
16+
export type Snapshot<T> = ReturnType<typeof $state.snapshot<T>>;

0 commit comments

Comments
 (0)