svelte-effect-runtime 2.0.0 → 2.0.2

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 (39) hide show
  1. package/.dist/chunks/{client-BeOE81fW.js → client-zavjI3Qd.js} +9 -9
  2. package/.dist/chunks/client-zavjI3Qd.js.map +1 -0
  3. package/.dist/chunks/{dispatcher-BSg2-ttN.js → dispatcher-g0HYqHOK.js} +3 -3
  4. package/.dist/chunks/{dispatcher-BSg2-ttN.js.map → dispatcher-g0HYqHOK.js.map} +1 -1
  5. package/.dist/chunks/{preprocess-BZyUYWY7.js → preprocess-BeZqJxso.js} +242 -128
  6. package/.dist/chunks/preprocess-BeZqJxso.js.map +1 -0
  7. package/.dist/chunks/{transform-BtlxgJrg.js → transform-BguSlVDO.js} +64 -17
  8. package/.dist/chunks/transform-BguSlVDO.js.map +1 -0
  9. package/.dist/dispatcher.js +1 -1
  10. package/.dist/error.d.ts +26 -14
  11. package/.dist/internal/generators.js +1 -1
  12. package/.dist/internal/remote-client.js +1 -1
  13. package/.dist/markup/promise.js +1 -1
  14. package/.dist/markup/run.js +1 -1
  15. package/.dist/markup/transform.js +1 -1
  16. package/.dist/markup/value.js +1 -1
  17. package/.dist/mod.d.ts +1 -1
  18. package/.dist/mod.js +2 -2
  19. package/.dist/mod.js.map +1 -1
  20. package/.dist/preprocess/imports.d.ts +1 -2
  21. package/.dist/preprocess/index.d.ts +1 -1
  22. package/.dist/preprocess/lower.d.ts +1 -1
  23. package/.dist/preprocess/runes.d.ts +24 -0
  24. package/.dist/preprocess/runtime-block.d.ts +5 -4
  25. package/.dist/preprocess/types.d.ts +15 -3
  26. package/.dist/preprocess.js +2 -2
  27. package/.dist/remote/client.js +1 -1
  28. package/.dist/remote/server.js +3 -3
  29. package/.dist/remote/server.js.map +1 -1
  30. package/.dist/runtime/preprocess.js +2 -2
  31. package/.dist/server/factories.d.ts +2 -2
  32. package/.dist/server/runtime.d.ts +2 -16
  33. package/.dist/server/types.d.ts +3 -3
  34. package/.dist/server.js +8 -8
  35. package/.dist/server.js.map +1 -1
  36. package/package.json +1 -1
  37. package/.dist/chunks/client-BeOE81fW.js.map +0 -1
  38. package/.dist/chunks/preprocess-BZyUYWY7.js.map +0 -1
  39. package/.dist/chunks/transform-BtlxgJrg.js.map +0 -1
