Skip to content

Commit 7cbd188

Browse files
authored
breaking: replace $state.frozen with $state.raw (#12808)
* breaking: replace `$state.frozen` with `$state.raw` * regenerate * rename * rename * rename * rename * rename * rename * rename * rename * rename * typo * add compiler error for existing `$state.frozen` uses * regenerate * rename * tidy up * move proxy logic into props function
1 parent fa5d3a9 commit 7cbd188

File tree

56 files changed

+187
-251
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+187
-251
lines changed

.changeset/four-yaks-boil.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
breaking: replace `$state.frozen` with `$state.raw`

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

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

6565
> The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
6666
67-
## state_frozen_invalid_argument
68-
69-
> 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`
70-
7167
## state_prototype_fixed
7268

7369
> Cannot set prototype of `$state` object

packages/svelte/src/ambient.d.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,13 @@ declare namespace $state {
102102
: never;
103103

104104
/**
105-
* Declares reactive read-only state that is shallowly immutable.
105+
* Declares state that is _not_ made deeply reactive — instead of mutating it,
106+
* you must reassign it.
106107
*
107108
* Example:
108109
* ```ts
109110
* <script>
110-
* let items = $state.frozen([0]);
111+
* let items = $state.raw([0]);
111112
*
112113
* const addItem = () => {
113114
* items = [...items, items.length];
@@ -123,8 +124,8 @@ declare namespace $state {
123124
*
124125
* @param initial The initial value
125126
*/
126-
export function frozen<T>(initial: T): Readonly<T>;
127-
export function frozen<T>(): Readonly<T> | undefined;
127+
export function raw<T>(initial: T): T;
128+
export function raw<T>(): T | undefined;
128129
/**
129130
* To take a static snapshot of a deeply reactive `$state` proxy, use `$state.snapshot`:
130131
*

packages/svelte/src/compiler/phases/2-analyze/visitors/BindDirective.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function BindDirective(node, context) {
3434
node.name !== 'this' && // bind:this also works for regular variables
3535
(!binding ||
3636
(binding.kind !== 'state' &&
37-
binding.kind !== 'frozen_state' &&
37+
binding.kind !== 'raw_state' &&
3838
binding.kind !== 'prop' &&
3939
binding.kind !== 'bindable_prop' &&
4040
binding.kind !== 'each' &&

packages/svelte/src/compiler/phases/2-analyze/visitors/CallExpression.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function CallExpression(node, context) {
7373
break;
7474

7575
case '$state':
76-
case '$state.frozen':
76+
case '$state.raw':
7777
case '$derived':
7878
case '$derived.by':
7979
if (

packages/svelte/src/compiler/phases/2-analyze/visitors/ExportNamedDeclaration.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function ExportNamedDeclaration(node, context) {
3232
e.derived_invalid_export(node);
3333
}
3434

35-
if ((binding.kind === 'state' || binding.kind === 'frozen_state') && binding.reassigned) {
35+
if ((binding.kind === 'state' || binding.kind === 'raw_state') && binding.reassigned) {
3636
e.state_invalid_export(node);
3737
}
3838
}

packages/svelte/src/compiler/phases/2-analyze/visitors/ExportSpecifier.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function ExportSpecifier(node, context) {
2626
if (
2727
binding !== null &&
2828
(binding.kind === 'state' ||
29-
binding.kind === 'frozen_state' ||
29+
binding.kind === 'raw_state' ||
3030
(binding.kind === 'normal' &&
3131
(binding.declaration_kind === 'let' || binding.declaration_kind === 'var')))
3232
) {
@@ -60,7 +60,7 @@ function validate_export(node, scope, name) {
6060
e.derived_invalid_export(node);
6161
}
6262

63-
if ((binding.kind === 'state' || binding.kind === 'frozen_state') && binding.reassigned) {
63+
if ((binding.kind === 'state' || binding.kind === 'raw_state') && binding.reassigned) {
6464
e.state_invalid_export(node);
6565
}
6666
}

packages/svelte/src/compiler/phases/2-analyze/visitors/Identifier.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @import { Expression, Identifier } from 'estree' */
22
/** @import { Context } from '../types' */
33
import is_reference from 'is-reference';
4-
import { should_proxy_or_freeze } from '../../3-transform/client/utils.js';
4+
import { should_proxy } from '../../3-transform/client/utils.js';
55
import * as e from '../../../errors.js';
66
import * as w from '../../../warnings.js';
77
import { is_rune } from '../../../../utils.js';
@@ -53,6 +53,10 @@ export function Identifier(node, context) {
5353
e.rune_renamed(parent, '$effect.active', '$effect.tracking');
5454
}
5555

56+
if (name === '$state.frozen') {
57+
e.rune_renamed(parent, '$state.frozen', '$state.raw');
58+
}
59+
5660
e.rune_invalid_name(parent, name);
5761
}
5862
}
@@ -132,8 +136,8 @@ export function Identifier(node, context) {
132136
(binding.initial?.type === 'CallExpression' &&
133137
binding.initial.arguments.length === 1 &&
134138
binding.initial.arguments[0].type !== 'SpreadElement' &&
135-
!should_proxy_or_freeze(binding.initial.arguments[0], context.state.scope)))) ||
136-
binding.kind === 'frozen_state' ||
139+
!should_proxy(binding.initial.arguments[0], context.state.scope)))) ||
140+
binding.kind === 'raw_state' ||
137141
binding.kind === 'derived') &&
138142
// We're only concerned with reads here
139143
(parent.type !== 'AssignmentExpression' || parent.left !== node) &&

packages/svelte/src/compiler/phases/2-analyze/visitors/VariableDeclarator.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export function VariableDeclarator(node, context) {
2121
// TODO feels like this should happen during scope creation?
2222
if (
2323
rune === '$state' ||
24-
rune === '$state.frozen' ||
24+
rune === '$state.raw' ||
2525
rune === '$derived' ||
2626
rune === '$derived.by' ||
2727
rune === '$props'
@@ -32,8 +32,8 @@ export function VariableDeclarator(node, context) {
3232
binding.kind =
3333
rune === '$state'
3434
? 'state'
35-
: rune === '$state.frozen'
36-
? 'frozen_state'
35+
: rune === '$state.raw'
36+
? 'raw_state'
3737
: rune === '$derived' || rune === '$derived.by'
3838
? 'derived'
3939
: path.is_rest

packages/svelte/src/compiler/phases/2-analyze/visitors/shared/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export function validate_no_const_assignment(node, argument, scope, is_binding)
7878
// // This takes advantage of the fact that we don't assign initial for let directives and then/catch variables.
7979
// // If we start doing that, we need another property on the binding to differentiate, or give up on the more precise error message.
8080
// binding.kind !== 'state' &&
81-
// binding.kind !== 'frozen_state' &&
81+
// binding.kind !== 'raw_state' &&
8282
// (binding.kind !== 'normal' || !binding.initial)
8383
// );
8484

0 commit comments

Comments
 (0)