@reactra/babel-plugin 0.1.0-alpha.0

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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/dist/ast/index.d.ts +2 -0
  4. package/dist/ast/index.d.ts.map +1 -0
  5. package/dist/ast/index.js +3 -0
  6. package/dist/ast/index.js.map +1 -0
  7. package/dist/ast/nodes.d.ts +437 -0
  8. package/dist/ast/nodes.d.ts.map +1 -0
  9. package/dist/ast/nodes.js +35 -0
  10. package/dist/ast/nodes.js.map +1 -0
  11. package/dist/behaviours/index.d.ts +18 -0
  12. package/dist/behaviours/index.d.ts.map +1 -0
  13. package/dist/behaviours/index.js +36 -0
  14. package/dist/behaviours/index.js.map +1 -0
  15. package/dist/behaviours/plugin.d.ts +22 -0
  16. package/dist/behaviours/plugin.d.ts.map +1 -0
  17. package/dist/behaviours/plugin.js +70 -0
  18. package/dist/behaviours/plugin.js.map +1 -0
  19. package/dist/behaviours/replayable.d.ts +10 -0
  20. package/dist/behaviours/replayable.d.ts.map +1 -0
  21. package/dist/behaviours/replayable.js +86 -0
  22. package/dist/behaviours/replayable.js.map +1 -0
  23. package/dist/behaviours/types.d.ts +77 -0
  24. package/dist/behaviours/types.d.ts.map +1 -0
  25. package/dist/behaviours/types.js +10 -0
  26. package/dist/behaviours/types.js.map +1 -0
  27. package/dist/behaviours/undoable.d.ts +10 -0
  28. package/dist/behaviours/undoable.d.ts.map +1 -0
  29. package/dist/behaviours/undoable.js +62 -0
  30. package/dist/behaviours/undoable.js.map +1 -0
  31. package/dist/compile.d.ts +69 -0
  32. package/dist/compile.d.ts.map +1 -0
  33. package/dist/compile.js +75 -0
  34. package/dist/compile.js.map +1 -0
  35. package/dist/conventions/index.d.ts +110 -0
  36. package/dist/conventions/index.d.ts.map +1 -0
  37. package/dist/conventions/index.js +193 -0
  38. package/dist/conventions/index.js.map +1 -0
  39. package/dist/index.d.ts +48 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +77 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/passes/index.d.ts +5 -0
  44. package/dist/passes/index.d.ts.map +1 -0
  45. package/dist/passes/index.js +6 -0
  46. package/dist/passes/index.js.map +1 -0
  47. package/dist/passes/pass-1-parse.d.ts +3 -0
  48. package/dist/passes/pass-1-parse.d.ts.map +1 -0
  49. package/dist/passes/pass-1-parse.js +21 -0
  50. package/dist/passes/pass-1-parse.js.map +1 -0
  51. package/dist/passes/pass-2-extract.d.ts +4 -0
  52. package/dist/passes/pass-2-extract.d.ts.map +1 -0
  53. package/dist/passes/pass-2-extract.js +762 -0
  54. package/dist/passes/pass-2-extract.js.map +1 -0
  55. package/dist/passes/pass-3-readset.d.ts +11 -0
  56. package/dist/passes/pass-3-readset.d.ts.map +1 -0
  57. package/dist/passes/pass-3-readset.js +338 -0
  58. package/dist/passes/pass-3-readset.js.map +1 -0
  59. package/dist/passes/pass-9-codegen.d.ts +27 -0
  60. package/dist/passes/pass-9-codegen.d.ts.map +1 -0
  61. package/dist/passes/pass-9-codegen.js +2755 -0
  62. package/dist/passes/pass-9-codegen.js.map +1 -0
  63. package/dist/preprocess/helpers.d.ts +71 -0
  64. package/dist/preprocess/helpers.d.ts.map +1 -0
  65. package/dist/preprocess/helpers.js +342 -0
  66. package/dist/preprocess/helpers.js.map +1 -0
  67. package/dist/preprocess/index.d.ts +6 -0
  68. package/dist/preprocess/index.d.ts.map +1 -0
  69. package/dist/preprocess/index.js +11 -0
  70. package/dist/preprocess/index.js.map +1 -0
  71. package/dist/preprocess/keywords.d.ts +28 -0
  72. package/dist/preprocess/keywords.d.ts.map +1 -0
  73. package/dist/preprocess/keywords.js +99 -0
  74. package/dist/preprocess/keywords.js.map +1 -0
  75. package/dist/preprocess/lexer.d.ts +8 -0
  76. package/dist/preprocess/lexer.d.ts.map +1 -0
  77. package/dist/preprocess/lexer.js +143 -0
  78. package/dist/preprocess/lexer.js.map +1 -0
  79. package/dist/preprocess/preprocess.d.ts +3 -0
  80. package/dist/preprocess/preprocess.d.ts.map +1 -0
  81. package/dist/preprocess/preprocess.js +568 -0
  82. package/dist/preprocess/preprocess.js.map +1 -0
  83. package/dist/preprocess/rewriters.d.ts +35 -0
  84. package/dist/preprocess/rewriters.d.ts.map +1 -0
  85. package/dist/preprocess/rewriters.js +1391 -0
  86. package/dist/preprocess/rewriters.js.map +1 -0
  87. package/dist/preprocess/source-map.d.ts +70 -0
  88. package/dist/preprocess/source-map.d.ts.map +1 -0
  89. package/dist/preprocess/source-map.js +253 -0
  90. package/dist/preprocess/source-map.js.map +1 -0
  91. package/dist/preprocess/types.d.ts +57 -0
  92. package/dist/preprocess/types.d.ts.map +1 -0
  93. package/dist/preprocess/types.js +7 -0
  94. package/dist/preprocess/types.js.map +1 -0
  95. package/dist/sidecar.d.ts +137 -0
  96. package/dist/sidecar.d.ts.map +1 -0
  97. package/dist/sidecar.js +172 -0
  98. package/dist/sidecar.js.map +1 -0
  99. package/package.json +42 -0
