@typeonce/effect-machine 0.29.0 → 0.31.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 +47 -2
- package/dist/Machine.d.ts +38 -0
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js +35 -0
- package/dist/Machine.js.map +1 -1
- package/dist/internal/machine/atom.d.ts +2 -0
- package/dist/internal/machine/atom.d.ts.map +1 -1
- package/dist/internal/machine/atom.js +63 -11
- package/dist/internal/machine/atom.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 +1 -0
- package/dist/internal/machine/machine.js.map +1 -1
- package/dist/internal/machine/planner.d.ts +1 -0
- package/dist/internal/machine/planner.d.ts.map +1 -1
- package/dist/internal/machine/planner.js +19 -0
- package/dist/internal/machine/planner.js.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.d.ts +74 -4
- package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.js +52 -3
- package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
- package/docs/effect-atom-react.md +48 -1
- package/docs/machine-review.md +2 -1
- package/package.json +1 -1
- package/src/Machine.ts +114 -0
- package/src/internal/machine/atom.ts +83 -18
- package/src/internal/machine/machine.ts +2 -0
- package/src/internal/machine/planner.ts +25 -0
- package/src/unstable/reactivity/AtomMachine.ts +104 -4
package/README.md
CHANGED
|
@@ -249,8 +249,9 @@ const definition = Machine.make({
|
|
|
249
249
|
})
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
-
Handlers see both protocols. Typed `send` and `Machine.plan`
|
|
253
|
-
events. Event tags must be unique and public/internal tags
|
|
252
|
+
Handlers see both protocols. Typed `send`, `Machine.can`, and `Machine.plan`
|
|
253
|
+
accept only public events. Event tags must be unique and public/internal tags
|
|
254
|
+
must be disjoint.
|
|
254
255
|
|
|
255
256
|
Export the descriptor returned by `Machine.events` instead of exporting its
|
|
256
257
|
schemas. This keeps the deferred constructors as the standard way to create
|
|
@@ -554,6 +555,23 @@ remain total and cannot use declinable transitions. Completion and invocation
|
|
|
554
555
|
outcomes have no ancestor candidate: declining one ignores that lifecycle
|
|
555
556
|
occurrence and leaves the current configuration active.
|
|
556
557
|
|
|
558
|
+
Use `Machine.can` when a caller needs to test a concrete event against a
|
|
559
|
+
snapshot. The direct and machine-specialized forms have the same semantics:
|
|
560
|
+
|
|
561
|
+
```ts
|
|
562
|
+
const canSubmit = yield * Machine.can(machine, snapshot, Submit({ draft }))
|
|
563
|
+
|
|
564
|
+
const canMachine = Machine.can(machine)
|
|
565
|
+
const canCancel = yield * canMachine(snapshot, Cancel())
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
`can` returns `true` when at least one required or non-declined handler accepts
|
|
569
|
+
the event. Targetless transitions count as accepted. Invalid event input fails
|
|
570
|
+
with `MachineSchemaDecodeError`; a valid unhandled event returns `false`.
|
|
571
|
+
Declinable resolvers run to decide acceptance, but collected commands,
|
|
572
|
+
emissions, and raised events are discarded. Required resolvers and transition
|
|
573
|
+
lifecycle do not run.
|
|
574
|
+
|
|
557
575
|
## Statechart capabilities
|
|
558
576
|
|
|
559
577
|
`Machine.states` supports:
|
|
@@ -746,6 +764,19 @@ const counterAtom = AtomMachine.bind(runtime).make(Counter)
|
|
|
746
764
|
|
|
747
765
|
Binding a shared runtime once is the canonical form for service-backed
|
|
748
766
|
applications. Service-free machines can use `AtomMachine.make(Counter)`.
|
|
767
|
+
Use `factory` when the same definition constructs several independent bridges:
|
|
768
|
+
|
|
769
|
+
```ts
|
|
770
|
+
const MachineAtoms = AtomMachine.bind(runtime)
|
|
771
|
+
const makeProcessMachine = MachineAtoms.factory(ProcessMachine)
|
|
772
|
+
|
|
773
|
+
const first = makeProcessMachine({ processId: "first" })
|
|
774
|
+
const second = makeProcessMachine({ processId: "second" })
|
|
775
|
+
type ProcessMachineAtom = ReturnType<typeof makeProcessMachine>
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
Each call creates a fresh lazy bridge. `factory` does not cache by input;
|
|
779
|
+
`AtomMachine.family` remains the keyed shared-identity interface.
|
|
749
780
|
|
|
750
781
|
The bridge exposes `ref`, `snapshot`, `state`, fail-aware `result`, writable
|
|
751
782
|
`send` and `stop` atoms, and `child(descriptor)`. Use `AtomMachine.select`,
|
|
@@ -753,6 +784,19 @@ The bridge exposes `ref`, `snapshot`, `state`, fail-aware `result`, writable
|
|
|
753
784
|
equality-aware derivations. Repeating one of these calls with the same bridge
|
|
754
785
|
and state path returns the same atom.
|
|
755
786
|
|
|
787
|
+
Use `AtomMachine.can` to project concrete event acceptance. Declare the
|
|
788
|
+
projection once and apply it to compatible bridges:
|
|
789
|
+
|
|
790
|
+
```ts
|
|
791
|
+
const submitAllowed = AtomMachine.can(Events.Submit({ draft }))
|
|
792
|
+
const canSubmitAtom = submitAllowed(machineAtom)
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
Pass an `Atom<EventInput>` instead when the event payload changes reactively.
|
|
796
|
+
Each projection returns the same derived atom for repeated applications to one
|
|
797
|
+
bridge. Startup and runtime failures remain typed, while done and stopped
|
|
798
|
+
machines return `false`.
|
|
799
|
+
|
|
756
800
|
Use `useMachineAtom` from `@typeonce/effect-machine-react` when one React
|
|
757
801
|
subtree owns the machine. It mounts the machine without subscribing the owner
|
|
758
802
|
to state. Pass the returned machine atom through props or Context, then call
|
|
@@ -769,6 +813,7 @@ preserving lazy registry startup and disposal:
|
|
|
769
813
|
```ts
|
|
770
814
|
const processAtoms = AtomMachine.bind(runtime).family(processMachine, {
|
|
771
815
|
atoms: {
|
|
816
|
+
canStart: AtomMachine.can(ProcessEvents.Start()),
|
|
772
817
|
details: AtomMachine.select("Processing"),
|
|
773
818
|
ready: AtomMachine.matches("Ready"),
|
|
774
819
|
send: (machine) => machine.send
|
package/dist/Machine.d.ts
CHANGED
|
@@ -5104,6 +5104,44 @@ export declare const configuration: <M extends Machine.Any>(machine: M, state: M
|
|
|
5104
5104
|
* @since 0.4.0
|
|
5105
5105
|
*/
|
|
5106
5106
|
export declare const enabled: <const States extends Machine.StateSchemas, const Events extends ReadonlyArray<Machine.TaggedSchema>, const Emits extends ReadonlyArray<Machine.TaggedSchema>, const Input extends Schema.Top = typeof Schema.Void, UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>, E = never, R = never, InitialE = never, InitialR = never, FinalStates extends Machine.StateIdentifier<States> = never, Output = never, OutputStates extends Machine.StateIdentifier<States> = never, InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events, ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []>(machine: Machine<States, Events, Input, UnhandledStates, E, R, InitialE, InitialR, FinalStates, Output, Emits, OutputStates, InputEvents, ParentEvents>, state: Machine.Snapshot<States>) => ReadonlyArray<Machine.TagOf<Events[number]>>;
|
|
5107
|
+
/**
|
|
5108
|
+
* Tests whether a concrete event would select at least one transition from a
|
|
5109
|
+
* decoded snapshot.
|
|
5110
|
+
*
|
|
5111
|
+
* **Details**
|
|
5112
|
+
*
|
|
5113
|
+
* Required handlers are accepted from their structural eligibility.
|
|
5114
|
+
* Declinable handlers run their resolver only far enough to decide whether
|
|
5115
|
+
* they accept the event. Any commands, emissions, or raised events collected
|
|
5116
|
+
* during that check are discarded.
|
|
5117
|
+
*
|
|
5118
|
+
* Event input is decoded through the machine's public event protocol. Invalid
|
|
5119
|
+
* input fails with `MachineSchemaDecodeError`. Final snapshots and valid events
|
|
5120
|
+
* with no accepting handler return `false`.
|
|
5121
|
+
*
|
|
5122
|
+
* **Gotchas**
|
|
5123
|
+
*
|
|
5124
|
+
* This query does not execute transitions or stabilize the resulting machine.
|
|
5125
|
+
* It does not run entry, exit, always, completion, child lifecycle, or command
|
|
5126
|
+
* effects. A `true` result therefore describes event acceptance only.
|
|
5127
|
+
*
|
|
5128
|
+
* **Example**
|
|
5129
|
+
*
|
|
5130
|
+
* ```ts
|
|
5131
|
+
* const canCheckout = Machine.can(checkoutMachine)
|
|
5132
|
+
*
|
|
5133
|
+
* const canSubmit = yield* canCheckout(snapshot, {
|
|
5134
|
+
* _tag: "SubmitOrder"
|
|
5135
|
+
* })
|
|
5136
|
+
* ```
|
|
5137
|
+
*
|
|
5138
|
+
* @category getters
|
|
5139
|
+
* @since 0.30.0
|
|
5140
|
+
*/
|
|
5141
|
+
export declare const can: {
|
|
5142
|
+
<const States extends Machine.StateSchemas, const Events extends ReadonlyArray<Machine.TaggedSchema>, const Emits extends ReadonlyArray<Machine.TaggedSchema>, const Input extends Schema.Top = typeof Schema.Void, UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>, E = never, R = never, InitialE = never, InitialR = never, FinalStates extends Machine.StateIdentifier<States> = never, Output = never, OutputStates extends Machine.StateIdentifier<States> = never, InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events, ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []>(machine: Machine<States, Events, Input, UnhandledStates, E, R, InitialE, InitialR, FinalStates, Output, Emits, OutputStates, InputEvents, ParentEvents> & EnsureExecutable<States, UnhandledStates, OutputStates> & Machine.RootCompatible<ParentEvents>): (state: Machine.Snapshot<States>, event: Machine.EventInputOf<InputEvents>) => Effect.Effect<boolean, MachineSchemaDecodeError>;
|
|
5143
|
+
<const States extends Machine.StateSchemas, const Events extends ReadonlyArray<Machine.TaggedSchema>, const Emits extends ReadonlyArray<Machine.TaggedSchema>, const Input extends Schema.Top = typeof Schema.Void, UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>, E = never, R = never, InitialE = never, InitialR = never, FinalStates extends Machine.StateIdentifier<States> = never, Output = never, OutputStates extends Machine.StateIdentifier<States> = never, InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events, ParentEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []>(machine: Machine<States, Events, Input, UnhandledStates, E, R, InitialE, InitialR, FinalStates, Output, Emits, OutputStates, InputEvents, ParentEvents> & EnsureExecutable<States, UnhandledStates, OutputStates> & Machine.RootCompatible<ParentEvents>, state: Machine.Snapshot<States>, event: Machine.EventInputOf<InputEvents>): Effect.Effect<boolean, MachineSchemaDecodeError>;
|
|
5144
|
+
};
|
|
5107
5145
|
/**
|
|
5108
5146
|
* Plans the next state snapshot synchronously.
|
|
5109
5147
|
*
|