@vielzeug/codex 2.1.1 → 2.1.4
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/data/catalog.json +17 -13
- package/data/llms-full.txt +16 -44
- package/data/llms.txt +2 -2
- package/data/manifest.json +1 -1
- package/data/packages/arsenal.json +1 -1
- package/data/packages/assay.json +26 -26
- package/data/packages/clockwork.json +3 -3
- package/data/packages/codex.json +23 -23
- package/data/packages/coins.json +5 -5
- package/data/packages/conduit.json +8 -8
- package/data/packages/courier.json +8 -8
- package/data/packages/dnd.json +6 -6
- package/data/packages/familiar.json +9 -9
- package/data/packages/flux.json +9 -9
- package/data/packages/forge.json +2 -2
- package/data/packages/keymap.json +6 -6
- package/data/packages/lingua.json +22 -22
- package/data/packages/necromancer.json +2 -2
- package/data/packages/orbit.json +21 -21
- package/data/packages/ore.json +49 -49
- package/data/packages/prism.json +22 -22
- package/data/packages/pulse.json +17 -17
- package/data/packages/ripple.json +22 -16
- package/data/packages/rune.json +29 -29
- package/data/packages/scout.json +2 -2
- package/data/packages/scroll.json +15 -15
- package/data/packages/sourcerer.json +28 -28
- package/data/packages/spell.json +23 -23
- package/data/packages/tempo.json +14 -14
- package/data/packages/vault.json +4 -4
- package/data/packages/ward.json +25 -25
- package/data/packages/wayfinder.json +44 -44
- package/data/refine.json +3649 -3457
- package/data/search.json +33 -33
- package/dist/catalog.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/http.js +1 -1
- package/dist/http.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/snapshot.js.map +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/packages.js.map +1 -1
- package/dist/tools/refine.js.map +1 -1
- package/mcp-setup.json +5 -5
- package/package.json +20 -20
package/data/catalog.json
CHANGED
|
@@ -196,7 +196,7 @@
|
|
|
196
196
|
"refine"
|
|
197
197
|
],
|
|
198
198
|
"slug": "codex",
|
|
199
|
-
"version": "2.1.
|
|
199
|
+
"version": "2.1.3"
|
|
200
200
|
},
|
|
201
201
|
{
|
|
202
202
|
"availableDocPages": [
|
|
@@ -479,7 +479,7 @@
|
|
|
479
479
|
"courier"
|
|
480
480
|
],
|
|
481
481
|
"slug": "flux",
|
|
482
|
-
"version": "2.0.
|
|
482
|
+
"version": "2.0.3"
|
|
483
483
|
},
|
|
484
484
|
{
|
|
485
485
|
"availableDocPages": [
|
|
@@ -663,7 +663,7 @@
|
|
|
663
663
|
"vault"
|
|
664
664
|
],
|
|
665
665
|
"slug": "ledger",
|
|
666
|
-
"version": "2.1.
|
|
666
|
+
"version": "2.1.1"
|
|
667
667
|
},
|
|
668
668
|
{
|
|
669
669
|
"availableDocPages": [
|
|
@@ -787,7 +787,7 @@
|
|
|
787
787
|
"prism"
|
|
788
788
|
],
|
|
789
789
|
"slug": "orbit",
|
|
790
|
-
"version": "2.0.
|
|
790
|
+
"version": "2.0.1"
|
|
791
791
|
},
|
|
792
792
|
{
|
|
793
793
|
"availableDocPages": [
|
|
@@ -855,7 +855,7 @@
|
|
|
855
855
|
"orbit"
|
|
856
856
|
],
|
|
857
857
|
"slug": "ore",
|
|
858
|
-
"version": "2.0.
|
|
858
|
+
"version": "2.0.4"
|
|
859
859
|
},
|
|
860
860
|
{
|
|
861
861
|
"availableDocPages": [
|
|
@@ -911,7 +911,7 @@
|
|
|
911
911
|
"orbit"
|
|
912
912
|
],
|
|
913
913
|
"slug": "prism",
|
|
914
|
-
"version": "2.1.
|
|
914
|
+
"version": "2.1.1"
|
|
915
915
|
},
|
|
916
916
|
{
|
|
917
917
|
"availableDocPages": [
|
|
@@ -966,7 +966,7 @@
|
|
|
966
966
|
"clockwork"
|
|
967
967
|
],
|
|
968
968
|
"slug": "pulse",
|
|
969
|
-
"version": "2.1.
|
|
969
|
+
"version": "2.1.1"
|
|
970
970
|
},
|
|
971
971
|
{
|
|
972
972
|
"availableDocPages": [
|
|
@@ -1064,7 +1064,7 @@
|
|
|
1064
1064
|
"keymap"
|
|
1065
1065
|
],
|
|
1066
1066
|
"slug": "refine",
|
|
1067
|
-
"version": "2.
|
|
1067
|
+
"version": "2.1.1"
|
|
1068
1068
|
},
|
|
1069
1069
|
{
|
|
1070
1070
|
"availableDocPages": [
|
|
@@ -1074,7 +1074,7 @@
|
|
|
1074
1074
|
"examples"
|
|
1075
1075
|
],
|
|
1076
1076
|
"category": "state",
|
|
1077
|
-
"description": "Framework-agnostic signals, derived values, effects, scopes,
|
|
1077
|
+
"description": "Framework-agnostic signals, derived values, effects, scopes, watchers, and async resources.",
|
|
1078
1078
|
"exampleIds": [
|
|
1079
1079
|
"async-resource",
|
|
1080
1080
|
"basic-signal",
|
|
@@ -1092,6 +1092,8 @@
|
|
|
1092
1092
|
"batch",
|
|
1093
1093
|
"createScope",
|
|
1094
1094
|
"untrack",
|
|
1095
|
+
"watch",
|
|
1096
|
+
"resource",
|
|
1095
1097
|
"isReactive"
|
|
1096
1098
|
],
|
|
1097
1099
|
"hasSource": true,
|
|
@@ -1103,6 +1105,8 @@
|
|
|
1103
1105
|
"graph",
|
|
1104
1106
|
"scope",
|
|
1105
1107
|
"batch",
|
|
1108
|
+
"watch",
|
|
1109
|
+
"resource",
|
|
1106
1110
|
"async"
|
|
1107
1111
|
],
|
|
1108
1112
|
"name": "@vielzeug/ripple",
|
|
@@ -1112,7 +1116,7 @@
|
|
|
1112
1116
|
"ledger"
|
|
1113
1117
|
],
|
|
1114
1118
|
"slug": "ripple",
|
|
1115
|
-
"version": "2.0
|
|
1119
|
+
"version": "2.1.0"
|
|
1116
1120
|
},
|
|
1117
1121
|
{
|
|
1118
1122
|
"availableDocPages": [
|
|
@@ -1266,7 +1270,7 @@
|
|
|
1266
1270
|
"ripple"
|
|
1267
1271
|
],
|
|
1268
1272
|
"slug": "scout",
|
|
1269
|
-
"version": "2.1.
|
|
1273
|
+
"version": "2.1.1"
|
|
1270
1274
|
},
|
|
1271
1275
|
{
|
|
1272
1276
|
"availableDocPages": [
|
|
@@ -1321,7 +1325,7 @@
|
|
|
1321
1325
|
"refine"
|
|
1322
1326
|
],
|
|
1323
1327
|
"slug": "scroll",
|
|
1324
|
-
"version": "2.0.
|
|
1328
|
+
"version": "2.0.1"
|
|
1325
1329
|
},
|
|
1326
1330
|
{
|
|
1327
1331
|
"availableDocPages": [
|
|
@@ -1681,5 +1685,5 @@
|
|
|
1681
1685
|
"version": "2.0.0"
|
|
1682
1686
|
}
|
|
1683
1687
|
],
|
|
1684
|
-
"version": "2.1.
|
|
1688
|
+
"version": "2.1.3"
|
|
1685
1689
|
}
|
package/data/llms-full.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vielzeug — Full Documentation
|
|
2
2
|
|
|
3
|
-
> Complete documentation for 32 packages. Version: 2.1.
|
|
3
|
+
> Complete documentation for 32 packages. Version: 2.1.3
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -14826,7 +14826,6 @@ ripple.dispose();
|
|
|
14826
14826
|
- `createScope()` groups owned reactive work.
|
|
14827
14827
|
- `watch()` observes one selected source transition.
|
|
14828
14828
|
- `resource()` loads async values with stale-work cancellation.
|
|
14829
|
-
- `createStore()` wraps explicit value replacement and updater functions.
|
|
14830
14829
|
|
|
14831
14830
|
## Documentation
|
|
14832
14831
|
|
|
@@ -14856,17 +14855,13 @@ ripple.dispose();
|
|
|
14856
14855
|
| `untrack()` | Read without tracking | Sync | Read still happens immediately |
|
|
14857
14856
|
| `watch()` | Observe selected output | Sync | Use `effect()` for broad reads |
|
|
14858
14857
|
| `resource()` | Load async source | Async | Read dependencies in source callback |
|
|
14859
|
-
| `createStore()` | Hold replacement-based state | Sync | Return replacement objects from updates |
|
|
14860
14858
|
| `isReactive()` | Test `Readable` identity | Sync | Does not test arbitrary objects |
|
|
14861
14859
|
|
|
14862
14860
|
## Package Entry Point
|
|
14863
14861
|
|
|
14864
14862
|
| Import | Purpose |
|
|
14865
14863
|
| --- | --- |
|
|
14866
|
-
| `@vielzeug/ripple` |
|
|
14867
|
-
| `@vielzeug/ripple/watch` | `watch()` and `WatchOptions` |
|
|
14868
|
-
| `@vielzeug/ripple/async` | `resource()`, `Resource`, `AsyncState`, `ResourceOptions` |
|
|
14869
|
-
| `@vielzeug/ripple/store` | `createStore()`, `Store`, `StoreOptions` |
|
|
14864
|
+
| `@vielzeug/ripple` | All primitives, types, and errors — signals, computed, effects, scopes, watch, resource, and the isolated graph factory |
|
|
14870
14865
|
|
|
14871
14866
|
## Graph Creation
|
|
14872
14867
|
|
|
@@ -14926,7 +14921,7 @@ console.log(isReactive(signal(0)));
|
|
|
14926
14921
|
function signal(initial: T, options?: SignalOptions): Signal;
|
|
14927
14922
|
```
|
|
14928
14923
|
|
|
14929
|
-
Creates writable state on the default graph.
|
|
14924
|
+
Creates writable state on the default graph. Use `update()` for immutable replacement patterns.
|
|
14930
14925
|
|
|
14931
14926
|
**Returns:** `Signal`.
|
|
14932
14927
|
|
|
@@ -14937,6 +14932,9 @@ import { signal } from '@vielzeug/ripple';
|
|
|
14937
14932
|
|
|
14938
14933
|
const count = signal(0);
|
|
14939
14934
|
count.value += 1;
|
|
14935
|
+
|
|
14936
|
+
const cart = signal({ items: 0 });
|
|
14937
|
+
cart.update((state) => ({ ...state, items: state.items + 1 }));
|
|
14940
14938
|
```
|
|
14941
14939
|
|
|
14942
14940
|
---
|
|
@@ -14966,7 +14964,7 @@ console.log(doubled.value);
|
|
|
14966
14964
|
### `effect(callback, options?)`
|
|
14967
14965
|
|
|
14968
14966
|
```ts
|
|
14969
|
-
function effect(callback: () => Cleanup |
|
|
14967
|
+
function effect(callback: () => Cleanup | undefined, options?: EffectOptions): EffectHandle;
|
|
14970
14968
|
```
|
|
14971
14969
|
|
|
14972
14970
|
Runs immediately and reruns when its tracked reads change. A returned cleanup runs before the next callback or disposal.
|
|
@@ -15042,7 +15040,7 @@ scope.run(() => effect(() => console.log(count.value)));
|
|
|
15042
15040
|
scope.dispose();
|
|
15043
15041
|
```
|
|
15044
15042
|
|
|
15045
|
-
## Watch
|
|
15043
|
+
## Watch and Resources
|
|
15046
15044
|
|
|
15047
15045
|
### `watch(source, callback, options?)`
|
|
15048
15046
|
|
|
@@ -15061,8 +15059,7 @@ Observes selected output changes using the default graph or a `Ripple.watch()` m
|
|
|
15061
15059
|
**Example:**
|
|
15062
15060
|
|
|
15063
15061
|
```ts
|
|
15064
|
-
import { signal } from '@vielzeug/ripple';
|
|
15065
|
-
import { watch } from '@vielzeug/ripple/watch';
|
|
15062
|
+
import { signal, watch } from '@vielzeug/ripple';
|
|
15066
15063
|
|
|
15067
15064
|
const count = signal(0);
|
|
15068
15065
|
const stop = watch(count, (value, previous) => console.log(previous, value), { immediate: true });
|
|
@@ -15088,8 +15085,7 @@ Tracks `source`, aborts stale loader work, and exposes `AsyncState`. Source and
|
|
|
15088
15085
|
**Example:**
|
|
15089
15086
|
|
|
15090
15087
|
```ts
|
|
15091
|
-
import { signal } from '@vielzeug/ripple';
|
|
15092
|
-
import { resource } from '@vielzeug/ripple/async';
|
|
15088
|
+
import { resource, signal } from '@vielzeug/ripple';
|
|
15093
15089
|
|
|
15094
15090
|
const userId = signal('42');
|
|
15095
15091
|
const user = resource(() => userId.value, async (id) => ({ id }));
|
|
@@ -15098,27 +15094,6 @@ if (user.value.status === 'error') console.error(user.value.error);
|
|
|
15098
15094
|
user.dispose();
|
|
15099
15095
|
```
|
|
15100
15096
|
|
|
15101
|
-
---
|
|
15102
|
-
|
|
15103
|
-
### `createStore(initial, options?)`
|
|
15104
|
-
|
|
15105
|
-
```ts
|
|
15106
|
-
function createStore(initial: T, options?: StoreOptions): Store;
|
|
15107
|
-
```
|
|
15108
|
-
|
|
15109
|
-
Creates one writable value wrapper with explicit `set()` and `update()` operations.
|
|
15110
|
-
|
|
15111
|
-
**Returns:** `Store`.
|
|
15112
|
-
|
|
15113
|
-
**Example:**
|
|
15114
|
-
|
|
15115
|
-
```ts
|
|
15116
|
-
import { createStore } from '@vielzeug/ripple/store';
|
|
15117
|
-
|
|
15118
|
-
const user = createStore({ name: 'Ada', visits: 0 });
|
|
15119
|
-
user.update((value) => ({ ...value, visits: value.visits + 1 }));
|
|
15120
|
-
```
|
|
15121
|
-
|
|
15122
15097
|
## Types
|
|
15123
15098
|
|
|
15124
15099
|
```ts
|
|
@@ -15131,7 +15106,6 @@ type ComputedOptions = { equals?: Equality; name?: string };
|
|
|
15131
15106
|
type EffectOptions = { name?: string; scheduler?: 'microtask' | 'sync' };
|
|
15132
15107
|
type WatchOptions = { equals?: Equality; immediate?: boolean; name?: string; once?: boolean };
|
|
15133
15108
|
type ResourceOptions = { name?: string };
|
|
15134
|
-
type StoreOptions = { name?: string };
|
|
15135
15109
|
|
|
15136
15110
|
type ReactiveEvent =
|
|
15137
15111
|
| { readonly kind: 'compute'; readonly name?: string }
|
|
@@ -15155,19 +15129,17 @@ interface Readable {
|
|
|
15155
15129
|
readonly value: T;
|
|
15156
15130
|
}
|
|
15157
15131
|
|
|
15158
|
-
interface Signal extends Readable { value: T }
|
|
15132
|
+
interface Signal extends Readable { update(updater: (prev: T) => T): void; value: T }
|
|
15159
15133
|
interface Disposable { dispose(): void; readonly disposed: boolean; readonly disposalSignal: AbortSignal; [Symbol.dispose](): void }
|
|
15160
15134
|
type EffectHandle = Disposable;
|
|
15161
15135
|
interface Scope extends Disposable { run(fn: () => T): T }
|
|
15162
15136
|
|
|
15163
15137
|
interface Resource extends Readable>, Disposable { reload(): void }
|
|
15164
|
-
interface Store extends Readable { set(value: T): void; update(updater: (value: T) => T): void }
|
|
15165
15138
|
|
|
15166
15139
|
interface Ripple {
|
|
15167
15140
|
batch(fn: () => T): T;
|
|
15168
15141
|
computed(derive: () => T, options?: ComputedOptions): Readable;
|
|
15169
15142
|
createScope(name?: string): Scope;
|
|
15170
|
-
createStore(initial: T, options?: StoreOptions): Store;
|
|
15171
15143
|
dispose(): void;
|
|
15172
15144
|
readonly disposed: boolean;
|
|
15173
15145
|
effect(callback: () => Cleanup | void, options?: EffectOptions): EffectHandle;
|
|
@@ -15298,14 +15270,14 @@ user.dispose();
|
|
|
15298
15270
|
|
|
15299
15271
|
## Object State
|
|
15300
15272
|
|
|
15301
|
-
`
|
|
15273
|
+
`signal()` with `update()` holds one value and supports immutable replacement patterns. Return replacement objects from `update()` when object consumers depend on immutable updates.
|
|
15302
15274
|
|
|
15303
15275
|
```ts
|
|
15304
|
-
const cart = ripple.
|
|
15276
|
+
const cart = ripple.signal({ items: 0, label: 'empty' });
|
|
15305
15277
|
const items = ripple.computed(() => cart.value.items);
|
|
15306
15278
|
|
|
15307
15279
|
cart.update((state) => ({ ...state, items: state.items + 1 }));
|
|
15308
|
-
cart.
|
|
15280
|
+
cart.value = { items: 3, label: 'ready' };
|
|
15309
15281
|
|
|
15310
15282
|
console.log(items.value);
|
|
15311
15283
|
```
|
|
@@ -15431,7 +15403,7 @@ ripple.dispose();
|
|
|
15431
15403
|
- [Batch and Untrack](./examples/batch-and-untrack.md)
|
|
15432
15404
|
- [Scope Ownership](./examples/scope-ownership.md)
|
|
15433
15405
|
- [Watch Selected Value](./examples/watch-selected-value.md)
|
|
15434
|
-
- [
|
|
15406
|
+
- [Immutable State](./examples/immutable-store.md)
|
|
15435
15407
|
- [Isolated Graph](./examples/isolated-runtime.md)
|
|
15436
15408
|
- [Async Resource](./examples/async-resource.md)
|
|
15437
15409
|
|
|
@@ -15442,7 +15414,7 @@ ripple.dispose();
|
|
|
15442
15414
|
- Batch & Untrack (id: `batch-untrack`)
|
|
15443
15415
|
- Microtask Effect (id: `effect-options`)
|
|
15444
15416
|
- Nested Effect Ownership (id: `scope-ownership`)
|
|
15445
|
-
- Immutable
|
|
15417
|
+
- Immutable State (id: `store-basics`)
|
|
15446
15418
|
- Watch Selected Value (id: `watch-selected-value`)
|
|
15447
15419
|
|
|
15448
15420
|
---
|
package/data/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vielzeug
|
|
2
2
|
|
|
3
|
-
> 32 focused TypeScript packages. Version: 2.1.
|
|
3
|
+
> 32 focused TypeScript packages. Version: 2.1.3
|
|
4
4
|
|
|
5
5
|
Install any package independently: `pnpm add @vielzeug/<name>`
|
|
6
6
|
|
|
@@ -27,7 +27,7 @@ Install any package independently: `pnpm add @vielzeug/<name>`
|
|
|
27
27
|
- [@vielzeug/prism](/prism/): Reactive SVG charting library — line, bar, and area charts. Signal-driven updates, CSS-themeable, accessible.
|
|
28
28
|
- [@vielzeug/pulse](/pulse/): Explicitly connected, typed WebSocket sessions with scoped channels, presence, reconnect restoration, and heartbeat.
|
|
29
29
|
- [@vielzeug/refine](/refine/): Accessible, themeable web components built with Ore for framework and vanilla DOM apps.
|
|
30
|
-
- [@vielzeug/ripple](/ripple/): Framework-agnostic signals, derived values, effects, scopes,
|
|
30
|
+
- [@vielzeug/ripple](/ripple/): Framework-agnostic signals, derived values, effects, scopes, watchers, and async resources.
|
|
31
31
|
- [@vielzeug/rune](/rune/): Browser/Node logger with levels, namespaces, pluggable transports, lazy bindings, and timing helpers.
|
|
32
32
|
- [@vielzeug/sandbox](/sandbox/): Isolated iframe runtime with a typed postMessage bridge for safe execution of untrusted HTML — component previews, playgrounds, plugin sandboxes, and more.
|
|
33
33
|
- [@vielzeug/scout](/scout/): Trigram-indexed fuzzy search with per-field weights, match highlighting, and an optional reactive layer.
|
package/data/manifest.json
CHANGED
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
"typeSignatures": {
|
|
162
162
|
"ArsenalError": "export class ArsenalError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is ArsenalError {\n return err instanceof ArsenalError;\n }\n}",
|
|
163
163
|
"ArsenalSerializationError": "export class ArsenalSerializationError extends ArsenalError {}",
|
|
164
|
-
"chunk": "export function chunk(input: string, size?: number): string[];\n\nexport function chunk<T>(input: T[], size?: number): T[][];\n\nexport function chunk<T>(input: T[] | string, size = 2): string[] | T[][] {\n if (!Array.isArray(input) && typeof input !== 'string')\n throw new TypeError('chunk: argument must be an array or string');\n\n if (!Number.isInteger(size) || size < 1) throw new RangeError('chunk: size must be a positive integer');\n\n return Array.from({ length: Math.ceil(input.length / size) }, (_, i) => input.slice(i * size, i * size + size)) as\n string[]
|
|
164
|
+
"chunk": "export function chunk(input: string, size?: number): string[];\n\nexport function chunk<T>(input: T[], size?: number): T[][];\n\nexport function chunk<T>(input: T[] | string, size = 2): string[] | T[][] {\n if (!Array.isArray(input) && typeof input !== 'string')\n throw new TypeError('chunk: argument must be an array or string');\n\n if (!Number.isInteger(size) || size < 1) throw new RangeError('chunk: size must be a positive integer');\n\n return Array.from({ length: Math.ceil(input.length / size) }, (_, i) => input.slice(i * size, i * size + size)) as\n | string[]\n | T[][];\n}",
|
|
165
165
|
"filterMap": "export function filterMap<T, R>(array: T[], callback: (item: T, index: number, array: T[]) => R | undefined): R[] {\n const result: R[] = [];\n\n for (let index = 0; index < array.length; index++) {\n const value = callback(array[index], index, array);\n\n if (value !== undefined) {\n result.push(value);\n }\n }\n\n return result;\n}",
|
|
166
166
|
"groupBy": "export function groupBy<T>(array: T[], selector: (item: T) => Primitive): Record<string, T[]> {\n const result: Record<string, T[]> = {};\n\n for (const item of array) {\n const rawKey = selector(item);\n const key = rawKey === undefined || rawKey === null ? '_' : String(rawKey);\n\n if (isUnsafeKey(key)) continue;\n\n if (!result[key]) {\n result[key] = [];\n }\n\n result[key].push(item);\n }\n\n return result;\n}",
|
|
167
167
|
"indexBy": "export function indexBy<T>(array: T[], selector: (item: T) => Primitive): Record<string, T> {\n const result: Record<string, T> = {};\n\n for (const item of array) {\n const key = String(selector(item));\n\n if (isUnsafeKey(key)) continue;\n\n result[key] = item;\n }\n\n return result;\n}",
|
package/data/packages/assay.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"apiSource": "export { AssayError, AssayQueryError, AssayTimeoutError } from './errors';\n\nexport {\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n
|
|
2
|
+
"apiSource": "export { AssayError, AssayQueryError, AssayTimeoutError } from './errors';\n\nexport {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';\nexport { getSlotted, type QueryScope, queryAllInShadow, queryInShadow, queryPart, within } from './query';\nexport {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';\n",
|
|
3
3
|
"docs": {
|
|
4
4
|
"index": "---\ntitle: Assay — Framework-agnostic DOM testing primitives\ndescription: Scoped DOM queries, exact event dispatch, and cancellable async waiting for browser tests.\npackage: assay\ncategory: testing\nkeywords: [testing, dom, events, queries, custom-elements]\nrelated: [ore, refine]\nexports:\n [\n within,\n queryInShadow,\n queryAllInShadow,\n queryPart,\n getSlotted,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n waitUntil,\n retry,\n waitForEvent,\n delay,\n nextTick,\n AssayError,\n AssayQueryError,\n AssayTimeoutError,\n ]\nenvironments: [browser]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"assay\" />\n\n## Why Assay?\n\nAssay provides focused DOM test primitives that work with vanilla elements, custom elements, and framework-rendered output. It scopes queries, dispatches exact browser event classes, and waits on explicit conditions without imposing a renderer or browser automation stack.\n\n```ts\n// Before\nbutton.dispatchEvent(new MouseEvent('click', { bubbles: true }));\nawait new Promise((resolve) => setTimeout(resolve, 100));\n\n// After\nfireClick(view.get('button.submit'));\nawait waitUntil(() => view.queryByText('Saved') !== null);\n```\n\n| Feature | Assay | Testing Library DOM | Browser automation |\n| ------------------- | -------------------------------------------- | ---------------------------------------- | ---------------------------------------- |\n| Bundle size | <PackageInfo package=\"assay\" type=\"size\" /> | Larger query layer | Browser runtime required |\n| Zero dependencies | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Scoped DOM queries | `within()` and shadow helpers | Renderer-oriented queries | Manual selectors |\n| Deterministic waits | `waitUntil()` and `waitForEvent()` | Framework-dependent | Full browser timing |\n\n<div class=\"decision-callout\">\n\n**Use Assay when** a DOM unit test needs readable queries, dispatched events, or a bounded async wait without adopting a rendering framework.\n\n**Consider browser integration tests when** correctness depends on browser default actions, focus behavior, pointer capture, layout, or accessibility-tree behavior.\n\n</div>\n\n## Installation\n\n::: code-group\n\n```sh [pnpm]\npnpm add -D @vielzeug/assay\n```\n\n```sh [npm]\nnpm install -D @vielzeug/assay\n```\n\n```sh [yarn]\nyarn add -D @vielzeug/assay\n```\n\n:::\n\n## Quick Start\n\nScope a test fixture, dispatch an event, and wait for resulting DOM state.\n\n```ts\nimport { fireClick, waitUntil, within } from '@vielzeug/assay';\n\nconst panel = document.createElement('section');\npanel.innerHTML = '<button>Save</button><output></output>';\npanel.querySelector('button')!.addEventListener('click', () => {\n panel.querySelector('output')!.textContent = 'Saved';\n});\n\nconst view = within(panel);\nfireClick(view.get('button'));\nawait waitUntil(() => view.queryByText('Saved') !== null);\n```\n\n## Features\n\n<div class=\"features-grid\">\n\n- `within(root)` scopes nullable and required DOM queries.\n- `queryInShadow`, `queryPart`, and `getSlotted` cross custom-element boundaries explicitly.\n- `fireClick`, `fireInput`, `fireKeyDown`, and peers dispatch exact synchronous events.\n- `waitUntil`, `retry`, and `waitForEvent` provide bounded, abortable async waiting.\n- `delay` and `nextTick` model explicit timer and microtask scheduling.\n- `AssayError`, `AssayQueryError`, and `AssayTimeoutError` provide typed failures.\n\n</div>\n\n## Documentation\n\n<div class=\"doc-links\">\n\n- [Usage Guide](./usage.md)\n- [API Reference](./api.md)\n- [Examples](./examples.md)\n- [Migration Guide](./migration.md)\n\n</div>\n\n## See Also\n\n<div class=\"see-also\">\n\n- [Ore](/ore/) — component authoring and test fixtures that pair with Assay DOM helpers.\n- [Refine](/refine/) — accessible components with component-specific test assertions.\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
|
|
5
5
|
"api": "---\ntitle: Assay — API Reference\ndescription: API reference for @vielzeug/assay queries, event dispatch, and async waiting.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Execution mode | Common gotcha |\n| -------------------------------------------- | ------------------------------------------- | -------------- | ------------------------------------------------ |\n| `within` | Creates scoped query API | Sync | Required `get*` methods throw `AssayQueryError` |\n| `queryInShadow` / `queryPart` / `getSlotted` | Crosses custom-element boundaries | Sync | Open shadow roots are required |\n| `fire*` / `dispatch` | Dispatches platform event instances | Sync | Does not reproduce browser default behavior |\n| `waitUntil` / `retry` / `waitForEvent` | Waits for conditions, assertions, or events | Async | Use a signal or timeout for bounded waits |\n| `delay` / `nextTick` | Schedules timers or microtasks | Async | Prefer `nextTick()` for microtask-scheduled work |\n\n## Package Entry Point\n\n| Import | Purpose |\n| ----------------- | ---------------------------------------------------- |\n| `@vielzeug/assay` | DOM queries, events, wait helpers, errors, and types |\n\n## Queries\n\n### `within(root)`\n\nCreates a `QueryScope` for an `Element`, `ShadowRoot`, `Document`, or `DocumentFragment`.\n\n| Method | Returns | Use |\n| --------------------------------- | ----------------- | -------------------------------------------- |\n| `get(selector)` | `Element` | Required CSS match; throws `AssayQueryError` |\n| `query(selector)` | `Element \\| null` | Optional CSS match |\n| `queryAll(selector)` | `Element[]` | All CSS matches |\n| `getByText(text, selector?)` | `Element` | Required exact trimmed-text match |\n| `queryByText(text, selector?)` | `Element \\| null` | Optional exact trimmed-text match |\n| `queryAllByText(text, selector?)` | `Element[]` | All exact trimmed-text matches |\n| `getByTestId(id)` | `Element` | Required `data-testid` match |\n| `queryByTestId(id)` | `Element \\| null` | Optional `data-testid` match |\n| `queryAllByTestId(id)` | `Element[]` | All `data-testid` matches |\n\nText selectors default to `'*'`. Required-query failures include the lookup and a bounded view of the scoped DOM.\n\n### Shadow and slot helpers\n\n| Function | Returns | Description |\n| ---------------------------------- | ----------------- | ---------------------------------------------------- |\n| `queryInShadow(host, selector)` | `Element \\| null` | First match in an open shadow root |\n| `queryAllInShadow(host, selector)` | `Element[]` | All matches in an open shadow root |\n| `queryPart(host, part)` | `Element \\| null` | First shadow element whose `part` token matches |\n| `getSlotted(host, slotName?)` | `Element[]` | Direct light-DOM children in a named or default slot |\n\nThese helpers return `null` or `[]` when there is no shadow root. Dynamic test IDs, parts, and slot names are matched\nas attribute values rather than interpolated into CSS selectors.\n\n## Event dispatch\n\nAll event helpers synchronously return `dispatchEvent()`'s boolean result.\n\n```ts\nimport {\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from '@vielzeug/assay';\n\nfireClick(button, { clientX: 20 });\nfireInput(input);\nfireKeyDown(input, { key: 'Enter' });\nfireCustom(element, { detail: { id: '42' }, type: 'item-added' });\ndispatch(element, new Event('ready'));\n```\n\n| Function | Event class | Defaults |\n| --------------------------- | --------------- | ------------------------------------------------------ |\n| `fireBlur` / `fireFocus` | `FocusEvent` | Platform defaults (`bubbles: false`) |\n| `fireChange` | `Event` | `bubbles: true` |\n| `fireInput` | `InputEvent` | `bubbles: true` |\n| `fireClick` | `MouseEvent` | `bubbles: true`, `cancelable: true` |\n| `fireKeyDown` / `fireKeyUp` | `KeyboardEvent` | `bubbles: true`, `cancelable: true` |\n| `fireSubmit` | `SubmitEvent` | `bubbles: true`, `cancelable: true` |\n| `fireCustom` | `CustomEvent` | `bubbles: true`, `cancelable: true`, `composed: false` |\n\n`fireCustom(target, { type, ...init })` requires the event type in its options object. Assay intentionally does not\nprovide browser-default or fallback pointer/touch simulation.\n\n## Async waiting\n\n```ts\nawait waitUntil(() => ready, { interval: 20, signal, timeout: 1000 });\nawait retry(() => expect(spy).toHaveBeenCalled(), { signal, timeout: 1000 });\nawait waitForEvent(target, 'ready', { signal, timeout: 1000 });\nawait delay(100, { signal });\nawait nextTick();\n```\n\n| Function | Success condition | Options |\n| -------------------------------------- | ------------------------ | ------------------------------------------ |\n| `waitUntil(predicate, options?)` | Predicate returns `true` | `timeout`, `interval`, `signal` |\n| `retry(assertion, options?)` | Assertion stops throwing | `timeout`, `interval`, `signal`, `message` |\n| `waitForEvent(target, type, options?)` | Target emits `type` | `timeout`, `signal` |\n| `delay(ms?, options?)` | Timer elapses | `signal` |\n| `nextTick()` | Next microtask | none |\n\n`waitUntil`, `retry`, and `waitForEvent` reject with `AssayTimeoutError` when their timeout expires. A supplied abort\nsignal rejects with its reason and removes timers and event listeners.\n\n## Types\n\n```ts\nexport interface QueryScope {\n get(selector: string): Element;\n query(selector: string): Element | null;\n queryAll(selector: string): Element[];\n getByText(text: string, selector?: string): Element;\n queryByText(text: string, selector?: string): Element | null;\n queryAllByText(text: string, selector?: string): Element[];\n getByTestId(id: string): Element;\n queryByTestId(id: string): Element | null;\n queryAllByTestId(id: string): Element[];\n}\n```\n\n`CustomEventOptions`, `DelayOptions`, `RetryOptions`, and `WaitOptions` are exported option types for event and wait helpers.\n\n## Errors\n\n| Error | Meaning |\n| ------------------- | -------------------------------------- |\n| `AssayError` | Base class for Assay-originated errors |\n| `AssayQueryError` | A required `get*` query had no match |\n| `AssayTimeoutError` | A wait operation reached its timeout |\n\n`AssayError.is(value)` narrows any value to the Assay error hierarchy.\n",
|
|
@@ -11,30 +11,30 @@
|
|
|
11
11
|
"AssayError": "export { AssayError, AssayQueryError, AssayTimeoutError } from './errors';",
|
|
12
12
|
"AssayQueryError": "export { AssayError, AssayQueryError, AssayTimeoutError } from './errors';",
|
|
13
13
|
"AssayTimeoutError": "export { AssayError, AssayQueryError, AssayTimeoutError } from './errors';",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"queryAllInShadow": "export {
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
14
|
+
"CustomEventOptions": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
15
|
+
"dispatch": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
16
|
+
"fireBlur": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
17
|
+
"fireChange": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
18
|
+
"fireClick": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
19
|
+
"fireCustom": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
20
|
+
"fireFocus": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
21
|
+
"fireInput": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
22
|
+
"fireKeyDown": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
23
|
+
"fireKeyUp": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
24
|
+
"fireSubmit": "export {\n type CustomEventOptions,\n dispatch,\n fireBlur,\n fireChange,\n fireClick,\n fireCustom,\n fireFocus,\n fireInput,\n fireKeyDown,\n fireKeyUp,\n fireSubmit,\n} from './events';",
|
|
25
|
+
"getSlotted": "export { getSlotted, type QueryScope, queryAllInShadow, queryInShadow, queryPart, within } from './query';",
|
|
26
|
+
"QueryScope": "export { getSlotted, type QueryScope, queryAllInShadow, queryInShadow, queryPart, within } from './query';",
|
|
27
|
+
"queryAllInShadow": "export { getSlotted, type QueryScope, queryAllInShadow, queryInShadow, queryPart, within } from './query';",
|
|
28
|
+
"queryInShadow": "export { getSlotted, type QueryScope, queryAllInShadow, queryInShadow, queryPart, within } from './query';",
|
|
29
|
+
"queryPart": "export { getSlotted, type QueryScope, queryAllInShadow, queryInShadow, queryPart, within } from './query';",
|
|
30
|
+
"within": "export { getSlotted, type QueryScope, queryAllInShadow, queryInShadow, queryPart, within } from './query';",
|
|
31
|
+
"DelayOptions": "export {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';",
|
|
32
|
+
"delay": "export {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';",
|
|
33
|
+
"nextTick": "export {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';",
|
|
34
|
+
"RetryOptions": "export {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';",
|
|
35
|
+
"retry": "export {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';",
|
|
36
|
+
"WaitOptions": "export {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';",
|
|
37
|
+
"waitForEvent": "export {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';",
|
|
38
|
+
"waitUntil": "export {\n type DelayOptions,\n delay,\n nextTick,\n type RetryOptions,\n retry,\n type WaitOptions,\n waitForEvent,\n waitUntil,\n} from './wait';"
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"apiSource": "export { ClockworkError } from './errors.js';\nexport { defineMachine } from './interpret.js';\nexport type {\n Actor,\n ActorErrorContext,\n ActorErrorDisposition,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';\
|
|
2
|
+
"apiSource": "export type { ClockworkErrorCode } from './errors.js';\nexport { ClockworkError } from './errors.js';\nexport { defineMachine } from './interpret.js';\nexport type {\n Actor,\n ActorErrorContext,\n ActorErrorDisposition,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';\n",
|
|
3
3
|
"docs": {
|
|
4
4
|
"index": "---\ntitle: Clockwork — Typed finite state machines for TypeScript\ndescription: Framework-neutral typed state machines with pure transitions, actor-owned runtime work, timers, invokes, and explicit effects.\npackage: clockwork\ncategory: state\nkeywords: [state-machine, finite-state, typed, actor, async-tasks]\nrelated: [herald, ripple, ward]\nexports: [defineMachine, ClockworkError, Machine, Actor, MachineConfig, MachineSnapshot, TransitionResult]\nenvironments: [browser, node, ssr, deno]\n---\n\n<!-- markdownlint-disable MD025 MD033 MD060 -->\n\n<PackageHero package=\"clockwork\" />\n\n## Why Clockwork?\n\nApplication workflows often mix state changes with timers, requests, rendering, and cleanup. Clockwork keeps transition logic pure while each disposable actor owns runtime work. You can test state decisions without starting effects or invokes.\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\n\n// Before\nif (status === 'idle') status = 'loading';\nfetchItems().then((items) => {\n status = 'ready';\n data = items;\n});\n\n// After\ntype Event = { type: 'FETCH' } | { items: string[]; type: 'DONE' };\nconst machine = defineMachine<{ items: string[] }, Event>()({\n context: { items: [] },\n initial: 'idle',\n states: {\n idle: { on: { FETCH: { target: 'loading' } } },\n loading: {\n invoke: [{\n src: ({ signal }) => fetch('/api/items', { signal }).then((response) => response.json() as Promise<string[]>),\n onDone: ({ result }) => ({ items: result, type: 'DONE' }),\n }],\n on: { DONE: { reduce: ({ event }) => ({ items: event.items }), target: 'ready' } },\n },\n ready: {},\n },\n});\n```\n\n| Feature | Clockwork | XState | Zustand |\n| --- | --- | --- | --- |\n| Bundle size | <PackageInfo package=\"clockwork\" type=\"size\" /> | Larger actor/statechart runtime | Smaller store runtime |\n| Zero dependencies | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> | <ore-icon name=\"check\" size=\"16\"></ore-icon> |\n| Pure transition API | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"triangle-alert\" size=\"16\"></ore-icon> Statechart-focused | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Owned cancellation | <ore-icon name=\"check\" size=\"16\"></ore-icon> Actor disposal | <ore-icon name=\"check\" size=\"16\"></ore-icon> | <ore-icon name=\"x\" size=\"16\"></ore-icon> |\n| Framework coupling | <ore-icon name=\"check\" size=\"16\"></ore-icon> None | <ore-icon name=\"check\" size=\"16\"></ore-icon> None | <ore-icon name=\"check\" size=\"16\"></ore-icon> None |\n\n<div class=\"decision-callout\">\n\n**Use Clockwork when** your feature has explicit workflow states, cancellable work, or effects that must run after a state commit.\n\n**Consider XState when** you need statecharts, visual tooling, or its broader actor ecosystem.\n\n</div>\n\n## Installation\n\n::: code-group\n\n```sh [pnpm]\npnpm add @vielzeug/clockwork\n```\n\n```sh [npm]\nnpm install @vielzeug/clockwork\n```\n\n```sh [yarn]\nyarn add @vielzeug/clockwork\n```\n\n:::\n\n## Quick Start\n\nDefine the context and event union, create an actor, observe its snapshot, then dispose it when its owner ends.\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\n\ntype Event = { type: 'DEC' } | { type: 'INC' };\n\nconst counter = defineMachine<{ count: number }, Event>()({\n context: { count: 0 },\n initial: 'idle',\n states: {\n idle: {\n on: {\n DEC: { reduce: ({ context }) => ({ count: context.count - 1 }), target: 'idle' },\n INC: { reduce: ({ context }) => ({ count: context.count + 1 }), target: 'idle' },\n },\n },\n },\n});\n\nusing actor = counter.createActor();\nactor.subscribe((snapshot) => console.log(snapshot));\nactor.send({ type: 'INC' });\n// { context: { count: 1 }, state: 'idle' }\n```\n\n## Features\n\n<div class=\"features-grid\">\n\n- **`defineMachine()`** — validates and compiles one flat machine definition.\n- **`machine.transition()`** — evaluates a transition without actor runtime work.\n- **`machine.createActor()`** — creates isolated, disposable runtime ownership.\n- **`reduce`** — returns a replacement context from a transition.\n- **`effects`** — run only after the actor commits and notifies subscribers.\n- **`invoke`** — runs cancellable asynchronous work on state entry.\n- **`after`** — schedules cancellable delayed transitions.\n- **`actor.snapshot`** — exposes the current readonly state/context value.\n\n</div>\n\n## Documentation\n\n<div class=\"doc-links\">\n\n- [Usage Guide](./usage.md)\n- [API Reference](./api.md)\n- [Examples](./examples.md)\n- [Migration Guide](./migration.md)\n\n</div>\n\n## See Also\n\n<div class=\"see-also\">\n\n- [Herald](/herald/) — publish events between independent actors without coupling machine definitions.\n- [Ripple](/ripple/) — bridge actor snapshots into a reactive graph when you need fine-grained rendering.\n- [Ward](/ward/) — call authorization predicates from transition guards.\n\n</div>\n\n<!-- markdownlint-enable MD025 MD033 MD060 -->\n",
|
|
5
5
|
"api": "---\ntitle: Clockwork — API Reference\ndescription: Reference for Clockwork machine definitions, actors, devtools, and types.\n---\n\n[[toc]]\n\n## API Overview\n\n| Symbol | Purpose | Execution mode | Common gotcha |\n| --- | --- | --- | --- |\n| `defineMachine()` | Compile a typed flat machine definition | Sync | Call the generic factory before supplying the definition |\n| `Machine.transition()` | Resolve a pure next snapshot | Sync | Does not run effects, invokes, or timers |\n| `Machine.createActor()` | Create a runtime owner | Sync | Fresh and restored actors have different entry behavior |\n| `Actor.send()` | Dispatch an event | Sync | Returns `void`; re-entrant events queue internally |\n| `debugActor()` | Observe committed snapshots | Sync | Observes only; it does not trace sends or errors |\n| `ClockworkError` | Report definition and snapshot validation failures | Sync | Use `code`, not message text |\n\n## Package Entry Points\n\n| Import | Purpose |\n| --- | --- |\n| `@vielzeug/clockwork` | Machine compiler, actor runtime, errors, and types |\n| `@vielzeug/clockwork/devtools` | Opt-in snapshot observation through `debugActor()` |\n\n## Core Functions\n\n### `defineMachine()`\n\n```ts\nfunction defineMachine<\n Context extends Record<string, unknown> = Record<string, never>,\n Event extends MachineEvent = MachineEvent,\n>(): <State extends string>(definition: MachineConfig<State, Context, Event>) => Machine<State, Context, Event>;\n```\n\nReturns a factory that validates and compiles a typed flat machine definition. Context must be a non-array record. Omit `context` only when the context type has no keys.\n\n**Returns:** A definition function that returns `Machine`.\n\n**Example:**\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\n\ntype Event = { type: 'START' };\n\nconst machine = defineMachine<Record<string, never>, Event>()({\n initial: 'idle',\n states: { idle: { on: { START: { target: 'running' } } }, running: {} },\n});\n```\n\nThrows `ClockworkError` when a definition has an invalid context, initial state, target, transition, effect, invoke, or timer delay.\n\n---\n\n### `debugActor()`\n\n```ts\nfunction debugActor<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent>(\n actor: Actor<State, Context, Event>,\n options?: DebugActorOptions<State, Context>,\n): () => void;\n```\n\nSubscribes to committed actor snapshots and logs each one with `console.debug` by default. It does not modify actor behavior and does not observe dispatched events or runtime errors.\n\n**Returns:** An unsubscribe cleanup function.\n\n**Example:**\n\n```ts\nimport { defineMachine } from '@vielzeug/clockwork';\nimport { debugActor } from '@vielzeug/clockwork/devtools';\n\nconst machine = defineMachine<Record<string, never>, { type: 'NEXT' }>()({\n initial: 'idle',\n states: { idle: { on: { NEXT: { target: 'idle' } } } },\n});\n\nconst actor = machine.createActor();\nconst stopDebugging = debugActor(actor);\nactor.send({ type: 'NEXT' });\nstopDebugging();\nactor.dispose();\n```\n\n## Machine Methods\n\n### `machine.transition()`\n\n```ts\ntransition(\n snapshot: MachineSnapshot<State, Context>,\n event: Event,\n): TransitionResult<State, Context>;\n```\n\nResolves a snapshot for one user event without actor runtime work.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `snapshot` | `MachineSnapshot<State, Context>` | Input state and context |\n| `event` | `Event` | User event to evaluate |\n\n**Returns:** A `TransitionResult` with `transition` or `ignored` type.\n\n**Example:**\n\n```ts\nconst result = machine.transition(machine.initialSnapshot, { type: 'START' });\n```\n\n---\n\n### `machine.can()`\n\n```ts\ncan(snapshot: MachineSnapshot<State, Context>, event: Event): boolean;\n```\n\nReturns whether a transition exists and its guard passes.\n\n**Returns:** `true` when the supplied snapshot accepts the event.\n\n---\n\n### `machine.createActor()`\n\n```ts\ncreateActor(options?: ActorOptions<State, Context, Event>): Actor<State, Context, Event>;\n```\n\nCreates an independent actor for event dispatch, timers, invokes, effects, subscriptions, and disposal. A fresh actor starts the initial state's entry effects and resources. An actor restored with `options.snapshot` starts only the restored state's resources: invokes and timers, not entry effects.\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `options.snapshot` | `MachineSnapshot<State, Context>` | Optional restored actor snapshot |\n| `options.maxTransitions` | `number` | Positive queued-transition limit for one synchronous flush |\n| `options.onError` | `(error, context) => 'continue' \\| 'dispose'` | Explicit disposition for runtime failures |\n\n**Returns:** Disposable `Actor`.\n\n**Example:**\n\n```ts\nconst actor = machine.createActor({\n onError(error, { phase, state }) {\n console.error(phase, state, error);\n return 'continue';\n },\n snapshot: { context: {}, state: 'idle' },\n});\n```\n\n## Actor Methods\n\n### `actor.send()`\n\n```ts\nsend(event: Event): void;\n```\n\nDispatches a user event to the current actor state. Events sent while the actor is processing queue and flush synchronously; sends to a disposed actor are ignored. Use `actor.snapshot` after sending to read the current snapshot.\n\n**Returns:** Nothing.\n\n---\n\n### `actor.can()`\n\n```ts\ncan(event: Event): boolean;\n```\n\nReturns whether the current actor snapshot accepts an event. Returns `false` after disposal.\n\n**Returns:** Boolean transition availability.\n\n---\n\n### `actor.subscribe()`\n\n```ts\nsubscribe(listener: (snapshot: MachineSnapshot<State, Context>) => void): () => void;\n```\n\nRegisters a listener for committed snapshots. The listener does not run immediately.\n\n**Returns:** An unsubscribe function.\n\n---\n\n### `actor.dispose()`\n\n```ts\ndispose(): void;\n[Symbol.dispose](): void;\n```\n\nCancels timers and invokes, clears queued events and listeners, and aborts `disposalSignal`.\n\n**Returns:** Nothing. Idempotent.\n\n## Types\n\n### `MachineEvent`\n\n```ts\ntype MachineEvent = { readonly type: string };\n```\n\nBase constraint for event unions.\n\n### `EventType<Event>` and `EventByType<Event, Type>`\n\n```ts\ntype EventType<Event extends MachineEvent> = Event['type'] & string;\n\ntype EventByType<Event extends MachineEvent, Type extends EventType<Event>> =\n Extract<Event, { type: Type }>;\n```\n\nExtract event type names and a matching event from an event union.\n\n### `MachineSnapshot<State, Context>`\n\n```ts\ntype MachineSnapshot<State extends string, Context extends Record<string, unknown>> = {\n readonly context: Readonly<Context>;\n readonly state: State;\n};\n```\n\nThe plain readonly snapshot value used by machines and actors. Readonly is a TypeScript contract; Clockwork does not copy or freeze snapshots at runtime.\n\n### `Guard<Context, Event>` and `Reducer<Context, Event>`\n\n```ts\ntype Guard<Context extends Record<string, unknown>, Event> = (args: {\n readonly context: Readonly<Context>;\n readonly event: Event;\n}) => boolean;\n\ntype Reducer<Context extends Record<string, unknown>, Event> = (args: {\n readonly context: Readonly<Context>;\n readonly event: Event;\n}) => Context;\n```\n\nA guard selects a transition. A reducer returns replacement context, which must be a non-array record.\n\n### `EffectArgs<Context, Event>` and `Effect<Context, Event>`\n\n```ts\ntype EffectArgs<Context extends Record<string, unknown>, Event extends MachineEvent> = {\n readonly context: Readonly<Context>;\n readonly event: Event | undefined;\n readonly send: (event: Event) => void;\n readonly signal: AbortSignal;\n};\n\ntype Effect<Context extends Record<string, unknown>, Event extends MachineEvent> =\n (args: EffectArgs<Context, Event>) => void;\n```\n\nPost-commit effects receive `undefined` for initial entry and actor timer transitions. They cannot update machine context directly.\n\n### `Transition<State, Context, Event, Type>` and `TransitionInput`\n\n```ts\ntype Transition<\n State extends string,\n Context extends Record<string, unknown>,\n Event extends MachineEvent,\n Type extends EventType<Event> = EventType<Event>,\n> = {\n readonly effects?: readonly Effect<Context, Event>[];\n readonly guard?: Guard<Context, EventByType<Event, Type>>;\n readonly reduce?: Reducer<Context, EventByType<Event, Type>>;\n readonly target: State;\n};\n\ntype TransitionInput<\n State extends string,\n Context extends Record<string, unknown>,\n Event extends MachineEvent,\n Type extends EventType<Event> = EventType<Event>,\n> = Transition<State, Context, Event, Type> | readonly Transition<State, Context, Event, Type>[];\n```\n\nAn ordered transition array selects the first guard that passes.\n\n### `After<State, Context, Event>`\n\n```ts\ntype After<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> = {\n readonly delay: number;\n readonly effects?: readonly Effect<Context, Event>[];\n readonly guard?: Guard<Context, Event | undefined>;\n readonly reduce?: Reducer<Context, Event | undefined>;\n readonly target: State;\n};\n```\n\nA delayed state transition. Its guard and reducer receive `event: undefined`.\n\n### `InvokeArgs<Context, Event>` and `Invoke<Context, Event, Result>`\n\n```ts\ntype InvokeArgs<Context extends Record<string, unknown>, Event extends MachineEvent> = {\n readonly context: Readonly<Context>;\n readonly event: Event | undefined;\n readonly signal: AbortSignal;\n};\n\ntype Invoke<Context extends Record<string, unknown>, Event extends MachineEvent, Result = unknown> = {\n readonly onDone?: (args: { readonly context: Readonly<Context>; readonly result: Result }) => Event;\n readonly onError?: (args: { readonly context: Readonly<Context>; readonly error: unknown }) => Event;\n readonly src: (args: InvokeArgs<Context, Event>) => Promise<Result> | Result;\n};\n```\n\nAn actor-owned task started on state entry. `event` is the triggering event or `undefined` for initial or restored resources.\n\n### `StateNode<State, Context, Event>` and `MachineConfig<State, Context, Event>`\n\n```ts\ntype StateNode<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> = {\n readonly after?: readonly After<State, Context, Event>[];\n readonly entry?: readonly Effect<Context, Event>[];\n readonly exit?: readonly Effect<Context, Event>[];\n readonly invoke?: readonly Invoke<Context, Event>[];\n readonly on?: Partial<{ [Type in EventType<Event>]: TransitionInput<State, Context, Event, Type> }>;\n};\n\ntype MachineConfig<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> =\n (keyof Context extends never ? { readonly context?: Context } : { readonly context: Context }) & {\n readonly initial: State;\n readonly states: Record<State, StateNode<State, Context, Event>>;\n };\n```\n\nA flat machine definition. State nodes cannot contain child states.\n\n### `TransitionResult<State, Context>`\n\n```ts\ntype TransitionResult<State extends string, Context extends Record<string, unknown>> = {\n readonly snapshot: MachineSnapshot<State, Context>;\n readonly type: 'ignored' | 'transition';\n};\n```\n\nResult of a pure user-event transition. It contains no effect plan.\n\n### `ActorErrorContext<State, Event>`, `ActorErrorDisposition`, and `ActorOptions<State, Context, Event>`\n\n```ts\ntype ActorErrorContext<State extends string, Event extends MachineEvent> = {\n readonly event?: Event;\n readonly phase: 'effect' | 'invoke' | 'subscriber' | 'transition';\n readonly state: State;\n};\n\ntype ActorErrorDisposition = 'continue' | 'dispose';\n\ntype ActorOptions<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> = {\n readonly maxTransitions?: number;\n readonly onError?: (error: unknown, context: ActorErrorContext<State, Event>) => ActorErrorDisposition;\n readonly snapshot?: MachineSnapshot<State, Context>;\n};\n```\n\n`onError` must explicitly return `'continue'` to keep the actor alive or `'dispose'` to end it. Without an error handler, Clockwork disposes the actor silently.\n\n### `Actor<State, Context, Event>`\n\n```ts\ntype Actor<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> = {\n [Symbol.dispose](): void;\n can(event: Event): boolean;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n send(event: Event): void;\n readonly snapshot: MachineSnapshot<State, Context>;\n subscribe(listener: (snapshot: MachineSnapshot<State, Context>) => void): () => void;\n};\n```\n\nAn actor's `snapshot` is the current plain readonly snapshot.\n\n### `Machine<State, Context, Event>`\n\n```ts\ntype Machine<State extends string, Context extends Record<string, unknown>, Event extends MachineEvent> = {\n can(snapshot: MachineSnapshot<State, Context>, event: Event): boolean;\n createActor(options?: ActorOptions<State, Context, Event>): Actor<State, Context, Event>;\n readonly initialSnapshot: MachineSnapshot<State, Context>;\n transition(snapshot: MachineSnapshot<State, Context>, event: Event): TransitionResult<State, Context>;\n};\n```\n\nA compiled, reusable machine. Its transition lookup is map-based, so unknown or poison event names such as `__proto__` are safely ignored when no transition exists.\n\n### `DebugActorOptions<State, Context>`\n\n```ts\ntype DebugActorOptions<State extends string, Context extends Record<string, unknown>> = {\n readonly logger?: (snapshot: MachineSnapshot<State, Context>) => void;\n};\n```\n\nOptional logger for `debugActor()`. Logger failures are ignored so observation cannot affect the actor's error policy.\n\n## Errors\n\n### `ClockworkError`\n\n`ClockworkError` reports invalid definitions, contexts, snapshots, and actor transition limits. It has `code`, `details`, and standard `Error` fields. Use `ClockworkError.is(error)` to narrow an unknown error.\n\n```ts\nif (ClockworkError.is(error)) {\n console.error(error.code, error.details);\n}\n```\n",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
}
|
|
40
40
|
],
|
|
41
41
|
"typeSignatures": {
|
|
42
|
+
"ClockworkErrorCode": "export type { ClockworkErrorCode } from './errors.js';",
|
|
42
43
|
"ClockworkError": "export { ClockworkError } from './errors.js';",
|
|
43
44
|
"defineMachine": "export { defineMachine } from './interpret.js';",
|
|
44
45
|
"Actor": "export type {\n Actor,\n ActorErrorContext,\n ActorErrorDisposition,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
|
|
@@ -61,7 +62,6 @@
|
|
|
61
62
|
"StateNode": "export type {\n Actor,\n ActorErrorContext,\n ActorErrorDisposition,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
|
|
62
63
|
"Transition": "export type {\n Actor,\n ActorErrorContext,\n ActorErrorDisposition,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
|
|
63
64
|
"TransitionInput": "export type {\n Actor,\n ActorErrorContext,\n ActorErrorDisposition,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';",
|
|
64
|
-
"TransitionResult": "export type {\n Actor,\n ActorErrorContext,\n ActorErrorDisposition,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';"
|
|
65
|
-
"ClockworkErrorCode": "export type { ClockworkErrorCode } from './errors.js';"
|
|
65
|
+
"TransitionResult": "export type {\n Actor,\n ActorErrorContext,\n ActorErrorDisposition,\n ActorOptions,\n After,\n Effect,\n EffectArgs,\n EventByType,\n EventType,\n Guard,\n Invoke,\n InvokeArgs,\n Machine,\n MachineConfig,\n MachineEvent,\n MachineSnapshot,\n Reducer,\n StateNode,\n Transition,\n TransitionInput,\n TransitionResult,\n} from './types.js';"
|
|
66
66
|
}
|
|
67
67
|
}
|