@doeixd/machine 0.0.12 → 0.0.17

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.
Files changed (50) hide show
  1. package/README.md +90 -15
  2. package/dist/cjs/development/core.js +1852 -0
  3. package/dist/cjs/development/core.js.map +7 -0
  4. package/dist/cjs/development/index.js +1348 -1374
  5. package/dist/cjs/development/index.js.map +4 -4
  6. package/dist/cjs/production/core.js +1 -0
  7. package/dist/cjs/production/index.js +5 -5
  8. package/dist/esm/development/core.js +1829 -0
  9. package/dist/esm/development/core.js.map +7 -0
  10. package/dist/esm/development/index.js +1348 -1374
  11. package/dist/esm/development/index.js.map +4 -4
  12. package/dist/esm/production/core.js +1 -0
  13. package/dist/esm/production/index.js +5 -5
  14. package/dist/types/core.d.ts +18 -0
  15. package/dist/types/core.d.ts.map +1 -0
  16. package/dist/types/functional-combinators.d.ts +60 -5
  17. package/dist/types/functional-combinators.d.ts.map +1 -1
  18. package/dist/types/index.d.ts +242 -19
  19. package/dist/types/index.d.ts.map +1 -1
  20. package/dist/types/middleware/composition.d.ts +460 -0
  21. package/dist/types/middleware/composition.d.ts.map +1 -0
  22. package/dist/types/middleware/core.d.ts +196 -0
  23. package/dist/types/middleware/core.d.ts.map +1 -0
  24. package/dist/types/middleware/history.d.ts +54 -0
  25. package/dist/types/middleware/history.d.ts.map +1 -0
  26. package/dist/types/middleware/index.d.ts +10 -0
  27. package/dist/types/middleware/index.d.ts.map +1 -0
  28. package/dist/types/middleware/snapshot.d.ts +63 -0
  29. package/dist/types/middleware/snapshot.d.ts.map +1 -0
  30. package/dist/types/middleware/time-travel.d.ts +81 -0
  31. package/dist/types/middleware/time-travel.d.ts.map +1 -0
  32. package/package.json +19 -6
  33. package/src/core.ts +167 -0
  34. package/src/entry-react.ts +9 -0
  35. package/src/entry-solid.ts +9 -0
  36. package/src/functional-combinators.ts +76 -3
  37. package/src/index.ts +376 -102
  38. package/src/middleware/composition.ts +944 -0
  39. package/src/middleware/core.ts +573 -0
  40. package/src/middleware/history.ts +104 -0
  41. package/src/middleware/index.ts +13 -0
  42. package/src/middleware/snapshot.ts +153 -0
  43. package/src/middleware/time-travel.ts +236 -0
  44. package/src/middleware.ts +735 -1614
  45. package/src/prototype_functional.ts +46 -0
  46. package/src/reproduce_issue.ts +26 -0
  47. package/dist/types/middleware.d.ts +0 -1048
  48. package/dist/types/middleware.d.ts.map +0 -1
  49. package/dist/types/runtime-extract.d.ts +0 -53
  50. package/dist/types/runtime-extract.d.ts.map +0 -1
