svelte-effect-runtime 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/.dist/chunks/client-BrZka6DW.js +530 -0
  2. package/.dist/chunks/client-BrZka6DW.js.map +1 -0
  3. package/.dist/chunks/compiler-COVzgLYo.js +412 -0
  4. package/.dist/chunks/compiler-COVzgLYo.js.map +1 -0
  5. package/.dist/chunks/descriptors-B4otDlm1.js +216 -0
  6. package/.dist/chunks/descriptors-B4otDlm1.js.map +1 -0
  7. package/.dist/chunks/diagnostics-BDrky-Di.js +359 -0
  8. package/.dist/chunks/diagnostics-BDrky-Di.js.map +1 -0
  9. package/.dist/chunks/dispatcher-BA0PLQhA.js +16 -0
  10. package/.dist/chunks/dispatcher-BA0PLQhA.js.map +1 -0
  11. package/.dist/chunks/{dispatcher-DOx8iC6r.js → dispatcher-_x0MQZBS.js} +84 -258
  12. package/.dist/chunks/dispatcher-_x0MQZBS.js.map +1 -0
  13. package/.dist/chunks/{errors-IJjsUwrE.js → errors-CLsbGjIa.js} +39 -44
  14. package/.dist/chunks/errors-CLsbGjIa.js.map +1 -0
  15. package/.dist/chunks/live-BundLSoY.js +146 -0
  16. package/.dist/chunks/live-BundLSoY.js.map +1 -0
  17. package/.dist/chunks/live-CHK0RrZu.js +10 -0
  18. package/.dist/chunks/live-CHK0RrZu.js.map +1 -0
  19. package/.dist/chunks/{remote-client-CVI4t66c.js → remote-client-mkQAfP1G.js} +29 -23
  20. package/.dist/chunks/remote-client-mkQAfP1G.js.map +1 -0
  21. package/.dist/chunks/{runtime-GBQz32DZ.js → runtime-HDTlEnzp.js} +3 -27
  22. package/.dist/chunks/runtime-HDTlEnzp.js.map +1 -0
  23. package/.dist/chunks/{server-D1LcDnZE.js → server-BNrA1I-u.js} +15 -84
  24. package/.dist/chunks/server-BNrA1I-u.js.map +1 -0
  25. package/.dist/chunks/source-scan-9pZxnfct.js +1059 -0
  26. package/.dist/chunks/source-scan-9pZxnfct.js.map +1 -0
  27. package/.dist/chunks/{transform-jNUr65K9.js → transform-BXyYUAez.js} +184 -358
  28. package/.dist/chunks/transform-BXyYUAez.js.map +1 -0
  29. package/.dist/compiler/markup-identifiers.d.ts +2 -0
  30. package/.dist/compiler/remote-client.d.ts +1 -19
  31. package/.dist/compiler/source-scan.d.ts +11 -108
  32. package/.dist/compiler/sveltekit-remote-bridge.d.ts +3 -0
  33. package/.dist/compiler.d.ts +6 -0
  34. package/.dist/compiler.js +1 -1
  35. package/.dist/detect.d.ts +0 -31
  36. package/.dist/detect.js +0 -39
  37. package/.dist/detect.js.map +1 -1
  38. package/.dist/diagnostics.d.ts +0 -16
  39. package/.dist/dispatcher/deps.d.ts +3 -14
  40. package/.dist/dispatcher/fibers.d.ts +5 -46
  41. package/.dist/dispatcher/index.d.ts +1 -143
  42. package/.dist/dispatcher/types.d.ts +0 -151
  43. package/.dist/dispatcher.js +1 -1
  44. package/.dist/errors.d.ts +30 -42
  45. package/.dist/generated/dispatcher.d.ts +0 -50
  46. package/.dist/generators.d.ts +1 -12
  47. package/.dist/internal/descriptors.d.ts +0 -16
  48. package/.dist/internal/generators.js +13 -8
  49. package/.dist/internal/generators.js.map +1 -1
  50. package/.dist/internal/live.d.ts +9 -0
  51. package/.dist/internal/remote-client.js +2 -2
  52. package/.dist/internal/remote-server.js +2 -2
  53. package/.dist/internal/schema.d.ts +0 -54
  54. package/.dist/live.d.ts +9 -26
  55. package/.dist/markup/event-attributes.d.ts +0 -32
  56. package/.dist/markup/promise.d.ts +1 -23
  57. package/.dist/markup/promise.js +2 -18
  58. package/.dist/markup/promise.js.map +1 -1
  59. package/.dist/markup/run.d.ts +1 -10
  60. package/.dist/markup/run.js +2 -11
  61. package/.dist/markup/run.js.map +1 -1
  62. package/.dist/markup/transform/apply.d.ts +4 -4
  63. package/.dist/markup/transform/classify.d.ts +2 -11
  64. package/.dist/markup/transform/constants.d.ts +1 -1
  65. package/.dist/markup/transform/effect-bindings.d.ts +2 -26
  66. package/.dist/markup/transform/effect-callbacks.d.ts +0 -20
  67. package/.dist/markup/transform/emit.d.ts +2 -11
  68. package/.dist/markup/transform/expressions.d.ts +0 -35
  69. package/.dist/markup/transform/scan.d.ts +3 -22
  70. package/.dist/markup/transform/types.d.ts +1 -129
  71. package/.dist/markup/transform.js +1 -1
  72. package/.dist/markup/value.d.ts +1 -18
  73. package/.dist/markup/value.js +2 -19
  74. package/.dist/markup/value.js.map +1 -1
  75. package/.dist/mod.d.ts +3 -8
  76. package/.dist/mod.js +5 -5
  77. package/.dist/mod.js.map +1 -1
  78. package/.dist/remote/cause-codec.d.ts +3 -37
  79. package/.dist/remote/client/command.d.ts +3 -17
  80. package/.dist/remote/client/form-data.d.ts +0 -7
  81. package/.dist/remote/client/form-enhance.d.ts +0 -7
  82. package/.dist/remote/client/form-transport.d.ts +14 -20
  83. package/.dist/remote/client/form.d.ts +4 -24
  84. package/.dist/remote/client/index.d.ts +2 -1
  85. package/.dist/remote/client/prerender.d.ts +6 -0
  86. package/.dist/remote/client/query-result.d.ts +2 -14
  87. package/.dist/remote/client/query.d.ts +8 -48
  88. package/.dist/remote/client/responses.d.ts +3 -27
  89. package/.dist/remote/client/types.d.ts +16 -110
  90. package/.dist/remote/client/utils.d.ts +0 -8
  91. package/.dist/remote/client.d.ts +2 -2
  92. package/.dist/remote/client.js +2 -2
  93. package/.dist/remote/effect.d.ts +6 -0
  94. package/.dist/remote/failures.d.ts +4 -0
  95. package/.dist/remote/query-update.d.ts +2 -0
  96. package/.dist/remote/resource.d.ts +25 -0
  97. package/.dist/remote/server.d.ts +5 -50
  98. package/.dist/remote/server.js +2 -2
  99. package/.dist/remote/shared.d.ts +6 -145
  100. package/.dist/remote/shared.js +6 -127
  101. package/.dist/remote/shared.js.map +1 -1
  102. package/.dist/runtime/transform.js +5 -22
  103. package/.dist/runtime/transform.js.map +1 -1
  104. package/.dist/script-transform/ast.d.ts +0 -46
  105. package/.dist/script-transform/imports.d.ts +0 -38
  106. package/.dist/script-transform/lower.d.ts +0 -9
  107. package/.dist/script-transform/runes.d.ts +0 -10
  108. package/.dist/script-transform/runtime-block.d.ts +0 -17
  109. package/.dist/script-transform/source.d.ts +0 -24
  110. package/.dist/script-transform/types.d.ts +1 -126
  111. package/.dist/server/effects.d.ts +4 -53
  112. package/.dist/server/factories.d.ts +7 -7
  113. package/.dist/server/index.d.ts +1 -1
  114. package/.dist/server/invalid.d.ts +0 -7
  115. package/.dist/server/live-snapshot.d.ts +5 -0
  116. package/.dist/server/remote-handler-context.d.ts +5 -0
  117. package/.dist/server/runtime.d.ts +6 -24
  118. package/.dist/server/schema.d.ts +0 -14
  119. package/.dist/server/transport.d.ts +2 -0
  120. package/.dist/server/types.d.ts +49 -26
  121. package/.dist/server/wrappers.d.ts +3 -40
  122. package/.dist/server.d.ts +1 -1
  123. package/.dist/server.js +200 -215
  124. package/.dist/server.js.map +1 -1
  125. package/.dist/yieldable.d.ts +1 -35
  126. package/package.json +2 -2
  127. package/.dist/chunks/client-DcZUV4rR.js +0 -653
  128. package/.dist/chunks/client-DcZUV4rR.js.map +0 -1
  129. package/.dist/chunks/compiler-BBPNyXmQ.js +0 -460
  130. package/.dist/chunks/compiler-BBPNyXmQ.js.map +0 -1
  131. package/.dist/chunks/dispatcher-DOx8iC6r.js.map +0 -1
  132. package/.dist/chunks/dispatcher-H-Ia0Os4.js +0 -47
  133. package/.dist/chunks/dispatcher-H-Ia0Os4.js.map +0 -1
  134. package/.dist/chunks/errors-IJjsUwrE.js.map +0 -1
  135. package/.dist/chunks/live-BXAKre_4.js +0 -104
  136. package/.dist/chunks/live-BXAKre_4.js.map +0 -1
  137. package/.dist/chunks/remote-client-CVI4t66c.js.map +0 -1
  138. package/.dist/chunks/runtime-GBQz32DZ.js.map +0 -1
  139. package/.dist/chunks/schema-D9pct6Y5.js +0 -89
  140. package/.dist/chunks/schema-D9pct6Y5.js.map +0 -1
  141. package/.dist/chunks/server-D1LcDnZE.js.map +0 -1
  142. package/.dist/chunks/source-scan-C4PsggID.js +0 -341
  143. package/.dist/chunks/source-scan-C4PsggID.js.map +0 -1
  144. package/.dist/chunks/transform-jNUr65K9.js.map +0 -1
  145. package/.dist/remote/client/effect.d.ts +0 -29
  146. package/.dist/remote/client/failures.d.ts +0 -42
