aktion-runtime 0.5.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 (76) hide show
  1. package/README.md +1246 -0
  2. package/dist/aktion.iife.js +8431 -0
  3. package/dist/aktion.iife.js.map +1 -0
  4. package/dist/aktion.js +22594 -0
  5. package/dist/aktion.js.map +1 -0
  6. package/dist/aktion.umd.cjs +8431 -0
  7. package/dist/aktion.umd.cjs.map +1 -0
  8. package/dist/index.cjs +3 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +5 -0
  11. package/dist/system_prompt.txt +1095 -0
  12. package/dist/system_prompt_chat.txt +404 -0
  13. package/dist/types/element.d.ts +175 -0
  14. package/dist/types/icons/index.d.ts +45 -0
  15. package/dist/types/index.d.ts +15 -0
  16. package/dist/types/language/builtins.d.ts +33 -0
  17. package/dist/types/language/components.d.ts +28 -0
  18. package/dist/types/language/grammar.d.ts +121 -0
  19. package/dist/types/language/index.d.ts +41 -0
  20. package/dist/types/language/snippets.d.ts +17 -0
  21. package/dist/types/library/components/_internal.d.ts +56 -0
  22. package/dist/types/library/components/advanced-charts.d.ts +6 -0
  23. package/dist/types/library/components/advanced-data.d.ts +6 -0
  24. package/dist/types/library/components/advanced-forms.d.ts +12 -0
  25. package/dist/types/library/components/advanced-patterns.d.ts +13 -0
  26. package/dist/types/library/components/charts.d.ts +5 -0
  27. package/dist/types/library/components/chat.d.ts +6 -0
  28. package/dist/types/library/components/content.d.ts +33 -0
  29. package/dist/types/library/components/data.d.ts +9 -0
  30. package/dist/types/library/components/editors.d.ts +5 -0
  31. package/dist/types/library/components/feedback.d.ts +14 -0
  32. package/dist/types/library/components/forms-shared.d.ts +7 -0
  33. package/dist/types/library/components/forms.d.ts +21 -0
  34. package/dist/types/library/components/helpers.d.ts +33 -0
  35. package/dist/types/library/components/layout.d.ts +20 -0
  36. package/dist/types/library/components/media.d.ts +7 -0
  37. package/dist/types/library/components/menu.d.ts +5 -0
  38. package/dist/types/library/components/navigation.d.ts +6 -0
  39. package/dist/types/library/components/new-components.d.ts +13 -0
  40. package/dist/types/library/components/patterns.d.ts +39 -0
  41. package/dist/types/library/components/router.d.ts +2 -0
  42. package/dist/types/library/components/theme.d.ts +2 -0
  43. package/dist/types/library/index.d.ts +5 -0
  44. package/dist/types/library/registry.d.ts +15 -0
  45. package/dist/types/library/types.d.ts +140 -0
  46. package/dist/types/library/utils.d.ts +73 -0
  47. package/dist/types/library/validate.d.ts +27 -0
  48. package/dist/types/parser/frontier.d.ts +65 -0
  49. package/dist/types/parser/index.d.ts +4 -0
  50. package/dist/types/parser/lexer.d.ts +46 -0
  51. package/dist/types/parser/parser.d.ts +2 -0
  52. package/dist/types/parser/types.d.ts +349 -0
  53. package/dist/types/prompt/generator.d.ts +33 -0
  54. package/dist/types/prompt/index.d.ts +1 -0
  55. package/dist/types/renderer/index.d.ts +1 -0
  56. package/dist/types/renderer/morph.d.ts +42 -0
  57. package/dist/types/renderer/renderer.d.ts +73 -0
  58. package/dist/types/runtime/builtins.d.ts +27 -0
  59. package/dist/types/runtime/console.d.ts +21 -0
  60. package/dist/types/runtime/effects.d.ts +69 -0
  61. package/dist/types/runtime/evaluator.d.ts +151 -0
  62. package/dist/types/runtime/http.d.ts +85 -0
  63. package/dist/types/runtime/i18n.d.ts +40 -0
  64. package/dist/types/runtime/index.d.ts +9 -0
  65. package/dist/types/runtime/router.d.ts +105 -0
  66. package/dist/types/runtime/state.d.ts +84 -0
  67. package/dist/types/runtime/storage.d.ts +50 -0
  68. package/dist/types/theme/index.d.ts +175 -0
  69. package/dist/types/theme/styles.d.ts +9 -0
  70. package/dist/types/tooling/codemod.d.ts +36 -0
  71. package/dist/types/tooling/delta.d.ts +74 -0
  72. package/dist/types/tooling/formatter.d.ts +8 -0
  73. package/dist/types/tooling/index.d.ts +29 -0
  74. package/dist/types/tooling/inspector.d.ts +49 -0
  75. package/dist/types/tooling/language-service.d.ts +57 -0
  76. package/package.json +63 -0
