@typeonce/effect-machine 0.14.1 → 0.15.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.
@@ -11,6 +11,7 @@ import type {
11
11
  ChildAddress,
12
12
  ChildMachine,
13
13
  Command,
14
+ Definition,
14
15
  ExecutionServices,
15
16
  InitialEvent as InitialEventModel,
16
17
  Logic,
@@ -79,7 +80,14 @@ type ValidateDefinedStates<States extends Machine.StateSchemas> = [States] exten
79
80
  type InvalidDefinedStateTreeInput<States extends Machine.StateSchemas> = [States] extends
80
81
  [Machine.ValidateStateSchemas<States>] ? never
81
82
  : States & Machine.ValidateStateSchemas<States>
82
- interface DefineStates {
83
+ type ReusableStateNodeConfig =
84
+ | Machine.AtomicStateNodeConfig
85
+ | Machine.CompoundStateNodeConfig
86
+ | Machine.ParallelStateNodeConfig
87
+ interface StateConstructor {
88
+ <const Node extends ReusableStateNodeConfig>(node: Node): Node
89
+ }
90
+ interface StatesConstructor {
83
91
  <const States extends Machine.StateSchemas>(
84
92
  states: States,
85
93
  ..._validation: ValidateDefinedStates<NoInfer<States>>
@@ -106,8 +114,8 @@ const Proto = {
106
114
 
107
115
  const makeBoundInvoke = (config: unknown): unknown => config
108
116
 
109
- const cloneWithHandlers = (
110
- self: Machine.Any,
117
+ const makeWithHandlers = (
118
+ self: Definition.Any,
111
119
  handlers: Machine.StateConfigs<any, any, any, any, any, any, any>
112
120
  ): Machine.Any => {
113
121
  const machine = Object.create(Proto)
@@ -123,7 +131,6 @@ const cloneWithHandlers = (
123
131
  machine.stateNodes = self.stateNodes
124
132
  machine.makeTargetBuilder = self.makeTargetBuilder
125
133
  machine.handlers = handlers
126
- machine.handle = makeHandle(machine)
127
134
  machine.invoke = makeBoundInvoke
128
135
  Protocol.copyProtocol(self, machine)
129
136
  return machine
@@ -525,15 +532,12 @@ const flattenHandlers = (
525
532
  }
526
533
  }
527
534
 
528
- const makeHandle = (self: Machine.Any): Machine.Any["handle"] =>
535
+ const makeHandle = (self: Definition.Any): Definition.Any["handle"] =>
529
536
  ((config: Record<string, unknown>) => {
530
- const handlers: Record<PropertyKey, Machine.AnyStateConfig> = Object.assign(
531
- Object.create(null),
532
- self.handlers
533
- )
537
+ const handlers: Record<PropertyKey, Machine.AnyStateConfig> = Object.create(null)
534
538
  flattenHandlers(handlers, self.stateNodes, self.states, "", config)
535
- return cloneWithHandlers(self, handlers)
536
- }) as Machine.Any["handle"]
539
+ return makeWithHandlers(self, handlers)
540
+ }) as Definition.Any["handle"]
537
541
 
538
542
  export const isMachine = (
539
543
  u: unknown
@@ -1141,12 +1145,19 @@ const compileInitial = (
1141
1145
  }
1142
1146
  }
1143
1147
 
1144
- export const defineStates: DefineStates = (<const States extends Machine.StateSchemas>(
1148
+ export const state: StateConstructor = (<const Node extends ReusableStateNodeConfig>(node: Node): Node => {
1149
+ StateDefinition.validateStateDefinitions({ state: node }, "Machine.state")
1150
+ return StateDefinition.captureStateDefinitions({ state: node }).state
1151
+ }) as StateConstructor
1152
+
1153
+ export const states: StatesConstructor = (<const States extends Machine.StateSchemas>(
1145
1154
  states: States
1146
1155
  ): Machine.DefinedStates<States> => {
1147
- StateDefinition.validateStateDefinitions(states, "Machine.defineStates")
1156
+ StateDefinition.validateStateDefinitions(states, "Machine.states")
1157
+ const captured = StateDefinition.captureStateDefinitions(states)
1148
1158
  return {
1149
- states,
1159
+ states: captured,
1160
+ path: ((path: string) => path) as Machine.DefinedStates<States>["path"],
1150
1161
  get:
1151
1162
  ((snapshot: Machine.AtomicSnapshot<string, unknown>, path: string) =>
1152
1163
  Topology.getSnapshotByPath(snapshot, path).pipe(
@@ -1163,7 +1174,7 @@ export const defineStates: DefineStates = (<const States extends Machine.StateSc
1163
1174
  ((snapshot: Machine.AtomicSnapshot<string, unknown>, path: string) =>
1164
1175
  Option.isSome(Topology.getSnapshotByPath(snapshot, path))) as Machine.DefinedStates<States>["matches"]
1165
1176
  }
1166
- }) as DefineStates
1177
+ }) as StatesConstructor
1167
1178
 
1168
1179
  type MakeConfig<
1169
1180
  States extends Machine.StateSchemas,
@@ -1201,19 +1212,15 @@ type MakeResult<
1201
1212
  InitialR,
1202
1213
  InternalEvents extends ReadonlyArray<Machine.TaggedSchema>,
1203
1214
  ParentEvents extends ReadonlyArray<Machine.TaggedSchema>
1204
- > = Machine<
1215
+ > = Definition<
1205
1216
  States,
1206
1217
  readonly [...InputEvents, ...InternalEvents],
1207
1218
  Input,
1208
- Machine.StateIdentifier<States>,
1209
- never,
1210
- never,
1211
1219
  InitialE,
1212
1220
  InitialR,
1213
1221
  Machine.FinalStateFromDefinition<States>,
1214
1222
  Machine.TerminalOutput<States>,
1215
1223
  Emits,
1216
- never,
1217
1224
  InputEvents,
1218
1225
  ParentEvents
1219
1226
  >
@@ -18,7 +18,7 @@ export type AllowedStateNodeProperty<Kind extends StateNodeKind> = (typeof State
18
18
 
19
19
  export type AllowedPseudoStateAnnotationProperty = (typeof PseudoStateAnnotationProperties)[number]
20
20
 
21
- export type StateDefinitionBoundary = "Machine.defineStates" | "Machine.make"
21
+ export type StateDefinitionBoundary = "Machine.state" | "Machine.states" | "Machine.make"
22
22
 
23
23
  const hasOwn = (value: object, key: PropertyKey): boolean => Object.prototype.hasOwnProperty.call(value, key)
24
24
 
@@ -279,3 +279,43 @@ export const validateStateDefinitions = (
279
279
  states: unknown,
280
280
  boundary: StateDefinitionBoundary
281
281
  ): void => validateStateTree(boundary, states, "", false)
282
+
283
+ const captureAnnotations = (annotations: unknown): unknown =>
284
+ typeof annotations === "object" && annotations !== null
285
+ ? Object.freeze({ ...annotations })
286
+ : annotations
287
+
288
+ const captureStateTree = (states: Readonly<Record<string, unknown>>): Readonly<Record<string, unknown>> => {
289
+ const captured: Record<string, unknown> = {}
290
+ for (const key of Object.keys(states)) {
291
+ const node = states[key]
292
+ if (Schema.isSchema(node)) {
293
+ Object.defineProperty(captured, key, {
294
+ value: node,
295
+ enumerable: true,
296
+ configurable: false,
297
+ writable: false
298
+ })
299
+ continue
300
+ }
301
+ const config = node as Readonly<Record<string, unknown>>
302
+ const copy: Record<string, unknown> = { ...config }
303
+ if ("states" in config) {
304
+ copy.states = captureStateTree(config.states as Readonly<Record<string, unknown>>)
305
+ }
306
+ if ("annotations" in config) {
307
+ copy.annotations = captureAnnotations(config.annotations)
308
+ }
309
+ Object.defineProperty(captured, key, {
310
+ value: Object.freeze(copy),
311
+ enumerable: true,
312
+ configurable: false,
313
+ writable: false
314
+ })
315
+ }
316
+ return Object.freeze(captured)
317
+ }
318
+
319
+ /** Captures caller-owned structural containers while preserving schema identity. */
320
+ export const captureStateDefinitions = <States>(states: States): States =>
321
+ captureStateTree(states as Readonly<Record<string, unknown>>) as States
@@ -1509,7 +1509,7 @@ export const compileModel = (model: FiniteModel): Machine.Machine.Any => {
1509
1509
  const flattened = validateModel(model)
1510
1510
  const byPath = new Map(flattened.map((state) => [state.path, state]))
1511
1511
  const stateTree = makeStateTree(model.roots, undefined)
1512
- const defined = Machine.defineStates(stateTree as any)
1512
+ const defined = Machine.states(stateTree as any)
1513
1513
  const eventSchemas = model.events.map((event) => Schema.TaggedStruct(event, {}))
1514
1514
  const initial = byPath.get(model.initial)!
1515
1515
  const machine = Machine.make({
@@ -227,7 +227,7 @@ export interface Scenarios<M extends AnyMachine> {
227
227
  *
228
228
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
229
229
  * class Reset extends Schema.TaggedClass<Reset>("Reset")("Reset", {}) {}
230
- * const States = Machine.defineStates({ Idle })
230
+ * const States = Machine.states({ Idle })
231
231
  * const machine = Machine.make({
232
232
  * states: States.states,
233
233
  * events: Machine.events(Reset),
@@ -488,7 +488,7 @@ export { ProbeUnavailableError } from "../internal/testing/machine/verification.
488
488
  * import { MachineTest } from "@typeonce/effect-machine/testing"
489
489
  *
490
490
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
491
- * const States = Machine.defineStates({ Idle })
491
+ * const States = Machine.states({ Idle })
492
492
  * const machine = Machine.make({
493
493
  * states: States.states,
494
494
  * events: Machine.events(),
@@ -1101,7 +1101,7 @@ export const Invariant: {
1101
1101
  * class Count extends Schema.TaggedClass<Count>("Count")("Count", {
1102
1102
  * value: Schema.Number
1103
1103
  * }) {}
1104
- * const States = Machine.defineStates({ Count })
1104
+ * const States = Machine.states({ Count })
1105
1105
  * const machine = Machine.make({
1106
1106
  * states: States.states,
1107
1107
  * events: Machine.events(),
@@ -1436,7 +1436,7 @@ export type ExploreOptions<M extends AnyMachine, Key extends ExplorationKey = Ex
1436
1436
  * value: Schema.Number
1437
1437
  * }) {}
1438
1438
  * class Increment extends Schema.TaggedClass<Increment>("Increment")("Increment", {}) {}
1439
- * const States = Machine.defineStates({ Count })
1439
+ * const States = Machine.states({ Count })
1440
1440
  * const machine = Machine.make({
1441
1441
  * states: States.states,
1442
1442
  * events: Machine.events(Increment),
@@ -1629,7 +1629,7 @@ export type RunServices<M extends AnyMachine> = IsAny<
1629
1629
  * import { MachineTest } from "@typeonce/effect-machine/testing"
1630
1630
  *
1631
1631
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
1632
- * const States = Machine.defineStates({ Idle })
1632
+ * const States = Machine.states({ Idle })
1633
1633
  * const machine = Machine.make({
1634
1634
  * states: States.states,
1635
1635
  * events: Machine.events(),
@@ -1893,7 +1893,7 @@ export interface Coverage<M extends AnyMachine> {
1893
1893
  * import { MachineTest } from "@typeonce/effect-machine/testing"
1894
1894
  *
1895
1895
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
1896
- * const States = Machine.defineStates({ Idle })
1896
+ * const States = Machine.states({ Idle })
1897
1897
  * const machine = Machine.make({
1898
1898
  * states: States.states,
1899
1899
  * events: Machine.events(),
@@ -2118,7 +2118,7 @@ export interface VerifyOptions {
2118
2118
  * import { MachineTest } from "@typeonce/effect-machine/testing"
2119
2119
  *
2120
2120
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
2121
- * const States = Machine.defineStates({ Idle })
2121
+ * const States = Machine.states({ Idle })
2122
2122
  * const machine = Machine.make({
2123
2123
  * states: States.states,
2124
2124
  * events: Machine.events(),
@@ -312,7 +312,7 @@ export const layerMemory: Layer.Layer<Storage> = internal.layerMemory
312
312
  * import { ClusterMachine } from "@typeonce/effect-machine/cluster"
313
313
  *
314
314
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
315
- * const States = Machine.defineStates({ Idle })
315
+ * const States = Machine.states({ Idle })
316
316
  * const machine = Machine.make({
317
317
  * states: States.states,
318
318
  * events: Machine.events(),
@@ -366,7 +366,7 @@ type ChildState<Child extends Machine.ChildMachine.Any> = RefState<Machine.Child
366
366
  * class Count extends Schema.TaggedClass<Count>("Count")("Count", {
367
367
  * value: Schema.Number
368
368
  * }) {}
369
- * const States = Machine.defineStates({ Count })
369
+ * const States = Machine.states({ Count })
370
370
  * const machine = Machine.make({
371
371
  * states: States.states,
372
372
  * events: Machine.events(),
@@ -480,7 +480,7 @@ export const selectSnapshotChild: <
480
480
  * import { AtomMachine } from "@typeonce/effect-machine/reactivity"
481
481
  *
482
482
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
483
- * const States = Machine.defineStates({ Idle })
483
+ * const States = Machine.states({ Idle })
484
484
  * const machine = Machine.make({
485
485
  * states: States.states,
486
486
  * events: Machine.events(),
@@ -653,7 +653,7 @@ export interface Bound<Services, RuntimeError = never> {
653
653
  * import { AtomMachine } from "@typeonce/effect-machine/reactivity"
654
654
  *
655
655
  * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
656
- * const States = Machine.defineStates({ Idle })
656
+ * const States = Machine.states({ Idle })
657
657
  * const machine = Machine.make({
658
658
  * states: States.states,
659
659
  * events: Machine.events(),