package/README.md CHANGED
@@ -67,24 +67,24 @@ The library offers multiple patterns for different use cases. **šŸ“– [Pattern De
67
67
 
68
68
  ## Quick Start
69
69
 
70
- ### Basic Counter (Simple State)
70
+ ### Basic Counter (Functional Builder Pattern)
71
71
 
72
- **Immutable approach (recommended):**
72
+ **Recommended approach (type-safe and ergonomic):**
73
73
 
74
74
  ```typescript
75
75
  import { createMachine } from "@doeixd/machine";
76
76
 
77
77
  const counter = createMachine(
78
78
  { count: 0 }, // Initial state (sā‚€)
79
- {
80
- // Transitions (Ī“)
81
- increment: function() {
82
- return createMachine({ count: this.count + 1 }, this);
79
+ (next) => ({
80
+ // Transitions (Ī“) - `this` is automatically typed
81
+ increment() {
82
+ return next({ count: this.count + 1 });
83
83
  },
84
- add: function(n: number) {
85
- return createMachine({ count: this.count + n }, this);
84
+ add(n: number) {
85
+ return next({ count: this.count + n });
86
86
  }
87
- }
87
+ })
88
88
  );
89
89
 
90
90
  const next = counter.increment();
@@ -94,6 +94,26 @@ console.log(next.context.count); // 1
94
94
  console.log(counter.context.count); // 0
95
95
  ```
96
96
 
97
+ **Benefits:**
98
+ - **Type-safe**: Full TypeScript inference for `this` context
99
+ - **Ergonomic**: No need to manually pass transition objects
100
+ - **Clean**: Automatic binding and context inference
101
+ - **Composable**: Transitions are automatically available on all returned machines
102
+
103
+ **Traditional approach (also supported):**
104
+
105
+ ```typescript
106
+ const transitions = {
107
+ increment: function() {
108
+ return createMachine({ count: this.count + 1 }, transitions);
109
+ },
110
+ add: function(n: number) {
111
+ return createMachine({ count: this.count + n }, transitions);
112
+ }
113
+ };
114
+ const counter = createMachine({ count: 0 }, transitions);
115
+ ```
116
+
97
117
  **Mutable approach (also supported):**
98
118
 
99
119
  ```typescript
@@ -112,6 +132,29 @@ counter.increment();
112
132
  console.log(counter.context.count); // 1 (mutated in place)
113
133
  ```
114
134
 
135
+ ### Smart State Creation with `state()`
136
+
137
+ The `state()` function automatically chooses between traditional and functional patterns:
138
+
139
+ ```typescript
140
+ import { state } from "@doeixd/machine";
141
+
142
+ // Traditional pattern (like createMachine)
143
+ const counter1 = state({ count: 0 }, {
144
+ increment() { return state({ count: this.context.count + 1 }, this); }
145
+ });
146
+
147
+ // Functional pattern (like createFunctionalMachine)
148
+ const createCounter = state({ count: 0 });
149
+ const counter2 = createCounter({
150
+ increment: ctx => ({ count: ctx.count + 1 }),
151
+ add: (ctx, n: number) => ({ count: ctx.count + n })
152
+ });
153
+
154
+ console.log(counter1.increment().context.count); // 1
155
+ console.log(counter2.increment().add(5).context.count); // 6
156
+ ```
157
+
115
158
  This shows the **flexibility** of the library: immutability is the default pattern because it's safer, but you can choose mutability when it makes sense for your use case.
116
159
 
117
160
  ### Type-State Programming (Compile-Time State Safety)
@@ -390,9 +433,25 @@ This is the essence of Type-State Programming: **Make illegal states unrepresent
390
433
 
391
434
  ### Machine Creation
392
435
 
393
- #### `createMachine<C, T>(context, transitions)`
436
+ #### `createMachine<C, T>(context, factory)`
437
+
438
+ Creates a synchronous state machine using the **Functional Builder** pattern. This is the recommended approach for type safety and ergonomics, as it automatically infers `this` context and binds transitions.
439
+
440
+ ```typescript
441
+ const machine = createMachine({ count: 0 }, (next) => ({
442
+ increment() {
443
+ // `this` is correctly inferred as Context
444
+ return next({ count: this.count + 1 });
445
+ },
446
+ add(n: number) {
447
+ return next({ count: this.count + n });
448
+ }
449
+ }));
450
+ ```
451
+
452
+ #### `createMachine<C, T>(context, transitions)` (Traditional)
394
453
 
395
- Creates a synchronous state machine.
454
+ Creates a synchronous state machine from a context and transition functions.
396
455
 
397
456
  ```typescript
398
457
  const machine = createMachine(
@@ -405,6 +464,22 @@ const machine = createMachine(
405
464
  );
406
465
  ```
407
466
 
467
+ #### `createMachine<C, T>(context, factory)`
468
+
469
+ Creates a synchronous state machine using the **Functional Builder** pattern. This is the recommended approach for type safety and ergonomics, as it automatically infers `this` context and binds transitions.
470
+
471
+ ```typescript
472
+ const machine = createMachine({ count: 0 }, (transition) => ({
473
+ increment() {
474
+ // `this` is correctly inferred as Context
475
+ return transition({ count: this.count + 1 });
476
+ },
477
+ add(n: number) {
478
+ return transition({ count: this.count + n });
479
+ }
480
+ }));
481
+ ```
482
+
408
483
  #### `createAsyncMachine<C, T>(context, transitions)`
409
484
 
410
485
  Creates an async state machine (for side effects, API calls, etc.).
@@ -412,16 +487,16 @@ Creates an async state machine (for side effects, API calls, etc.).
412
487
  ```typescript
413
488
  const machine = createAsyncMachine(
414
489
  { status: "idle", data: null },
415
- {
490
+ (next) => ({
416
491
  async fetch() {
417
492
  try {
418
493
  const data = await api.getData();
419
- return createAsyncMachine({ status: "success", data }, this);
494
+ return next({ status: "success", data });
420
495
  } catch (error) {
421
- return createAsyncMachine({ status: "error", data: null }, this);
496
+ return next({ status: "error", data: null });
422
497
  }
423
498
  }
424
- }
499
+ })
425
500
  );
426
501
  ```
427
502