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.
- package/README.md +1246 -0
- package/dist/aktion.iife.js +8431 -0
- package/dist/aktion.iife.js.map +1 -0
- package/dist/aktion.js +22594 -0
- package/dist/aktion.js.map +1 -0
- package/dist/aktion.umd.cjs +8431 -0
- package/dist/aktion.umd.cjs.map +1 -0
- package/dist/index.cjs +3 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/system_prompt.txt +1095 -0
- package/dist/system_prompt_chat.txt +404 -0
- package/dist/types/element.d.ts +175 -0
- package/dist/types/icons/index.d.ts +45 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/language/builtins.d.ts +33 -0
- package/dist/types/language/components.d.ts +28 -0
- package/dist/types/language/grammar.d.ts +121 -0
- package/dist/types/language/index.d.ts +41 -0
- package/dist/types/language/snippets.d.ts +17 -0
- package/dist/types/library/components/_internal.d.ts +56 -0
- package/dist/types/library/components/advanced-charts.d.ts +6 -0
- package/dist/types/library/components/advanced-data.d.ts +6 -0
- package/dist/types/library/components/advanced-forms.d.ts +12 -0
- package/dist/types/library/components/advanced-patterns.d.ts +13 -0
- package/dist/types/library/components/charts.d.ts +5 -0
- package/dist/types/library/components/chat.d.ts +6 -0
- package/dist/types/library/components/content.d.ts +33 -0
- package/dist/types/library/components/data.d.ts +9 -0
- package/dist/types/library/components/editors.d.ts +5 -0
- package/dist/types/library/components/feedback.d.ts +14 -0
- package/dist/types/library/components/forms-shared.d.ts +7 -0
- package/dist/types/library/components/forms.d.ts +21 -0
- package/dist/types/library/components/helpers.d.ts +33 -0
- package/dist/types/library/components/layout.d.ts +20 -0
- package/dist/types/library/components/media.d.ts +7 -0
- package/dist/types/library/components/menu.d.ts +5 -0
- package/dist/types/library/components/navigation.d.ts +6 -0
- package/dist/types/library/components/new-components.d.ts +13 -0
- package/dist/types/library/components/patterns.d.ts +39 -0
- package/dist/types/library/components/router.d.ts +2 -0
- package/dist/types/library/components/theme.d.ts +2 -0
- package/dist/types/library/index.d.ts +5 -0
- package/dist/types/library/registry.d.ts +15 -0
- package/dist/types/library/types.d.ts +140 -0
- package/dist/types/library/utils.d.ts +73 -0
- package/dist/types/library/validate.d.ts +27 -0
- package/dist/types/parser/frontier.d.ts +65 -0
- package/dist/types/parser/index.d.ts +4 -0
- package/dist/types/parser/lexer.d.ts +46 -0
- package/dist/types/parser/parser.d.ts +2 -0
- package/dist/types/parser/types.d.ts +349 -0
- package/dist/types/prompt/generator.d.ts +33 -0
- package/dist/types/prompt/index.d.ts +1 -0
- package/dist/types/renderer/index.d.ts +1 -0
- package/dist/types/renderer/morph.d.ts +42 -0
- package/dist/types/renderer/renderer.d.ts +73 -0
- package/dist/types/runtime/builtins.d.ts +27 -0
- package/dist/types/runtime/console.d.ts +21 -0
- package/dist/types/runtime/effects.d.ts +69 -0
- package/dist/types/runtime/evaluator.d.ts +151 -0
- package/dist/types/runtime/http.d.ts +85 -0
- package/dist/types/runtime/i18n.d.ts +40 -0
- package/dist/types/runtime/index.d.ts +9 -0
- package/dist/types/runtime/router.d.ts +105 -0
- package/dist/types/runtime/state.d.ts +84 -0
- package/dist/types/runtime/storage.d.ts +50 -0
- package/dist/types/theme/index.d.ts +175 -0
- package/dist/types/theme/styles.d.ts +9 -0
- package/dist/types/tooling/codemod.d.ts +36 -0
- package/dist/types/tooling/delta.d.ts +74 -0
- package/dist/types/tooling/formatter.d.ts +8 -0
- package/dist/types/tooling/index.d.ts +29 -0
- package/dist/types/tooling/inspector.d.ts +49 -0
- package/dist/types/tooling/language-service.d.ts +57 -0
- 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 {};
|