@@ -0,0 +1,349 @@
1
+ /**
2
+ * AST types for Aktion.
3
+ *
4
+ * The grammar is line-oriented:
5
+ * identifier = Expression
6
+ * $stateVariable = LiteralDefault
7
+ * name = Query(...) | Mutation(...)
8
+ *
9
+ * Expressions form a tree of literals, references, calls, and operators.
10
+ */
11
+ export type Expression = LiteralExpr | IdentifierExpr | StateRefExpr | ArrayExpr | ObjectExpr | MemberExpr | UnaryExpr | BinaryExpr | TernaryExpr | CallExpr | MethodCallExpr | BuiltinCallExpr | TemplateLiteralExpr | SpreadExpr | NamedArgExpr | IfExpr | MatchExpr | ForExpr | LambdaExpr | JsBlockExpr | BindExpr | BlockExpr;
12
+ /** `if cond { ... } else { ... }` expression — see §8.1. */
13
+ export interface IfExpr {
14
+ kind: "If";
15
+ test: Expression;
16
+ consequent: BlockExpr;
17
+ alternate?: IfExpr | BlockExpr;
18
+ loc?: SourceLocation;
19
+ }
20
+ /** `match value { pat -> expr, _ -> expr }` expression — see §8.2. */
21
+ export interface MatchExpr {
22
+ kind: "Match";
23
+ discriminant: Expression;
24
+ arms: ReadonlyArray<MatchArm>;
25
+ loc?: SourceLocation;
26
+ }
27
+ export interface MatchArm {
28
+ /** Literal pattern (string / number / boolean / null / identifier) or `_`. */
29
+ pattern: Expression | "_";
30
+ body: Expression;
31
+ }
32
+ /** `for x in arr { body }` expression — see §8.3. */
33
+ export interface ForExpr {
34
+ kind: "For";
35
+ /** Item binding name. */
36
+ item: string;
37
+ /** Optional `(item, idx)` destructuring index name. */
38
+ index?: string;
39
+ /** Optional `{a, b, c}` destructuring — binds each named field of the row. */
40
+ destructure?: ReadonlyArray<string>;
41
+ iterable: Expression;
42
+ body: BlockExpr;
43
+ loc?: SourceLocation;
44
+ }
45
+ /** `(args) => body` lambda. The body is a single expression OR a `js{}` block. */
46
+ export interface LambdaExpr {
47
+ kind: "Lambda";
48
+ params: ReadonlyArray<LambdaParam>;
49
+ body: Expression | JsBlockExpr;
50
+ loc?: SourceLocation;
51
+ }
52
+ export interface LambdaParam {
53
+ name: string;
54
+ defaultValue?: Expression;
55
+ }
56
+ /** `js{ ... raw js ... }` opaque block. Runs verbatim under an `effect` or `action` body. */
57
+ export interface JsBlockExpr {
58
+ kind: "JsBlock";
59
+ body: string;
60
+ loc?: SourceLocation;
61
+ }
62
+ /**
63
+ * `bind:prop: stateRef` argument. Desugars at runtime to
64
+ * `prop: stateRef, on<Prop>Change: (v) => stateRef = v`.
65
+ */
66
+ export interface BindExpr {
67
+ kind: "Bind";
68
+ prop: string;
69
+ target: Expression;
70
+ loc?: SourceLocation;
71
+ }
72
+ /**
73
+ * Statement block delimited by `{ ... }`. Used as the body of `component`,
74
+ * `effect`, `action`, `if`, `match`, `for`, and lambdas with multiple
75
+ * statements. The last expression in the block (if any) is its value.
76
+ */
77
+ export interface BlockExpr {
78
+ kind: "Block";
79
+ body: ReadonlyArray<Statement>;
80
+ loc?: SourceLocation;
81
+ }
82
+ /**
83
+ * Named component argument inside a call list: `GridItem(child, span: "1/4")`.
84
+ * Only valid in `(...)` argument lists, not inside `[...]` arrays.
85
+ */
86
+ export interface NamedArgExpr {
87
+ kind: "NamedArg";
88
+ name: string;
89
+ value: Expression;
90
+ loc?: SourceLocation;
91
+ }
92
+ export interface SourceLocation {
93
+ line: number;
94
+ column: number;
95
+ }
96
+ export interface LiteralExpr {
97
+ kind: "Literal";
98
+ value: string | number | boolean | null;
99
+ loc?: SourceLocation;
100
+ }
101
+ export interface IdentifierExpr {
102
+ kind: "Identifier";
103
+ name: string;
104
+ loc?: SourceLocation;
105
+ }
106
+ export interface StateRefExpr {
107
+ kind: "StateRef";
108
+ name: string;
109
+ loc?: SourceLocation;
110
+ }
111
+ export interface ArrayExpr {
112
+ kind: "Array";
113
+ elements: Expression[];
114
+ loc?: SourceLocation;
115
+ }
116
+ export interface ObjectProperty {
117
+ key: string;
118
+ value: Expression;
119
+ /** True for `{...source}` shorthand — `key` is ignored when set. */
120
+ spread?: boolean;
121
+ }
122
+ export interface ObjectExpr {
123
+ kind: "Object";
124
+ properties: ObjectProperty[];
125
+ loc?: SourceLocation;
126
+ }
127
+ export interface MemberExpr {
128
+ kind: "Member";
129
+ object: Expression;
130
+ /** Dot-access property name (`obj.field`). */
131
+ property?: string;
132
+ /** Bracket-access key (`arr[i]`, `obj[$key]`). */
133
+ computed?: Expression;
134
+ /** True for `obj?.prop` / `obj?.[key]` — short-circuits when `obj` is null/undefined. */
135
+ optional?: boolean;
136
+ loc?: SourceLocation;
137
+ }
138
+ /**
139
+ * Spread element used inside array literals (`[...a, b]`). Object spread is
140
+ * modelled as an `ObjectProperty` with `spread: true` because the parser
141
+ * already enumerates props.
142
+ */
143
+ export interface SpreadExpr {
144
+ kind: "Spread";
145
+ argument: Expression;
146
+ loc?: SourceLocation;
147
+ }
148
+ /**
149
+ * Template literal: `` `Hello ${$user.name}, you have ${$count} messages` ``.
150
+ *
151
+ * Encoded as alternating raw string chunks (`quasis`) and embedded
152
+ * expressions. `quasis.length === expressions.length + 1` — there is always
153
+ * one more chunk than expression, even when the template starts or ends
154
+ * with an interpolation (the boundary chunk is empty in that case). This
155
+ * mirrors how the JavaScript AST represents template literals.
156
+ */
157
+ export interface TemplateLiteralExpr {
158
+ kind: "Template";
159
+ quasis: string[];
160
+ expressions: Expression[];
161
+ loc?: SourceLocation;
162
+ }
163
+ export interface UnaryExpr {
164
+ kind: "Unary";
165
+ operator: "!" | "-";
166
+ argument: Expression;
167
+ loc?: SourceLocation;
168
+ }
169
+ export type BinaryOperator = "+" | "-" | "*" | "/" | "%" | "==" | "!=" | ">" | "<" | ">=" | "<=" | "&&" | "||"
170
+ /**
171
+ * Nullish coalescing — returns `left` unless it is `null` or `undefined`.
172
+ * Distinct from `||`, which also short-circuits on `0`, `""`, and `false`.
173
+ */
174
+ | "??";
175
+ export interface BinaryExpr {
176
+ kind: "Binary";
177
+ operator: BinaryOperator;
178
+ left: Expression;
179
+ right: Expression;
180
+ loc?: SourceLocation;
181
+ }
182
+ export interface TernaryExpr {
183
+ kind: "Ternary";
184
+ test: Expression;
185
+ consequent: Expression;
186
+ alternate: Expression;
187
+ loc?: SourceLocation;
188
+ }
189
+ export interface CallExpr {
190
+ kind: "Call";
191
+ callee: string;
192
+ arguments: Expression[];
193
+ loc?: SourceLocation;
194
+ }
195
+ /**
196
+ * `object.method(args...)` invocation. Used for namespaced globals like
197
+ * `storage.set(...)`, `console.log(...)`, and chained member calls on
198
+ * runtime values (`$res.refetch()`). Named args inside the argument list
199
+ * are collected into a single trailing options object — so
200
+ * `storage.cookies.set("k", "v", expires: 1, path: "/")` resolves to
201
+ * `set("k", "v", { expires: 1, path: "/" })`.
202
+ */
203
+ export interface MethodCallExpr {
204
+ kind: "MethodCall";
205
+ object: Expression;
206
+ method: string;
207
+ arguments: Expression[];
208
+ /** True for `obj?.method(...)` — short-circuits to `undefined` when `obj` is null. */
209
+ optional?: boolean;
210
+ loc?: SourceLocation;
211
+ }
212
+ export interface BuiltinCallExpr {
213
+ kind: "BuiltinCall";
214
+ name: string;
215
+ arguments: Expression[];
216
+ loc?: SourceLocation;
217
+ }
218
+ export interface AssignmentStatement {
219
+ kind: "Assignment";
220
+ identifier: string;
221
+ isState: boolean;
222
+ expression: Expression;
223
+ loc?: SourceLocation;
224
+ }
225
+ /**
226
+ * `component Name(p, q: default, slots: { footer? }) { ... }` declaration.
227
+ * The body is a `BlockExpr`; the last expression is the rendered output.
228
+ */
229
+ export interface ComponentDeclaration {
230
+ kind: "ComponentDeclaration";
231
+ name: string;
232
+ params: ReadonlyArray<DeclParam>;
233
+ /** Names of the declared slots, e.g. `{ footer? }` -> `["footer"]`. */
234
+ slots: ReadonlyArray<string>;
235
+ body: BlockExpr;
236
+ loc?: SourceLocation;
237
+ }
238
+ /**
239
+ * Parameter on a `component`, `action`, or `effect` declaration. Distinct
240
+ * from `library/components` `ComponentParam` (the editor-level surface
241
+ * projection) — kept under a different name to avoid an ambiguous re-export
242
+ * from the package root.
243
+ */
244
+ export interface DeclParam {
245
+ name: string;
246
+ defaultValue?: Expression;
247
+ optional?: boolean;
248
+ }
249
+ /**
250
+ * `effect [ ...dependencies ] { body }` declaration.
251
+ *
252
+ * Effects are anonymous — the parser auto-assigns a stable name from the
253
+ * declaration's source location so the runtime can keep track of them
254
+ * across re-parses. The optional bracketed dependency list mixes state
255
+ * triggers (`$name`), lifecycle / interval triggers (`on:mount`,
256
+ * `on:unmount`, `on:every(N)`), and rate-limit modifiers (`debounce(N)`,
257
+ * `throttle(N)`) in any order.
258
+ *
259
+ * `effect { ... }` (no brackets) and `effect [on:mount] { ... }` are
260
+ * equivalent — both run the body once on mount.
261
+ */
262
+ export interface EffectDeclaration {
263
+ kind: "EffectDeclaration";
264
+ /** Auto-generated name (`__effect_L{line}_C{column}`) — used as a runtime key. */
265
+ name: string;
266
+ triggers: ReadonlyArray<EffectTrigger>;
267
+ /** Optional rate-limit modifier (`debounce(N)` / `throttle(N)`). */
268
+ rateLimit?: EffectRateLimit;
269
+ body: BlockExpr;
270
+ loc?: SourceLocation;
271
+ }
272
+ /** Trigger literal (`$state`, `on:mount`, `on:unmount`, `on:every(N)`). */
273
+ export type EffectTrigger = {
274
+ kind: "state";
275
+ name: string;
276
+ } | {
277
+ kind: "lifecycle";
278
+ name: "mount" | "unmount";
279
+ } | {
280
+ kind: "every";
281
+ intervalMs: number;
282
+ };
283
+ /** Rate-limit modifier on an `effect` (`debounce(N)` / `throttle(N)`). */
284
+ export interface EffectRateLimit {
285
+ kind: "debounce" | "throttle";
286
+ /** Window in milliseconds. */
287
+ ms: number;
288
+ }
289
+ /**
290
+ * `action Name(args) [optimistic] { body }` declaration. Actions are
291
+ * explicit-call effects; their body runs whenever the action is invoked
292
+ * from an event handler (`onClick: actionName`).
293
+ */
294
+ export interface ActionDeclaration {
295
+ kind: "ActionDeclaration";
296
+ name: string;
297
+ params: ReadonlyArray<DeclParam>;
298
+ optimistic: boolean;
299
+ body: BlockExpr;
300
+ loc?: SourceLocation;
301
+ }
302
+ /** `emit "name" { detail }` outbound event statement. */
303
+ export interface EmitStatement {
304
+ kind: "Emit";
305
+ eventName: string;
306
+ detail: Expression;
307
+ loc?: SourceLocation;
308
+ }
309
+ /** `cleanup(fn)` registration call — only valid inside `effect` bodies. */
310
+ export interface CleanupStatement {
311
+ kind: "Cleanup";
312
+ callback: Expression;
313
+ loc?: SourceLocation;
314
+ }
315
+ /** `await expr` statement / expression — only valid inside `action`/`effect`. */
316
+ export interface AwaitStatement {
317
+ kind: "Await";
318
+ argument: Expression;
319
+ loc?: SourceLocation;
320
+ }
321
+ /** `return [expr]` statement — only valid inside `action`/`effect`/`component`. */
322
+ export interface ReturnStatement {
323
+ kind: "Return";
324
+ argument?: Expression;
325
+ loc?: SourceLocation;
326
+ }
327
+ /** Bare expression statement at the top of a block / body. */
328
+ export interface ExpressionStatement {
329
+ kind: "ExpressionStatement";
330
+ expression: Expression;
331
+ loc?: SourceLocation;
332
+ }
333
+ export type Statement = AssignmentStatement | ComponentDeclaration | EffectDeclaration | ActionDeclaration | EmitStatement | CleanupStatement | AwaitStatement | ReturnStatement | ExpressionStatement;
334
+ export interface Program {
335
+ statements: Statement[];
336
+ errors: ParseError[];
337
+ /**
338
+ * Non-fatal diagnostics surfaced by schema validation (§15). The
339
+ * program still runs — these are advisory hints for authors who chose
340
+ * a token outside the closed enum, supplied an unknown named arg, or
341
+ * tripped some other "this will not look right" lint.
342
+ */
343
+ warnings?: ParseError[];
344
+ }
345
+ export interface ParseError {
346
+ message: string;
347
+ line: number;
348
+ column: number;
349
+ }
@@ -0,0 +1,33 @@
1
+ import { ComponentLibrary, ComponentSpec } from '../library/types.js';
2
+ export interface ToolSpec {
3
+ name: string;
4
+ description: string;
5
+ /** Example argument shape the LLM should call with. */
6
+ argsExample?: Record<string, unknown>;
7
+ /** Whether this endpoint is read-only or mutating. Influences method hint. */
8
+ kind?: "Query" | "Mutation";
9
+ }
10
+ export type PromptMode = "full" | "chat";
11
+ export interface PromptOptions {
12
+ mode?: PromptMode;
13
+ /** Replace the default opening sentence describing the assistant's role. */
14
+ preamble?: string;
15
+ /** Bullets appended under an `## Additional rules` section near the end. */
16
+ additionalRules?: ReadonlyArray<string>;
17
+ /** Worked-example snippets shown under `## Examples`. Defaults to a curated set. */
18
+ examples?: ReadonlyArray<string>;
19
+ /** Host-provided endpoint catalogue. Surfaced under `## Available endpoints`. */
20
+ tools?: ReadonlyArray<ToolSpec>;
21
+ /** Endpoint usage examples. Surfaced under `## Endpoint examples`. */
22
+ toolExamples?: ReadonlyArray<string>;
23
+ /** Force-include the HTTP/tool-calling teaching sections in `full` mode. */
24
+ toolCalls?: boolean;
25
+ /** Force-include the reactive-state + builtins sections in `full` mode. */
26
+ bindings?: boolean;
27
+ /** Permit fenced ```aktion blocks inside markdown prose (full mode). */
28
+ inlineMode?: boolean;
29
+ /** Tell the LLM to emit only changed statements (full mode). */
30
+ editMode?: boolean;
31
+ }
32
+ export declare function generatePrompt(library: ComponentLibrary, options?: PromptOptions): string;
33
+ export declare function describeComponentSpec(spec: ComponentSpec): string;
@@ -0,0 +1 @@
1
+ export * from './generator.js';
@@ -0,0 +1 @@
1
+ export * from './renderer.js';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Minimal DOM reconciler ("morph").
3
+ *
4
+ * The renderer used to discard the whole subtree on every state change and
5
+ * recreate it from scratch (`replaceChildren(newTree)`). That works for static
6
+ * UIs but destroys any state the browser owns on the live DOM:
7
+ *
8
+ * - text-input value, selection, IME composition
9
+ * - scroll position of a long list
10
+ * - <details>.open after the user clicked the summary
11
+ * - focus on a typed input (email/number/url, where setSelectionRange
12
+ * throws and the cursor jumps to the start)
13
+ *
14
+ * `morphChildren(container, newRoot)` walks the live DOM in parallel with the
15
+ * freshly-rendered DOM, keeps as many existing nodes as possible, and only
16
+ * patches what changed. The result is a React-like reconciliation pass that
17
+ * keeps form fields stable while still letting the renderer rebuild the
18
+ * tree every tick.
19
+ *
20
+ * Two contracts the rest of the runtime relies on:
21
+ *
22
+ * 1. Event handlers are attached as DOM properties (`el.onclick = fn`)
23
+ * rather than via `addEventListener`. This lets the morph copy the
24
+ * fresh closure (`newEl.onclick`) onto the kept node (`oldEl.onclick`)
25
+ * without leaking the previous listener.
26
+ * 2. Components that own UI state across re-renders (e.g. `Tabs` active
27
+ * pane) use `helpers.useInstanceState(...)`. The morph just reuses
28
+ * the existing DOM; whatever attribute values land in the fresh tree
29
+ * are the ones that get applied.
30
+ */
31
+ /**
32
+ * Patch `container` so its children match `newRoot`. `newRoot` can be a
33
+ * `DocumentFragment` (treated as a sibling list) or a single node (treated
34
+ * as the sole child).
35
+ */
36
+ export declare function morphChildren(container: Element, newRoot: Node): void;
37
+ /**
38
+ * Reconcile a single live node against its freshly-rendered counterpart.
39
+ * Returns the resulting node (either the patched `oldNode` or a freshly
40
+ * inserted `newNode`).
41
+ */
42
+ export declare function morphNode(oldNode: Node, newNode: Node): Node;
@@ -0,0 +1,73 @@
1
+ import { EvaluationContext } from '../runtime/evaluator.js';
2
+ import { StateStore } from '../runtime/state.js';
3
+ import { Router } from '../runtime/router.js';
4
+ import { ComponentLibrary } from '../library/types.js';
5
+ export interface RenderOptions {
6
+ library: ComponentLibrary;
7
+ state: StateStore;
8
+ /** Hash-based router. Required: components read the active path through it. */
9
+ router: Router;
10
+ /** Optional callback for `helpers.sendToAssistant(message)` dispatch. */
11
+ onAssistantMessage?: (message: string) => void;
12
+ /** Optional override for `helpers.openUrl(url)` (defaults to `window.open`). */
13
+ onOpenUrl?: (url: string) => void;
14
+ /**
15
+ * Evaluation context used to expand user-declared `component` calls
16
+ * (per-instance state isolation, lazy body evaluation, §7). The host
17
+ * element passes its program context here; if absent, user components
18
+ * render as `[unknown component: <Name>]` so the failure is visible.
19
+ */
20
+ evaluationContext?: () => EvaluationContext;
21
+ }
22
+ export declare class Renderer {
23
+ private options;
24
+ /**
25
+ * Persistent state cells, keyed by `instancePath::userKey`. Lives as long
26
+ * as the component instance is rendered. Stale entries are garbage-
27
+ * collected at the end of each render (see `endRender`).
28
+ */
29
+ private readonly instanceStates;
30
+ /**
31
+ * Cleanup callbacks per instance path. Each entry holds either a single
32
+ * disposer (anonymous registration) or a map keyed by user-provided
33
+ * identifier so callers can register, replace, and (transitively) cancel
34
+ * prior cleanups for the same logical concern.
35
+ */
36
+ private readonly instanceDisposers;
37
+ /** Instance paths seen during the current render — used to GC stale state. */
38
+ private aliveInstances;
39
+ constructor(options: RenderOptions);
40
+ /**
41
+ * Swap the component library backing this renderer. Used when the host
42
+ * element calls `registerComponents(...)` after first paint — preserves
43
+ * any `useInstanceState` slots so stateful primitives (Tabs, Popover,
44
+ * DropdownMenu, …) don't snap back to their initial values mid-session.
45
+ */
46
+ setLibrary(library: ComponentLibrary): void;
47
+ /**
48
+ * Drop all persistent per-instance state. Called when the host element
49
+ * is `clear()`ed so a fresh program starts with a clean slate.
50
+ */
51
+ reset(): void;
52
+ /** Begin a fresh render pass; tracks which instances are still alive. */
53
+ beginRender(): void;
54
+ /**
55
+ * End the current render pass. Drops instance state for components that
56
+ * disappeared from the tree so the map doesn't grow unbounded.
57
+ */
58
+ endRender(): void;
59
+ private safeDispose;
60
+ render(value: unknown): Node;
61
+ private renderAt;
62
+ /**
63
+ * Expand a user-declared `component Foo(p) { ... }` invocation. Each
64
+ * instance gets a stable instance key derived from its render path (or
65
+ * the caller's explicit `key:` override); the evaluator then evaluates
66
+ * the component's body with a fresh per-instance state-alias scope so
67
+ * two `Counter()` instances hold independent atoms (§7).
68
+ */
69
+ private renderUserComponent;
70
+ private renderComponent;
71
+ private eventFor;
72
+ private defaultValueGetter;
73
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Built-in `@Name(...)` functions for Aktion.
3
+ *
4
+ * These are pure data transformations. The legacy action-step builtins
5
+ * (`@Run`, `@Set`, `@Reset`, `@ToAssistant`, `@OpenUrl`, `@Navigate`,
6
+ * `@Js`) and the `@Const` memo helper were removed. Use `action <Name>() {
7
+ * … }` declarations + lambda handlers (`onClick: save`) instead, and just
8
+ * `$name = expression` for plain reactive bindings.
9
+ */
10
+ export type BuiltinFn = (args: unknown[]) => unknown;
11
+ export declare const dataBuiltins: Record<string, BuiltinFn>;
12
+ /**
13
+ * Marker emitted by the `Theme({...})` construct. Carries an arbitrary token
14
+ * map that the element applies on top of the base theme between render
15
+ * cycles. Distinct from `ComponentNode` so the renderer can ignore it (it is
16
+ * a side-effect, not a piece of UI to draw).
17
+ *
18
+ * Authors declare a theme like any other top-level binding:
19
+ *
20
+ * theme = Theme({ colors: { primary: "#0969da" }, radius: { button: "6px" } })
21
+ * root = Stack([...])
22
+ */
23
+ export interface ThemeNode {
24
+ kind: "Theme";
25
+ tokens: Record<string, string>;
26
+ }
27
+ export declare const isThemeNode: (value: unknown) => value is ThemeNode;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Console namespace for Aktion.
3
+ *
4
+ * Exposes a `console` global that forwards to the browser's built-in
5
+ * `console` methods (`log`, `error`, `warn`, `info`, `debug`). The
6
+ * forwarder gracefully no-ops when no global console is available (e.g.
7
+ * during SSR or inside a worker without a console binding) so authors
8
+ * can sprinkle `console.log(...)` calls without breaking partial-stream
9
+ * renders.
10
+ *
11
+ * The runtime intentionally does NOT shadow JavaScript's full console
12
+ * surface — just the five methods that LLM-authored scripts reach for.
13
+ */
14
+ export interface ConsoleNamespace {
15
+ log: (...args: unknown[]) => void;
16
+ error: (...args: unknown[]) => void;
17
+ warn: (...args: unknown[]) => void;
18
+ info: (...args: unknown[]) => void;
19
+ debug: (...args: unknown[]) => void;
20
+ }
21
+ export declare const consoleNs: ConsoleNamespace;
@@ -0,0 +1,69 @@
1
+ import { ActionDeclaration, EffectDeclaration } from '../parser/types.js';
2
+ import { EvaluationContext } from './evaluator.js';
3
+ import { StateStore } from './state.js';
4
+ export interface EffectRunnerOptions {
5
+ state: StateStore;
6
+ /** Called whenever an effect mutates state or completes — schedules render. */
7
+ notify: () => void;
8
+ /** Called when the action body emits a CustomEvent via `emit`. */
9
+ onEmit?: (eventName: string, detail: unknown) => void;
10
+ /** Host element — exposed to `js{}` block bodies as `ctx.host`. */
11
+ host?: HTMLElement;
12
+ /**
13
+ * Optional pluggable async tool registry — exposed to `js{}` blocks as
14
+ * `ctx.tools.<name>(...)`. Each entry is invoked with whatever args the
15
+ * JS body passes; the return value is awaited. Hosts can register fetch
16
+ * shims, persistence helpers, etc.
17
+ */
18
+ tools?: Record<string, (...args: unknown[]) => unknown>;
19
+ }
20
+ export declare class EffectRunner {
21
+ private readonly options;
22
+ private mounted;
23
+ private errors;
24
+ constructor(options: EffectRunnerOptions);
25
+ /** Get any errors raised at mount-time (denied capabilities, parse issues). */
26
+ getErrors(): ReadonlyArray<string>;
27
+ /**
28
+ * Mount every effect declaration in `decls`. Idempotent: declarations
29
+ * that are already mounted under the same name are left alone, those
30
+ * that vanish from the new program are torn down.
31
+ */
32
+ syncEffects(decls: ReadonlyArray<EffectDeclaration>, getCtx: () => EvaluationContext): void;
33
+ reset(): void;
34
+ private mount;
35
+ private unmount;
36
+ }
37
+ interface JsBlockExecOptions {
38
+ state: StateStore;
39
+ host?: HTMLElement;
40
+ tools?: Record<string, (...args: unknown[]) => unknown>;
41
+ }
42
+ /**
43
+ * Build a standalone `js{ … }` runner closure for the renderer / inline
44
+ * lambdas to invoke. Identical sandbox surface as the effect/action
45
+ * runners (host, tools, state get/set, optional cleanup hook).
46
+ */
47
+ export declare function createInlineJsExecutor(options: JsBlockExecOptions): (body: string, args?: Record<string, unknown>) => unknown;
48
+ export interface ActionRunnerOptions {
49
+ state: StateStore;
50
+ notify: () => void;
51
+ onEmit?: (eventName: string, detail: unknown) => void;
52
+ onAssistantMessage?: (message: string) => void;
53
+ /** Host element exposed to `js{}` blocks as `ctx.host`. */
54
+ host?: HTMLElement;
55
+ /** Pluggable tool registry exposed to `js{}` blocks as `ctx.tools.<name>`. */
56
+ tools?: Record<string, (...args: unknown[]) => unknown>;
57
+ }
58
+ /**
59
+ * Run an `action` declaration. When the declaration is `optimistic` we
60
+ * snapshot every state atom touched before the first `await`; if any
61
+ * subsequent step throws, the snapshot is restored.
62
+ */
63
+ export declare class ActionDeclRunner {
64
+ private readonly options;
65
+ constructor(options: ActionRunnerOptions);
66
+ run(decl: ActionDeclaration, callArgs: unknown[], ctx: EvaluationContext): Promise<unknown>;
67
+ private runStatement;
68
+ }
69
+ export {};