@@ -1,22 +1,10 @@
1
- import { D as UnsupportedMarkupEffectPositionError, k as YieldStarInEventCallbackError, n as AsyncEffectInSyncRuneError, t as AsyncEffectInEventCallbackError } from "./errors-IJjsUwrE.js";
2
- import { t as scan_svelte_effect_source } from "./source-scan-C4PsggID.js";
1
+ import { j as YieldStarInEventCallbackError, k as UnsupportedMarkupEffectPositionError, n as AsyncEffectInSyncRuneError, t as AsyncEffectInEventCallbackError } from "./errors-CLsbGjIa.js";
2
+ import { t as scan_svelte_effect_source } from "./source-scan-9pZxnfct.js";
3
3
  import { contains_top_level_yield_star } from "../detect.js";
4
4
  import ts from "typescript";
5
5
  import { parse } from "svelte/compiler";
6
6
  import MagicString from "magic-string";
7
7
  //#region src/script-transform/imports.ts
8
- /**
9
- * Builds the import statements injected by the script transform.
10
- *
11
- * @since 2.0.0
12
- * @param has_effect_import - Whether the user already imports `Effect`.
13
- * @param has_dispatcher_import - Whether the user already imports
14
- * `get_dispatcher`.
15
- * @param has_untrack_import - Whether the user already imports `untrack`.
16
- * @param bindings - Local names reserved for generated runtime helpers.
17
- * @param options - Runtime helper imports required by this transformed script.
18
- * @returns Newline-separated import statements to inject.
19
- */
20
8
  function make_imports(has_effect_import, has_dispatcher_import, has_untrack_import, bindings = {
21
9
  cancel: "__SER___cancel",
22
10
  dispatcher: "get_dispatcher",
@@ -54,15 +42,6 @@ function make_named_import(imported_name, local_name, type_only = false) {
54
42
  const prefix = type_only ? "type " : "";
55
43
  return imported_name === local_name ? `${prefix}${imported_name}` : `${prefix}${imported_name} as ${local_name}`;
56
44
  }
57
- /**
58
- * Checks whether a source file imports a local binding from a module.
59
- *
60
- * @since 2.0.0
61
- * @param source_file - Parsed TypeScript source file to inspect.
62
- * @param module_name - Module specifier to match.
63
- * @param local_name - Local binding name to look for.
64
- * @returns Whether that binding is already locally available.
65
- */
66
45
  function has_local_import_binding(source_file, module_name, local_name) {
67
46
  return source_file.statements.some((stmt) => {
68
47
  if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier) || stmt.moduleSpecifier.text !== module_name) return false;
@@ -75,13 +54,6 @@ function has_local_import_binding(source_file, module_name, local_name) {
75
54
  return named_bindings.elements.some((element) => !element.isTypeOnly && element.name.text === local_name);
76
55
  });
77
56
  }
78
- /**
79
- * Collects every local binding declared at module top level.
80
- *
81
- * @since 2.4.2
82
- * @param source_file - Parsed TypeScript source file to inspect.
83
- * @returns Top-level names declared by imports, declarations, and variables.
84
- */
85
57
  function collect_top_level_binding_names(source_file) {
86
58
  return source_file.statements.flatMap(collect_statement_binding_names);
87
59
  }
@@ -108,8 +80,45 @@ function collect_binding_name_text(name) {
108
80
  });
109
81
  }
110
82
  //#endregion
