@typeonce/effect-machine 0.10.0 → 0.12.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 +76 -13
- package/dist/Machine.d.ts +202 -90
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js +38 -9
- package/dist/Machine.js.map +1 -1
- package/dist/internal/machine/atom.d.ts +1 -1
- package/dist/internal/machine/atom.d.ts.map +1 -1
- package/dist/internal/machine/atom.js +38 -7
- package/dist/internal/machine/atom.js.map +1 -1
- package/dist/internal/machine/cluster.js +2 -2
- package/dist/internal/machine/cluster.js.map +1 -1
- package/dist/internal/machine/commandRuntime.d.ts.map +1 -1
- package/dist/internal/machine/commandRuntime.js +2 -2
- package/dist/internal/machine/commandRuntime.js.map +1 -1
- package/dist/internal/machine/configuration.d.ts +7 -7
- package/dist/internal/machine/configuration.d.ts.map +1 -1
- package/dist/internal/machine/configuration.js +3 -3
- package/dist/internal/machine/configuration.js.map +1 -1
- package/dist/internal/machine/executionPlan.d.ts +3 -3
- package/dist/internal/machine/executionPlan.d.ts.map +1 -1
- package/dist/internal/machine/executionPlan.js +25 -25
- package/dist/internal/machine/executionPlan.js.map +1 -1
- package/dist/internal/machine/invocation.js +1 -1
- package/dist/internal/machine/invocation.js.map +1 -1
- package/dist/internal/machine/machine.d.ts +1 -0
- package/dist/internal/machine/machine.d.ts.map +1 -1
- package/dist/internal/machine/machine.js +4 -0
- package/dist/internal/machine/machine.js.map +1 -1
- package/dist/internal/machine/planner.d.ts +2 -2
- package/dist/internal/machine/planner.d.ts.map +1 -1
- package/dist/internal/machine/planner.js +20 -20
- package/dist/internal/machine/planner.js.map +1 -1
- package/dist/internal/machine/process.d.ts +3 -0
- package/dist/internal/machine/process.d.ts.map +1 -1
- package/dist/internal/machine/process.js +6 -3
- package/dist/internal/machine/process.js.map +1 -1
- package/dist/internal/machine/runtime.d.ts +17 -3
- package/dist/internal/machine/runtime.d.ts.map +1 -1
- package/dist/internal/machine/runtime.js +82 -32
- package/dist/internal/machine/runtime.js.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.d.ts +4 -2
- package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.js +4 -2
- package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
- package/docs/agent-guide.md +78 -19
- package/package.json +1 -1
- package/src/Machine.ts +704 -96
- package/src/internal/machine/atom.ts +50 -52
- package/src/internal/machine/cluster.ts +2 -2
- package/src/internal/machine/commandRuntime.ts +4 -2
- package/src/internal/machine/configuration.ts +10 -10
- package/src/internal/machine/executionPlan.ts +35 -35
- package/src/internal/machine/invocation.ts +1 -1
- package/src/internal/machine/machine.ts +6 -0
- package/src/internal/machine/planner.ts +30 -24
- package/src/internal/machine/process.ts +60 -3
- package/src/internal/machine/runtime.ts +176 -47
- package/src/unstable/reactivity/AtomMachine.ts +4 -2
|
@@ -20,8 +20,10 @@ export { NotReadyError } from "../../internal/machine/atom.js";
|
|
|
20
20
|
export { ChildNotActiveError } from "../../internal/machine/atom.js";
|
|
21
21
|
const ExternalRequirementsTypeId = "~effect/reactivity/AtomMachine/ExternalRequirements";
|
|
22
22
|
/**
|
|
23
|
-
* Observes ephemeral notifications from the
|
|
24
|
-
*
|
|
23
|
+
* Observes ephemeral notifications from the running machine owned by a machine
|
|
24
|
+
* atom. When this stream activates a fresh bridge, it subscribes before machine
|
|
25
|
+
* initialization and observes initial-entry emissions. It never replays
|
|
26
|
+
* emissions from a machine that was already running.
|
|
25
27
|
*
|
|
26
28
|
* @category getters
|
|
27
29
|
* @since 0.10.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AtomMachine.js","sourceRoot":"","sources":["../../../src/unstable/reactivity/AtomMachine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,QAAQ,MAAM,gCAAgC,CAAA;AAK1D;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAE9D;;;;;GAKG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAMpE,MAAM,0BAA0B,GAAG,qDAAqD,CAAA;AAoIxF
|
|
1
|
+
{"version":3,"file":"AtomMachine.js","sourceRoot":"","sources":["../../../src/unstable/reactivity/AtomMachine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,QAAQ,MAAM,gCAAgC,CAAA;AAK1D;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAE9D;;;;;GAKG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAMpE,MAAM,0BAA0B,GAAG,qDAAqD,CAAA;AAoIxF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,SAAS,GAE+C,QAAQ,CAAC,SAAS,CAAA;AAEvF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAMvB,QAAQ,CAAC,cAAc,CAAA;AAkJ3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,MAAM,MAAM,GASf,QAAQ,CAAC,MAAM,CAAA;AAEnB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GASvB,QAAQ,CAAC,cAAc,CAAA;AAE3B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,WAAW,GASpB,QAAQ,CAAC,WAAW,CAAA;AAExB;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAS5B,QAAQ,CAAC,mBAAmB,CAAA;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,OAAO,GAUmD,QAAQ,CAAC,OAAO,CAAA;AAEvF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAMrB,QAAQ,CAAC,YAAY,CAAA;AAEzB,MAAM,uBAAuB,GAAG,kDAAkD,CAAA;AAgHlF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,CAAC,MAAM,IAAI,GAoDb,QAAQ,CAAC,IAAI,CAAA;AAEjB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,MAAM,GAQf,QAAQ,CAAC,MAAM,CAAA;AAEnB;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,IAAI,GAEoB,QAAQ,CAAC,IAAI,CAAA"}
|
package/docs/agent-guide.md
CHANGED
|
@@ -4,6 +4,21 @@ This is the model-facing reference for the currently published
|
|
|
4
4
|
`@typeonce/effect-machine` API. Prefer these patterns over reconstructing the API
|
|
5
5
|
from its internal implementation.
|
|
6
6
|
|
|
7
|
+
## Design priorities
|
|
8
|
+
|
|
9
|
+
Prefer, in order: compile-time type safety, explicit and opinionated semantics,
|
|
10
|
+
readable and concise machine models, and alignment with Effect core. Convenience
|
|
11
|
+
must come from builders and inference rather than ambiguous omissions or weaker
|
|
12
|
+
contracts. The package is pre-1.0, so improve or remove an existing API when a
|
|
13
|
+
clearer long-term design replaces it; do not preserve an inferior design with
|
|
14
|
+
aliases by default.
|
|
15
|
+
|
|
16
|
+
Keep the core machine model local. Before adding a public name or capability,
|
|
17
|
+
check Effect's existing modules and especially Cluster. Distributed identity,
|
|
18
|
+
placement, discovery, transport, routing, delivery, sharding, and remote
|
|
19
|
+
lifecycle belong to Cluster; expose integration through an explicit adapter
|
|
20
|
+
instead of creating a similar local abstraction with different semantics.
|
|
21
|
+
|
|
7
22
|
## Public imports
|
|
8
23
|
|
|
9
24
|
```ts
|
|
@@ -88,7 +103,7 @@ the deferred constructors preserve that identity after decoding.
|
|
|
88
103
|
- Reuse an exported child descriptor for inline invocation, `sendTo`, and child
|
|
89
104
|
lookup. Independently constructed descriptors are equivalent only when both
|
|
90
105
|
their id and machine identity match.
|
|
91
|
-
- `events` is the public
|
|
106
|
+
- `events` is the public machine-input protocol. `internalEvents` contains
|
|
92
107
|
machine-local raised events. `parentEvents` describes the public events a
|
|
93
108
|
child may send to its owner. `emittedEvents` describes outward ephemeral
|
|
94
109
|
notifications and is never delivered implicitly to a parent.
|
|
@@ -105,15 +120,16 @@ its extra control is required:
|
|
|
105
120
|
`AtomMachine.resume(machine, snapshot)` for service-free machines.
|
|
106
121
|
- Use one invocation object: `effect` for one-shot work, `after` for a timer,
|
|
107
122
|
`logic` for reusable process logic, and `child` for a complete child
|
|
108
|
-
statechart. `Machine.invoke({...})` preserves owner
|
|
109
|
-
|
|
110
|
-
|
|
123
|
+
statechart. `Machine.invoke({...})` preserves owner state and source channels
|
|
124
|
+
across sibling lifecycle handlers. Use `definition.invoke({...})` when a
|
|
125
|
+
callback uses `self` or `parent`; the bound constructor preserves the
|
|
126
|
+
definition's exact public input and `parentEvents` protocols.
|
|
111
127
|
- Use `Machine.child(id, machine)` for a complete statechart descriptor and
|
|
112
128
|
`Machine.childAddress<Event>(id)` for a low-level process address. A logic
|
|
113
129
|
invocation is addressable only when `Machine.invoke` receives that
|
|
114
130
|
address explicitly.
|
|
115
131
|
- Use the callback's `enqueue` argument for `raise`, `emit`, `sendTo`, and
|
|
116
|
-
`stop`. These operations record closed
|
|
132
|
+
`stop`. These operations record closed machine commands and do not run Effects.
|
|
117
133
|
|
|
118
134
|
## Atomic, compound, parallel, and history states
|
|
119
135
|
|
|
@@ -320,7 +336,7 @@ the default.
|
|
|
320
336
|
The machine's readiness type tracks missing defaults and shallow initializers.
|
|
321
337
|
History is an overwriteable register, not a stack: restoration does not consume
|
|
322
338
|
it, and the next parent exit replaces it. Entry actions and invokes run again;
|
|
323
|
-
prior effects,
|
|
339
|
+
prior effects, machine instances, and timers are not rewound.
|
|
324
340
|
|
|
325
341
|
## Choosing a target
|
|
326
342
|
|
|
@@ -406,7 +422,7 @@ only schema-backed paths; use `matches` or `getSnapshot` for any active path.
|
|
|
406
422
|
`context.containingState` is the immediate typed state value (`undefined` at a
|
|
407
423
|
root or when that state is schema-less). `context.ancestors` contains only
|
|
408
424
|
valued structural ancestors. This is separate from `context.parent`, which is
|
|
409
|
-
the owning
|
|
425
|
+
the owning machine target or `undefined` for a root machine. Use full state paths
|
|
410
426
|
when another ancestor value is needed:
|
|
411
427
|
|
|
412
428
|
```ts
|
|
@@ -490,7 +506,7 @@ are an upper bound on concrete destinations, not an exhaustive result set.
|
|
|
490
506
|
`reenter: true` remains meaningful with `target.none()`: the source exits and
|
|
491
507
|
enters again while its logical configuration is retained.
|
|
492
508
|
|
|
493
|
-
Closed statechart and
|
|
509
|
+
Closed statechart and machine operations use `enqueue`:
|
|
494
510
|
|
|
495
511
|
```ts
|
|
496
512
|
Submit: ({ target }, enqueue) => {
|
|
@@ -499,7 +515,7 @@ Submit: ({ target }, enqueue) => {
|
|
|
499
515
|
}
|
|
500
516
|
```
|
|
501
517
|
|
|
502
|
-
Declare emission constructors separately from
|
|
518
|
+
Declare emission constructors separately from machine inputs:
|
|
503
519
|
|
|
504
520
|
```ts
|
|
505
521
|
const Emissions = Machine.emittedEvents(SaveRequested, AuditRecorded)
|
|
@@ -513,12 +529,24 @@ const definition = Machine.make({
|
|
|
513
529
|
```
|
|
514
530
|
|
|
515
531
|
`enqueue.raise(...)` is a same-macrostep input to self. `enqueue.sendTo(...)`
|
|
516
|
-
targets
|
|
532
|
+
targets a machine mailbox and is processed later. `enqueue.emit(...)` is neither:
|
|
517
533
|
it publishes a one-off outward notification. Observe it with
|
|
518
|
-
`ref.emissions`, a hot non-replayed `Stream` that completes with the
|
|
534
|
+
`ref.emissions`, a hot non-replayed `Stream` that completes with the machine.
|
|
519
535
|
`ref.changes` is stateful and begins with the current lifecycle snapshot.
|
|
520
|
-
|
|
521
|
-
|
|
536
|
+
Use `Machine.prepare(machine)` to obtain `changes` and `emissions` before
|
|
537
|
+
initialization. Subscribe to the desired stream and then evaluate
|
|
538
|
+
`prepared.start`. `Machine.start(machine)` remains the one-step convenience
|
|
539
|
+
when startup observation is unnecessary. Emissions are still never retained or
|
|
540
|
+
replayed; state remains the representation for facts that must be retained.
|
|
541
|
+
|
|
542
|
+
```ts
|
|
543
|
+
const prepared = yield* Machine.prepare(machine)
|
|
544
|
+
yield* prepared.emissions.pipe(
|
|
545
|
+
Stream.runForEach(handleEmission),
|
|
546
|
+
Effect.forkScoped({ startImmediately: true })
|
|
547
|
+
)
|
|
548
|
+
const ref = yield* prepared.start
|
|
549
|
+
```
|
|
522
550
|
|
|
523
551
|
For child-to-parent input, export a public builder protocol and reuse it at both
|
|
524
552
|
composition boundaries:
|
|
@@ -551,10 +579,12 @@ const parent = Machine.make({
|
|
|
551
579
|
Invoking the child under a parent that lacks any required `parentEvents` case
|
|
552
580
|
is a type error. Within child handlers, `parent` accepts only that protocol.
|
|
553
581
|
The same child may run as a root, where `parent` is `undefined`. `self` accepts
|
|
554
|
-
the machine's public inputs.
|
|
555
|
-
|
|
582
|
+
the machine's public inputs. Both are minimal `MachineTarget<Event>` values,
|
|
583
|
+
provided by the shared `MachineReferences<InputEvents, ParentEvents>` handler
|
|
584
|
+
context. Neither machine target is a structural state value; use
|
|
585
|
+
`containingState` and `ancestors` for statechart ancestry.
|
|
556
586
|
|
|
557
|
-
Atom-backed
|
|
587
|
+
Atom-backed machines retain the same transient semantics. Use
|
|
558
588
|
`AtomMachine.emissions(machineAtom)` for a root and
|
|
559
589
|
`AtomMachine.childEmissions(childAtom)` for the currently active child. Both
|
|
560
590
|
return streams requiring the corresponding `AtomRegistry`; emissions are not
|
|
@@ -682,6 +712,33 @@ invoke: Machine.invoke({
|
|
|
682
712
|
})
|
|
683
713
|
```
|
|
684
714
|
|
|
715
|
+
The standalone constructor cannot know the owning machine's input protocols,
|
|
716
|
+
so its `self` and `parent` references are non-sendable. When a source sends
|
|
717
|
+
through either reference, use the owning definition's bound constructor:
|
|
718
|
+
|
|
719
|
+
```ts
|
|
720
|
+
const definition = Machine.make({
|
|
721
|
+
events: Commands,
|
|
722
|
+
internalEvents: InternalEvents,
|
|
723
|
+
parentEvents: ParentEvents,
|
|
724
|
+
// ...
|
|
725
|
+
})
|
|
726
|
+
|
|
727
|
+
const machine = definition.handle({
|
|
728
|
+
Saving: {
|
|
729
|
+
invoke: definition.invoke({
|
|
730
|
+
id: "notify-parent",
|
|
731
|
+
effect: ({ parent }) =>
|
|
732
|
+
parent === undefined
|
|
733
|
+
? Effect.void
|
|
734
|
+
: parent.send(ParentEvents.SaveStarted()),
|
|
735
|
+
onDone: ({ target }) => target.none(),
|
|
736
|
+
onFailure: ({ target }) => target.none()
|
|
737
|
+
})
|
|
738
|
+
}
|
|
739
|
+
})
|
|
740
|
+
```
|
|
741
|
+
|
|
685
742
|
A direct `invoke: { ... }` object remains available when lifecycle handlers do
|
|
686
743
|
not need source-derived context.
|
|
687
744
|
|
|
@@ -729,9 +786,11 @@ parentRef.child(Editor)
|
|
|
729
786
|
parentAtom.child(Editor)
|
|
730
787
|
```
|
|
731
788
|
|
|
732
|
-
Child emissions
|
|
733
|
-
|
|
734
|
-
|
|
789
|
+
Child emissions remain on the child's hot `emissions` stream; they are never
|
|
790
|
+
delivered implicitly to the parent. A child sends an input explicitly with
|
|
791
|
+
`enqueue.sendTo(parent, ParentEvents.Example())`. `onSnapshot`, `onDone`, and
|
|
792
|
+
`onFailure` are direct parent transitions. Invoked child IDs must be unique
|
|
793
|
+
while simultaneously active.
|
|
735
794
|
|
|
736
795
|
Descriptors with the same id and machine identity address the same child, even
|
|
737
796
|
when independently constructed. The descriptor objects themselves are not
|