@typeonce/effect-machine 0.6.1 → 0.7.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 +4 -3
- package/dist/Machine.d.ts +24 -6
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js.map +1 -1
- package/dist/internal/machine/atom.d.ts +5 -0
- package/dist/internal/machine/atom.d.ts.map +1 -1
- package/dist/internal/machine/atom.js +6 -3
- package/dist/internal/machine/atom.js.map +1 -1
- package/dist/internal/machine/machine.d.ts.map +1 -1
- package/dist/internal/machine/machine.js +1 -1
- package/dist/internal/machine/machine.js.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.d.ts +26 -0
- package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.js +23 -0
- package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
- package/docs/agent-guide.md +14 -0
- package/package.json +1 -1
- package/src/Machine.ts +51 -15
- package/src/internal/machine/atom.ts +51 -3
- package/src/internal/machine/machine.ts +8 -5
- package/src/unstable/reactivity/AtomMachine.ts +47 -0
package/docs/agent-guide.md
CHANGED
|
@@ -357,6 +357,15 @@ States.getSnapshot(snapshot, "Route.Ready")
|
|
|
357
357
|
States.matches(snapshot, "Route.Ready.Saving")
|
|
358
358
|
```
|
|
359
359
|
|
|
360
|
+
Snapshots returned by `getSnapshot` can be queried again with `get`,
|
|
361
|
+
`getSnapshot`, or `matches`. Paths remain absolute and are restricted to the
|
|
362
|
+
extracted snapshot and its descendants:
|
|
363
|
+
|
|
364
|
+
```ts
|
|
365
|
+
const ready = Option.getOrThrow(States.getSnapshot(snapshot, "Route.Ready"))
|
|
366
|
+
States.matches(ready, "Route.Ready.Saving")
|
|
367
|
+
```
|
|
368
|
+
|
|
360
369
|
All paths are checked against the definition. `context.parent` is the immediate
|
|
361
370
|
typed parent (`undefined` at a root). Use `parents` when another ancestor is
|
|
362
371
|
needed:
|
|
@@ -642,11 +651,16 @@ the `DefinedStates` object:
|
|
|
642
651
|
|
|
643
652
|
```ts
|
|
644
653
|
AtomMachine.select(machineAtom, "Ready")
|
|
654
|
+
AtomMachine.selectSnapshot(machineAtom, "Ready")
|
|
645
655
|
AtomMachine.matches(machineAtom, "Ready.Saving")
|
|
646
656
|
AtomMachine.selectChild(childAtom, "Editing")
|
|
657
|
+
AtomMachine.selectSnapshotChild(childAtom, "Editing")
|
|
647
658
|
AtomMachine.matchesChild(childAtom, "Editing")
|
|
648
659
|
```
|
|
649
660
|
|
|
661
|
+
`select` returns only the decoded state value. Use `selectSnapshot` when a
|
|
662
|
+
component needs the selected node's compound or parallel child topology.
|
|
663
|
+
|
|
650
664
|
Like ordinary Effect Atom combinators, each selector call returns a derived
|
|
651
665
|
atom. Define it at a stable composition boundary or memoize it when constructing
|
|
652
666
|
it inside a component.
|
package/package.json
CHANGED
package/src/Machine.ts
CHANGED
|
@@ -2341,14 +2341,26 @@ export declare namespace Machine {
|
|
|
2341
2341
|
readonly initial: InitialBuilder<States>
|
|
2342
2342
|
|
|
2343
2343
|
/**
|
|
2344
|
-
* Returns the decoded value for an active state path.
|
|
2344
|
+
* Returns the decoded value for an active state path. The supplied
|
|
2345
|
+
* snapshot may be a complete root snapshot or a snapshot previously
|
|
2346
|
+
* extracted from this definition. Extracted snapshots accept only their
|
|
2347
|
+
* own absolute path and descendant paths.
|
|
2345
2348
|
*
|
|
2346
2349
|
* @since 0.4.0
|
|
2347
2350
|
*/
|
|
2348
|
-
readonly get:
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2351
|
+
readonly get: {
|
|
2352
|
+
<Path extends StateIdentifier<States>>(
|
|
2353
|
+
snapshot: Snapshot<States>,
|
|
2354
|
+
path: Path
|
|
2355
|
+
): Option.Option<StateByIdentifier<States, Path>>
|
|
2356
|
+
<
|
|
2357
|
+
const From extends StateIdentifier<States>,
|
|
2358
|
+
const Path extends StateIdentifier<States>
|
|
2359
|
+
>(
|
|
2360
|
+
snapshot: SnapshotByIdentifier<States, From>,
|
|
2361
|
+
path: Path & (Path extends NoInfer<From> | `${NoInfer<From>}.${string}` ? unknown : never)
|
|
2362
|
+
): Option.Option<StateByIdentifier<States, Path>>
|
|
2363
|
+
}
|
|
2352
2364
|
|
|
2353
2365
|
/**
|
|
2354
2366
|
* Returns the decoded value for an active state path together with all of
|
|
@@ -2366,24 +2378,48 @@ export declare namespace Machine {
|
|
|
2366
2378
|
) => Option.Option<StateWithParents<States, Path>>
|
|
2367
2379
|
|
|
2368
2380
|
/**
|
|
2369
|
-
* Returns the snapshot for an active state path.
|
|
2381
|
+
* Returns the snapshot for an active state path. The supplied snapshot may
|
|
2382
|
+
* be a complete root snapshot or a snapshot previously extracted from this
|
|
2383
|
+
* definition. Extracted snapshots accept only their own absolute path and
|
|
2384
|
+
* descendant paths.
|
|
2370
2385
|
*
|
|
2371
2386
|
* @since 0.4.0
|
|
2372
2387
|
*/
|
|
2373
|
-
readonly getSnapshot:
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2388
|
+
readonly getSnapshot: {
|
|
2389
|
+
<Path extends StateIdentifier<States>>(
|
|
2390
|
+
snapshot: Snapshot<States>,
|
|
2391
|
+
path: Path
|
|
2392
|
+
): Option.Option<SnapshotByIdentifier<States, Path>>
|
|
2393
|
+
<
|
|
2394
|
+
const From extends StateIdentifier<States>,
|
|
2395
|
+
const Path extends StateIdentifier<States>
|
|
2396
|
+
>(
|
|
2397
|
+
snapshot: SnapshotByIdentifier<States, From>,
|
|
2398
|
+
path: Path & (Path extends NoInfer<From> | `${NoInfer<From>}.${string}` ? unknown : never)
|
|
2399
|
+
): Option.Option<SnapshotByIdentifier<States, Path>>
|
|
2400
|
+
}
|
|
2377
2401
|
|
|
2378
2402
|
/**
|
|
2379
|
-
* Returns whether a state path is active in the snapshot.
|
|
2403
|
+
* Returns whether a state path is active in the snapshot. The supplied
|
|
2404
|
+
* snapshot may be a complete root snapshot or a snapshot previously
|
|
2405
|
+
* extracted from this definition. Extracted snapshots accept only their
|
|
2406
|
+
* own absolute path and descendant paths.
|
|
2380
2407
|
*
|
|
2381
2408
|
* @since 0.4.0
|
|
2382
2409
|
*/
|
|
2383
|
-
readonly matches:
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2410
|
+
readonly matches: {
|
|
2411
|
+
<Path extends StateIdentifier<States>>(
|
|
2412
|
+
snapshot: Snapshot<States>,
|
|
2413
|
+
path: Path
|
|
2414
|
+
): boolean
|
|
2415
|
+
<
|
|
2416
|
+
const From extends StateIdentifier<States>,
|
|
2417
|
+
const Path extends StateIdentifier<States>
|
|
2418
|
+
>(
|
|
2419
|
+
snapshot: SnapshotByIdentifier<States, From>,
|
|
2420
|
+
path: Path & (Path extends NoInfer<From> | `${NoInfer<From>}.${string}` ? unknown : never)
|
|
2421
|
+
): boolean
|
|
2422
|
+
}
|
|
2387
2423
|
}
|
|
2388
2424
|
|
|
2389
2425
|
/**
|
|
@@ -435,9 +435,13 @@ type SnapshotValueByIdentifier<State, Path extends SnapshotIdentifier<State>> =
|
|
|
435
435
|
Node extends { readonly path: Path; readonly value: infer Value } ? Value : never
|
|
436
436
|
: never
|
|
437
437
|
|
|
438
|
+
type SnapshotByIdentifier<State, Path extends SnapshotIdentifier<State>> = SnapshotNode<State> extends infer Node ?
|
|
439
|
+
Node extends { readonly path: Path } ? Node : never
|
|
440
|
+
: never
|
|
441
|
+
|
|
438
442
|
type ChildState<Child extends Machine.ChildMachine.Any> = RefState<Machine.ChildMachine.Ref<Child>>
|
|
439
443
|
|
|
440
|
-
const
|
|
444
|
+
const selectValueByPath = <
|
|
441
445
|
State extends Machine.Machine.AtomicSnapshot<string, unknown>,
|
|
442
446
|
Path extends SnapshotIdentifier<State>
|
|
443
447
|
>(
|
|
@@ -448,6 +452,15 @@ const selectSnapshot = <
|
|
|
448
452
|
Option.map((snapshot) => snapshot.value)
|
|
449
453
|
) as Option.Option<SnapshotValueByIdentifier<State, Path>>
|
|
450
454
|
|
|
455
|
+
const selectSnapshotByPath = <
|
|
456
|
+
State extends Machine.Machine.AtomicSnapshot<string, unknown>,
|
|
457
|
+
Path extends SnapshotIdentifier<State>
|
|
458
|
+
>(
|
|
459
|
+
snapshot: State,
|
|
460
|
+
path: Path
|
|
461
|
+
): Option.Option<SnapshotByIdentifier<State, Path>> =>
|
|
462
|
+
Topology.getSnapshotByPath(snapshot, path) as Option.Option<SnapshotByIdentifier<State, Path>>
|
|
463
|
+
|
|
451
464
|
export const select = <
|
|
452
465
|
State extends Machine.Machine.AtomicSnapshot<string, unknown>,
|
|
453
466
|
Event,
|
|
@@ -461,7 +474,24 @@ export const select = <
|
|
|
461
474
|
): Atom.Atom<
|
|
462
475
|
AsyncResult.AsyncResult<Option.Option<SnapshotValueByIdentifier<State, Path>>, StartError | Error>
|
|
463
476
|
> =>
|
|
464
|
-
Atom.mapResult(self.result, (snapshot) =>
|
|
477
|
+
Atom.mapResult(self.result, (snapshot) => selectValueByPath(snapshot, path)).pipe(
|
|
478
|
+
Atom.withEquality(Equal.equals)
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
export const selectSnapshot = <
|
|
482
|
+
State extends Machine.Machine.AtomicSnapshot<string, unknown>,
|
|
483
|
+
Event,
|
|
484
|
+
Error,
|
|
485
|
+
Output,
|
|
486
|
+
StartError,
|
|
487
|
+
const Path extends SnapshotIdentifier<State>
|
|
488
|
+
>(
|
|
489
|
+
self: MachineAtom<State, Event, Error, Output, StartError>,
|
|
490
|
+
path: Path
|
|
491
|
+
): Atom.Atom<
|
|
492
|
+
AsyncResult.AsyncResult<Option.Option<SnapshotByIdentifier<State, Path>>, StartError | Error>
|
|
493
|
+
> =>
|
|
494
|
+
Atom.mapResult(self.result, (snapshot) => selectSnapshotByPath(snapshot, path)).pipe(
|
|
465
495
|
Atom.withEquality(Equal.equals)
|
|
466
496
|
)
|
|
467
497
|
|
|
@@ -480,7 +510,25 @@ export const selectChild = <
|
|
|
480
510
|
> =>
|
|
481
511
|
Atom.mapResult(
|
|
482
512
|
self.result,
|
|
483
|
-
Option.flatMap((snapshot) =>
|
|
513
|
+
Option.flatMap((snapshot) => selectValueByPath(snapshot, path))
|
|
514
|
+
).pipe(Atom.withEquality(Equal.equals))
|
|
515
|
+
|
|
516
|
+
export const selectSnapshotChild = <
|
|
517
|
+
Child extends Machine.ChildMachine.Any,
|
|
518
|
+
StartError,
|
|
519
|
+
const Path extends SnapshotIdentifier<ChildState<Child>>
|
|
520
|
+
>(
|
|
521
|
+
self: ChildMachineAtom<Child, StartError>,
|
|
522
|
+
path: Path
|
|
523
|
+
): Atom.Atom<
|
|
524
|
+
AsyncResult.AsyncResult<
|
|
525
|
+
Option.Option<SnapshotByIdentifier<ChildState<Child>, Path>>,
|
|
526
|
+
StartError | RefError<Machine.ChildMachine.Ref<Child>>
|
|
527
|
+
>
|
|
528
|
+
> =>
|
|
529
|
+
Atom.mapResult(
|
|
530
|
+
self.result,
|
|
531
|
+
Option.flatMap((snapshot) => selectSnapshotByPath(snapshot, path))
|
|
484
532
|
).pipe(Atom.withEquality(Equal.equals))
|
|
485
533
|
|
|
486
534
|
export const matches = <
|
|
@@ -713,10 +713,11 @@ export const defineStates: DefineStates = (<const States extends Machine.StateSc
|
|
|
713
713
|
return {
|
|
714
714
|
states,
|
|
715
715
|
initial: makeSnapshotBuilder(states, { mode: "initial", prefix: "" }) as Machine.InitialBuilder<States>,
|
|
716
|
-
get:
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
716
|
+
get:
|
|
717
|
+
((snapshot: Machine.AtomicSnapshot<string, unknown>, path: string) =>
|
|
718
|
+
Topology.getSnapshotByPath(snapshot, path).pipe(
|
|
719
|
+
Option.map((snapshot) => snapshot.value)
|
|
720
|
+
)) as Machine.DefinedStates<States>["get"],
|
|
720
721
|
getWithParents: ((snapshot, path) => {
|
|
721
722
|
const parents: Record<string, unknown> = {}
|
|
722
723
|
return Topology.getSnapshotByPath(snapshot, path, parents).pipe(
|
|
@@ -724,7 +725,9 @@ export const defineStates: DefineStates = (<const States extends Machine.StateSc
|
|
|
724
725
|
)
|
|
725
726
|
}) as Machine.DefinedStates<States>["getWithParents"],
|
|
726
727
|
getSnapshot: Topology.getSnapshotByPath as unknown as Machine.DefinedStates<States>["getSnapshot"],
|
|
727
|
-
matches:
|
|
728
|
+
matches:
|
|
729
|
+
((snapshot: Machine.AtomicSnapshot<string, unknown>, path: string) =>
|
|
730
|
+
Option.isSome(Topology.getSnapshotByPath(snapshot, path))) as Machine.DefinedStates<States>["matches"]
|
|
728
731
|
}
|
|
729
732
|
}) as DefineStates
|
|
730
733
|
|
|
@@ -295,6 +295,10 @@ type SnapshotValueByIdentifier<State, Path extends SnapshotIdentifier<State>> =
|
|
|
295
295
|
Node extends { readonly path: Path; readonly value: infer Value } ? Value : never
|
|
296
296
|
: never
|
|
297
297
|
|
|
298
|
+
type SnapshotByIdentifier<State, Path extends SnapshotIdentifier<State>> = SnapshotNode<State> extends infer Node ?
|
|
299
|
+
Node extends { readonly path: Path } ? Node : never
|
|
300
|
+
: never
|
|
301
|
+
|
|
298
302
|
type ChildState<Child extends Machine.ChildMachine.Any> = RefState<Machine.ChildMachine.Ref<Child>>
|
|
299
303
|
|
|
300
304
|
/**
|
|
@@ -339,6 +343,27 @@ export const select: <
|
|
|
339
343
|
AsyncResult.AsyncResult<Option.Option<SnapshotValueByIdentifier<State, Path>>, StartError | Error>
|
|
340
344
|
> = internal.select
|
|
341
345
|
|
|
346
|
+
/**
|
|
347
|
+
* Selects the typed logical snapshot for an active state path.
|
|
348
|
+
*
|
|
349
|
+
* Unlike {@link select}, the selected value retains its child snapshot
|
|
350
|
+
* topology. The derived atom suppresses structurally equal updates. Keep the
|
|
351
|
+
* returned atom stable when constructing it inside a component.
|
|
352
|
+
*
|
|
353
|
+
* @category combinators
|
|
354
|
+
* @since 0.7.0
|
|
355
|
+
*/
|
|
356
|
+
export const selectSnapshot: <
|
|
357
|
+
State extends Machine.Machine.AtomicSnapshot<string, unknown>,
|
|
358
|
+
Event,
|
|
359
|
+
Error,
|
|
360
|
+
Output,
|
|
361
|
+
StartError,
|
|
362
|
+
const Path extends SnapshotIdentifier<State>
|
|
363
|
+
>(self: MachineAtom<State, Event, Error, Output, StartError>, path: Path) => Atom.Atom<
|
|
364
|
+
AsyncResult.AsyncResult<Option.Option<SnapshotByIdentifier<State, Path>>, StartError | Error>
|
|
365
|
+
> = internal.selectSnapshot
|
|
366
|
+
|
|
342
367
|
/**
|
|
343
368
|
* Selects the typed value for an active state path in an invoked child.
|
|
344
369
|
*
|
|
@@ -367,6 +392,28 @@ export const selectChild: <
|
|
|
367
392
|
>
|
|
368
393
|
> = internal.selectChild
|
|
369
394
|
|
|
395
|
+
/**
|
|
396
|
+
* Selects the typed logical snapshot for an active state path in an invoked
|
|
397
|
+
* child.
|
|
398
|
+
*
|
|
399
|
+
* An inactive child or state path produces `Option.none()`. Unlike
|
|
400
|
+
* {@link selectChild}, the selected value retains its child snapshot topology.
|
|
401
|
+
* The derived atom suppresses structurally equal updates.
|
|
402
|
+
*
|
|
403
|
+
* @category combinators
|
|
404
|
+
* @since 0.7.0
|
|
405
|
+
*/
|
|
406
|
+
export const selectSnapshotChild: <
|
|
407
|
+
Child extends Machine.ChildMachine.Any,
|
|
408
|
+
StartError,
|
|
409
|
+
const Path extends SnapshotIdentifier<ChildState<Child>>
|
|
410
|
+
>(self: ChildMachineAtom<Child, StartError>, path: Path) => Atom.Atom<
|
|
411
|
+
AsyncResult.AsyncResult<
|
|
412
|
+
Option.Option<SnapshotByIdentifier<ChildState<Child>, Path>>,
|
|
413
|
+
StartError | RefError<Machine.ChildMachine.Ref<Child>>
|
|
414
|
+
>
|
|
415
|
+
> = internal.selectSnapshotChild
|
|
416
|
+
|
|
370
417
|
/**
|
|
371
418
|
* Returns whether a state path is active.
|
|
372
419
|
*
|