aktion-runtime 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -94,9 +94,12 @@ Everything you need at runtime ships in a single bundle:
94
94
  work — anonymous blocks where the dependency list mixes state triggers
95
95
  (`$atom`), lifecycle triggers (`on:mount`, `on:unmount`, `on:every(N)`),
96
96
  and rate-limit modifiers (`debounce(N)`, `throttle(N)`). `effect { … }`
97
- with an empty list is equivalent to `effect [on:mount] { … }`.
98
- `action Name(args) { }` declares click-driven mutations and may
99
- optionally `return` a value.
97
+ with an empty list is equivalent to `effect [on:mount] { … }`. Declare
98
+ an effect **at the top level** for program-wide work, or **inside a
99
+ `component { … }` body** to scope it to a single instance — timers,
100
+ watched atoms, and `cleanup(fn)` registrations tear down when the
101
+ component leaves the tree. `action Name(args) { … }` declares
102
+ click-driven mutations and may optionally `return` a value.
100
103
  - **A built-in router.** `pages = _router_({ "/path": Component(), "/users/:id": UserPage(id: params.id), default: NotFound() })` plus
101
104
  `NavLink(label, to)` and a reserved `_route_` handle that exposes
102
105
  `_route_.path`, `_route_.params`, `_route_.query`, `_route_.pattern`,
@@ -147,26 +150,26 @@ For non-module setups (older bundlers, embedded contexts) use the IIFE build:
147
150
  …or install from npm and import once from your client-side entry point:
148
151
 
149
152
  ```bash
150
- npm install @aktion/runtime
151
- # yarn add @aktion/runtime
152
- # pnpm add @aktion/runtime
153
+ npm install aktion-runtime
154
+ # yarn add aktion-runtime
155
+ # pnpm add aktion-runtime
153
156
  ```
154
157
 
155
158
  ```js
156
- import "@aktion/runtime";
159
+ import "aktion-runtime";
157
160
  ```
158
161
 
159
162
  The package is published as
160
- [`@aktion/runtime`](https://www.npmjs.com/package/@aktion/runtime). The
163
+ [`aktion-runtime`](https://www.npmjs.com/package/aktion-runtime). The
161
164
  npm tarball ships only the compiled `dist/` output (ESM + CJS + UMD +
162
165
  IIFE bundles, type declarations, the stylesheet, and the two
163
166
  `system_prompt*.txt` files), so installs stay small. Subpath imports
164
167
  are available for convenience:
165
168
 
166
169
  ```js
167
- import "@aktion/runtime/style.css";
170
+ import "aktion-runtime/style.css";
168
171
  const SYSTEM_PROMPT = await fetch(
169
- new URL("@aktion/runtime/system_prompt.txt", import.meta.url),
172
+ new URL("aktion-runtime/system_prompt.txt", import.meta.url),
170
173
  ).then((r) => r.text());
171
174
  ```
172
175
 
@@ -385,7 +388,11 @@ _app_ = pages
385
388
  lifecycle / interval triggers (`on:mount`, `on:unmount`,
386
389
  `on:every(N)`), and rate-limit modifiers (`debounce(N)`,
387
390
  `throttle(N)`). `effect { ... }` (no brackets) is equivalent to
388
- `effect [on:mount] { ... }`.
391
+ `effect [on:mount] { ... }`. Declare at the program top level for
392
+ global work, or inside a `component { … }` body to scope the effect
393
+ to that instance — the runtime mounts it on first render and tears
394
+ down its timers / subscriptions / `cleanup(fn)` handlers when the
395
+ instance leaves the tree.
389
396
  - Expression-form control flow: `if cond { … } else { … }`,
390
397
  `match expr { "a": A() default: Else() }`, `for x in xs { Row(x) }`.
391
398
  Match and router arms use `:` and `default:` (not `->` / `_`).
@@ -489,6 +496,33 @@ component TaskRow(task) {
489
496
  }
490
497
  ```
491
498
 
499
+ ### Component-scoped effects
500
+
501
+ `effect [ ...deps ] { … }` blocks can live at the program top level
502
+ **or** inside a `component { … }` body. Inside a component body the
503
+ runtime mounts the effect when the instance first renders and tears it
504
+ down (clearing timers, unsubscribing watched atoms, firing every
505
+ registered `cleanup(fn)`) the moment the instance disappears from the
506
+ tree. Two `LiveClock()` calls produce two independent intervals — and
507
+ removing one stops only that one:
508
+
509
+ ```text
510
+ _app_ = Stack([LiveClock("UTC"), LiveClock("Local")])
511
+
512
+ component LiveClock(label) {
513
+ $now = @Now()
514
+ effect [on:every(1000)] {
515
+ $now = @Now()
516
+ }
517
+ return Stack([Text(label), Text(@FormatDate($now, "time"))])
518
+ }
519
+ ```
520
+
521
+ Use a top-level `effect [...] { … }` for global work (analytics,
522
+ app-wide keyboard shortcuts, hydration of shared atoms); use a
523
+ component-local effect whenever the background work logically belongs
524
+ to the UI it serves.
525
+
492
526
  ### Schema-as-truth diagnostics
493
527
 
494
528
  `validateProgramSchema(program, library)` (exported from
@@ -947,7 +981,7 @@ import {
947
981
  getDiagnostics, // merged parse + schema errors (LSP-ready)
948
982
  getCompletions, // context-aware completions
949
983
  getHoverInfo, // hover docs for symbols
950
- } from "@aktion/runtime";
984
+ } from "aktion-runtime";
951
985
  ```
952
986
 
953
987
  - `formatProgram` projects the parsed AST back to canonical source —
@@ -981,7 +1015,7 @@ consumes from the CDN.
981
1015
  | `language.html` | Full Aktion language reference. |
982
1016
  | `components.html` | Every built-in component with a live preview, positional signatures, prop tables, and enum values. |
983
1017
  | `actions.html` | `action Name() { … }` guide — declarative state mutations, optimistic snapshot/rollback, lambda-based click handlers, navigation, and end-to-end examples. |
984
- | `side-effects.html` | `effect [ ...deps ] { … }` guide — anonymous side effects, dependency entries (state, lifecycle, intervals, debounce/throttle), cleanup, and effect vs. action. |
1018
+ | `side-effects.html` | `effect [ ...deps ] { … }` guide — anonymous side effects, dependency entries (state, lifecycle, intervals, debounce/throttle), top-level vs. component-local scope, cleanup, and effect vs. action. |
985
1019
  | `javascript-interactions.html` | `effect [ ...deps ] { js { … } }` + action `js{}` bodies — the JS escape hatch. |
986
1020
  | `routing.html` | Hash-based routing guide — always available at runtime. |
987
1021
  | `themes.html` | Built-in themes gallery, live picker, side-by-side compare, and the token customization studio. |
@@ -1098,7 +1132,7 @@ dist/system_prompt_chat.txt # Compact chat-focused prompt
1098
1132
 
1099
1133
  ### Publish to npm
1100
1134
 
1101
- The package is published as `@aktion/runtime`. The `files` field
1135
+ The package is published as `aktion-runtime`. The `files` field
1102
1136
  restricts the tarball to `dist/` only, and `prepublishOnly` runs the
1103
1137
  full build, so a release is:
1104
1138