@@ -466,6 +466,22 @@ function make_relocation(candidate, replacement_text, inner) {
466
466
  //#endregion
467
467
  //#region src/error.ts
468
468
  /**
469
+ * Formats a runtime-owned error message with a stable screaming-case code.
470
+ *
471
+ * @example
472
+ * ```ts
473
+ * throw new Error(make_error_message("DISPATCHER_DISPOSED", "Dispatcher has been disposed"));
474
+ * ```
475
+ *
476
+ * @since 2.0.0
477
+ * @param code - Stable screaming-case identifier for the error category.
478
+ * @param message - Human-readable error message without the leading code.
479
+ * @returns The complete error message prefixed with the stable code.
480
+ */
481
+ function make_error_message(code, message) {
482
+ return `[${code}]: ${message}`;
483
+ }
484
+ /**
469
485
  * Base error class for all preprocessor errors emitted during script and
470
486
  * markup transformation. Carries the source filename so error messages can
471
487
  * reference the affected file.
@@ -486,38 +502,69 @@ var PreprocessError = class extends Error {
486
502
  }
487
503
  };
488
504
  /**
489
- * Thrown when `await` is used at the top level of a `<script effect>` block.
490
- * Top-level `await` is not supported — users should use
491
- * `yield* Effect.promise(...)` or `yield* Effect.tryPromise(...)` instead.
505
+ * Thrown when a statement mixes JavaScript `await` with Effect `yield*` work
506
+ * that must be lowered into an `Effect.gen` program.
492
507
  *
493
508
  * @since 2.0.0
494
509
  */
495
- var TopLevelAwaitError = class extends PreprocessError {
510
+ var AwaitInEffectWorkError = class extends PreprocessError {
496
511
  /**
497
- * The full text of the problematic statement containing the `await`.
512
+ * The full text of the problematic statement containing mixed async work.
498
513
  *
499
514
  * @since 2.0.0
500
515
  */
501
516
  statement_text;
502
517
  constructor(filename, statement_text) {
503
518
  super([
504
- `${filename}: top-level await is not supported in <script effect>.`,
505
- `Use yield* Effect.promise(...) or yield* Effect.tryPromise(...) instead.`,
519
+ make_error_message("AWAIT_IN_EFFECT_WORK", `${filename}: await cannot be mixed with yield* in Effect work.`),
520
+ `Top-level await is supported as ordinary Svelte async rendering, but statements lowered into Effect.gen must use yield* for async Effect work.`,
506
521
  "",
507
522
  `Problematic statement:`,
508
523
  statement_text
509
524
  ].join("\n"), filename);
510
- this.name = "TopLevelAwaitError";
525
+ this.name = "AwaitInEffectWorkError";
511
526
  this.statement_text = statement_text;
512
527
  }
513
528
  };
514
529
  /**
515
- * Thrown when an event handler contains `yield*` inside a nested callback that
516
- * is not itself a generator function.
530
+ * Thrown when async Effect work appears inside a Svelte rune position that
531
+ * must stay synchronous.
532
+ *
533
+ * @since 2.0.0
534
+ */
535
+ var AsyncEffectInSyncRuneError = class extends PreprocessError {
536
+ /**
537
+ * The name of the rune that contained async Effect work.
538
+ *
539
+ * @since 2.0.0
540
+ */
541
+ rune_name;
542
+ /**
543
+ * The full text of the expression that triggered the error.
544
+ *
545
+ * @since 2.0.0
546
+ */
547
+ expression_text;
548
+ constructor(rune_name, expression_text, filename) {
549
+ super([
550
+ make_error_message("ASYNC_EFFECT_IN_SYNC_RUNE", `${filename}: yield* cannot be used inside ${rune_name}().`),
551
+ `${rune_name}() must stay synchronous. Do not put async Effect work inside this rune.`,
552
+ "",
553
+ `Problematic expression:`,
554
+ expression_text
555
+ ].join("\n"), filename);
556
+ this.name = "AsyncEffectInSyncRuneError";
557
+ this.rune_name = rune_name;
558
+ this.expression_text = expression_text;
559
+ }
560
+ };
561
+ /**
562
+ * Thrown when async Effect work appears inside a non-generator callback nested
563
+ * in a markup event handler.
517
564
  *
518
565
  * @example
519
566
  * ```ts
520
- * throw new NestedYieldStarInEventHandlerError(
567
+ * throw new AsyncEffectInEventCallbackError(
521
568
  * "Component.svelte",
522
569
  * "Effect.try(() => yield* save())",
523
570
  * );
@@ -525,7 +572,7 @@ var TopLevelAwaitError = class extends PreprocessError {
525
572
  *
526
573
  * @since 2.0.0
527
574
  */
528
- var NestedYieldStarInEventHandlerError = class extends PreprocessError {
575
+ var AsyncEffectInEventCallbackError = class extends PreprocessError {
529
576
  /**
530
577
  * The full text of the problematic event handler body.
531
578
  *
@@ -534,7 +581,7 @@ var NestedYieldStarInEventHandlerError = class extends PreprocessError {
534
581
  expression_text;
535
582
  constructor(filename, expression_text) {
536
583
  super([
537
- `${filename}: yield* cannot be used inside a nested non-generator callback in a markup event handler.`,
584
+ make_error_message("ASYNC_EFFECT_IN_EVENT_CALLBACK", `${filename}: yield* cannot be used inside a nested non-generator callback in a markup event handler.`),
538
585
  `Move the yield* to the event handler body. Effect.try and Effect.sync callbacks are plain synchronous JavaScript; do not call Effect-returning functions inside them.`,
539
586
  "",
540
587
  `Run the remote Effect directly:`,
@@ -546,7 +593,7 @@ var NestedYieldStarInEventHandlerError = class extends PreprocessError {
546
593
  `Problematic expression:`,
547
594
  expression_text
548
595
  ].join("\n"), filename);
549
- this.name = "NestedYieldStarInEventHandlerError";
596
+ this.name = "AsyncEffectInEventCallbackError";
550
597
  this.expression_text = expression_text;
551
598
  }
552
599
  };
@@ -769,7 +816,7 @@ function is_event_expression(inner) {
769
816
  function analyze_event_yield(inner, filename) {
770
817
  const event = strip_arrow_function(inner);
771
818
  const analysis = analyze_event_body_yield_star(event.body);
772
- if (analysis.has_nested_invalid_yield_star) throw new NestedYieldStarInEventHandlerError(filename, event.body);
819
+ if (analysis.has_nested_invalid_yield_star) throw new AsyncEffectInEventCallbackError(filename, event.body);
773
820
  return { has_top_level_yield_star: analysis.has_top_level_yield_star };
774
821
  }
775
822
  function contains_yield_star_in_text(text) {
@@ -831,6 +878,6 @@ function transform_markup_effect(content, filename) {
831
878
  };
832
879
  }
833
880
  //#endregion
834
- export { TopLevelAwaitError as n, transform_markup_effect as t };
881
+ export { collect_free_identifiers as i, AsyncEffectInSyncRuneError as n, AwaitInEffectWorkError as r, transform_markup_effect as t };
835
882
 
836
- //# sourceMappingURL=transform-BtlxgJrg.js.map
883
+ //# sourceMappingURL=transform-BguSlVDO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform-BguSlVDO.js","names":[],"sources":["../../../modules/svelte-effect-runtime/src/markup/transform/constants.ts","../../../modules/svelte-effect-runtime/src/markup/transform/apply.ts","../../../modules/svelte-effect-runtime/src/markup/transform/classify.ts","../../../modules/svelte-effect-runtime/src/markup/transform/expressions.ts","../../../modules/svelte-effect-runtime/src/markup/transform/emit.ts","../../../modules/svelte-effect-runtime/src/error.ts","../../../modules/svelte-effect-runtime/src/markup/transform/scan.ts","../../../modules/svelte-effect-runtime/src/markup/transform/index.ts"],"sourcesContent":["export const HELPERS = {\n value: \"__ser_markup_value\",\n promise: \"__ser_markup_promise\",\n run: \"__ser_markup_run\",\n} as const;\n","import type MagicString from \"magic-string\";\n\nimport { HELPERS } from \"./constants.ts\";\nimport type {\n HelperDeclaration,\n Insertion,\n MarkupRelocation,\n PendingRelocation,\n Replacement,\n} from \"./types.ts\";\n\nexport function create_source_map(\n magic: MagicString,\n filename: string,\n): Record<string, unknown> {\n const map = magic.generateMap({\n hires: true,\n includeContent: true,\n source: filename,\n });\n\n return map as unknown as Record<string, unknown>;\n}\n\nexport function blank_script_blocks(content: string): string {\n return content.replace(\n /<script\\b[^>]*>[\\s\\S]*?<\\/script\\s*>/gi,\n (match) => {\n const lines = match.split(\"\\n\");\n return lines.map((l) => \" \".repeat(l.length)).join(\"\\n\");\n },\n );\n}\n\nexport function inject_helpers(\n magic: MagicString,\n content: string,\n helpers: HelperDeclaration[] = [],\n): Insertion | undefined {\n if (content.includes(HELPERS.value)) {\n return undefined;\n }\n\n const helper_segments: Array<{\n text: string;\n relocation?: PendingRelocation;\n }> = [\n `import { value as ${HELPERS.value} } from \"svelte-effect-runtime/internal/generators\";`,\n `import { promise as ${HELPERS.promise} } from \"svelte-effect-runtime/internal/generators\";`,\n `import { run as ${HELPERS.run} } from \"svelte-effect-runtime/internal/generators\";`,\n ...helpers,\n ].map((helper) =>\n typeof helper === \"string\" ? { text: helper } : helper\n );\n\n const helper_block = helper_segments.map((segment) => segment.text).join(\n \"\\n\",\n );\n\n const script_tag = find_instance_script_tag(content);\n\n if (script_tag) {\n const text = `\\n${helper_block}\\n`;\n\n magic.appendLeft(script_tag.end, text);\n\n return {\n start: script_tag.end,\n text,\n relocations: make_insertion_relocations(helper_segments, \"\\n\"),\n };\n } else {\n const text = `<script>\\n${helper_block}\\n</script>\\n\\n`;\n\n magic.prepend(text);\n\n return {\n start: 0,\n text,\n relocations: make_insertion_relocations(helper_segments, \"<script>\\n\"),\n };\n }\n}\n\nexport function create_relocations(\n replacements: Replacement[],\n helper_insertion: Insertion | undefined,\n): MarkupRelocation[] {\n const edits = [\n helper_insertion && {\n start: helper_insertion.start,\n removedLength: 0,\n insertedLength: helper_insertion.text.length,\n },\n ...replacements.map((replacement) => ({\n start: replacement.start,\n removedLength: replacement.end - replacement.start,\n insertedLength: replacement.text.length,\n })),\n ].filter(Boolean) as Array<{\n start: number;\n removedLength: number;\n insertedLength: number;\n }>;\n\n const replacement_relocations = replacements.flatMap((replacement) => {\n if (!replacement.relocation) {\n return [];\n }\n\n const delta_before = edits\n .filter((edit) => edit.start < replacement.start)\n .reduce(\n (total, edit) => total + edit.insertedLength - edit.removedLength,\n 0,\n );\n const generated_start = replacement.start + delta_before;\n\n return [{\n originalStart: replacement.relocation.originalStart,\n originalEnd: replacement.relocation.originalEnd,\n generatedStart: generated_start +\n replacement.relocation.generatedStartInReplacement,\n generatedEnd: generated_start +\n replacement.relocation.generatedEndInReplacement,\n }];\n });\n\n const helper_relocations = helper_insertion?.relocations?.map(\n (relocation) => ({\n originalStart: relocation.originalStart,\n originalEnd: relocation.originalEnd,\n generatedStart: helper_insertion.start +\n relocation.generatedStartInReplacement,\n generatedEnd: helper_insertion.start +\n relocation.generatedEndInReplacement,\n }),\n ) ?? [];\n\n return [\n ...replacement_relocations,\n ...helper_relocations,\n ];\n}\n\nfunction make_insertion_relocations(\n segments: Array<{\n text: string;\n relocation?: PendingRelocation;\n }>,\n prefix: string,\n): PendingRelocation[] {\n const relocations: PendingRelocation[] = [];\n let offset = prefix.length;\n\n for (const segment of segments) {\n if (segment.relocation) {\n relocations.push({\n originalStart: segment.relocation.originalStart,\n originalEnd: segment.relocation.originalEnd,\n generatedStartInReplacement: offset +\n segment.relocation.generatedStartInReplacement,\n generatedEndInReplacement: offset +\n segment.relocation.generatedEndInReplacement,\n });\n }\n\n offset += segment.text.length + 1;\n }\n\n return relocations;\n}\n\nfunction find_instance_script_tag(\n content: string,\n): { start: number; end: number } | undefined {\n const pattern = /<script\\b([^>]*)>([\\s\\S]*?)<\\/script\\s*>/gi;\n\n for (const match of content.matchAll(pattern)) {\n if (match.index === undefined) continue;\n\n const attrs = match[1] ?? \"\";\n if (\n /\\bcontext\\s*=\\s*[\"']module[\"']/.test(attrs) ||\n /\\bmodule\\b/.test(attrs)\n ) {\n continue;\n }\n\n const open_end = match[0].indexOf(\">\") + 1;\n return {\n start: match.index + open_end,\n end: match.index + match[0].length - \"</script>\".length,\n };\n }\n\n return undefined;\n}\n","import type { AST } from \"svelte/compiler\";\n\nimport type { MarkupCandidate, TagKind } from \"./types.ts\";\n\n/**\n * Matches sanitized placeholders back to their Svelte AST context.\n *\n * @since 2.0.0\n * @param ast - Parsed Svelte AST for the sanitized component markup.\n * @param candidates - Placeholder candidates produced by the scanner.\n * @returns Candidates paired with the markup context that determines how they\n * should be emitted.\n */\nexport function classify_candidates(\n ast: AST.Root,\n candidates: MarkupCandidate[],\n): Array<{ candidate: MarkupCandidate; kind: TagKind }> {\n const by_placeholder = new Map(\n candidates.map((candidate) => [candidate.placeholder, candidate]),\n );\n\n const classified: Array<{ candidate: MarkupCandidate; kind: TagKind }> = [];\n const matched = new Set<string>();\n\n walk_ast(ast.fragment, by_placeholder, matched, classified);\n\n return classified;\n}\n\nfunction walk_ast(\n fragment: AST.Fragment,\n candidates: Map<string, MarkupCandidate>,\n matched: Set<string>,\n classified: Array<{ candidate: MarkupCandidate; kind: TagKind }>,\n): void {\n for (const node of fragment.nodes) {\n visit_ast_node(node, candidates, matched, classified);\n }\n}\n\nfunction visit_ast_node(\n node: AST.Fragment[\"nodes\"][number],\n candidates: Map<string, MarkupCandidate>,\n matched: Set<string>,\n classified: Array<{ candidate: MarkupCandidate; kind: TagKind }>,\n): void {\n switch (node.type) {\n case \"ExpressionTag\":\n classify_expression(\n node.expression,\n \"plain\",\n candidates,\n matched,\n classified,\n );\n return;\n\n case \"IfBlock\":\n classify_expression(node.test, \"plain\", candidates, matched, classified);\n walk_ast(node.consequent, candidates, matched, classified);\n if (node.alternate) {\n walk_ast(node.alternate, candidates, matched, classified);\n }\n return;\n\n case \"EachBlock\":\n classify_expression(\n node.expression,\n \"each\",\n candidates,\n matched,\n classified,\n );\n walk_ast(node.body, candidates, matched, classified);\n if (node.fallback) {\n walk_ast(node.fallback, candidates, matched, classified);\n }\n return;\n\n case \"AwaitBlock\":\n classify_expression(\n node.expression,\n \"await\",\n candidates,\n matched,\n classified,\n );\n if (node.pending) {\n walk_ast(node.pending, candidates, matched, classified);\n }\n if (node.then) walk_ast(node.then, candidates, matched, classified);\n if (node.catch) walk_ast(node.catch, candidates, matched, classified);\n return;\n\n case \"RenderTag\":\n classify_expression(\n node.expression,\n \"render\",\n candidates,\n matched,\n classified,\n );\n return;\n\n case \"HtmlTag\":\n classify_expression(\n node.expression,\n \"plain\",\n candidates,\n matched,\n classified,\n );\n return;\n\n case \"DebugTag\":\n classify_debug_tag(node, candidates, matched, classified);\n return;\n\n case \"ConstTag\":\n case \"DeclarationTag\":\n classify_declaration_tag(node, candidates, matched, classified);\n return;\n\n case \"KeyBlock\":\n classify_expression(\n node.expression,\n \"plain\",\n candidates,\n matched,\n classified,\n );\n walk_ast(node.fragment, candidates, matched, classified);\n return;\n\n case \"RegularElement\":\n case \"Component\":\n case \"TitleElement\":\n case \"SlotElement\":\n case \"SvelteBody\":\n case \"SvelteBoundary\":\n case \"SvelteComponent\":\n case \"SvelteDocument\":\n case \"SvelteElement\":\n case \"SvelteFragment\":\n case \"SvelteHead\":\n case \"SvelteSelf\":\n case \"SvelteWindow\":\n visit_element_attributes(node, candidates, matched, classified);\n walk_ast(node.fragment, candidates, matched, classified);\n return;\n\n default:\n return;\n }\n}\n\nfunction classify_debug_tag(\n node: Extract<AST.Fragment[\"nodes\"][number], { type: \"DebugTag\" }>,\n candidates: Map<string, MarkupCandidate>,\n matched: Set<string>,\n classified: Array<{ candidate: MarkupCandidate; kind: TagKind }>,\n): void {\n const idents = node.identifiers;\n\n if (!idents || idents.length === 0) {\n return;\n }\n\n for (const ident of idents) {\n classify_expression(ident, \"plain\", candidates, matched, classified);\n }\n}\n\nfunction classify_declaration_tag(\n node: Extract<\n AST.Fragment[\"nodes\"][number],\n { type: \"ConstTag\" | \"DeclarationTag\" }\n >,\n candidates: Map<string, MarkupCandidate>,\n matched: Set<string>,\n classified: Array<{ candidate: MarkupCandidate; kind: TagKind }>,\n): void {\n for (const decl of node.declaration.declarations) {\n if (!decl.init) {\n continue;\n }\n\n classify_expression(decl.init, \"plain\", candidates, matched, classified);\n }\n}\n\ninterface ElementLikeNode {\n attributes: Array<{\n type: string;\n name?: string;\n value?: unknown;\n expression?: unknown;\n }>;\n fragment: AST.Fragment;\n}\n\nfunction visit_element_attributes(\n node: ElementLikeNode,\n candidates: Map<string, MarkupCandidate>,\n matched: Set<string>,\n classified: Array<{ candidate: MarkupCandidate; kind: TagKind }>,\n): void {\n for (const attr of node.attributes) {\n if (\n attr.type === \"Attribute\" &&\n attr.name &&\n (attr.name.startsWith(\"on:\") || /^on[a-z]/.test(attr.name))\n ) {\n visit_attribute_value(\n attr.value as\n | true\n | AST.ExpressionTag\n | Array<AST.Text | AST.ExpressionTag>,\n \"event\",\n candidates,\n matched,\n classified,\n );\n continue;\n }\n\n if (attr.type === \"OnDirective\" && attr.expression) {\n classify_expression(\n attr.expression as ExpressionLike,\n \"event\",\n candidates,\n matched,\n classified,\n );\n continue;\n }\n }\n}\n\nfunction visit_attribute_value(\n value: true | AST.ExpressionTag | Array<AST.Text | AST.ExpressionTag>,\n kind: TagKind,\n candidates: Map<string, MarkupCandidate>,\n matched: Set<string>,\n classified: Array<{ candidate: MarkupCandidate; kind: TagKind }>,\n): void {\n if (value === true) {\n return;\n }\n\n if (Array.isArray(value)) {\n for (const part of value) {\n if (part.type === \"ExpressionTag\") {\n classify_expression(\n part.expression,\n kind,\n candidates,\n matched,\n classified,\n );\n }\n }\n return;\n }\n\n classify_expression(\n value.expression,\n kind,\n candidates,\n matched,\n classified,\n );\n}\n\ntype ExpressionLike = {\n type: string;\n name?: string;\n callee?: { type: string; name?: string };\n};\n\nfunction classify_expression(\n expression: ExpressionLike | null | undefined,\n kind: TagKind,\n candidates: Map<string, MarkupCandidate>,\n matched: Set<string>,\n classified: Array<{ candidate: MarkupCandidate; kind: TagKind }>,\n): void {\n if (!expression) {\n return;\n }\n\n const candidate = find_candidate(expression, candidates);\n\n if (!candidate || matched.has(candidate.placeholder)) {\n return;\n }\n\n matched.add(candidate.placeholder);\n classified.push({ candidate, kind });\n}\n\nfunction find_candidate(\n expression: ExpressionLike,\n candidates: Map<string, MarkupCandidate>,\n): MarkupCandidate | undefined {\n if (expression.type === \"Identifier\" && expression.name) {\n return candidates.get(expression.name);\n }\n\n if (\n expression.type === \"CallExpression\" &&\n expression.callee?.type === \"Identifier\" &&\n expression.callee.name\n ) {\n return candidates.get(expression.callee.name);\n }\n\n return undefined;\n}\n","import ts from \"typescript\";\n\n/**\n * Strips an event handler arrow function down to its executable body.\n *\n * @since 2.0.0\n * @param expr - Event handler expression text from the original markup.\n * @returns Handler parameters, body text, and body offsets inside `expr`.\n */\nexport function strip_arrow_function(\n expr: string,\n): { params: string; body: string; body_start: number; body_end: number } {\n const arrow_idx = expr.indexOf(\"=>\");\n\n if (arrow_idx === -1) {\n return { params: \"()\", body: expr, body_start: 0, body_end: expr.length };\n }\n\n const params = expr.slice(0, arrow_idx).trim();\n const raw_body = expr.slice(arrow_idx + 2);\n const leading_ws = raw_body.length - raw_body.trimStart().length;\n let body_start = arrow_idx + 2 + leading_ws;\n let body_end = expr.length - (raw_body.length - raw_body.trimEnd().length);\n let body = expr.slice(body_start, body_end);\n\n if (body.startsWith(\"{\") && body.endsWith(\"}\")) {\n body_start += 1;\n body_end -= 1;\n body = body.slice(1, -1);\n }\n\n const body_leading_ws = body.length - body.trimStart().length;\n const body_trailing_ws = body.length - body.trimEnd().length;\n\n body_start += body_leading_ws;\n body_end -= body_trailing_ws;\n body = body.trim();\n\n if (body.endsWith(\";\")) {\n body = body.slice(0, -1);\n body_end -= 1;\n }\n\n return { params, body, body_start, body_end };\n}\n\n/**\n * Classifies `yield*` placement inside an event handler body.\n *\n * @example\n * ```ts\n * analyze_event_body_yield_star(\"yield* save()\");\n * ```\n *\n * @since 2.0.0\n * @param body - Event handler body text after the outer arrow has been\n * stripped.\n * @returns Whether the body has top-level yield* expressions and whether any\n * yield* appears inside a nested non-generator callback.\n */\nexport function analyze_event_body_yield_star(body: string): {\n has_top_level_yield_star: boolean;\n has_nested_invalid_yield_star: boolean;\n} {\n const wrapped = `function* __ser_event() { ${body}; }`;\n const sf = ts.createSourceFile(\n \"event.ts\",\n wrapped,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n const stmt = sf.statements[0];\n\n if (!ts.isFunctionDeclaration(stmt) || !stmt.body) {\n return {\n has_top_level_yield_star: false,\n has_nested_invalid_yield_star: /\\byield\\s*\\*/.test(body),\n };\n }\n\n const result = {\n has_top_level_yield_star: false,\n has_nested_invalid_yield_star: false,\n };\n\n visit_event_body(stmt.body, \"top_level\", result);\n\n return result;\n}\n\n/**\n * Collects free identifiers that must be captured as reactive dependencies.\n *\n * @since 2.0.0\n * @param expr_text - Markup expression text to inspect.\n * @returns Identifier names referenced by the expression.\n */\nexport function collect_free_identifiers(expr_text: string): string[] {\n const wrapped = `function* __w() { return (${expr_text}); }`;\n let sf: ts.SourceFile;\n\n try {\n sf = ts.createSourceFile(\n \"expr.ts\",\n wrapped,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n } catch {\n return [];\n }\n\n const fn = sf.statements[0];\n\n if (!ts.isFunctionDeclaration(fn) || !fn.body) {\n return [];\n }\n\n const ids: string[] = [];\n const seen = new Set<string>();\n\n visit_ids(fn.body, seen, ids);\n\n return ids;\n}\n\nfunction visit_ids(\n node: ts.Node,\n seen: Set<string>,\n ids: string[],\n): void {\n if (\n ts.isArrowFunction(node) ||\n ts.isFunctionExpression(node) ||\n ts.isFunctionDeclaration(node)\n ) {\n return;\n }\n\n if (ts.isIdentifier(node)) {\n if (\n node.text === \"yield\" ||\n node.text === \"undefined\" ||\n node.text === \"null\" ||\n node.text === \"true\" ||\n node.text === \"false\" ||\n node.text === \"this\"\n ) {\n return;\n }\n\n if (is_property_access_name(node)) {\n return;\n }\n\n if (!seen.has(node.text)) {\n seen.add(node.text);\n ids.push(node.text);\n }\n return;\n }\n\n node.forEachChild((child) => visit_ids(child, seen, ids));\n}\n\ntype EventYieldContext = \"top_level\" | \"nested_generator\" | \"nested_invalid\";\n\ninterface EventYieldAnalysis {\n has_top_level_yield_star: boolean;\n has_nested_invalid_yield_star: boolean;\n}\n\nfunction visit_event_body(\n node: ts.Node,\n context: EventYieldContext,\n result: EventYieldAnalysis,\n): void {\n if (is_yield_star_expression(node)) {\n if (context === \"top_level\") {\n result.has_top_level_yield_star = true;\n } else if (context === \"nested_invalid\") {\n result.has_nested_invalid_yield_star = true;\n }\n\n node.forEachChild((child) => visit_event_body(child, context, result));\n return;\n }\n\n if (is_nested_function_boundary(node)) {\n const next_context = is_generator_function_boundary(node)\n ? \"nested_generator\"\n : \"nested_invalid\";\n\n node.forEachChild((child) => visit_event_body(child, next_context, result));\n return;\n }\n\n node.forEachChild((child) => visit_event_body(child, context, result));\n}\n\nfunction is_nested_function_boundary(node: ts.Node): boolean {\n return (\n ts.isArrowFunction(node) ||\n ts.isFunctionExpression(node) ||\n ts.isFunctionDeclaration(node) ||\n ts.isMethodDeclaration(node) ||\n ts.isGetAccessorDeclaration(node) ||\n ts.isSetAccessorDeclaration(node)\n );\n}\n\nfunction is_generator_function_boundary(node: ts.Node): boolean {\n return (\n (ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node) ||\n ts.isMethodDeclaration(node)) &&\n node.asteriskToken !== undefined\n );\n}\n\nfunction is_yield_star_expression(node: ts.Node): boolean {\n if (ts.isYieldExpression(node)) {\n return node.asteriskToken !== undefined;\n }\n\n return (\n ts.isBinaryExpression(node) &&\n node.operatorToken.kind === ts.SyntaxKind.AsteriskToken &&\n ts.isIdentifier(node.left) &&\n node.left.text === \"yield\"\n );\n}\n\nfunction is_property_access_name(node: ts.Identifier): boolean {\n const parent = node.parent;\n\n return (\n (ts.isPropertyAccessExpression(parent) && parent.name === node) ||\n (ts.isPropertyAssignment(parent) && parent.name === node) ||\n (ts.isBindingElement(parent) && parent.propertyName === node) ||\n ts.isImportSpecifier(parent) ||\n ts.isExportSpecifier(parent)\n );\n}\n","import { HELPERS } from \"./constants.ts\";\nimport {\n collect_free_identifiers,\n strip_arrow_function,\n} from \"./expressions.ts\";\nimport type {\n HelperDeclaration,\n MarkupCandidate,\n PendingRelocation,\n Replacement,\n TagKind,\n} from \"./types.ts\";\n\n/**\n * Emits source edits for classified markup Effect expressions.\n *\n * @since 2.0.0\n * @param classified - Candidates paired with their Svelte markup context.\n * @returns Replacements ready to apply to the original component source.\n */\nexport function emit_replacements(\n classified: Array<{ candidate: MarkupCandidate; kind: TagKind }>,\n): Replacement[] {\n return classified.map(({ candidate, kind }) =>\n emit_replacement(candidate, kind)\n );\n}\n\nfunction emit_replacement(\n candidate: MarkupCandidate,\n kind: TagKind,\n): Replacement {\n const id = make_cache_id(candidate);\n const id_text = JSON.stringify(id);\n const helper_name = make_helper_name(candidate);\n\n let replacement_text: string;\n let helpers: HelperDeclaration[];\n let relocation: PendingRelocation | undefined;\n\n if (kind === \"await\") {\n const effect = make_effect_helper(candidate, helper_name);\n\n replacement_text = emit_promise_expression(id_text, effect);\n helpers = [effect.helper];\n } else if (kind === \"render\") {\n const effect = make_effect_helper(candidate, helper_name);\n\n replacement_text = emit_render_expression(id_text, effect);\n helpers = [effect.helper];\n } else if (kind === \"each\") {\n const effect = make_effect_helper(candidate, helper_name);\n\n replacement_text = emit_each_expression(id_text, effect);\n helpers = [effect.helper];\n } else if (kind === \"event\") {\n const event = strip_arrow_function(candidate.expr_text);\n replacement_text =\n `${event.params} => { void ${HELPERS.run}(function* () { ${event.body}; }); }`;\n helpers = [];\n relocation = make_relocation(candidate, replacement_text, {\n originalStart: event.body_start,\n originalEnd: event.body_end,\n generatedText: event.body,\n });\n } else {\n const effect = make_effect_helper(candidate, helper_name);\n\n replacement_text = emit_each_expression(id_text, effect);\n helpers = [effect.helper];\n }\n\n return {\n start: candidate.start,\n end: candidate.end,\n text: replacement_text,\n helpers,\n relocation,\n };\n}\n\nfunction emit_promise_expression(\n id_text: string,\n effect: EffectHelper,\n): string {\n return `${HELPERS.promise}(${id_text}, ${effect.deps_text}, () => ${effect.call})`;\n}\n\nfunction emit_render_expression(\n id_text: string,\n effect: EffectHelper,\n): string {\n return `(await ${emit_promise_expression(id_text, effect)})()`;\n}\n\nfunction emit_each_expression(\n id_text: string,\n effect: EffectHelper,\n): string {\n return `await ${emit_promise_expression(id_text, effect)}`;\n}\n\ninterface EffectHelper {\n helper: HelperDeclaration;\n call: string;\n deps_text: string;\n}\n\nfunction make_effect_helper(\n candidate: MarkupCandidate,\n helper_name: string,\n): EffectHelper {\n const deps = collect_free_identifiers(candidate.expr_text);\n const params_text = deps.join(\", \");\n const args_text = deps.join(\", \");\n const deps_text = deps.length === 0 ? \"[]\" : `[${args_text}]`;\n const call = `${helper_name}(${args_text})`;\n const text =\n `function* ${helper_name}(${params_text}) { return (${candidate.expr_text}); }`;\n const generated_start = text.indexOf(candidate.expr_text);\n\n return {\n call,\n deps_text,\n helper: {\n text,\n relocation: {\n originalStart: candidate.start,\n originalEnd: candidate.end,\n generatedStartInReplacement: generated_start,\n generatedEndInReplacement: generated_start +\n candidate.expr_text.length,\n },\n },\n };\n}\n\nfunction make_cache_id(candidate: MarkupCandidate): string {\n return `${candidate.filename}:${candidate.start}:${candidate.end}`;\n}\n\nfunction make_helper_name(candidate: MarkupCandidate): string {\n return `__ser_markup_effect_${candidate.start}_${candidate.end}`;\n}\n\nfunction make_relocation(\n candidate: MarkupCandidate,\n replacement_text: string,\n inner: {\n originalStart: number;\n originalEnd: number;\n generatedText: string;\n },\n): PendingRelocation | undefined {\n const generated_start = replacement_text.indexOf(inner.generatedText);\n\n if (generated_start === -1) {\n return undefined;\n }\n\n return {\n originalStart: candidate.start + inner.originalStart,\n originalEnd: candidate.start + inner.originalEnd,\n generatedStartInReplacement: generated_start,\n generatedEndInReplacement: generated_start + inner.generatedText.length,\n };\n}\n","/**\n * Formats a runtime-owned error message with a stable screaming-case code.\n *\n * @example\n * ```ts\n * throw new Error(make_error_message(\"DISPATCHER_DISPOSED\", \"Dispatcher has been disposed\"));\n * ```\n *\n * @since 2.0.0\n * @param code - Stable screaming-case identifier for the error category.\n * @param message - Human-readable error message without the leading code.\n * @returns The complete error message prefixed with the stable code.\n */\nexport function make_error_message(code: string, message: string): string {\n return `[${code}]: ${message}`;\n}\n\n/**\n * Base error class for all preprocessor errors emitted during script and\n * markup transformation. Carries the source filename so error messages can\n * reference the affected file.\n *\n * @since 2.0.0\n */\nexport class PreprocessError extends Error {\n /**\n * The source filename that triggered this error.\n *\n * @since 2.0.0\n */\n readonly filename: string;\n\n constructor(message: string, filename: string) {\n super(message);\n this.name = \"PreprocessError\";\n this.filename = filename;\n }\n}\n\n/**\n * Thrown when a statement mixes JavaScript `await` with Effect `yield*` work\n * that must be lowered into an `Effect.gen` program.\n *\n * @since 2.0.0\n */\nexport class AwaitInEffectWorkError extends PreprocessError {\n /**\n * The full text of the problematic statement containing mixed async work.\n *\n * @since 2.0.0\n */\n readonly statement_text: string;\n\n constructor(filename: string, statement_text: string) {\n super(\n [\n make_error_message(\n \"AWAIT_IN_EFFECT_WORK\",\n `${filename}: await cannot be mixed with yield* in Effect work.`,\n ),\n `Top-level await is supported as ordinary Svelte async rendering, but statements lowered into Effect.gen must use yield* for async Effect work.`,\n \"\",\n `Problematic statement:`,\n statement_text,\n ].join(\"\\n\"),\n filename,\n );\n this.name = \"AwaitInEffectWorkError\";\n this.statement_text = statement_text;\n }\n}\n\n/**\n * Thrown when async Effect work appears inside a Svelte rune position that\n * must stay synchronous.\n *\n * @since 2.0.0\n */\nexport class AsyncEffectInSyncRuneError extends PreprocessError {\n /**\n * The name of the rune that contained async Effect work.\n *\n * @since 2.0.0\n */\n readonly rune_name: string;\n\n /**\n * The full text of the expression that triggered the error.\n *\n * @since 2.0.0\n */\n readonly expression_text: string;\n\n constructor(rune_name: string, expression_text: string, filename: string) {\n super(\n [\n make_error_message(\n \"ASYNC_EFFECT_IN_SYNC_RUNE\",\n `${filename}: yield* cannot be used inside ${rune_name}().`,\n ),\n `${rune_name}() must stay synchronous. Do not put async Effect work inside this rune.`,\n \"\",\n `Problematic expression:`,\n expression_text,\n ].join(\"\\n\"),\n filename,\n );\n this.name = \"AsyncEffectInSyncRuneError\";\n this.rune_name = rune_name;\n this.expression_text = expression_text;\n }\n}\n\n/**\n * Thrown when async Effect work appears inside a non-generator callback nested\n * in a markup event handler.\n *\n * @example\n * ```ts\n * throw new AsyncEffectInEventCallbackError(\n * \"Component.svelte\",\n * \"Effect.try(() => yield* save())\",\n * );\n * ```\n *\n * @since 2.0.0\n */\nexport class AsyncEffectInEventCallbackError extends PreprocessError {\n /**\n * The full text of the problematic event handler body.\n *\n * @since 2.0.0\n */\n readonly expression_text: string;\n\n constructor(filename: string, expression_text: string) {\n super(\n [\n make_error_message(\n \"ASYNC_EFFECT_IN_EVENT_CALLBACK\",\n `${filename}: yield* cannot be used inside a nested non-generator callback in a markup event handler.`,\n ),\n `Move the yield* to the event handler body. Effect.try and Effect.sync callbacks are plain synchronous JavaScript; do not call Effect-returning functions inside them.`,\n \"\",\n `Run the remote Effect directly:`,\n ` onclick={() => yield* UpvotePost(id)}`,\n \"\",\n `Recover from remote failures by composing the Effect value:`,\n ` onclick={() => yield* UpvotePost(id).pipe(Effect.catch(() => Effect.void))}`,\n \"\",\n `Problematic expression:`,\n expression_text,\n ].join(\"\\n\"),\n filename,\n );\n this.name = \"AsyncEffectInEventCallbackError\";\n this.expression_text = expression_text;\n }\n}\n","import { contains_top_level_yield_star } from \"$/detect.ts\";\nimport { AsyncEffectInEventCallbackError } from \"$/error.ts\";\nimport MagicString from \"magic-string\";\nimport ts from \"typescript\";\n\nimport {\n analyze_event_body_yield_star,\n strip_arrow_function,\n} from \"./expressions.ts\";\nimport type { MarkupCandidate, TagKind } from \"./types.ts\";\n\ninterface SanitizeResult {\n code: string;\n candidates: MarkupCandidate[];\n}\n\ninterface DeclarationInitializer {\n start: number;\n end: number;\n expr_text: string;\n}\n\nexport function sanitize_markup(\n content: string,\n filename: string,\n): SanitizeResult {\n const candidates: MarkupCandidate[] = [];\n const magic = new MagicString(content);\n let helper_index = 0;\n let cursor = 0;\n\n while (cursor < content.length) {\n const open = content.indexOf(\"{\", cursor);\n if (open === -1) break;\n\n /** Skip braces inside <script> and <style> blocks. */\n if (is_inside_excluded_block(content, open)) {\n cursor = open + 1;\n continue;\n }\n\n /** Find the matching closing brace. */\n const close = find_closing_brace(content, open + 1);\n if (close === -1) {\n cursor = open + 1;\n continue;\n }\n\n const inner = content.slice(open + 1, close);\n\n const trimmed = inner.trimStart();\n const leading_ws = inner.length - trimmed.length;\n\n const tag_info = get_tag_info(trimmed);\n\n const declaration_initializers = collect_declaration_initializers(\n content,\n open,\n leading_ws,\n trimmed,\n );\n\n if (declaration_initializers.length > 0) {\n for (const initializer of declaration_initializers) {\n const placeholder = `__ser_markup_placeholder_${helper_index}`;\n helper_index += 1;\n\n candidates.push({\n placeholder,\n start: initializer.start,\n end: initializer.end,\n expr_text: initializer.expr_text,\n filename,\n key: \"plain\",\n });\n\n magic.overwrite(initializer.start, initializer.end, placeholder);\n }\n\n cursor = close + 1;\n continue;\n }\n\n let expr_body = trimmed.slice(tag_info.prefix_length);\n\n /** For @const, only use the RHS after `=` as the expression body. */\n const equal_idx = tag_info.kind === \"plain\" && trimmed.startsWith(\"@const \")\n ? expr_body.indexOf(\"=\")\n : -1;\n\n /** Check if this is an event handler (arrow function containing yield*). */\n const is_event = is_event_expression(inner);\n\n /** Determine if this brace contains yield* that needs lowering. */\n const event_yield = is_event\n ? analyze_event_yield(inner, filename)\n : undefined;\n const has_yield = event_yield?.has_top_level_yield_star ??\n contains_yield_star_in_text(expr_body);\n\n if (!has_yield) {\n cursor = close + 1;\n continue;\n }\n\n /** The expression starts after the tag prefix. For @const, after the `=`. */\n let extra_prefix = 0;\n\n if (equal_idx !== -1) {\n const after_eq_raw = expr_body.slice(equal_idx + 1);\n expr_body = after_eq_raw.trimStart();\n extra_prefix = equal_idx + 1 + (after_eq_raw.length - expr_body.length);\n }\n\n const expr_start = open + 1 + leading_ws + tag_info.prefix_length +\n extra_prefix;\n\n /** For each/await, the expression ends before ` as ` or ` then `/` catch `. */\n let expr_end = close;\n\n const key = tag_info.kind;\n\n if (key === \"each\") {\n const as_idx = expr_body.lastIndexOf(\" as \");\n if (as_idx !== -1) expr_end = expr_start + as_idx;\n }\n\n if (key === \"await\") {\n const then_idx = expr_body.indexOf(\" then \");\n const catch_idx = expr_body.indexOf(\" catch \");\n const boundary = Math.min(\n then_idx === -1 ? Infinity : then_idx,\n catch_idx === -1 ? Infinity : catch_idx,\n );\n if (boundary !== Infinity) expr_end = expr_start + boundary;\n }\n\n const expr_text = content.slice(expr_start, expr_end).trim();\n\n if (expr_text.length === 0) {\n cursor = close + 1;\n continue;\n }\n\n /** Create a placeholder and replace the expression (preserving tag prefixes). */\n const placeholder = `__ser_markup_placeholder_${helper_index}`;\n helper_index += 1;\n\n candidates.push({\n placeholder,\n start: expr_start,\n end: expr_end,\n expr_text,\n filename,\n key,\n });\n\n magic.overwrite(\n expr_start,\n expr_end,\n key === \"render\" ? `${placeholder}()` : placeholder,\n );\n\n cursor = close + 1;\n }\n\n return { code: magic.toString(), candidates };\n}\n\nfunction is_inside_excluded_block(content: string, pos: number): boolean {\n const script = find_tag_end(content, \"script\", pos);\n const style = find_tag_end(content, \"style\", pos);\n\n return (\n (script !== undefined && pos < script.end && pos > script.start) ||\n (style !== undefined && pos < style.end && pos > style.start)\n );\n}\n\nfunction find_tag_end(\n content: string,\n tag: string,\n after_pos: number,\n): { start: number; end: number } | undefined {\n const pattern = new RegExp(\n `<${tag}\\\\b[^>]*>([\\\\s\\\\S]*?)<\\\\/${tag}\\\\s*>`,\n \"gi\",\n );\n\n for (const match of content.matchAll(pattern)) {\n if (match.index === undefined) continue;\n const end_pos = match.index + match[0].length;\n if (match.index <= after_pos && after_pos < end_pos) {\n return { start: match.index, end: end_pos };\n }\n }\n\n return undefined;\n}\n\n/** Brace matching helpers for extracting complete markup expressions. */\n\nfunction find_closing_brace(content: string, start: number): number {\n let depth = 0;\n\n for (let i = start; i < content.length; i += 1) {\n const ch = content[i];\n\n if (ch === \"{\" && content[i - 1] !== \"$\") {\n depth += 1;\n } else if (ch === \"}\") {\n if (depth === 0) return i;\n depth -= 1;\n } else if (ch === \"'\" || ch === '\"' || ch === \"`\") {\n i = skip_string(content, i, ch);\n if (i === -1) return -1;\n } else if (ch === \"/\" && content[i + 1] === \"/\") {\n i = skip_line_comment(content, i);\n } else if (ch === \"/\" && content[i + 1] === \"*\") {\n i = skip_block_comment(content, i);\n if (i === -1) return -1;\n }\n }\n\n return -1;\n}\n\nfunction skip_string(content: string, start: number, quote: string): number {\n for (let i = start + 1; i < content.length; i += 1) {\n if (content[i] === \"\\\\\") {\n i += 1;\n continue;\n }\n if (content[i] === quote) return i;\n }\n return -1;\n}\n\nfunction skip_line_comment(content: string, start: number): number {\n for (let i = start + 2; i < content.length; i += 1) {\n if (content[i] === \"\\n\") return i;\n }\n return content.length;\n}\n\nfunction skip_block_comment(content: string, start: number): number {\n for (let i = start + 2; i < content.length; i += 1) {\n if (content[i] === \"*\" && content[i + 1] === \"/\") return i + 1;\n }\n return -1;\n}\n\ninterface TagInfo {\n kind: TagKind;\n prefix_length: number;\n}\n\nfunction get_tag_info(trimmed: string): TagInfo {\n if (trimmed.startsWith(\"#each \")) {\n return { kind: \"each\", prefix_length: \"#each \".length };\n }\n if (trimmed.startsWith(\"#await \")) {\n return { kind: \"await\", prefix_length: \"#await \".length };\n }\n if (trimmed.startsWith(\"@render \")) {\n return { kind: \"render\", prefix_length: \"@render \".length };\n }\n\n /** Strip prefix-only tags — the expression starts after the tag keyword. */\n if (trimmed.startsWith(\"#if \")) {\n return { kind: \"plain\", prefix_length: \"#if \".length };\n }\n if (trimmed.startsWith(\":else if \")) {\n return { kind: \"plain\", prefix_length: \":else if \".length };\n }\n if (trimmed.startsWith(\"#key \")) {\n return { kind: \"plain\", prefix_length: \"#key \".length };\n }\n if (trimmed.startsWith(\"@const \")) {\n return { kind: \"plain\", prefix_length: \"@const \".length };\n }\n if (trimmed.startsWith(\"@html \")) {\n return { kind: \"plain\", prefix_length: \"@html \".length };\n }\n if (trimmed.startsWith(\"@debug \")) {\n return { kind: \"plain\", prefix_length: \"@debug \".length };\n }\n\n return { kind: \"plain\", prefix_length: 0 };\n}\n\nfunction collect_declaration_initializers(\n content: string,\n open: number,\n leading_ws: number,\n trimmed: string,\n): DeclarationInitializer[] {\n if (!is_declaration_tag_text(trimmed)) {\n return [];\n }\n\n const source_file = ts.createSourceFile(\n \"declaration-tag.ts\",\n `${trimmed};`,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n\n const stmt = source_file.statements[0];\n\n if (!stmt || !ts.isVariableStatement(stmt)) {\n return [];\n }\n\n const tag_start = open + 1 + leading_ws;\n\n return stmt.declarationList.declarations\n .filter((decl) =>\n decl.initializer && contains_top_level_yield_star(decl.initializer)\n )\n .map((decl) => {\n const initializer = decl.initializer as ts.Expression;\n const start = tag_start + initializer.getStart(source_file);\n const end = tag_start + initializer.end;\n const expr_text = content.slice(start, end).trim();\n\n return {\n start,\n end,\n expr_text,\n };\n });\n}\n\nfunction is_declaration_tag_text(trimmed: string): boolean {\n return /^(?:const|let)\\s/.test(trimmed);\n}\n\nfunction is_event_expression(inner: string): boolean {\n const trimmed = inner.trimStart();\n\n return /^(?:\\([^)]*\\)|[A-Za-z_$][\\w$]*)\\s*=>/.test(trimmed);\n}\n\nfunction analyze_event_yield(\n inner: string,\n filename: string,\n): {\n has_top_level_yield_star: boolean;\n} {\n const event = strip_arrow_function(inner);\n const analysis = analyze_event_body_yield_star(event.body);\n\n if (analysis.has_nested_invalid_yield_star) {\n throw new AsyncEffectInEventCallbackError(filename, event.body);\n }\n\n return {\n has_top_level_yield_star: analysis.has_top_level_yield_star,\n };\n}\n\nfunction contains_yield_star_in_text(text: string): boolean {\n if (!/\\byield\\s*\\*/.test(text)) return false;\n\n try {\n const sf = ts.createSourceFile(\n \"expr.ts\",\n `const x = ${text};`,\n ts.ScriptTarget.Latest,\n true,\n ts.ScriptKind.TS,\n );\n const stmt = sf.statements[0];\n if (!ts.isVariableStatement(stmt)) return false;\n const decl = stmt.declarationList.declarations[0];\n if (!decl?.initializer) return false;\n return contains_top_level_yield_star(decl.initializer);\n } catch {\n return true;\n }\n}\n\n/** Free identifier collection helpers for generated closures. */\n","import { type AST, parse } from \"svelte/compiler\";\n\nimport MagicString from \"magic-string\";\n\nimport {\n blank_script_blocks,\n create_relocations,\n create_source_map,\n inject_helpers,\n} from \"./apply.ts\";\nimport { classify_candidates } from \"./classify.ts\";\nimport { emit_replacements } from \"./emit.ts\";\nimport { sanitize_markup } from \"./scan.ts\";\nimport type { MarkupTransformResult } from \"./types.ts\";\n\nexport type { MarkupRelocation, MarkupTransformResult } from \"./types.ts\";\n\n/**\n * Transforms Svelte markup containing `{yield* expr}` brace expressions\n * into calls to the markup runtime helpers (`value`, `promise`, `run`).\n *\n * Strategy: first find all brace expressions containing `yield*` via\n * character scanning, replace them with placeholder identifiers, then\n * parse the sanitized markup with Svelte's AST to determine the correct\n * context for each placeholder (plain expression, #each, #await, event\n * handler, etc.).\n *\n * @since 2.0.0\n * @param content - The raw `.svelte` file content.\n * @param filename - The source filename, used in error messages.\n * @returns The transformed markup and a flag indicating whether yield* was\n * found.\n */\nexport function transform_markup_effect(\n content: string,\n filename: string,\n): MarkupTransformResult {\n if (!/\\byield\\s*\\*/.test(content)) {\n return { code: content, has_yield: false };\n }\n\n /** Find all brace expressions containing yield* and replace with placeholders. */\n const work = sanitize_markup(content, filename);\n\n if (work.candidates.length === 0) {\n return { code: content, has_yield: false };\n }\n\n /** Parse the sanitized markup with Svelte's AST. Strip <script> blocks\n * first so TypeScript syntax (import type, etc.) doesn't break the parser. */\n const clean = blank_script_blocks(work.code);\n const ast = parse(clean, { filename, modern: true }) as AST.Root;\n\n /** Match placeholders to their AST context and build replacements. */\n const classified = classify_candidates(\n ast,\n work.candidates,\n );\n const replacements = emit_replacements(classified);\n const helpers = replacements.flatMap((replacement) =>\n replacement.helpers ?? []\n );\n\n const magic = new MagicString(content);\n\n replacements.sort((a, b) => b.start - a.start);\n\n for (const r of replacements) {\n magic.overwrite(r.start, r.end, r.text);\n }\n\n const helper_insertion = inject_helpers(magic, content, helpers);\n const relocations = create_relocations(replacements, helper_insertion);\n\n return {\n code: magic.toString(),\n has_yield: true,\n map: create_source_map(magic, filename),\n relocations,\n };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { n as get_dispatcher, r as reset_dispatcher, t as Dispatcher } from "./chunks/dispatcher-BSg2-ttN.js";
1
+ import { n as get_dispatcher, r as reset_dispatcher, t as Dispatcher } from "./chunks/dispatcher-g0HYqHOK.js";
2
2
  export { Dispatcher, get_dispatcher, reset_dispatcher };
package/.dist/error.d.ts CHANGED
@@ -1,3 +1,17 @@
1
+ /**
2
+ * Formats a runtime-owned error message with a stable screaming-case code.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * throw new Error(make_error_message("DISPATCHER_DISPOSED", "Dispatcher has been disposed"));
7
+ * ```
8
+ *
9
+ * @since 2.0.0
10
+ * @param code - Stable screaming-case identifier for the error category.
11
+ * @param message - Human-readable error message without the leading code.
12
+ * @returns The complete error message prefixed with the stable code.
13
+ */
14
+ export declare function make_error_message(code: string, message: string): string;
1
15
  /**
2
16
  * Base error class for all preprocessor errors emitted during script and
3
17
  * markup transformation. Carries the source filename so error messages can
@@ -15,15 +29,14 @@ export declare class PreprocessError extends Error {
15
29
  constructor(message: string, filename: string);
16
30
  }
17
31
  /**
18
- * Thrown when `await` is used at the top level of a `<script effect>` block.
19
- * Top-level `await` is not supported — users should use
20
- * `yield* Effect.promise(...)` or `yield* Effect.tryPromise(...)` instead.
32
+ * Thrown when a statement mixes JavaScript `await` with Effect `yield*` work
33
+ * that must be lowered into an `Effect.gen` program.
21
34
  *
22
35
  * @since 2.0.0
23
36
  */
24
- export declare class TopLevelAwaitError extends PreprocessError {
37
+ export declare class AwaitInEffectWorkError extends PreprocessError {
25
38
  /**
26
- * The full text of the problematic statement containing the `await`.
39
+ * The full text of the problematic statement containing mixed async work.
27
40
  *
28
41
  * @since 2.0.0
29
42
  */
@@ -31,15 +44,14 @@ export declare class TopLevelAwaitError extends PreprocessError {
31
44
  constructor(filename: string, statement_text: string);
32
45
  }
33
46
  /**
34
- * Thrown when `yield*` appears inside a Svelte rune whose semantics do not
35
- * support async expressions. Users should extract the `yield*` into a
36
- * separate `$state` binding and feed the resolved value into the rune.
47
+ * Thrown when async Effect work appears inside a Svelte rune position that
48
+ * must stay synchronous.
37
49
  *
38
50
  * @since 2.0.0
39
51
  */
40
- export declare class YieldStarInRuneError extends PreprocessError {
52
+ export declare class AsyncEffectInSyncRuneError extends PreprocessError {
41
53
  /**
42
- * The name of the rune that contained the yield* expression.
54
+ * The name of the rune that contained async Effect work.
43
55
  *
44
56
  * @since 2.0.0
45
57
  */
@@ -53,12 +65,12 @@ export declare class YieldStarInRuneError extends PreprocessError {
53
65
  constructor(rune_name: string, expression_text: string, filename: string);
54
66
  }
55
67
  /**
56
- * Thrown when an event handler contains `yield*` inside a nested callback that
57
- * is not itself a generator function.
68
+ * Thrown when async Effect work appears inside a non-generator callback nested
69
+ * in a markup event handler.
58
70
  *
59
71
  * @example
60
72
  * ```ts
61
- * throw new NestedYieldStarInEventHandlerError(
73
+ * throw new AsyncEffectInEventCallbackError(
62
74
  * "Component.svelte",
63
75
  * "Effect.try(() => yield* save())",
64
76
  * );
@@ -66,7 +78,7 @@ export declare class YieldStarInRuneError extends PreprocessError {
66
78
  *
67
79
  * @since 2.0.0
68
80
  */
69
- export declare class NestedYieldStarInEventHandlerError extends PreprocessError {
81
+ export declare class AsyncEffectInEventCallbackError extends PreprocessError {
70
82
  /**
71
83
  * The full text of the problematic event handler body.
72
84
  *
@@ -1,4 +1,4 @@
1
- import { n as get_dispatcher } from "../chunks/dispatcher-BSg2-ttN.js";
1
+ import { n as get_dispatcher } from "../chunks/dispatcher-g0HYqHOK.js";
2
2
  import { value } from "../markup/value.js";
3
3
  import { promise } from "../markup/promise.js";
4
4
  import { run } from "../markup/run.js";
@@ -1,2 +1,2 @@
1
- import { i as create_remote_command_adapter, n as create_remote_query_adapter, r as create_remote_form_adapter, t as create_remote_live_query_adapter } from "../chunks/client-BeOE81fW.js";
1
+ import { i as create_remote_command_adapter, n as create_remote_query_adapter, r as create_remote_form_adapter, t as create_remote_live_query_adapter } from "../chunks/client-zavjI3Qd.js";
2
2
  export { create_remote_command_adapter, create_remote_form_adapter, create_remote_live_query_adapter, create_remote_query_adapter };
@@ -1,4 +1,4 @@
1
- import { n as get_dispatcher } from "../chunks/dispatcher-BSg2-ttN.js";
1
+ import { n as get_dispatcher } from "../chunks/dispatcher-g0HYqHOK.js";
2
2
  //#region src/markup/promise.ts
3
3
  /**
4
4
  * Runtime helper emitted by the markup preprocessor for
@@ -1,4 +1,4 @@
1
- import { n as get_dispatcher } from "../chunks/dispatcher-BSg2-ttN.js";
1
+ import { n as get_dispatcher } from "../chunks/dispatcher-g0HYqHOK.js";
2
2
  import { Effect } from "effect";
3
3
  //#region src/markup/run.ts
4
4
  /**
@@ -1,2 +1,2 @@
1
- import { t as transform_markup_effect } from "../chunks/transform-BtlxgJrg.js";
1
+ import { t as transform_markup_effect } from "../chunks/transform-BguSlVDO.js";
2
2
  export { transform_markup_effect };
@@ -1,4 +1,4 @@
1
- import { n as get_dispatcher } from "../chunks/dispatcher-BSg2-ttN.js";
1
+ import { n as get_dispatcher } from "../chunks/dispatcher-g0HYqHOK.js";
2
2
  //#region src/markup/value.ts
3
3
  /**
4
4
  * Runtime helper emitted by the markup preprocessor for `{yield* expr}`
package/.dist/mod.d.ts CHANGED
@@ -165,7 +165,7 @@ export { is_form_error, is_remote_http_error, is_remote_transport_error, is_remo
165
165
  /** Re-export app setup helpers so users can import them from root. */
166
166
  export { effect, type EffectOptions } from "./vite.js";
167
167
  /** Re-export server helper types from the root entrypoint. */
168
- export type { EffectLike, EffectRemoteBatchHandler, EffectRemoteCommand, EffectRemoteForm, EffectRemoteFunction, EffectRemoteLiveQuery, EffectRemoteLiveQueryFunction, EffectRemoteLiveSource, EffectRemoteQuery, EffectRemoteQueryFunction, FormInvalid, PrerenderOptions, QueryBatchFactory, QueryFactory, QueryLiveFactory, RemoteLiveHandler, RemoteFormHandler, RemoteHandler, SchemaInput, CommandFactory, FormFactory, PrerenderFactory, ServerRuntimeFactory, StandardSchema, } from "./server/types.js";
168
+ export type { CommandFactory, EffectLike, EffectRemoteBatchHandler, EffectRemoteCommand, EffectRemoteForm, EffectRemoteFunction, EffectRemoteLiveQuery, EffectRemoteLiveQueryFunction, EffectRemoteLiveSource, EffectRemoteQuery, EffectRemoteQueryFunction, FormFactory, FormInvalid, PrerenderFactory, PrerenderOptions, QueryBatchFactory, QueryFactory, QueryLiveFactory, RemoteFormHandler, RemoteHandler, RemoteLiveHandler, SchemaInput, ServerRuntimeFactory, StandardSchema, } from "./server/types.js";
169
169
  /**
170
170
  * Creates the Svelte preprocessor that lowers script and markup `yield*`
171
171
  * expressions. The heavy transform module is loaded lazily so browser imports
package/.dist/mod.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as Dispatcher } from "./chunks/dispatcher-BSg2-ttN.js";
1
+ import { t as Dispatcher } from "./chunks/dispatcher-g0HYqHOK.js";
2
2
  import { is_form_error, is_remote_http_error, is_remote_transport_error, is_remote_validation_error } from "./remote/shared.js";
3
3
  import { effect } from "./vite.js";
4
4
  //#region src/mod.ts
@@ -182,7 +182,7 @@ function make_server_only_function(name) {
182
182
  };
183
183
  }
184
184
  function make_server_only_error(name) {
185
- return /* @__PURE__ */ new Error(`${name} is only available in SvelteKit server files. Ensure the SER Vite plugin is enabled so root imports are rewritten to \`svelte-effect-runtime/server\` before evaluation.`);
185
+ return /* @__PURE__ */ new Error(`[SERVER_ONLY_IMPORT]: ${name} is only available in SvelteKit server files. Ensure the SER Vite plugin is enabled so root imports are rewritten to \`svelte-effect-runtime/server\` before evaluation.`);
186
186
  }
187
187
  //#endregion
188
188
  export { ClientRuntime, Command, Form, Prerender, Query, RequestEvent, ServerRuntime, effect, get_server_runtime_or_throw, is_form_error, is_remote_http_error, is_remote_transport_error, is_remote_validation_error, preprocess };
package/.dist/mod.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","names":[],"sources":["../../modules/svelte-effect-runtime/src/mod.ts"],"sourcesContent":["import { Dispatcher as InternalDispatcher } from \"$/dispatcher.ts\";\nimport type { RequestEvent as RequestEventShape } from \"$/server/runtime.ts\";\nimport type {\n CommandFactory,\n FormFactory,\n PrerenderFactory,\n QueryFactory,\n ServerRuntimeFactory,\n} from \"$/server/types.ts\";\nimport type { Context, Layer, ManagedRuntime } from \"effect\";\n\n/**\n * Result returned by the root Svelte markup preprocessor hook.\n *\n * @since 2.0.0\n */\ninterface MarkupResult {\n code: string;\n}\n\n/**\n * Root preprocessor group shape. The root export keeps transform code lazy so\n * client imports do not pull parser-only dependencies into the browser.\n *\n * @since 2.0.0\n */\ninterface PreprocessGroup {\n name: string;\n markup(\n options: { content: string; filename?: string },\n ): MarkupResult | Promise<MarkupResult>;\n}\n\n/**\n * Public API surface for `svelte-effect-runtime`.\n *\n * Call {@link ClientRuntime.make} in `hooks.client.ts`, call\n * {@link ServerRuntime.make} in `hooks.server.ts`, and let the Vite plugin\n * route server-only helpers to the server entrypoint automatically.\n *\n * @module\n */\n\n/**\n * Client-side runtime singleton. Call `ClientRuntime.make(layer?)` once\n * in `hooks.client.ts` to provide services to every component's effect\n * blocks.\n *\n * If never called, a default empty-layer runtime is created lazily on\n * the first `yield*` expression.\n *\n * @example\n * ```ts\n * import { ClientRuntime } from \"svelte-effect-runtime\";\n * import { Db } from \"./db.ts\";\n *\n * ClientRuntime.make(Db.Live);\n * ```\n *\n * @since 2.0.0\n */\nexport class ClientRuntime {\n /**\n * Build and cache the client-side dispatcher runtime.\n *\n * @since 2.0.0\n * @param layer - Optional Effect layer to provide to the runtime.\n */\n static make<R = never>(layer?: Layer.Layer<R>): void {\n InternalDispatcher.make(layer);\n }\n}\n\n/**\n * Server-side runtime singleton export. In SvelteKit server files the Vite\n * plugin rewrites root imports to `svelte-effect-runtime/server`, so this\n * name resolves to the real server implementation before it is evaluated.\n *\n * @example\n * ```ts\n * import { ServerRuntime } from \"svelte-effect-runtime\";\n *\n * ServerRuntime.make();\n * ```\n *\n * @since 2.0.0\n */\nexport const ServerRuntime: ServerRuntimeFactory = make_server_only_class(\n \"ServerRuntime\",\n) as never;\n\n/**\n * Remote query factory export for `.remote.ts` files imported from the root\n * entrypoint. The Vite plugin rewrites it to the real server implementation.\n *\n * @example\n * ```ts\n * import { Query } from \"svelte-effect-runtime\";\n *\n * export const GetPosts = Query(Effect.succeed([]));\n * ```\n *\n * @since 2.0.0\n */\nexport const Query: QueryFactory = Object.assign(\n make_server_only_function(\"Query\"),\n {\n batch: make_server_only_function(\"Query.batch\"),\n live: make_server_only_function(\"Query.live\"),\n },\n) as never;\n\n/**\n * Remote command factory export for `.remote.ts` files imported from the root\n * entrypoint. The Vite plugin rewrites it to the real server implementation.\n *\n * @example\n * ```ts\n * import { Command } from \"svelte-effect-runtime\";\n *\n * export const SavePost = Command(Schema.String, (id) => Effect.succeed(id));\n * ```\n *\n * @since 2.0.0\n */\nexport const Command: CommandFactory = make_server_only_function(\n \"Command\",\n) as never;\n\n/**\n * Remote form factory export for `.remote.ts` files imported from the root\n * entrypoint. The Vite plugin rewrites it to the real server implementation.\n *\n * @example\n * ```ts\n * import { Form } from \"svelte-effect-runtime\";\n *\n * export const CreatePost = Form(PostInput, ({ data }) => Effect.succeed(data));\n * ```\n *\n * @since 2.0.0\n */\nexport const Form: FormFactory = make_server_only_function(\n \"Form\",\n) as never;\n\n/**\n * Remote prerender factory export for `.remote.ts` files imported from the\n * root entrypoint. The Vite plugin rewrites it to the real server\n * implementation.\n *\n * @example\n * ```ts\n * import { Prerender } from \"svelte-effect-runtime\";\n *\n * export const GetBuildInfo = Prerender(() => Effect.succeed(\"ready\"));\n * ```\n *\n * @since 2.0.0\n */\nexport const Prerender: PrerenderFactory = make_server_only_function(\n \"Prerender\",\n) as never;\n\n/**\n * Current SvelteKit request event service export for `.remote.ts` files\n * imported from the root entrypoint. The Vite plugin rewrites it to the real\n * server implementation.\n *\n * @example\n * ```ts\n * import { RequestEvent } from \"svelte-effect-runtime\";\n *\n * const event = yield* RequestEvent;\n * ```\n *\n * @since 2.0.0\n */\nexport const RequestEvent: Context.Reference<RequestEventShape> =\n make_server_only_function(\"RequestEvent\") as never;\n\n/**\n * Returns the active server runtime when imported from a server file. The Vite\n * plugin rewrites root imports to the real server implementation.\n *\n * @example\n * ```ts\n * import { get_server_runtime_or_throw } from \"svelte-effect-runtime\";\n *\n * const runtime = get_server_runtime_or_throw();\n * ```\n *\n * @since 2.0.0\n */\nexport const get_server_runtime_or_throw: () => ManagedRuntime.ManagedRuntime<\n unknown,\n never\n> = make_server_only_function(\"get_server_runtime_or_throw\") as never;\n\n/** Re-export error types users need for typed catch handlers. */\nexport type {\n FormError,\n FormIssue,\n RemoteFailure,\n RemoteHttpError,\n RemoteTransportError,\n RemoteValidationError,\n} from \"$/remote/shared.ts\";\n\nexport {\n is_form_error,\n is_remote_http_error,\n is_remote_transport_error,\n is_remote_validation_error,\n} from \"$/remote/shared.ts\";\n\n/** Re-export app setup helpers so users can import them from root. */\nexport { effect, type EffectOptions } from \"$/vite.ts\";\n\n/** Re-export server helper types from the root entrypoint. */\nexport type {\n EffectLike,\n EffectRemoteBatchHandler,\n EffectRemoteCommand,\n EffectRemoteForm,\n EffectRemoteFunction,\n EffectRemoteLiveQuery,\n EffectRemoteLiveQueryFunction,\n EffectRemoteLiveSource,\n EffectRemoteQuery,\n EffectRemoteQueryFunction,\n FormInvalid,\n PrerenderOptions,\n QueryBatchFactory,\n QueryFactory,\n QueryLiveFactory,\n RemoteLiveHandler,\n RemoteFormHandler,\n RemoteHandler,\n SchemaInput,\n CommandFactory,\n FormFactory,\n PrerenderFactory,\n ServerRuntimeFactory,\n StandardSchema,\n} from \"$/server/types.ts\";\n\n/**\n * Creates the Svelte preprocessor that lowers script and markup `yield*`\n * expressions. The heavy transform module is loaded lazily so browser imports\n * from the package root stay client-safe.\n *\n * @example\n * ```js\n * import { preprocess } from \"svelte-effect-runtime\";\n *\n * export default {\n * preprocess: [preprocess()],\n * };\n * ```\n *\n * @since 2.0.0\n * @returns A Svelte preprocessor group with an async markup hook.\n */\nexport function preprocess(): PreprocessGroup {\n return {\n name: \"svelte-effect-runtime\",\n\n async markup(options: { content: string; filename?: string }) {\n const runtime = await import(\"./runtime/preprocess.ts\");\n const group = runtime.preprocess();\n\n return await group.markup(options);\n },\n };\n}\n\nfunction make_server_only_class(name: string): unknown {\n return class ServerOnlyRuntime {\n static make(): never {\n throw make_server_only_error(name);\n }\n };\n}\n\nfunction make_server_only_function(name: string): (...args: unknown[]) => never {\n return (..._args: unknown[]): never => {\n throw make_server_only_error(name);\n };\n}\n\nfunction make_server_only_error(name: string): Error {\n return new Error(\n `${name} is only available in SvelteKit server files. ` +\n `Ensure the SER Vite plugin is enabled so root imports are rewritten ` +\n `to \\`svelte-effect-runtime/server\\` before evaluation.`,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,IAAa,gBAAb,MAA2B;;;;;;;CAOzB,OAAO,KAAgB,OAA8B;AACnD,aAAmB,KAAK,MAAM;;;;;;;;;;;;;;;;;AAkBlC,MAAa,gBAAsC,uBACjD,gBACD;;;;;;;;;;;;;;AAeD,MAAa,QAAsB,OAAO,OACxC,0BAA0B,QAAQ,EAClC;CACE,OAAO,0BAA0B,cAAc;CAC/C,MAAM,0BAA0B,aAAa;CAC9C,CACF;;;;;;;;;;;;;;AAeD,MAAa,UAA0B,0BACrC,UACD;;;;;;;;;;;;;;AAeD,MAAa,OAAoB,0BAC/B,OACD;;;;;;;;;;;;;;;AAgBD,MAAa,YAA8B,0BACzC,YACD;;;;;;;;;;;;;;;AAgBD,MAAa,eACX,0BAA0B,eAAe;;;;;;;;;;;;;;AAe3C,MAAa,8BAGT,0BAA0B,8BAA8B;;;;;;;;;;;;;;;;;;AAmE5D,SAAgB,aAA8B;AAC5C,QAAO;EACL,MAAM;EAEN,MAAM,OAAO,SAAiD;AAI5D,UAAO,OAHS,MAAM,OAAO,4BACP,YAAY,CAEf,OAAO,QAAQ;;EAErC;;AAGH,SAAS,uBAAuB,MAAuB;AACrD,QAAO,MAAM,kBAAkB;EAC7B,OAAO,OAAc;AACnB,SAAM,uBAAuB,KAAK;;;;AAKxC,SAAS,0BAA0B,MAA6C;AAC9E,SAAQ,GAAG,UAA4B;AACrC,QAAM,uBAAuB,KAAK;;;AAItC,SAAS,uBAAuB,MAAqB;AACnD,wBAAO,IAAI,MACT,GAAG,KAAK,0KAGT"}
1
+ {"version":3,"file":"mod.js","names":[],"sources":["../../modules/svelte-effect-runtime/src/mod.ts"],"sourcesContent":["import { Dispatcher as InternalDispatcher } from \"$/dispatcher.ts\";\nimport type { RequestEvent as RequestEventShape } from \"$/server/runtime.ts\";\nimport type {\n CommandFactory,\n FormFactory,\n PrerenderFactory,\n QueryFactory,\n ServerRuntimeFactory,\n} from \"$/server/types.ts\";\nimport type { Context, Layer, ManagedRuntime } from \"effect\";\n\n/**\n * Result returned by the root Svelte markup preprocessor hook.\n *\n * @since 2.0.0\n */\ninterface MarkupResult {\n code: string;\n}\n\n/**\n * Root preprocessor group shape. The root export keeps transform code lazy so\n * client imports do not pull parser-only dependencies into the browser.\n *\n * @since 2.0.0\n */\ninterface PreprocessGroup {\n name: string;\n markup(\n options: { content: string; filename?: string },\n ): MarkupResult | Promise<MarkupResult>;\n}\n\n/**\n * Public API surface for `svelte-effect-runtime`.\n *\n * Call {@link ClientRuntime.make} in `hooks.client.ts`, call\n * {@link ServerRuntime.make} in `hooks.server.ts`, and let the Vite plugin\n * route server-only helpers to the server entrypoint automatically.\n *\n * @module\n */\n\n/**\n * Client-side runtime singleton. Call `ClientRuntime.make(layer?)` once\n * in `hooks.client.ts` to provide services to every component's effect\n * blocks.\n *\n * If never called, a default empty-layer runtime is created lazily on\n * the first `yield*` expression.\n *\n * @example\n * ```ts\n * import { ClientRuntime } from \"svelte-effect-runtime\";\n * import { Db } from \"./db.ts\";\n *\n * ClientRuntime.make(Db.Live);\n * ```\n *\n * @since 2.0.0\n */\nexport class ClientRuntime {\n /**\n * Build and cache the client-side dispatcher runtime.\n *\n * @since 2.0.0\n * @param layer - Optional Effect layer to provide to the runtime.\n */\n static make<R = never>(layer?: Layer.Layer<R>): void {\n InternalDispatcher.make(layer);\n }\n}\n\n/**\n * Server-side runtime singleton export. In SvelteKit server files the Vite\n * plugin rewrites root imports to `svelte-effect-runtime/server`, so this\n * name resolves to the real server implementation before it is evaluated.\n *\n * @example\n * ```ts\n * import { ServerRuntime } from \"svelte-effect-runtime\";\n *\n * ServerRuntime.make();\n * ```\n *\n * @since 2.0.0\n */\nexport const ServerRuntime: ServerRuntimeFactory = make_server_only_class(\n \"ServerRuntime\",\n) as never;\n\n/**\n * Remote query factory export for `.remote.ts` files imported from the root\n * entrypoint. The Vite plugin rewrites it to the real server implementation.\n *\n * @example\n * ```ts\n * import { Query } from \"svelte-effect-runtime\";\n *\n * export const GetPosts = Query(Effect.succeed([]));\n * ```\n *\n * @since 2.0.0\n */\nexport const Query: QueryFactory = Object.assign(\n make_server_only_function(\"Query\"),\n {\n batch: make_server_only_function(\"Query.batch\"),\n live: make_server_only_function(\"Query.live\"),\n },\n) as never;\n\n/**\n * Remote command factory export for `.remote.ts` files imported from the root\n * entrypoint. The Vite plugin rewrites it to the real server implementation.\n *\n * @example\n * ```ts\n * import { Command } from \"svelte-effect-runtime\";\n *\n * export const SavePost = Command(Schema.String, (id) => Effect.succeed(id));\n * ```\n *\n * @since 2.0.0\n */\nexport const Command: CommandFactory = make_server_only_function(\n \"Command\",\n) as never;\n\n/**\n * Remote form factory export for `.remote.ts` files imported from the root\n * entrypoint. The Vite plugin rewrites it to the real server implementation.\n *\n * @example\n * ```ts\n * import { Form } from \"svelte-effect-runtime\";\n *\n * export const CreatePost = Form(PostInput, ({ data }) => Effect.succeed(data));\n * ```\n *\n * @since 2.0.0\n */\nexport const Form: FormFactory = make_server_only_function(\n \"Form\",\n) as never;\n\n/**\n * Remote prerender factory export for `.remote.ts` files imported from the\n * root entrypoint. The Vite plugin rewrites it to the real server\n * implementation.\n *\n * @example\n * ```ts\n * import { Prerender } from \"svelte-effect-runtime\";\n *\n * export const GetBuildInfo = Prerender(() => Effect.succeed(\"ready\"));\n * ```\n *\n * @since 2.0.0\n */\nexport const Prerender: PrerenderFactory = make_server_only_function(\n \"Prerender\",\n) as never;\n\n/**\n * Current SvelteKit request event service export for `.remote.ts` files\n * imported from the root entrypoint. The Vite plugin rewrites it to the real\n * server implementation.\n *\n * @example\n * ```ts\n * import { RequestEvent } from \"svelte-effect-runtime\";\n *\n * const event = yield* RequestEvent;\n * ```\n *\n * @since 2.0.0\n */\nexport const RequestEvent: Context.Reference<RequestEventShape> =\n make_server_only_function(\"RequestEvent\") as never;\n\n/**\n * Returns the active server runtime when imported from a server file. The Vite\n * plugin rewrites root imports to the real server implementation.\n *\n * @example\n * ```ts\n * import { get_server_runtime_or_throw } from \"svelte-effect-runtime\";\n *\n * const runtime = get_server_runtime_or_throw();\n * ```\n *\n * @since 2.0.0\n */\nexport const get_server_runtime_or_throw: () => ManagedRuntime.ManagedRuntime<\n unknown,\n never\n> = make_server_only_function(\"get_server_runtime_or_throw\") as never;\n\n/** Re-export error types users need for typed catch handlers. */\nexport type {\n FormError,\n FormIssue,\n RemoteFailure,\n RemoteHttpError,\n RemoteTransportError,\n RemoteValidationError,\n} from \"$/remote/shared.ts\";\n\nexport {\n is_form_error,\n is_remote_http_error,\n is_remote_transport_error,\n is_remote_validation_error,\n} from \"$/remote/shared.ts\";\n\n/** Re-export app setup helpers so users can import them from root. */\nexport { effect, type EffectOptions } from \"$/vite.ts\";\n\n/** Re-export server helper types from the root entrypoint. */\nexport type {\n CommandFactory,\n EffectLike,\n EffectRemoteBatchHandler,\n EffectRemoteCommand,\n EffectRemoteForm,\n EffectRemoteFunction,\n EffectRemoteLiveQuery,\n EffectRemoteLiveQueryFunction,\n EffectRemoteLiveSource,\n EffectRemoteQuery,\n EffectRemoteQueryFunction,\n FormFactory,\n FormInvalid,\n PrerenderFactory,\n PrerenderOptions,\n QueryBatchFactory,\n QueryFactory,\n QueryLiveFactory,\n RemoteFormHandler,\n RemoteHandler,\n RemoteLiveHandler,\n SchemaInput,\n ServerRuntimeFactory,\n StandardSchema,\n} from \"$/server/types.ts\";\n\n/**\n * Creates the Svelte preprocessor that lowers script and markup `yield*`\n * expressions. The heavy transform module is loaded lazily so browser imports\n * from the package root stay client-safe.\n *\n * @example\n * ```js\n * import { preprocess } from \"svelte-effect-runtime\";\n *\n * export default {\n * preprocess: [preprocess()],\n * };\n * ```\n *\n * @since 2.0.0\n * @returns A Svelte preprocessor group with an async markup hook.\n */\nexport function preprocess(): PreprocessGroup {\n return {\n name: \"svelte-effect-runtime\",\n\n async markup(options: { content: string; filename?: string }) {\n const runtime = await import(\"./runtime/preprocess.ts\");\n const group = runtime.preprocess();\n\n return await group.markup(options);\n },\n };\n}\n\nfunction make_server_only_class(name: string): unknown {\n return class ServerOnlyRuntime {\n static make(): never {\n throw make_server_only_error(name);\n }\n };\n}\n\nfunction make_server_only_function(\n name: string,\n): (...args: unknown[]) => never {\n return (..._args: unknown[]): never => {\n throw make_server_only_error(name);\n };\n}\n\nfunction make_server_only_error(name: string): Error {\n return new Error(\n `[SERVER_ONLY_IMPORT]: ${name} is only available in SvelteKit server files. ` +\n `Ensure the SER Vite plugin is enabled so root imports are rewritten ` +\n `to \\`svelte-effect-runtime/server\\` before evaluation.`,\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,IAAa,gBAAb,MAA2B;;;;;;;CAOzB,OAAO,KAAgB,OAA8B;AACnD,aAAmB,KAAK,MAAM;;;;;;;;;;;;;;;;;AAkBlC,MAAa,gBAAsC,uBACjD,gBACD;;;;;;;;;;;;;;AAeD,MAAa,QAAsB,OAAO,OACxC,0BAA0B,QAAQ,EAClC;CACE,OAAO,0BAA0B,cAAc;CAC/C,MAAM,0BAA0B,aAAa;CAC9C,CACF;;;;;;;;;;;;;;AAeD,MAAa,UAA0B,0BACrC,UACD;;;;;;;;;;;;;;AAeD,MAAa,OAAoB,0BAC/B,OACD;;;;;;;;;;;;;;;AAgBD,MAAa,YAA8B,0BACzC,YACD;;;;;;;;;;;;;;;AAgBD,MAAa,eACX,0BAA0B,eAAe;;;;;;;;;;;;;;AAe3C,MAAa,8BAGT,0BAA0B,8BAA8B;;;;;;;;;;;;;;;;;;AAmE5D,SAAgB,aAA8B;AAC5C,QAAO;EACL,MAAM;EAEN,MAAM,OAAO,SAAiD;AAI5D,UAAO,OAHS,MAAM,OAAO,4BACP,YAAY,CAEf,OAAO,QAAQ;;EAErC;;AAGH,SAAS,uBAAuB,MAAuB;AACrD,QAAO,MAAM,kBAAkB;EAC7B,OAAO,OAAc;AACnB,SAAM,uBAAuB,KAAK;;;;AAKxC,SAAS,0BACP,MAC+B;AAC/B,SAAQ,GAAG,UAA4B;AACrC,QAAM,uBAAuB,KAAK;;;AAItC,SAAS,uBAAuB,MAAqB;AACnD,wBAAO,IAAI,MACT,yBAAyB,KAAK,0KAG/B"}
@@ -4,12 +4,11 @@ import ts from "typescript";
4
4
  *
5
5
  * @since 2.0.0
6
6
  * @param has_effect_import - Whether the user already imports `Effect`.
7
- * @param has_onmount_import - Whether the user already imports `onMount`.
8
7
  * @param has_dispatcher_import - Whether the user already imports
9
8
  * `get_dispatcher`.
10
9
  * @returns Newline-separated import statements to inject.
11
10
  */
12
- export declare function make_imports(has_effect_import: boolean, has_onmount_import: boolean, has_dispatcher_import: boolean): string;
11
+ export declare function make_imports(has_effect_import: boolean, has_dispatcher_import: boolean): string;
13
12
  /**
14
13
  * Checks whether a source file imports a local binding from a module.
15
14
  *
@@ -3,7 +3,7 @@ export type { BlockRef, ScriptTransformResult } from "./types.js";
3
3
  /**
4
4
  * Transforms a `<script effect>` body by extracting top-level `yield*`
5
5
  * expressions into `$state` temp bindings and wrapping the lowered
6
- * assignments in an `Effect.gen` block that runs on mount.
6
+ * assignments in a dependency-tracked `$effect` block.
7
7
  *
8
8
  * @example
9
9
  * ```ts
@@ -1,5 +1,5 @@
1
- import ts from "typescript";
2
1
  import type { LoweredStatement, ScriptLoweringContext } from "./types.js";
2
+ import ts from "typescript";
3
3
  /**
4
4
  * Delegates a statement to the correct lowerer based on syntax kind.
5
5
  *
@@ -0,0 +1,24 @@
1
+ import ts from "typescript";
2
+ /**
3
+ * Validates that `yield*` only appears in rune positions the script-effect
4
+ * transform can lower without changing the rune's normal Svelte contract.
5
+ *
6
+ * @since 2.0.0
7
+ * @param node - AST node to scan.
8
+ * @param content - Original script source used for diagnostics.
9
+ * @param filename - Source filename used for diagnostics.
10
+ * @returns Nothing.
11
+ */
12
+ export declare function validate_rune_yield_usage(node: ts.Node, content: string, filename: string): void;
13
+ /**
14
+ * Identifies `$state(...)` and `$state.raw(...)` initializer calls.
15
+ *
16
+ * @since 2.0.0
17
+ * @param expr - Expression to classify.
18
+ * @param content - Original script source used to preserve argument text.
19
+ * @returns State rune details when the expression is a state initializer.
20
+ */
21
+ export declare function get_state_rune_initializer(expr: ts.Expression, content: string): {
22
+ rune_name: "$state" | "$state.raw";
23
+ value_text: string;
24
+ } | undefined;
@@ -1,8 +1,9 @@
1
+ import type { EffectBlock } from "./types.js";
1
2
  /**
2
- * Builds the runtime block appended to lowered script effect code.
3
+ * Builds the runtime blocks appended to lowered script effect code.
3
4
  *
4
5
  * @since 2.0.0
5
- * @param assignments - Effect-body assignment strings.
6
- * @returns Full `Effect.gen` plus `onMount` block.
6
+ * @param blocks - Effect bodies and dependency reads to emit.
7
+ * @returns Full `$effect` blocks that fork generated `Effect.gen` programs.
7
8
  */
8
- export declare function make_runtime_block(assignments: string[]): string;
9
+ export declare function make_runtime_block(blocks: EffectBlock[]): string;
@@ -42,14 +42,26 @@ export interface LoweredStatement {
42
42
  temps: TempBinding[];
43
43
  /** The rewritten statement text with yield* replaced by temp refs. */
44
44
  rewritten_text: string;
45
- /** The assignments to emit in the effect body (includes `yield*`). */
46
- effect_assignments: string[];
45
+ /** Effect bodies to emit in dependency-tracked runtime blocks. */
46
+ effect_blocks: EffectBlock[];
47
47
  /** Original statement range to replace in the source. */
48
48
  range: {
49
49
  start: number;
50
50
  end: number;
51
51
  };
52
52
  }
53
+ /**
54
+ * Describes a generated script effect body and the identifiers it reads
55
+ * synchronously for Svelte dependency tracking.
56
+ *
57
+ * @since 2.0.0
58
+ */
59
+ export interface EffectBlock {
60
+ /** Statements to emit inside the generated `Effect.gen` body. */
61
+ statements: string[];
62
+ /** Identifier reads that should rerun this block when they change. */
63
+ deps: string[];
64
+ }
53
65
  /**
54
66
  * Describes how a single expression was lowered.
55
67
  *
@@ -58,7 +70,7 @@ export interface LoweredStatement {
58
70
  export interface LoweredExpression {
59
71
  temps: TempBinding[];
60
72
  rewritten_expr: string;
61
- effect_assignments: string[];
73
+ effect_blocks: EffectBlock[];
62
74
  }
63
75
  /**
64
76
  * Stateful services used while lowering one script block.
@@ -1,3 +1,3 @@
1
- import { t as transform_markup_effect } from "./chunks/transform-BtlxgJrg.js";
2
- import { t as transform_script_effect } from "./chunks/preprocess-BZyUYWY7.js";
1
+ import { t as transform_markup_effect } from "./chunks/transform-BguSlVDO.js";
2
+ import { t as transform_script_effect } from "./chunks/preprocess-BeZqJxso.js";
3
3
  export { transform_markup_effect, transform_script_effect };
@@ -1,2 +1,2 @@
1
- import { i as create_remote_command_adapter, n as create_remote_query_adapter, r as create_remote_form_adapter, t as create_remote_live_query_adapter } from "../chunks/client-BeOE81fW.js";
1
+ import { i as create_remote_command_adapter, n as create_remote_query_adapter, r as create_remote_form_adapter, t as create_remote_live_query_adapter } from "../chunks/client-zavjI3Qd.js";
2
2
  export { create_remote_command_adapter, create_remote_form_adapter, create_remote_live_query_adapter, create_remote_query_adapter };