83
+ //#region src/compiler/markup-identifiers.ts
84
+ const wrapper_name = "__SER___markup_identifiers";
85
+ const identifier_names_by_scan = /* @__PURE__ */ new WeakMap();
86
+ function collect_markup_identifier_names(source_scan) {
87
+ const cached_names = identifier_names_by_scan.get(source_scan);
88
+ if (cached_names) return cached_names;
89
+ const names = new Set(source_scan.markup_binding_names);
90
+ for (const expression of source_scan.markup_expressions) collect_source_file_identifier_names(ts.createSourceFile("markup-identifiers.ts", make_identifier_parse_source(expression.inner), ts.ScriptTarget.Latest, true, ts.ScriptKind.TS), names);
91
+ names.delete(wrapper_name);
92
+ identifier_names_by_scan.set(source_scan, names);
93
+ return names;
94
+ }
95
+ function make_identifier_parse_source(expression) {
96
+ const snippet = expression.match(/^(\s*)#snippet\s+([\s\S]*)$/);
97
+ if (snippet) return `function* ${wrapper_name}() { ${snippet[1]}function ${snippet[2]} {} }`;
98
+ return `function* ${wrapper_name}() { ${expression} }`;
99
+ }
100
+ function collect_source_file_identifier_names(source_file, names) {
101
+ const visit = (node) => {
102
+ if (ts.isIdentifier(node) && !is_non_runtime_property_name(node)) names.add(node.text);
103
+ ts.forEachChild(node, visit);
104
+ };
105
+ visit(source_file);
106
+ }
107
+ function is_non_runtime_property_name(identifier) {
108
+ const parent = identifier.parent;
109
+ return is_within_type_node(identifier) || ts.isPropertyAccessExpression(parent) && parent.name === identifier || ts.isPropertyAssignment(parent) && parent.name === identifier || ts.isPropertySignature(parent) && parent.name === identifier || ts.isMethodDeclaration(parent) && parent.name === identifier || ts.isMethodSignature(parent) && parent.name === identifier || ts.isGetAccessorDeclaration(parent) && parent.name === identifier || ts.isSetAccessorDeclaration(parent) && parent.name === identifier || ts.isPropertyDeclaration(parent) && parent.name === identifier || ts.isEnumMember(parent) && parent.name === identifier || ts.isBindingElement(parent) && parent.propertyName === identifier;
110
+ }
111
+ function is_within_type_node(identifier) {
112
+ let ancestor = identifier.parent;
113
+ while (ancestor) {
114
+ if (ts.isTypeNode(ancestor)) return true;
115
+ ancestor = ancestor.parent;
116
+ }
117
+ return false;
118
+ }
119
+ //#endregion
111
120
  //#region src/markup/transform/constants.ts
112
- const HELPERS = {
121
+ const default_helper_bindings = {
113
122
  codes: "Code",
114
123
  dispatcher: "Dispatcher",
115
124
  yieldable: "ToEffect"
@@ -123,27 +132,22 @@ function create_source_map$1(magic, filename) {
123
132
  source: filename
124
133
  });
125
134
  }
126
- function blank_script_blocks(content) {
127
- return content.replace(/<script\b[^>]*>[\s\S]*?<\/script\s*>/gi, (match) => {
128
- return match.split("\n").map((l) => " ".repeat(l.length)).join("\n");
129
- });
130
- }
131
- function inject_helpers(magic, content, helpers = [], bindings = HELPERS) {
135
+ function inject_helpers(magic, source_scan, helpers = [], bindings = default_helper_bindings) {
132
136
  const import_helpers = unique_import_helpers(helpers);
133
137
  const local_helpers = helpers.filter((helper) => !is_import_helper(helper));
134
138
  const helper_segments = [
135
- make_import_helper(content, make_dispatcher_import(bindings)),
139
+ make_dispatcher_import(bindings),
136
140
  ...import_helpers,
137
141
  ...local_helpers
138
142
  ].filter((helper) => helper !== void 0).map((helper) => typeof helper === "string" ? { text: helper } : helper);
139
143
  if (helper_segments.length === 0) return;
140
144
  const helper_block = helper_segments.map((segment) => segment.text).join("\n");
141
- const script_tag = find_instance_script_tag(content);
142
- if (script_tag) {
145
+ const instance_script = source_scan.instance_script;
146
+ if (instance_script) {
143
147
  const text = `\n${helper_block}\n`;
144
- magic.appendLeft(script_tag.end, text);
148
+ magic.appendLeft(instance_script.content_end, text);
145
149
  return {
146
- start: script_tag.end,
150
+ start: instance_script.content_end,
147
151
  text,
148
152
  relocations: make_insertion_relocations(helper_segments, "\n")
149
153
  };
@@ -157,31 +161,44 @@ function inject_helpers(magic, content, helpers = [], bindings = HELPERS) {
157
161
  };
158
162
  }
159
163
  }
160
- function make_markup_helper_bindings(content) {
161
- const script_tag = find_instance_script_tag(content);
162
- const name_allocator = make_name_allocator(script_tag ? collect_script_binding_names(content.slice(script_tag.start, script_tag.end)) : []);
164
+ function make_markup_helper_bindings(source_scan) {
165
+ const script_binding_names = source_scan.scripts.flatMap((script) => collect_script_binding_names(script.text));
166
+ const markup_identifier_names = collect_markup_identifier_names(source_scan);
167
+ const name_allocator = make_name_allocator([...script_binding_names, ...markup_identifier_names]);
163
168
  return {
164
169
  bindings: {
165
- codes: name_allocator.reserve(HELPERS.codes),
166
- dispatcher: name_allocator.reserve(HELPERS.dispatcher),
167
- yieldable: name_allocator.reserve(HELPERS.yieldable)
170
+ codes: name_allocator.reserve(default_helper_bindings.codes),
171
+ dispatcher: name_allocator.reserve(default_helper_bindings.dispatcher),
172
+ yieldable: name_allocator.reserve(default_helper_bindings.yieldable)
168
173
  },
169
174
  name_allocator
170
175
  };
171
176
  }
172
177
  function create_relocations(replacements, helper_insertion) {
173
- const edits = [helper_insertion && {
174
- start: helper_insertion.start,
175
- removedLength: 0,
176
- insertedLength: helper_insertion.text.length
177
- }, ...replacements.map((replacement) => ({
178
- start: replacement.start,
179
- removedLength: replacement.end - replacement.start,
180
- insertedLength: replacement.text.length
181
- }))].filter(Boolean);
178
+ const ordered_replacements = [...replacements].sort((left, right) => left.start - right.start);
179
+ const replacement_deltas = /* @__PURE__ */ new Map();
180
+ let accumulated_delta = 0;
181
+ let replacement_delta_before_helper = 0;
182
+ let cursor = 0;
183
+ while (cursor < ordered_replacements.length) {
184
+ const start = ordered_replacements[cursor]?.start;
185
+ let group_end = cursor;
186
+ let group_delta = 0;
187
+ while (ordered_replacements[group_end]?.start === start) {
188
+ const replacement = ordered_replacements[group_end];
189
+ if (replacement) {
190
+ replacement_deltas.set(replacement, accumulated_delta);
191
+ group_delta += replacement.text.length - (replacement.end - replacement.start);
192
+ }
193
+ group_end += 1;
194
+ }
195
+ if (helper_insertion && start !== void 0 && start < helper_insertion.start) replacement_delta_before_helper += group_delta;
196
+ accumulated_delta += group_delta;
197
+ cursor = group_end;
198
+ }
182
199
  const replacement_relocations = replacements.flatMap((replacement) => {
183
200
  if (!replacement.relocation) return [];
184
- const delta_before = edits.filter((edit) => edit.start < replacement.start).reduce((total, edit) => total + edit.insertedLength - edit.removedLength, 0);
201
+ const delta_before = (replacement_deltas.get(replacement) ?? 0) + (helper_insertion && helper_insertion.start <= replacement.start ? helper_insertion.text.length : 0);
185
202
  const generated_start = replacement.start + delta_before;
186
203
  return [{
187
204
  originalStart: replacement.relocation.originalStart,
@@ -190,20 +207,17 @@ function create_relocations(replacements, helper_insertion) {
190
207
  generatedEnd: generated_start + replacement.relocation.generatedEndInReplacement
191
208
  }];
192
209
  });
210
+ const helper_generated_start = (helper_insertion?.start ?? 0) + replacement_delta_before_helper;
193
211
  const helper_relocations = helper_insertion?.relocations?.map((relocation) => ({
194
212
  originalStart: relocation.originalStart,
195
213
  originalEnd: relocation.originalEnd,
196
- generatedStart: helper_insertion.start + relocation.generatedStartInReplacement,
197
- generatedEnd: helper_insertion.start + relocation.generatedEndInReplacement
214
+ generatedStart: helper_generated_start + relocation.generatedStartInReplacement,
215
+ generatedEnd: helper_generated_start + relocation.generatedEndInReplacement
198
216
  })) ?? [];
199
217
  return [...replacement_relocations, ...helper_relocations];
200
218
  }
201
- function make_import_helper(content, import_text) {
202
- if (content.includes(import_text)) return;
203
- return import_text;
204
- }
205
219
  function make_dispatcher_import(bindings) {
206
- return `import { ${make_import_specifier(HELPERS.dispatcher, bindings.dispatcher)}, ${make_import_specifier(HELPERS.codes, bindings.codes)}, ${make_import_specifier(HELPERS.yieldable, bindings.yieldable)} } from "svelte-effect-runtime/internal/generators";`;
220
+ return `import { ${make_import_specifier(default_helper_bindings.dispatcher, bindings.dispatcher)}, ${make_import_specifier(default_helper_bindings.codes, bindings.codes)}, ${make_import_specifier(default_helper_bindings.yieldable, bindings.yieldable)} } from "svelte-effect-runtime/internal/generators";`;
207
221
  }
208
222
  function make_import_specifier(imported_name, local_name) {
209
223
  if (imported_name === local_name) return imported_name;
@@ -223,18 +237,6 @@ function make_insertion_relocations(segments, prefix) {
223
237
  }
224
238
  return relocations;
225
239
  }
226
- function find_instance_script_tag(content) {
227
- for (const match of content.matchAll(/<script\b([^>]*)>([\s\S]*?)<\/script\s*>/gi)) {
228
- if (match.index === void 0) continue;
229
- const attrs = match[1] ?? "";
230
- if (/\bcontext\s*=\s*["']module["']/.test(attrs) || /\bmodule\b/.test(attrs)) continue;
231
- const open_end = match[0].indexOf(">") + 1;
232
- return {
233
- start: match.index + open_end,
234
- end: match.index + match[0].length - 9
235
- };
236
- }
237
- }
238
240
  function unique_import_helpers(helpers) {
239
241
  const seen = /* @__PURE__ */ new Set();
240
242
  return helpers.filter((helper) => {
@@ -265,27 +267,12 @@ function make_name_allocator(initial_names) {
265
267
  }
266
268
  //#endregion
267
269
  //#region src/markup/transform/effect-bindings.ts
268
- const EFFECT_PACKAGE_MODULE = "effect";
269
- const EFFECT_DIRECT_MODULE = "effect/Effect";
270
- const GENERATED_EFFECT_NAME = "__SER___Effect";
271
- /**
272
- * Collects Effect import bindings that markup callback rewriting can trust.
273
- *
274
- * @example
275
- * ```ts
276
- * const bindings = collect_effect_callback_bindings(
277
- * `<script>import { Effect as E } from "effect";<\/script>`,
278
- * );
279
- * ```
280
- *
281
- * @since 2.4.0
282
- * @param content - Full Svelte component source before markup lowering.
283
- * @returns Binding metadata used to identify Effect callback combinators.
284
- */
285
- function collect_effect_callback_bindings(content) {
270
+ const effect_package_module = "effect";
271
+ const effect_direct_module = "effect/Effect";
272
+ const generated_effect_name = "__SER___Effect";
273
+ function collect_effect_callback_bindings(scripts) {
286
274
  const state = make_effect_binding_state();
287
- const scripts = collect_script_blocks(content);
288
- for (const script of scripts) collect_source_file_bindings(ts.createSourceFile("component-script.ts", script, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS), state);
275
+ for (const script of scripts) collect_source_file_bindings(ts.createSourceFile("component-script.ts", script.text, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS), state);
289
276
  ensure_implicit_effect_binding(state);
290
277
  const wrapper = choose_effect_wrapper(state);
291
278
  return {
@@ -307,9 +294,6 @@ function make_effect_binding_state() {
307
294
  implicit_effect_import: false
308
295
  };
309
296
  }
310
- function collect_script_blocks(content) {
311
- return [...content.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/gi)].map((match) => match[1] ?? "");
312
- }
313
297
  function collect_source_file_bindings(source_file, state) {
314
298
  for (const statement of source_file.statements) collect_statement_binding(statement, state);
315
299
  }
@@ -346,21 +330,21 @@ function collect_import_binding(statement, state) {
346
330
  }
347
331
  function collect_namespace_import_binding(module_name, local_name, state) {
348
332
  state.local_names.add(local_name);
349
- if (module_name === EFFECT_DIRECT_MODULE) {
333
+ if (module_name === effect_direct_module) {
350
334
  add_ordered_name(state.effect_module_names, local_name);
351
335
  return;
352
336
  }
353
- if (module_name === EFFECT_PACKAGE_MODULE) add_ordered_name(state.effect_package_names, local_name);
337
+ if (module_name === effect_package_module) add_ordered_name(state.effect_package_names, local_name);
354
338
  }
355
339
  function collect_named_import_binding(module_name, element, state) {
356
340
  const imported_name = element.propertyName?.text ?? element.name.text;
357
341
  const local_name = element.name.text;
358
342
  state.local_names.add(local_name);
359
- if (module_name === EFFECT_PACKAGE_MODULE && imported_name === "Effect") {
343
+ if (module_name === effect_package_module && imported_name === "Effect") {
360
344
  add_ordered_name(state.effect_object_names, local_name);
361
345
  return;
362
346
  }
363
- if (module_name === EFFECT_DIRECT_MODULE) state.direct_members.set(local_name, imported_name);
347
+ if (module_name === effect_direct_module) state.direct_members.set(local_name, imported_name);
364
348
  }
365
349
  function collect_binding_name(name, local_names) {
366
350
  if (ts.isIdentifier(name)) {
@@ -382,10 +366,10 @@ function has_effect_binding(state) {
382
366
  }
383
367
  function choose_effect_wrapper(state) {
384
368
  const effect_object = state.effect_object_names[0];
385
- if (effect_object) return {
369
+ if (effect_object) return state.implicit_effect_import ? {
386
370
  expression: effect_object,
387
- import_text: state.implicit_effect_import ? `import { Effect } from "effect";` : void 0
388
- };
371
+ import_text: `import { Effect } from "effect";`
372
+ } : { expression: effect_object };
389
373
  const effect_module = state.effect_module_names[0];
390
374
  if (effect_module) return { expression: effect_module };
391
375
  const effect_package = state.effect_package_names[0];
@@ -397,10 +381,10 @@ function choose_effect_wrapper(state) {
397
381
  };
398
382
  }
399
383
  function make_generated_effect_name(local_names) {
400
- if (!local_names.has(GENERATED_EFFECT_NAME)) return GENERATED_EFFECT_NAME;
384
+ if (!local_names.has(generated_effect_name)) return generated_effect_name;
401
385
  let index = 1;
402
- while (local_names.has(`${GENERATED_EFFECT_NAME}_${index}`)) index += 1;
403
- return `${GENERATED_EFFECT_NAME}_${index}`;
386
+ while (local_names.has(`${generated_effect_name}_${index}`)) index += 1;
387
+ return `${generated_effect_name}_${index}`;
404
388
  }
405
389
  function add_ordered_name(names, name) {
406
390
  if (names.includes(name)) return;
@@ -408,58 +392,17 @@ function add_ordered_name(names, name) {
408
392
  }
409
393
  //#endregion
410
394
  //#region src/markup/event-attributes.ts
411
- /**
412
- * Checks whether a parsed Svelte attribute has the same event shape that
413
- * Svelte's compiler recognizes.
414
- *
415
- * @example
416
- * ```ts
417
- * is_svelte_event_attribute({
418
- * type: "Attribute",
419
- * name: "onclick",
420
- * value: { type: "ExpressionTag" },
421
- * });
422
- * ```
423
- *
424
- * @since 4.0.0
425
- * @param attribute - Parsed Svelte attribute with its name and complete value
426
- * shape.
427
- * @returns Whether Svelte treats the attribute as an event attribute.
428
- */
429
395
  function is_svelte_event_attribute(attribute) {
430
396
  if (attribute.type !== "Attribute" || !attribute.name?.startsWith("on")) return false;
431
397
  const value = attribute.value;
432
398
  return value !== true && !Array.isArray(value) || Array.isArray(value) && value.length === 1 && value[0]?.type === "ExpressionTag";
433
399
  }
434
- /**
435
- * Normalizes an event-like attribute name to Svelte's lowercase DOM event
436
- * spelling while keeping the legacy directive prefix intact.
437
- *
438
- * @example
439
- * ```ts
440
- * normalize_event_attribute_name("onChange");
441
- * ```
442
- *
443
- * @since 3.4.11
444
- * @param name - Event-like attribute name read from Svelte source or the
445
- * parsed AST.
446
- * @returns Lowercase event attribute spelling for DOM-facing Svelte nodes.
447
- */
448
400
  function normalize_event_attribute_name(name) {
449
401
  if (name.startsWith("on:")) return `on:${name.slice(3).toLowerCase()}`;
450
402
  return name.toLowerCase();
451
403
  }
452
404
  //#endregion
453
405
  //#region src/markup/transform/classify.ts
454
- /**
455
- * Matches sanitized placeholders back to their Svelte AST context.
456
- *
457
- * @since 2.0.0
458
- * @param ast - Parsed Svelte AST for the sanitized component markup.
459
- * @param candidates - Placeholder candidates produced by the scanner.
460
- * @returns Candidates paired with the markup context that determines how they
461
- * should be emitted.
462
- */
463
406
  function classify_candidates(ast, candidates) {
464
407
  const by_placeholder = new Map(candidates.map((candidate) => [candidate.placeholder, candidate]));
465
408
  const classified = [];
@@ -495,7 +438,7 @@ function visit_ast_node(node, candidates, matched, classified) {
495
438
  classify_expression(node.expression, "render", candidates, matched, classified);
496
439
  return;
497
440
  case "HtmlTag":
498
- classify_expression(node.expression, "plain", candidates, matched, classified);
441
+ classify_expression(node.expression, "html", candidates, matched, classified);
499
442
  return;
500
443
  case "DebugTag": return;
501
444
  case "ConstTag":
@@ -623,83 +566,7 @@ function is_record(value) {
623
566
  return typeof value === "object" && value !== null;
624
567
  }
625
568
  //#endregion
626
- //#region src/script-transform/ast.ts
627
- /**
628
- * Checks whether a node is a `yield*` binary expression.
629
- *
630
- * @since 2.0.0
631
- * @param node - TypeScript AST node to check.
632
- * @returns Whether the node represents `yield * operand`.
633
- */
634
- function is_yield_star_expression$1(node) {
635
- return ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.AsteriskToken && ts.isIdentifier(node.left) && node.left.text === "yield";
636
- }
637
- /**
638
- * Checks whether a node owns its own yield semantics.
639
- *
640
- * @since 2.0.0
641
- * @param node - TypeScript AST node to check.
642
- * @returns Whether traversal should stop at this function boundary.
643
- */
644
- function is_function_boundary_node(node) {
645
- return ts.isArrowFunction(node) || ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isMethodDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node);
646
- }
647
- /**
648
- * Returns `true` if the node tree contains a top-level `await`.
649
- *
650
- * @since 2.0.0
651
- * @param node - Root node to search.
652
- * @returns Whether a top-level await expression was found.
653
- */
654
- function contains_top_level_await(node) {
655
- if (ts.isAwaitExpression(node)) return true;
656
- return node.getChildren().some((child) => !is_function_boundary_node(child) && contains_top_level_await(child));
657
- }
658
- /**
659
- * Collects top-level `yield*` nodes under an expression.
660
- *
661
- * @since 2.0.0
662
- * @param node - Root node to search.
663
- * @param on_found - Callback invoked for each matching yield node.
664
- * @returns Nothing.
665
- */
666
- function collect_yield_star_nodes(node, on_found) {
667
- if (is_function_boundary_node(node)) return;
668
- if (is_yield_star_expression$1(node)) {
669
- on_found(node);
670
- return;
671
- }
672
- node.forEachChild((child) => {
673
- collect_yield_star_nodes(child, on_found);
674
- });
675
- }
676
- /**
677
- * Finds the first top-level `yield*` expression below a node.
678
- *
679
- * @since 2.0.0
680
- * @param node - Root node to search.
681
- * @param on_found - Callback invoked with the first matching node.
682
- * @returns Nothing.
683
- */
684
- function find_yield_star_node(node, on_found) {
685
- if (is_function_boundary_node(node)) return;
686
- if (is_yield_star_expression$1(node)) {
687
- on_found(node);
688
- return;
689
- }
690
- node.forEachChild((child) => {
691
- find_yield_star_node(child, on_found);
692
- });
693
- }
694
- //#endregion
695
569
  //#region src/markup/transform/expressions.ts
696
- /**
697
- * Strips an event handler arrow function down to its executable body.
698
- *
699
- * @since 2.0.0
700
- * @param expr - Event handler expression text from the original markup.
701
- * @returns Handler parameters, body text, and body offsets inside `expr`.
702
- */
703
570
  function strip_arrow_function(expr) {
704
571
  const arrow_idx = expr.indexOf("=>");
705
572
  if (arrow_idx === -1) return {
@@ -735,13 +602,6 @@ function strip_arrow_function(expr) {
735
602
  body_end
736
603
  };
737
604
  }
738
- /**
739
- * Returns whether an expression is a callback function.
740
- *
741
- * @since 2.0.0
742
- * @param expr - Expression text from a markup attribute or expression tag.
743
- * @returns Whether the expression parses as an arrow or function expression.
744
- */
745
605
  function is_callback_function_expression(expr) {
746
606
  const wrapped = `const __SER___callback = ${expr};`;
747
607
  const stmt = ts.createSourceFile("callback.ts", wrapped, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS).statements[0];
@@ -749,20 +609,6 @@ function is_callback_function_expression(expr) {
749
609
  const initializer = stmt.declarationList.declarations[0]?.initializer;
750
610
  return initializer !== void 0 && (ts.isArrowFunction(initializer) || ts.isFunctionExpression(initializer));
751
611
  }
752
- /**
753
- * Classifies `yield*` placement inside an event handler body.
754
- *
755
- * @example
756
- * ```ts
757
- * analyze_event_body_yield_star("yield* save()");
758
- * ```
759
- *
760
- * @since 2.0.0
761
- * @param body - Event handler body text after the outer arrow has been
762
- * stripped.
763
- * @returns Whether the body has top-level yield* expressions and whether any
764
- * yield* appears inside a nested non-generator callback.
765
- */
766
612
  function analyze_event_body_yield_star(body) {
767
613
  const wrapped = `function* __SER___event() { ${body}; }`;
768
614
  const stmt = ts.createSourceFile("event.ts", wrapped, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS).statements[0];
@@ -777,13 +623,6 @@ function analyze_event_body_yield_star(body) {
777
623
  visit_event_body(stmt.body, "top_level", result);
778
624
  return result;
779
625
  }
780
- /**
781
- * Collects free identifiers that must be captured as reactive dependencies.
782
- *
783
- * @since 2.0.0
784
- * @param expr_text - Markup expression text to inspect.
785
- * @returns Identifier names referenced by the expression.
786
- */
787
626
  function collect_free_identifiers(expr_text) {
788
627
  const wrapped = `function* __SER___w() { return (${expr_text}); }`;
789
628
  let sf;
@@ -836,7 +675,7 @@ function add_binding_names(name, locals) {
836
675
  }
837
676
  }
838
677
  function visit_event_body(node, context, result) {
839
- if (is_yield_star_expression(node)) {
678
+ if (is_yield_star_expression$1(node)) {
840
679
  if (context === "top_level") result.has_top_level_yield_star = true;
841
680
  else if (context === "nested_invalid") result.has_nested_invalid_yield_star = true;
842
681
  node.forEachChild((child) => visit_event_body(child, context, result));
@@ -855,7 +694,7 @@ function is_nested_function_boundary(node) {
855
694
  function is_generator_function_boundary(node) {
856
695
  return (ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) && node.asteriskToken !== void 0;
857
696
  }
858
- function is_yield_star_expression(node) {
697
+ function is_yield_star_expression$1(node) {
859
698
  if (ts.isYieldExpression(node)) return node.asteriskToken !== void 0;
860
699
  return ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.AsteriskToken && ts.isIdentifier(node.left) && node.left.text === "yield";
861
700
  }
@@ -884,26 +723,6 @@ const effectful_handler_members = /* @__PURE__ */ new Set([
884
723
  "tapBoth"
885
724
  ]);
886
725
  const effectful_handler_property_names = /* @__PURE__ */ new Set(["onFailure", "onSuccess"]);
887
- /**
888
- * Rewrites effectful callback shorthand inside event handler expressions.
889
- *
890
- * @example
891
- * ```ts
892
- * normalize_effect_callback_yields(
893
- * `yield* action.pipe(Effect.flatMap((value) => yield* next(value)))`,
894
- * collect_effect_callback_bindings(source),
895
- * );
896
- * ```
897
- *
898
- * @since 2.0.0
899
- * @param expr_text - Markup expression text before it is wrapped in the
900
- * generated Effect runner.
901
- * @param bindings - Local Effect import bindings collected from the Svelte
902
- * component's script blocks.
903
- * @returns The expression with nested Effect callback `yield*` shorthand
904
- * lowered into explicit Effect callbacks, plus any import needed by generated
905
- * wrapper calls.
906
- */
907
726
  function normalize_effect_callback_yields(expr_text, bindings) {
908
727
  const source_text = `const __SER___expression = ${expr_text};`;
909
728
  const source_file = ts.createSourceFile("event-expression.ts", source_text, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
@@ -1089,16 +908,39 @@ function to_expr_pos(pos, context) {
1089
908
  return pos - context.offset;
1090
909
  }
1091
910
  //#endregion
911
+ //#region src/script-transform/ast.ts
912
+ function is_yield_star_expression(node) {
913
+ return ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.AsteriskToken && ts.isIdentifier(node.left) && node.left.text === "yield";
914
+ }
915
+ function is_function_boundary_node(node) {
916
+ return ts.isArrowFunction(node) || ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isMethodDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node);
917
+ }
918
+ function contains_top_level_await(node) {
919
+ if (ts.isAwaitExpression(node)) return true;
920
+ return node.getChildren().some((child) => !is_function_boundary_node(child) && contains_top_level_await(child));
921
+ }
922
+ function collect_yield_star_nodes(node, on_found) {
923
+ if (is_function_boundary_node(node)) return;
924
+ if (is_yield_star_expression(node)) {
925
+ on_found(node);
926
+ return;
927
+ }
928
+ node.forEachChild((child) => {
929
+ collect_yield_star_nodes(child, on_found);
930
+ });
931
+ }
932
+ function find_yield_star_node(node, on_found) {
933
+ if (is_function_boundary_node(node)) return;
934
+ if (is_yield_star_expression(node)) {
935
+ on_found(node);
936
+ return;
937
+ }
938
+ node.forEachChild((child) => {
939
+ find_yield_star_node(child, on_found);
940
+ });
941
+ }
942
+ //#endregion
1092
943
  //#region src/markup/transform/emit.ts
1093
- /**
1094
- * Emits source edits for classified markup Effect expressions.
1095
- *
1096
- * @since 2.0.0
1097
- * @param classified - Candidates paired with their Svelte markup context.
1098
- * @param effect_context - Effect import bindings available to markup
1099
- * expression rewrites.
1100
- * @returns Replacements ready to apply to the original component source.
1101
- */
1102
944
  function emit_replacements(classified, effect_context, helper_bindings, name_allocator, target) {
1103
945
  const expression_replacements = classified.map(({ candidate, kind }) => emit_replacement(candidate, kind, effect_context, helper_bindings, name_allocator, target));
1104
946
  return [...unique_attribute_name_replacements(classified).map((replacement) => ({
@@ -1151,6 +993,11 @@ function emit_replacement(candidate, kind, effect_context, helper_bindings, name
1151
993
  replacement_text = event.text;
1152
994
  helpers = normalized.helpers;
1153
995
  relocation = make_pending_relocation(candidate, replacement_text, event.expr_text, event.relocation);
996
+ } else if (kind === "html") {
997
+ const effect = make_inline_effect(normalized_candidate, helper_bindings);
998
+ replacement_text = emit_await_expression(id_text, effect, helper_bindings);
999
+ helpers = normalized.helpers;
1000
+ relocation = make_pending_relocation(candidate, replacement_text, effect.effect_text, effect.relocation);
1154
1001
  } else {
1155
1002
  const effect = make_effect_helper(normalized_candidate, helper_name, helper_bindings);
1156
1003
  replacement_text = emit_await_expression(id_text, effect, helper_bindings, server_fallback(is_server_target, "undefined"));
@@ -1161,7 +1008,7 @@ function emit_replacement(candidate, kind, effect_context, helper_bindings, name
1161
1008
  end: candidate.end,
1162
1009
  text: replacement_text,
1163
1010
  helpers,
1164
- relocation
1011
+ ...relocation ? { relocation } : {}
1165
1012
  };
1166
1013
  }
1167
1014
  function make_event_handler(candidate, helper_bindings) {
@@ -1225,6 +1072,18 @@ function make_effect_helper(candidate, helper_name, helper_bindings) {
1225
1072
  }
1226
1073
  };
1227
1074
  }
1075
+ function make_inline_effect(candidate, helper_bindings) {
1076
+ const deps = collect_free_identifiers(candidate.expr_text);
1077
+ const deps_text = deps.length === 0 ? "[]" : `[${deps.join(", ")}]`;
1078
+ const effect_text = wrap_yield_stars(candidate.expr_text, helper_bindings);
1079
+ const relocation = make_yield_operand_relocation(candidate.expr_text, effect_text, helper_bindings);
1080
+ return {
1081
+ call: `(function* () { return (${effect_text}); })()`,
1082
+ deps_text,
1083
+ effect_text,
1084
+ relocation
1085
+ };
1086
+ }
1228
1087
  function wrap_yield_stars(text, helper_bindings) {
1229
1088
  const source_file = ts.createSourceFile("markup-yield.ts", text, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
1230
1089
  const replacements = [];
@@ -1286,14 +1145,6 @@ function make_pending_relocation(candidate, replacement_text, expression_text, r
1286
1145
  }
1287
1146
  //#endregion
1288
1147
  //#region src/script-transform/source.ts
1289
- /**
1290
- * Creates a source map from transformed script back to the original block.
1291
- *
1292
- * @since 2.0.0
1293
- * @param magic - MagicString instance holding the transformed source.
1294
- * @param filename - Source filename used for the source map entry.
1295
- * @returns A plain source map object.
1296
- */
1297
1148
  function create_source_map(magic, filename) {
1298
1149
  return magic.generateMap({
1299
1150
  hires: true,
@@ -1301,53 +1152,27 @@ function create_source_map(magic, filename) {
1301
1152
  source: filename
1302
1153
  });
1303
1154
  }
1304
- /**
1305
- * Slices a substring matching a node's full source range.
1306
- *
1307
- * @since 2.0.0
1308
- * @param content - Original source text.
1309
- * @param node - AST node whose full range should be extracted.
1310
- * @returns Source text including leading trivia.
1311
- */
1312
1155
  function slice(content, node) {
1313
1156
  return content.slice(node.getFullStart(), node.end);
1314
1157
  }
1315
- /**
1316
- * Slices a substring matching a node's source range without leading trivia.
1317
- *
1318
- * @since 2.0.0
1319
- * @param content - Original source text.
1320
- * @param node - AST node whose non-trivia range should be extracted.
1321
- * @returns Source text excluding leading trivia.
1322
- */
1323
1158
  function slice_start(content, node) {
1324
1159
  return content.slice(node.getStart(), node.end);
1325
1160
  }
1326
1161
  //#endregion
1327
1162
  //#region src/script-transform/runes.ts
1328
- const ASYNC_EXPRESSION_RUNES = /* @__PURE__ */ new Set([
1163
+ const async_expression_runes = /* @__PURE__ */ new Set([
1329
1164
  "$derived",
1330
1165
  "$state",
1331
1166
  "$state.raw",
1332
1167
  "$state.snapshot",
1333
1168
  "$bindable"
1334
1169
  ]);
1335
- const CALLBACK_RUNES = /* @__PURE__ */ new Set([
1170
+ const callback_runes = /* @__PURE__ */ new Set([
1336
1171
  "$derived.by",
1337
1172
  "$effect",
1338
1173
  "$effect.pre",
1339
1174
  "$effect.root"
1340
1175
  ]);
1341
- /**
1342
- * Validates that `yield*` only appears in rune positions the script-effect
1343
- * transform can lower without changing the rune's normal Svelte contract.
1344
- *
1345
- * @since 2.0.0
1346
- * @param node - AST node to scan.
1347
- * @param content - Original script source used for diagnostics.
1348
- * @param filename - Source filename used for diagnostics.
1349
- * @returns Nothing.
1350
- */
1351
1176
  function validate_rune_yield_usage(node, content, filename) {
1352
1177
  visit_rune_yield_usage(node, content, filename);
1353
1178
  }
@@ -1360,8 +1185,8 @@ function visit_rune_yield_usage(node, content, filename) {
1360
1185
  function validate_call_expression(call, content, filename) {
1361
1186
  const rune_name = get_rune_name(call.expression);
1362
1187
  if (!rune_name) return;
1363
- if (!ASYNC_EXPRESSION_RUNES.has(rune_name) && contains_top_level_yield_star(call)) throw new AsyncEffectInSyncRuneError(rune_name, slice(content, call), filename);
1364
- if (!CALLBACK_RUNES.has(rune_name)) return;
1188
+ if (!async_expression_runes.has(rune_name) && contains_top_level_yield_star(call)) throw new AsyncEffectInSyncRuneError(rune_name, slice(content, call), filename);
1189
+ if (!callback_runes.has(rune_name)) return;
1365
1190
  const callback = call.arguments[0];
1366
1191
  if (!callback || !callback_has_top_level_yield_star(callback)) return;
1367
1192
  throw new AsyncEffectInSyncRuneError(rune_name, slice(content, call), filename);
@@ -1382,29 +1207,10 @@ function is_rune_root(name) {
1382
1207
  }
1383
1208
  //#endregion
1384
1209
  //#region src/markup/transform/scan.ts
1385
- /**
1386
- * Replaces markup `yield*` expressions with placeholders before Svelte parses
1387
- * the component.
1388
- *
1389
- * @example
1390
- * ```ts
1391
- * const sanitized = sanitize_markup(
1392
- * `<p>{yield* loadLabel()}</p>`,
1393
- * "Label.svelte",
1394
- * );
1395
- * ```
1396
- *
1397
- * @since 2.0.0
1398
- * @param content - Raw Svelte component source to scan for effectful markup
1399
- * expressions.
1400
- * @param filename - Source filename used when validation errors need to point
1401
- * back to the component being transformed.
1402
- * @returns Sanitized source plus placeholder candidates that should be lowered
1403
- * after Svelte classifies their markup positions.
1404
- */
1405
- function sanitize_markup(content, filename) {
1210
+ function sanitize_markup(source_scan) {
1211
+ const content = source_scan.source;
1212
+ const filename = source_scan.filename;
1406
1213
  const candidates = [];
1407
- const source_scan = scan_svelte_effect_source(content, filename);
1408
1214
  const magic = new MagicString(content);
1409
1215
  let helper_index = 0;
1410
1216
  for (const expression of source_scan.markup_expressions) {
@@ -1491,11 +1297,30 @@ function sanitize_markup(content, filename) {
1491
1297
  });
1492
1298
  magic.overwrite(expr_start, expr_end, key === "render" ? `${placeholder}()` : placeholder);
1493
1299
  }
1300
+ if (candidates.length === 0) return {
1301
+ parse_code: content,
1302
+ candidates
1303
+ };
1304
+ for (const region of source_scan.scripts) {
1305
+ const region_source = content.slice(region.start, region.end);
1306
+ magic.overwrite(region.start, region.end, blank_script_region(region_source, region.is_module, region.is_typescript));
1307
+ }
1308
+ for (const region of source_scan.styles) {
1309
+ const region_source = content.slice(region.start, region.end);
1310
+ magic.overwrite(region.start, region.end, blank_source_region(region_source));
1311
+ }
1494
1312
  return {
1495
- code: magic.toString(),
1313
+ parse_code: magic.toString(),
1496
1314
  candidates
1497
1315
  };
1498
1316
  }
1317
+ function blank_source_region(source) {
1318
+ return source.replace(/[^\r\n]/g, " ");
1319
+ }
1320
+ function blank_script_region(source, is_module, is_typescript) {
1321
+ const scaffold = `<script${is_module ? " module" : ""}${is_typescript ? " lang=ts" : ""}><\/script>`;
1322
+ return scaffold + blank_source_region(source.slice(scaffold.length));
1323
+ }
1499
1324
  function collect_expression_yield_expressions(content, expr_start, expr_text, filename) {
1500
1325
  const source_file = ts.createSourceFile("markup-expression.ts", `const __SER___expr = ${expr_text};`, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
1501
1326
  const stmt = source_file.statements[0];
@@ -1552,7 +1377,7 @@ function get_tag_info(trimmed) {
1552
1377
  prefix_length: 7
1553
1378
  };
1554
1379
  if (trimmed.startsWith("@html ")) return {
1555
- kind: "plain",
1380
+ kind: "html",
1556
1381
  prefix_length: 6
1557
1382
  };
1558
1383
  if (trimmed.startsWith("@debug ")) return {
@@ -1607,7 +1432,7 @@ function is_event_callback_expression(inner) {
1607
1432
  function analyze_event_yield(inner) {
1608
1433
  const event = strip_arrow_function(inner);
1609
1434
  const analysis = analyze_event_body_yield_star(event.body);
1610
- if (new RegExp(`${HELPERS.dispatcher}(?:_\\d+)?\\.emit\\(\\{\\s*type:\\s*${HELPERS.codes}(?:_\\d+)?\\.Markup\\.Run`).test(event.body)) return { has_top_level_yield_star: false };
1435
+ if (new RegExp(`${default_helper_bindings.dispatcher}(?:_\\d+)?\\.emit\\(\\{\\s*type:\\s*${default_helper_bindings.codes}(?:_\\d+)?\\.Markup\\.Run`).test(event.body)) return { has_top_level_yield_star: false };
1611
1436
  return { has_top_level_yield_star: analysis.has_top_level_yield_star || analysis.has_nested_invalid_yield_star || /\byield\s*\*/.test(event.body) };
1612
1437
  }
1613
1438
  function contains_yield_star_in_text(text) {
@@ -1655,16 +1480,17 @@ function transform_markup_effect(content, filename, options = {}) {
1655
1480
  code: content,
1656
1481
  has_yield: false
1657
1482
  };
1483
+ const source_scan = scan_svelte_effect_source(content, filename);
1658
1484
  /** Find all brace expressions containing yield* and replace with placeholders. */
1659
- const work = sanitize_markup(content, filename);
1660
- const effect_context = collect_effect_callback_bindings(content);
1661
- const helper_context = make_markup_helper_bindings(content);
1485
+ const work = sanitize_markup(source_scan);
1662
1486
  if (work.candidates.length === 0) return {
1663
1487
  code: content,
1664
1488
  has_yield: false
1665
1489
  };
1490
+ const effect_context = collect_effect_callback_bindings(source_scan.scripts);
1491
+ const helper_context = make_markup_helper_bindings(source_scan);
1666
1492
  /** Match placeholders to their AST context and build replacements. */
1667
- const classified = classify_candidates(parse(blank_script_blocks(work.code), {
1493
+ const classified = classify_candidates(parse(work.parse_code, {
1668
1494
  filename,
1669
1495
  modern: true
1670
1496
  }), work.candidates);
@@ -1676,7 +1502,7 @@ function transform_markup_effect(content, filename, options = {}) {
1676
1502
  const magic = new MagicString(content);
1677
1503
  replacements.sort((a, b) => b.start - a.start);
1678
1504
  for (const r of replacements) magic.overwrite(r.start, r.end, r.text);
1679
- const relocations = create_relocations(replacements, inject_helpers(magic, content, helpers, helper_context.bindings));
1505
+ const relocations = create_relocations(replacements, inject_helpers(magic, source_scan, helpers, helper_context.bindings));
1680
1506
  return {
1681
1507
  code: magic.toString(),
1682
1508
  has_yield: true,
@@ -1685,6 +1511,6 @@ function transform_markup_effect(content, filename, options = {}) {
1685
1511
  };
1686
1512
  }
1687
1513
  //#endregion
1688
- export { slice_start as a, contains_top_level_await as c, collect_top_level_binding_names as d, has_local_import_binding as f, slice as i, find_yield_star_node as l, validate_rune_yield_usage as n, collect_free_identifiers as o, make_imports as p, create_source_map as r, collect_yield_star_nodes as s, transform_markup_effect as t, is_yield_star_expression$1 as u };
1514
+ export { slice_start as a, find_yield_star_node as c, collect_top_level_binding_names as d, has_local_import_binding as f, slice as i, is_yield_star_expression as l, validate_rune_yield_usage as n, collect_yield_star_nodes as o, make_imports as p, create_source_map as r, contains_top_level_await as s, transform_markup_effect as t, collect_free_identifiers as u };
1689
1515
 
1690
- //# sourceMappingURL=transform-jNUr65K9.js.map
1516
+ //# sourceMappingURL=transform-BXyYUAez.js.map