Skip to content

Commit c0f9698

Browse files
committed
throw if argument is a state proxy
1 parent 3301a33 commit c0f9698

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

packages/svelte/messages/client-errors/errors.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@
6060

6161
> The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
6262
63+
## state_frozen_invalid_argument
64+
65+
> 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`
66+
6367
## state_prototype_fixed
6468

6569
> Cannot set prototype of `$state` object

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,20 @@ export function svelte_component_invalid_this_value() {
308308
// TODO print a link to the documentation
309309
throw new Error("svelte_component_invalid_this_value");
310310
}
311+
}
312+
313+
/**
314+
* 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`
315+
* @returns {never}
316+
*/
317+
export function state_frozen_invalid_argument() {
318+
if (DEV) {
319+
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\``);
320+
321+
error.name = 'Svelte error';
322+
throw error;
323+
} else {
324+
// TODO print a link to the documentation
325+
throw new Error("state_frozen_invalid_argument");
326+
}
311327
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { DEV } from 'esm-env';
22
import { define_property, is_array, is_frozen, object_freeze } from '../shared/utils.js';
33
import { STATE_FROZEN_SYMBOL, STATE_SYMBOL } from './constants.js';
4+
import * as e from './errors.js';
45

56
/**
67
* Expects a value that was wrapped with `freeze` and makes it frozen in DEV.
@@ -17,9 +18,8 @@ export function freeze(value) {
1718
) {
1819
var copy = /** @type {T} */ (value);
1920

20-
// If the object is already proxified, then clone the value
2121
if (STATE_SYMBOL in value) {
22-
copy = /** @type {T} */ (is_array(value) ? [...value] : { ...value });
22+
e.state_frozen_invalid_argument();
2323
}
2424

2525
define_property(copy, STATE_FROZEN_SYMBOL, {

packages/svelte/src/internal/client/freeze.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ test('freezes an object', () => {
1111
}, /Cannot assign to read only property/);
1212
});
1313

14-
test('preserves classes', () => {
15-
class Foo {}
16-
const frozen = freeze(proxy([new Foo()]));
17-
18-
assert.ok(frozen[0] instanceof Foo);
14+
test('throws if argument is a state proxy', () => {
15+
assert.throws(() => freeze(proxy({})), /state_frozen_invalid_argument/);
1916
});

0 commit comments

Comments
 (0)