Skip to content

Commit 4facc70

Browse files
committed
fix
1 parent ae73afd commit 4facc70

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

packages/svelte/src/compiler/phases/3-transform/client/transform-client.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -403,16 +403,8 @@ export function client_component(analysis, options) {
403403
// so that it can effectively clean up the store subscription even after the user effects runs
404404
if (should_inject_context) {
405405
if (analysis.needs_mutation_validation) {
406-
// It's easier to have the mutation validator instance be on the module level because of hoisted events
407-
state.hoisted.push(b.let('$$ownership_validator'));
408406
component_block.body.unshift(
409-
b.stmt(
410-
b.assignment(
411-
'=',
412-
b.id('$$ownership_validator'),
413-
b.call('$.create_ownership_validator', b.id('$$props'))
414-
)
415-
)
407+
b.var('$$ownership_validator', b.call('$.create_ownership_validator', b.id('$$props')))
416408
);
417409
}
418410

packages/svelte/src/compiler/phases/3-transform/client/utils.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
/** @import { ArrowFunctionExpression, Expression, FunctionDeclaration, FunctionExpression, Identifier, Pattern, PrivateIdentifier, Statement } from 'estree' */
2-
/** @import { AST, Binding } from '#compiler' */
1+
/** @import { ArrowFunctionExpression, AssignmentExpression, Expression, FunctionDeclaration, FunctionExpression, Identifier, Node, Pattern, UpdateExpression } from 'estree' */
2+
/** @import { Binding } from '#compiler' */
33
/** @import { ClientTransformState, ComponentClientTransformState, ComponentContext } from './types.js' */
44
/** @import { Analysis } from '../../types.js' */
55
/** @import { Scope } from '../../scope.js' */
66
import * as b from '../../../utils/builders.js';
7-
import { extract_identifiers, is_simple_expression } from '../../../utils/ast.js';
7+
import { is_simple_expression } from '../../../utils/ast.js';
88
import {
99
PROPS_IS_LAZY_INITIAL,
1010
PROPS_IS_IMMUTABLE,
@@ -13,7 +13,8 @@ import {
1313
PROPS_IS_BINDABLE
1414
} from '../../../../constants.js';
1515
import { dev } from '../../../state.js';
16-
import { get_value } from './visitors/shared/declarations.js';
16+
import { walk } from 'zimmerframe';
17+
import { validate_mutation } from './visitors/shared/utils.js';
1718

1819
/**
1920
* @param {Binding} binding
@@ -110,6 +111,30 @@ function get_hoisted_params(node, context) {
110111
}
111112
}
112113
}
114+
115+
if (dev) {
116+
// this is a little hacky, but necessary for ownership validation
117+
// to work inside hoisted event handlers
118+
119+
/**
120+
* @param {AssignmentExpression | UpdateExpression} node
121+
* @param {{ next: () => void, stop: () => void }} context
122+
*/
123+
function visit(node, { next, stop }) {
124+
if (validate_mutation(node, /** @type {any} */ (context), node) !== node) {
125+
params.push(b.id('$$ownership_validator'));
126+
stop();
127+
} else {
128+
next();
129+
}
130+
}
131+
132+
walk(/** @type {Node} */ (node), null, {
133+
AssignmentExpression: visit,
134+
UpdateExpression: visit
135+
});
136+
}
137+
113138
return params;
114139
}
115140

0 commit comments

Comments
 (0)