@@ -0,0 +1,70 @@
1
+ // @reactra/babel-plugin — plugin-class `uses` resolution (Behaviour Plugin spec §3).
2
+ //
3
+ // Owner spec: reactra-behaviour-plugin-spec.md §3 (three-way resolution) + §4
4
+ // (wrap emission). Names that are not compiler-native resolve here: the
5
+ // first-party set auto-imports from @reactra/behaviours/<name>; any other name
6
+ // must be bound by a top-level VALUE import already in the file, else R045
7
+ // (owned by Component DSL §14, raised in Pass 9 — the SVC015 owner/raiser split).
8
+ import { NATIVE_BEHAVIOURS } from "./index.js";
9
+ /** First-party plugin behaviours — DSL vocabulary with a compiler-constant import path (§3 row 2). */
10
+ export const FIRST_PARTY_PLUGINS = new Set([
11
+ "traceable",
12
+ "persistent",
13
+ "observable",
14
+ ]);
15
+ /**
16
+ * Binding names introduced by the file's top-level VALUE imports — named,
17
+ * default, and namespace forms; `import type` lines are skipped (a type can't
18
+ * wrap a component). Regex over the preserved user-import lines is sufficient:
19
+ * Pass 2 stores them verbatim and they are single statements by construction.
20
+ */
21
+ export const importedBindingNames = (userImports) => {
22
+ const names = new Set();
23
+ for (const line of userImports) {
24
+ if (/^\s*import\s+type\b/.test(line))
25
+ continue;
26
+ // Named specifiers: import { a, b as c, type T } from "…"
27
+ const named = line.match(/\{([^}]*)\}/);
28
+ if (named?.[1]) {
29
+ for (const spec of named[1].split(",")) {
30
+ const s = spec.trim();
31
+ if (s.length === 0 || s.startsWith("type "))
32
+ continue;
33
+ const renamed = s.match(/\bas\s+(\w+)$/);
34
+ names.add(renamed?.[1] ?? s.split(/\s+/)[0]);
35
+ }
36
+ }
37
+ // Default import: `import d from` / `import d, { … } from`
38
+ const def = line.match(/^\s*import\s+(\w+)\s*(?:,|from)/);
39
+ if (def?.[1])
40
+ names.add(def[1]);
41
+ // Namespace import: `import * as ns from`
42
+ const ns = line.match(/\*\s*as\s+(\w+)/);
43
+ if (ns?.[1])
44
+ names.add(ns[1]);
45
+ }
46
+ return names;
47
+ };
48
+ /**
49
+ * Resolve a component's plugin-class `uses` names (everything not in the
50
+ * native registry), in source order (Behaviour Plugin §3). Throws R045 for a
51
+ * name that is neither first-party nor bound by a value import in the file.
52
+ */
53
+ export const resolvePluginBehaviours = (c, graph) => {
54
+ const pluginNames = (c.uses?.names ?? []).filter((n) => !NATIVE_BEHAVIOURS.has(n));
55
+ if (pluginNames.length === 0)
56
+ return [];
57
+ const bound = importedBindingNames(graph.userImports);
58
+ return pluginNames.map((name) => {
59
+ if (FIRST_PARTY_PLUGINS.has(name))
60
+ return { name, firstParty: true };
61
+ if (bound.has(name))
62
+ return { name, firstParty: false };
63
+ throw new Error(`[reactra:compile] R045: \`uses ${name}\` in component "${c.name}" does not resolve — ` +
64
+ `"${name}" is not a compiler-native behaviour, not a first-party plugin ` +
65
+ `(traceable/persistent/observable), and not bound by a value import in this file. ` +
66
+ `Import it (\`import { ${name} } from "..."\`) or fix the name. ` +
67
+ `(Component DSL §14 R045; Behaviour Plugin spec §3.)`);
68
+ });
69
+ };
70
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/behaviours/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { CompilerNativeBehaviour } from "./types.ts";
2
+ /**
3
+ * `uses replayable` — inner-body session-recording instrumentation (Replay §4).
4
+ * Preamble binds the channel + a mount/unmount effect; EVERY action emits an
5
+ * `action` event (prologue) and a state-writer additionally emits a post-body
6
+ * `state_snapshot` (epilogue); each `resource` emits a status effect. Deps widen
7
+ * to all state names (Replay §4.3 rule 4 — "matches the undoable widening rule").
8
+ */
9
+ export declare const replayableBehaviour: CompilerNativeBehaviour;
10
+ //# sourceMappingURL=replayable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replayable.d.ts","sourceRoot":"","sources":["../../src/behaviours/replayable.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAqBzD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,uBA0DjC,CAAA"}
@@ -0,0 +1,86 @@
1
+ // @reactra/babel-plugin — `uses replayable` as a compiler-native behaviour entry.
2
+ //
3
+ // Owner spec: reactra-replay-spec.md §4 (seam values) + reactra-compiler-spec.md
4
+ // §4 Pass 9.1 (the registry shape this implements). Emits the inner-body
5
+ // instrumentation that drives the `@reactra/behaviours/replayable` runtime: a
6
+ // channel preamble + mount/unmount effect, a per-action `action` emit, a post-body
7
+ // `state_snapshot` for state-writers, and a per-resource status effect.
8
+ import * as t from "@babel/types";
9
+ /**
10
+ * The binding name to record in an `action` event's payload array. Identifiers
11
+ * pass through; an `x = default` param contributes `x`; a rest `...args` spreads.
12
+ * Non-identifier destructure patterns (rare; not in the spec examples) are
13
+ * skipped — recording their shape as a value is a later refinement.
14
+ */
15
+ const paramName = (p) => {
16
+ if (t.isIdentifier(p))
17
+ return p.name;
18
+ if (t.isAssignmentPattern(p) && t.isIdentifier(p.left))
19
+ return p.left.name;
20
+ if (t.isRestElement(p) && t.isIdentifier(p.argument))
21
+ return `...${p.argument.name}`;
22
+ return null;
23
+ };
24
+ const actionPayload = (a) => a.arrow.params
25
+ .map((p) => paramName(p))
26
+ .filter((n) => n !== null)
27
+ .join(", ");
28
+ /**
29
+ * `uses replayable` — inner-body session-recording instrumentation (Replay §4).
30
+ * Preamble binds the channel + a mount/unmount effect; EVERY action emits an
31
+ * `action` event (prologue) and a state-writer additionally emits a post-body
32
+ * `state_snapshot` (epilogue); each `resource` emits a status effect. Deps widen
33
+ * to all state names (Replay §4.3 rule 4 — "matches the undoable widening rule").
34
+ */
35
+ export const replayableBehaviour = {
36
+ name: "replayable",
37
+ runtime: { hook: "useReplayChannel", module: "@reactra/behaviours/replayable" },
38
+ reactImports: ["useCallback", "useEffect"],
39
+ exposedBindings: [],
40
+ widensAugmentedActionDeps: true,
41
+ emitPreamble(c, ctx) {
42
+ // v1.4 live re-drive (Replay §4.3 rule 1): the mount bracket registers the
43
+ // state→setter map. Keys iterate the states in source order; values resolve
44
+ // via the SAME ctx.setterNameFor the snapshot/restore paths use, so a
45
+ // renamed `__setX` setter is carried correctly — drift-proof by
46
+ // construction. A state-less component mounts bare (non-driveable).
47
+ const setters = [...ctx.stateNames].map((n) => `${n}: ${ctx.setterNameFor(n)}`).join(", ");
48
+ const mountArg = setters.length > 0 ? `{ ${setters} }` : "";
49
+ return [
50
+ ctx.line(` const __replay = useReplayChannel("${c.name}")`),
51
+ ctx.line(` useEffect(() => { __replay.mount(${mountArg}); return () => __replay.unmount() }, [])`),
52
+ ];
53
+ },
54
+ // Every action is a session event (Replay §4.3 rule 2) — not just state-writers.
55
+ augmentsAction() {
56
+ return true;
57
+ },
58
+ actionPrologue(a, _c, ctx) {
59
+ // A state-writer carries its straight-line write-set as the 3rd argument —
60
+ // names only, never values — so the runtime can redact the payload of an
61
+ // action that writes a `redactKeys` field (Replay §4.3 rule 2 / §5, v1.2).
62
+ // Pure side-effect actions keep the 2-arg form.
63
+ const writesArg = ctx.actionWritesState(a)
64
+ ? `, [${[...ctx.straightLineStateWrites(a).keys()].map((n) => JSON.stringify(n)).join(", ")}]`
65
+ : "";
66
+ // Trailing `;` so the prologue separates cleanly from the verbatim body that
67
+ // follows it (and from a co-applied behaviour's prologue — composition).
68
+ return `const __t0 = performance.now(); __replay.action("${a.name}", [${actionPayload(a)}]${writesArg});`;
69
+ },
70
+ // Only a state-writing action emits a post-body snapshot (Replay §4.3 rule 3).
71
+ // The object lists every state: a straight-line write contributes `X: <rhs>`,
72
+ // an unwritten state contributes its current binding (bare `X`).
73
+ actionEpilogue(a, _c, ctx) {
74
+ if (!ctx.actionWritesState(a))
75
+ return null;
76
+ const writes = ctx.straightLineStateWrites(a);
77
+ const obj = [...ctx.stateNames]
78
+ .map((n) => (writes.has(n) ? `${n}: ${writes.get(n)}` : n))
79
+ .join(", ");
80
+ return `__replay.snapshot({ ${obj} }, __t0)`;
81
+ },
82
+ emitResourceHooks(c, ctx) {
83
+ return c.resources.map((r) => ctx.line(` useEffect(() => { __replay.resource("${r.name}", ${r.name}.isPending ? "pending" : "resolved") }, [${r.name}.isPending])`));
84
+ },
85
+ };
86
+ //# sourceMappingURL=replayable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replayable.js","sourceRoot":"","sources":["../../src/behaviours/replayable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import type { ActionNode, ContainerNode } from "../ast/nodes.ts";
2
+ import type { Emitted } from "../passes/pass-9-codegen.ts";
3
+ /**
4
+ * The Pass-9 helpers a behaviour's seams receive, rather than closing over
5
+ * module-private state — this keeps the registry the single dispatch point
6
+ * (Compiler §4 Pass 9.1).
7
+ */
8
+ export interface BehaviourEmitCtx {
9
+ /** Every component `state` name. */
10
+ readonly stateNames: ReadonlySet<string>;
11
+ /** State names whose `useState` setter was renamed `__set<X>` (`classifyStateSetters`). */
12
+ readonly renamedStates: ReadonlySet<string>;
13
+ /** The identifier a `state X` write lowers to — public `setX` or the renamed `__setX`. */
14
+ setterNameFor(state: string): string;
15
+ /** Does this action body write ≥ 1 `state`? (`undoable` augments only writers.) */
16
+ actionWritesState(a: ActionNode): boolean;
17
+ /**
18
+ * Top-level (straight-line) `state = rhs` writes in an action body, as a
19
+ * `Map<stateName, rhsSourceText>` — what `replayable`'s snapshot object is built
20
+ * from (Replay §4.3 rule 3). Writes inside a branch/loop/callback are NOT
21
+ * included (RLIM-08): that field reflects its pre-update binding instead.
22
+ */
23
+ straightLineStateWrites(a: ActionNode): Map<string, string>;
24
+ /** Wrap a boilerplate line as an unmapped `Emitted` (Compiler §8: injected text, no DSL origin). */
25
+ line(text: string): Emitted;
26
+ }
27
+ /**
28
+ * One inner-body behaviour the compiler knows how to instrument, keyed by its
29
+ * `uses` name. `undoable` + `replayable` are the Phase-1 entries. The seam
30
+ * *values* are owned by the cited specs (Undo §4.2 / Replay §4.3); this
31
+ * interface is only the *shape* (Compiler §4 Pass 9.1).
32
+ *
33
+ * Scope: compiler-native (inner-body) behaviours only — NOT the plugin/HOF
34
+ * class (`traceable`/`persistent`/`observable`/third-party), which is the
35
+ * separate, deferred Behaviour Plugin spec.
36
+ */
37
+ export interface CompilerNativeBehaviour {
38
+ /** The `uses` name this entry handles (`"undoable"` | `"replayable"`). */
39
+ readonly name: string;
40
+ /** Runtime hook the preamble calls + the package it is imported from. */
41
+ readonly runtime: {
42
+ readonly hook: string;
43
+ readonly module: string;
44
+ };
45
+ /** React hooks this emission needs, beyond what `state`/`derived`/`action` pull. */
46
+ readonly reactImports: readonly string[];
47
+ /** Bare identifiers the preamble introduces into `view`/`action` scope; may be empty. */
48
+ readonly exposedBindings: readonly string[];
49
+ /**
50
+ * The TS type of each exposed binding, keyed by `exposedBindings` name — the
51
+ * machine-readable type contract the reactra2tsx shadow consumes (D1) so that
52
+ * `uses undoable` references (`undo`, `redo`, …) type-check instead of `TS2304`.
53
+ * A binding absent here lowers to `unknown` in the shadow. The compiler does NOT
54
+ * read this field — emission is unaffected.
55
+ */
56
+ readonly exposedTypes?: Readonly<Record<string, string>>;
57
+ /** Widen an augmented action's `useCallback` deps to all state names? */
58
+ readonly widensAugmentedActionDeps: boolean;
59
+ /** Lines emitted after `state`/`derived`/`ref` and before the actions (preamble + any mount/unmount effect). */
60
+ emitPreamble(c: ContainerNode, ctx: BehaviourEmitCtx): Emitted[];
61
+ /** Does this behaviour instrument action `a` at all? */
62
+ augmentsAction(a: ActionNode, c: ContainerNode, ctx: BehaviourEmitCtx): boolean;
63
+ /** Statement(s) prepended inside an augmented action body, before the user code. `null` = none. */
64
+ actionPrologue(a: ActionNode, c: ContainerNode, ctx: BehaviourEmitCtx): string | null;
65
+ /**
66
+ * Statement(s) appended inside an augmented action body, after the user code.
67
+ * `null` = none. (`undoable` returns `null`; the epilogue emission site lands
68
+ * with `replayable` — Piece A step 2 — since it is the first user.)
69
+ */
70
+ actionEpilogue(a: ActionNode, c: ContainerNode, ctx: BehaviourEmitCtx): string | null;
71
+ /**
72
+ * Lines emitted after the actions, e.g. one per-resource status `useEffect`.
73
+ * (`undoable` returns `[]`; the emission site lands with `replayable` — step 2.)
74
+ */
75
+ emitResourceHooks(c: ContainerNode, ctx: BehaviourEmitCtx): Emitted[];
76
+ }
77
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/behaviours/types.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACxC,2FAA2F;IAC3F,QAAQ,CAAC,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC3C,0FAA0F;IAC1F,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IACpC,mFAAmF;IACnF,iBAAiB,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAAA;IACzC;;;;;OAKG;IACH,uBAAuB,CAAC,CAAC,EAAE,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3D,oGAAoG;IACpG,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAA;CAC5B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACtC,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;IACpE,oFAAoF;IACpF,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,yFAAyF;IACzF,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACxD,yEAAyE;IACzE,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAA;IAE3C,gHAAgH;IAChH,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,EAAE,CAAA;IAChE,wDAAwD;IACxD,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAA;IAC/E,mGAAmG;IACnG,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAAA;IACrF;;;;OAIG;IACH,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAAA;IACrF;;;OAGG;IACH,iBAAiB,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,EAAE,CAAA;CACtE"}
@@ -0,0 +1,10 @@
1
+ // @reactra/babel-plugin — compiler-native behaviour registry types.
2
+ //
3
+ // Owner spec: reactra-compiler-spec.md §4 Pass 9.1. A `CompilerNativeBehaviour`
4
+ // generalises the inner-body instrumentation that `uses undoable` / `uses
5
+ // replayable` inject (Component DSL §9 "compiler-native behaviours"), so Pass 9
6
+ // dispatches through a table keyed by `uses` name instead of per-name branches.
7
+ // This file is the registry SHAPE; each behaviour's seam VALUES are owned by its
8
+ // spec (Undo spec §4.2 / Replay spec §4.3) and live in the per-behaviour module.
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/behaviours/types.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,gFAAgF;AAChF,0EAA0E;AAC1E,gFAAgF;AAChF,gFAAgF;AAChF,iFAAiF;AACjF,iFAAiF"}
@@ -0,0 +1,10 @@
1
+ import type { CompilerNativeBehaviour } from "./types.ts";
2
+ /**
3
+ * `uses undoable` — inner-body undo/redo instrumentation (Undo spec §4).
4
+ * Seams: a preamble (`__undo` ring buffer + `__snapshot`/`__restore` closures +
5
+ * the exposed `undo`/`redo`/… bindings) and a per-state-writing-action prologue
6
+ * (`__undo.push(__snapshot())`) whose deps widen to all state names. No epilogue,
7
+ * no resource hooks.
8
+ */
9
+ export declare const undoableBehaviour: CompilerNativeBehaviour;
10
+ //# sourceMappingURL=undoable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"undoable.d.ts","sourceRoot":"","sources":["../../src/behaviours/undoable.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,uBAoD/B,CAAA"}
@@ -0,0 +1,62 @@
1
+ // @reactra/babel-plugin — `uses undoable` as a compiler-native behaviour entry.
2
+ //
3
+ // Owner spec: reactra-undo-spec.md §4 (seam values) + reactra-compiler-spec.md
4
+ // §4 Pass 9.1 (the registry shape this implements). Lifted verbatim from the
5
+ // former inline `emitUndoablePreamble` + `isUndoable` action path in Pass 9 —
6
+ // emitted output is byte-identical (golden-suite guarded).
7
+ /**
8
+ * `uses undoable` — inner-body undo/redo instrumentation (Undo spec §4).
9
+ * Seams: a preamble (`__undo` ring buffer + `__snapshot`/`__restore` closures +
10
+ * the exposed `undo`/`redo`/… bindings) and a per-state-writing-action prologue
11
+ * (`__undo.push(__snapshot())`) whose deps widen to all state names. No epilogue,
12
+ * no resource hooks.
13
+ */
14
+ export const undoableBehaviour = {
15
+ name: "undoable",
16
+ runtime: { hook: "useUndoHistory", module: "@reactra/behaviours/undoable" },
17
+ // The preamble's undo/redo/clearHistory are `useCallback` even when the
18
+ // component declares no actions (Undo spec §4.1).
19
+ reactImports: ["useCallback"],
20
+ exposedBindings: ["undo", "redo", "canUndo", "canRedo", "historySize", "clearHistory"],
21
+ // Shadow type contract (D1) — matches what `useUndoHistory` exposes via the preamble.
22
+ exposedTypes: {
23
+ undo: "() => void",
24
+ redo: "() => void",
25
+ canUndo: "boolean",
26
+ canRedo: "boolean",
27
+ historySize: "number",
28
+ clearHistory: "() => void",
29
+ },
30
+ widensAugmentedActionDeps: true,
31
+ emitPreamble(c, ctx) {
32
+ const names = c.states.map((s) => s.name);
33
+ const snapshot = `{ ${names.join(", ")} }`;
34
+ const restore = names.map((n) => `${ctx.setterNameFor(n)}(s.${n})`).join("; ");
35
+ const deps = names.join(", ");
36
+ return [
37
+ ctx.line(` const __undo = useUndoHistory({ maxHistory: 50 })`),
38
+ ctx.line(` const __snapshot = () => (${snapshot})`),
39
+ ctx.line(` const __restore = (s) => { ${restore} }`),
40
+ ctx.line(` const undo = useCallback(() => { const s = __undo.undo(__snapshot()); if (s) __restore(s) }, [${deps}])`),
41
+ ctx.line(` const redo = useCallback(() => { const s = __undo.redo(__snapshot()); if (s) __restore(s) }, [${deps}])`),
42
+ ctx.line(` const canUndo = __undo.canUndo`),
43
+ ctx.line(` const canRedo = __undo.canRedo`),
44
+ ctx.line(` const historySize = __undo.size`),
45
+ ctx.line(` const clearHistory = useCallback(() => __undo.clear(), [])`),
46
+ ];
47
+ },
48
+ // Only state-writing actions get a snapshot (Undo spec §4.2 rule 2).
49
+ augmentsAction(a, _c, ctx) {
50
+ return ctx.actionWritesState(a);
51
+ },
52
+ actionPrologue() {
53
+ return "__undo.push(__snapshot());";
54
+ },
55
+ actionEpilogue() {
56
+ return null;
57
+ },
58
+ emitResourceHooks() {
59
+ return [];
60
+ },
61
+ };
62
+ //# sourceMappingURL=undoable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"undoable.js","sourceRoot":"","sources":["../../src/behaviours/undoable.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,8EAA8E;AAC9E,2DAA2D;AAI3D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAA4B;IACxD,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,8BAA8B,EAAE;IAC3E,wEAAwE;IACxE,kDAAkD;IAClD,YAAY,EAAE,CAAC,aAAa,CAAC;IAC7B,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,CAAC;IACtF,sFAAsF;IACtF,YAAY,EAAE;QACZ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,SAAS;QAClB,WAAW,EAAE,QAAQ;QACrB,YAAY,EAAE,YAAY;KAC3B;IACD,yBAAyB,EAAE,IAAI;IAE/B,YAAY,CAAC,CAAC,EAAE,GAAG;QACjB,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,QAAQ,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;QAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC7B,OAAO;YACL,GAAG,CAAC,IAAI,CAAC,qDAAqD,CAAC;YAC/D,GAAG,CAAC,IAAI,CAAC,+BAA+B,QAAQ,GAAG,CAAC;YACpD,GAAG,CAAC,IAAI,CAAC,gCAAgC,OAAO,IAAI,CAAC;YACrD,GAAG,CAAC,IAAI,CAAC,mGAAmG,IAAI,IAAI,CAAC;YACrH,GAAG,CAAC,IAAI,CAAC,mGAAmG,IAAI,IAAI,CAAC;YACrH,GAAG,CAAC,IAAI,CAAC,kCAAkC,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,kCAAkC,CAAC;YAC5C,GAAG,CAAC,IAAI,CAAC,mCAAmC,CAAC;YAC7C,GAAG,CAAC,IAAI,CAAC,8DAA8D,CAAC;SACzE,CAAA;IACH,CAAC;IAED,qEAAqE;IACrE,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG;QACvB,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAA;IACjC,CAAC;IAED,cAAc;QACZ,OAAO,4BAA4B,CAAA;IACrC,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAA;IACb,CAAC;IAED,iBAAiB;QACf,OAAO,EAAE,CAAA;IACX,CAAC;CACF,CAAA"}
@@ -0,0 +1,69 @@
1
+ import type { RawSourceMap } from "./preprocess/index.ts";
2
+ import type { Rewrite } from "./preprocess/types.ts";
3
+ import type { FileGraph } from "./ast/nodes.ts";
4
+ export interface CompileResult {
5
+ /** Final React 19 TSX source */
6
+ code: string;
7
+ /** The intermediate graph (useful for tests, devtools, sidecars) */
8
+ graph: FileGraph;
9
+ /**
10
+ * v3 **composed** source→compiled map (`#10-followup`, Compiler §8). Pass 9
11
+ * records one segment per user-code slice (`state`/`derived`/`action`/
12
+ * `resource`/`view`/`effect`/`mount` in components); `compile()` composes
13
+ * those through the preprocess map to DSL `(line, col)`. Compiler-injected
14
+ * boilerplate is unmapped by design. `sourcesContent` carries the DSL.
15
+ * `sourceFile` defaults to `"input.tsx"`; the Vite plugin passes the real `id`.
16
+ */
17
+ map: RawSourceMap;
18
+ /**
19
+ * The ordered list of rewrite operations produced by the preprocessor.
20
+ * Consumed by the language-tools shadow emitter to compose
21
+ * shadow→preprocessed positions all the way back to DSL offsets.
22
+ * Additive field — callers that ignore it are unaffected.
23
+ */
24
+ rewrites: Rewrite[];
25
+ }
26
+ /**
27
+ * The graph-only result: everything a consumer needs WITHOUT running codegen.
28
+ * Returned by {@link compileToGraph} for callers (the LSP) that read only the
29
+ * intermediate graph + rewrites and never need the emitted `code`/`map`.
30
+ */
31
+ export interface GraphResult {
32
+ /** The intermediate graph (Pass 2 extract + Pass 3 read-sets). */
33
+ graph: FileGraph;
34
+ /** Preprocessor rewrite operations (shadow→DSL position composition). */
35
+ rewrites: Rewrite[];
36
+ }
37
+ /**
38
+ * Compile Reactra DSL to the intermediate {@link GraphResult} WITHOUT codegen.
39
+ *
40
+ * The LSP/language-tools path consumes only `.graph` + `.rewrites`; running the
41
+ * full {@link compile} (including Pass 9 codegen) on every keystroke is wasted
42
+ * work (framework-review A5). This is the same prefix `compile` runs — they
43
+ * share {@link runToGraph}, so there is no second pipeline to drift.
44
+ *
45
+ * @param source raw Reactra source (.tsx with DSL keywords)
46
+ * @returns the intermediate graph + preprocessor rewrites (no emitted code)
47
+ */
48
+ export declare const compileToGraph: (source: string) => GraphResult;
49
+ /**
50
+ * Options accepted by {@link compile}. All are optional; omitting them
51
+ * yields the same behaviour as the original single-argument call.
52
+ */
53
+ export interface CompileOptions {
54
+ /**
55
+ * Source file path to embed in the returned source map's `sources[0]`
56
+ * + `file` fields. Vite's plugin layer threads its module `id` here.
57
+ * Defaults to `"input.tsx"` for self-contained smoke tests.
58
+ */
59
+ readonly sourceFile?: string;
60
+ }
61
+ /**
62
+ * Compile Reactra DSL source to React 19 TSX.
63
+ *
64
+ * @param source raw Reactra source (.tsx with DSL keywords)
65
+ * @param opts build-time options; see {@link CompileOptions}
66
+ * @returns object with `code` (compiled TSX) and `graph` (intermediate)
67
+ */
68
+ export declare const compile: (source: string, opts?: CompileOptions) => CompileResult;
69
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAKpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,KAAK,EAAE,SAAS,CAAA;IAChB;;;;;;;OAOG;IACH,GAAG,EAAE,YAAY,CAAA;IACjB;;;;;OAKG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAA;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,KAAK,EAAE,SAAS,CAAA;IAChB,yEAAyE;IACzE,QAAQ,EAAE,OAAO,EAAE,CAAA;CACpB;AAqBD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,KAAG,WAG/C,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAI7B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAAI,QAAQ,MAAM,EAAE,OAAM,cAAmB,KAAG,aAqBnE,CAAA"}
@@ -0,0 +1,75 @@
1
+ // Top-level Reactra compile entry point.
2
+ //
3
+ // Combines the pipeline:
4
+ // preprocess -> @babel/parser -> Pass 2 extract -> Pass 3 read-set -> Pass 9 codegen
5
+ //
6
+ // Phase-1 MVP: components compile to runnable React 19; stores and
7
+ // services emit placeholder factories (real wiring is Wave 3.3).
8
+ import { composeSourceMap, preprocess } from "./preprocess/index.js";
9
+ import { parsePreprocessed } from "./passes/pass-1-parse.js";
10
+ import { extractGraph } from "./passes/pass-2-extract.js";
11
+ import { analyzeReadSets } from "./passes/pass-3-readset.js";
12
+ import { codegen } from "./passes/pass-9-codegen.js";
13
+ /**
14
+ * The shared pipeline prefix: preprocess → parse → extract → read-sets, stopping
15
+ * before codegen. BOTH {@link compileToGraph} and {@link compile} consume this —
16
+ * the prefix exists exactly once, so a graph consumed via `compileToGraph` can
17
+ * never structurally drift from the graph `compile` emits (framework-review B1).
18
+ * `preprocessed` is returned for `compile`'s source-map composition; it is not
19
+ * part of the public {@link GraphResult}.
20
+ */
21
+ const runToGraph = (source) => {
22
+ const { code: preprocessed, rewrites } = preprocess(source);
23
+ const ast = parsePreprocessed(preprocessed);
24
+ const graph = extractGraph(source, preprocessed, ast);
25
+ // Pass 3 — read-set analysis: populate `deps` on component derived/action
26
+ // nodes so Pass 9 emits real `useMemo`/`useCallback` dependency arrays
27
+ // instead of the stale-closure `[]`.
28
+ analyzeReadSets(ast, graph);
29
+ return { graph, rewrites, preprocessed };
30
+ };
31
+ /**
32
+ * Compile Reactra DSL to the intermediate {@link GraphResult} WITHOUT codegen.
33
+ *
34
+ * The LSP/language-tools path consumes only `.graph` + `.rewrites`; running the
35
+ * full {@link compile} (including Pass 9 codegen) on every keystroke is wasted
36
+ * work (framework-review A5). This is the same prefix `compile` runs — they
37
+ * share {@link runToGraph}, so there is no second pipeline to drift.
38
+ *
39
+ * @param source raw Reactra source (.tsx with DSL keywords)
40
+ * @returns the intermediate graph + preprocessor rewrites (no emitted code)
41
+ */
42
+ export const compileToGraph = (source) => {
43
+ const { graph, rewrites } = runToGraph(source);
44
+ return { graph, rewrites };
45
+ };
46
+ /**
47
+ * Compile Reactra DSL source to React 19 TSX.
48
+ *
49
+ * @param source raw Reactra source (.tsx with DSL keywords)
50
+ * @param opts build-time options; see {@link CompileOptions}
51
+ * @returns object with `code` (compiled TSX) and `graph` (intermediate)
52
+ */
53
+ export const compile = (source, opts = {}) => {
54
+ // Shares the pipeline prefix with compileToGraph (single source of truth).
55
+ // Backlog 1a: `inject store X` resolves its name via `import type { X }`
56
+ // (cross-file) or a same-file declaration, so codegen no longer reads the
57
+ // `.reactra.json` sidecar index (the reader was deleted in Session 4).
58
+ const { graph, rewrites, preprocessed } = runToGraph(source);
59
+ const { code: compiledCode, marks } = codegen(graph);
60
+ // #10-followup (Compiler §8): compose the codegen hop (compiled → preprocessed,
61
+ // via the per-slice `marks`) with the preprocess hop (preprocessed → source)
62
+ // into a source→compiled map. Compiler boilerplate stays unmapped by design;
63
+ // `sourcesContent` carries the DSL so devtools always shows the original.
64
+ const sourceFile = opts.sourceFile ?? "input.tsx";
65
+ const map = composeSourceMap({
66
+ source,
67
+ preprocessed,
68
+ rewrites,
69
+ compiled: compiledCode,
70
+ marks,
71
+ sourceFile,
72
+ });
73
+ return { code: compiledCode, graph, map, rewrites };
74
+ };
75
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,yBAAyB;AACzB,uFAAuF;AACvF,EAAE;AACF,mEAAmE;AACnE,iEAAiE;AAEjE,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAGpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAsCpD;;;;;;;GAOG;AACH,MAAM,UAAU,GAAG,CAAC,MAAc,EAA0C,EAAE;IAC5E,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;IAC3D,MAAM,GAAG,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,CAAC,CAAA;IACrD,0EAA0E;IAC1E,uEAAuE;IACvE,qCAAqC;IACrC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IAC3B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;AAC1C,CAAC,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAc,EAAe,EAAE;IAC5D,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;IAC9C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAC5B,CAAC,CAAA;AAkBD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAc,EAAE,OAAuB,EAAE,EAAiB,EAAE;IAClF,2EAA2E;IAC3E,yEAAyE;IACzE,0EAA0E;IAC1E,uEAAuE;IACvE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;IAC5D,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;IACpD,gFAAgF;IAChF,6EAA6E;IAC7E,6EAA6E;IAC7E,0EAA0E;IAC1E,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,WAAW,CAAA;IACjD,MAAM,GAAG,GAAG,gBAAgB,CAAC;QAC3B,MAAM;QACN,YAAY;QACZ,QAAQ;QACR,QAAQ,EAAE,YAAY;QACtB,KAAK;QACL,UAAU;KACX,CAAC,CAAA;IACF,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAA;AACrD,CAAC,CAAA"}
@@ -0,0 +1,110 @@
1
+ import type { ContainerNode, ContainerKind } from "../ast/nodes.ts";
2
+ import { CONTAINER_MARKERS } from "../ast/nodes.ts";
3
+ /** Capitalise the first letter — used for setter names (`foo` → `Foo`). */
4
+ export declare const cap: (s: string) => string;
5
+ /**
6
+ * Positional order of the four arrows in a `__reactra_await__(resource,
7
+ * success, pending, error)` marker call. Both emitters index the call's
8
+ * `arguments` array via these constants so the resource/success/pending/error
9
+ * branches can never be wired up inconsistently across the two code paths.
10
+ *
11
+ * Pass 9: `pass-9-codegen.ts` await rewrite + the error-branch detector.
12
+ * Shadow: `shadow/emitter.ts` await lowering.
13
+ */
14
+ export declare const AWAIT_ARG_ORDER: {
15
+ readonly resource: 0;
16
+ readonly success: 1;
17
+ readonly pending: 2;
18
+ readonly error: 3;
19
+ };
20
+ /**
21
+ * The identifier `state X` writes lower to (Component DSL §2.1/§2.3). Normally
22
+ * the auto-emitted public setter `set<Cap(X)>`; but when a non-trivial
23
+ * `action set<Cap(X)>` owns that public name, the `useState` setter is renamed
24
+ * `__set<Cap(X)>` so the action and the real setter don't collide (improvements
25
+ * #4). `renamedStates` holds the state names in the renamed case — compute it
26
+ * with {@link classifyStateSetters}.
27
+ */
28
+ export declare const setterNameFor: (stateName: string, renamedStates: ReadonlySet<string>) => string;
29
+ /**
30
+ * The state name an `action set<Cap(X)>` targets, or `null` if the action name
31
+ * isn't of that shape. `setFilter` → `filter` (Pascal → camel: lowercase the
32
+ * first char after `set`); `set`/`setup-with-no-tail` → `null`.
33
+ *
34
+ * Exported because the R016 warning (Pass 9) reports the targeted state name.
35
+ */
36
+ export declare const setterActionTarget: (actionName: string) => string | null;
37
+ /**
38
+ * Classify `action set<Cap(X)>` declarations that name an existing `state X`
39
+ * (improvements #4, replacing the Day-21 hard R046 collision):
40
+ * - **trivial identity passthrough** → action **suppressed** (the auto-emitted
41
+ * `setX` already provides it); the caller emits R016 (warning);
42
+ * - **non-trivial** → the action **owns** the public `setX`; its state's
43
+ * `useState` setter is **renamed** `__setX` so they don't collide, and
44
+ * every `X = expr` write (here and elsewhere) lowers to `__setX`.
45
+ *
46
+ * Pure — returns the set of state names to rename and the set of action names
47
+ * to drop; the R016 warning is emitted by the caller (the single per-component
48
+ * emit point). Components only — store/service `state`/`action` emit through
49
+ * other paths, so a non-component container yields empty sets.
50
+ */
51
+ export declare const classifyStateSetters: (c: ContainerNode) => {
52
+ renamedStates: Set<string>;
53
+ suppressedActions: Set<string>;
54
+ };
55
+ /**
56
+ * Top-level container-wrapper markers, keyed to the `ContainerKind` they map to.
57
+ * Re-exported from `ast/nodes.ts` so there is exactly one home for the marker
58
+ * vocabulary (the conventions module). Pass 2 recognises these at the
59
+ * outer-decl level; the shadow emitter and parity test read them from here.
60
+ */
61
+ export { CONTAINER_MARKERS };
62
+ export type { ContainerKind };
63
+ /**
64
+ * Body-level markers emitted by the preprocessor inside a container body and
65
+ * consumed by Pass 2's body-marker switch (`pass-2-extract.ts`). This is the
66
+ * authoritative list — the convention-parity test (language-tools) asserts that
67
+ * every key here is handled by BOTH emitters (or explicitly punted), so a NEW
68
+ * marker can't be added without a human wiring it on both sides (framework
69
+ * review §B1: stop the two emitters drifting silently).
70
+ *
71
+ * Values are the literal marker strings — kept byte-identical to the strings
72
+ * the preprocessor emits and Pass 2 switches on. The set is `as const` so the
73
+ * key type is the exact string-literal union.
74
+ *
75
+ * `__reactra_await__` is included: it is a body-level marker, but Pass 2
76
+ * handles it in a dedicated view-walk (not the flat body switch). The parity
77
+ * manifest classifies it as VIEW-HANDLED rather than switch-handled.
78
+ */
79
+ export declare const BODY_MARKERS: {
80
+ readonly __reactra_state__: "state";
81
+ readonly __reactra_derived__: "derived";
82
+ readonly __reactra_action__: "action";
83
+ readonly __reactra_action_async__: "action";
84
+ readonly __reactra_resource__: "resource";
85
+ readonly __reactra_ref__: "ref";
86
+ readonly __reactra_mount__: "mount";
87
+ readonly __reactra_cleanup__: "cleanup";
88
+ readonly __reactra_effect__: "effect";
89
+ readonly __reactra_effect_on__: "effect";
90
+ readonly __reactra_view__: "view";
91
+ readonly __reactra_uses__: "uses";
92
+ readonly __reactra_inject__: "inject";
93
+ readonly __reactra_provide__: "provide";
94
+ readonly __reactra_param__: "param";
95
+ readonly __reactra_query__: "query";
96
+ readonly __reactra_meta__: "meta";
97
+ readonly __reactra_prefetch__: "prefetch";
98
+ readonly __reactra_transition__: "transition";
99
+ readonly __reactra_inject_store__: "inject-store";
100
+ readonly __reactra_inject_store_args__: "inject-store";
101
+ readonly __reactra_inject_store_keyed__: "inject-store";
102
+ readonly __reactra_error_boundary__: "errorBoundary";
103
+ readonly __reactra_suspense__: "suspense";
104
+ readonly __reactra_input__: "input";
105
+ readonly __reactra_preserved__: "preserved";
106
+ readonly __reactra_await__: "await";
107
+ };
108
+ /** A body-marker function name (the keys of {@link BODY_MARKERS}). */
109
+ export type BodyMarker = keyof typeof BODY_MARKERS;
110
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/conventions/index.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAc,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAMnD,2EAA2E;AAC3E,eAAO,MAAM,GAAG,GAAI,GAAG,MAAM,KAAG,MAAgD,CAAA;AAMhF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;;;CAKlB,CAAA;AAMV;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,WAAW,MAAM,EAAE,eAAe,WAAW,CAAC,MAAM,CAAC,KAAG,MACJ,CAAA;AAElF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAI,YAAY,MAAM,KAAG,MAAM,GAAG,IAKhE,CAAA;AA+BD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,GAC/B,GAAG,aAAa,KACf;IAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAY9D,CAAA;AAMD;;;;;GAKG;AACH,OAAO,EAAE,iBAAiB,EAAE,CAAA;AAC5B,YAAY,EAAE,aAAa,EAAE,CAAA;AAE7B;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Bf,CAAA;AAEV,sEAAsE;AACtE,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,YAAY,CAAA"}