mirror of https://github.com/sveltejs/svelte
parent
b462c8d2e9
commit
ef4b6facb6
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
breaking: replace `$state.frozen` with `$state.raw`
|
||||
@ -1,40 +0,0 @@
|
||||
import { DEV } from 'esm-env';
|
||||
import { define_property, is_array, is_frozen, object_freeze } from '../shared/utils.js';
|
||||
import { STATE_FROZEN_SYMBOL, STATE_SYMBOL } from './constants.js';
|
||||
import * as e from './errors.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)
|
||||
) {
|
||||
var copy = /** @type {T} */ (value);
|
||||
|
||||
if (STATE_SYMBOL in value) {
|
||||
e.state_frozen_invalid_argument();
|
||||
}
|
||||
|
||||
define_property(copy, STATE_FROZEN_SYMBOL, {
|
||||
value: true,
|
||||
writable: true,
|
||||
enumerable: false
|
||||
});
|
||||
|
||||
// Freeze the object in DEV
|
||||
if (DEV) {
|
||||
object_freeze(copy);
|
||||
}
|
||||
|
||||
return /** @type {Readonly<T>} */ (copy);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
import { freeze } from './freeze.js';
|
||||
import { assert, test } from 'vitest';
|
||||
import { proxy } from './proxy.js';
|
||||
|
||||
test('freezes an object', () => {
|
||||
const frozen = freeze({ a: 1 });
|
||||
|
||||
assert.throws(() => {
|
||||
// @ts-expect-error
|
||||
frozen.a += 1;
|
||||
}, /Cannot assign to read only property/);
|
||||
});
|
||||
|
||||
test('throws if argument is a state proxy', () => {
|
||||
assert.throws(() => freeze(proxy({})), /state_frozen_invalid_argument/);
|
||||
});
|
||||
@ -1,14 +1,12 @@
|
||||
<script>
|
||||
class Counter {
|
||||
count = $state.frozen({ a: 0 });
|
||||
count = $state.raw({ a: 0 });
|
||||
}
|
||||
const counter = new Counter();
|
||||
</script>
|
||||
|
||||
<button on:click={() => {
|
||||
try {
|
||||
counter.count.a++
|
||||
} catch (e) {
|
||||
console.log('read only')
|
||||
}
|
||||
}}>{counter.count.a}</button>
|
||||
<button
|
||||
on:click={() => {
|
||||
counter.count.a++;
|
||||
}}>{counter.count.a}</button
|
||||
>
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
<script>
|
||||
let frozen_items = $state.frozen([
|
||||
{id: 0, text: 'a'},
|
||||
{id: 1, text: 'b'},
|
||||
{id: 2, text: 'c'}
|
||||
])
|
||||
let raw_items = $state.raw([
|
||||
{ id: 0, text: 'a' },
|
||||
{ id: 1, text: 'b' },
|
||||
{ id: 2, text: 'c' }
|
||||
]);
|
||||
</script>
|
||||
|
||||
{#each frozen_items as item (item.id)}
|
||||
{#each raw_items as item (item.id)}
|
||||
{console.log(item.text)}
|
||||
{item.text}
|
||||
{item.text}
|
||||
{/each}
|
||||
|
||||
<button onclick={() => {
|
||||
frozen_items = [...frozen_items, {id: 3, text: 'd'}]
|
||||
}}></button>
|
||||
<button
|
||||
onclick={() => {
|
||||
raw_items = [...raw_items, { id: 3, text: 'd' }];
|
||||
}}
|
||||
></button>
|
||||
|
||||
Loading…
Reference in new issue