@doeixd/machine 0.0.13 ā 0.0.18
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 +77 -25
- package/dist/cjs/development/core.js +1852 -0
- package/dist/cjs/development/core.js.map +7 -0
- package/dist/cjs/development/index.js +1377 -1372
- package/dist/cjs/development/index.js.map +4 -4
- package/dist/cjs/production/core.js +1 -0
- package/dist/cjs/production/index.js +5 -5
- package/dist/esm/development/core.js +1829 -0
- package/dist/esm/development/core.js.map +7 -0
- package/dist/esm/development/index.js +1377 -1372
- package/dist/esm/development/index.js.map +4 -4
- package/dist/esm/production/core.js +1 -0
- package/dist/esm/production/index.js +5 -5
- package/dist/types/core.d.ts +18 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/extract.d.ts +15 -1
- package/dist/types/extract.d.ts.map +1 -1
- package/dist/types/functional-combinators.d.ts +3 -5
- package/dist/types/functional-combinators.d.ts.map +1 -1
- package/dist/types/index.d.ts +254 -18
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/middleware/composition.d.ts +460 -0
- package/dist/types/middleware/composition.d.ts.map +1 -0
- package/dist/types/middleware/core.d.ts +196 -0
- package/dist/types/middleware/core.d.ts.map +1 -0
- package/dist/types/middleware/history.d.ts +54 -0
- package/dist/types/middleware/history.d.ts.map +1 -0
- package/dist/types/middleware/index.d.ts +10 -0
- package/dist/types/middleware/index.d.ts.map +1 -0
- package/dist/types/middleware/snapshot.d.ts +63 -0
- package/dist/types/middleware/snapshot.d.ts.map +1 -0
- package/dist/types/middleware/time-travel.d.ts +81 -0
- package/dist/types/middleware/time-travel.d.ts.map +1 -0
- package/package.json +19 -6
- package/src/core.ts +167 -0
- package/src/entry-react.ts +9 -0
- package/src/entry-solid.ts +9 -0
- package/src/extract.ts +61 -61
- package/src/functional-combinators.ts +3 -3
- package/src/generators.ts +6 -6
- package/src/index.ts +389 -101
- package/src/middleware/composition.ts +944 -0
- package/src/middleware/core.ts +573 -0
- package/src/middleware/history.ts +104 -0
- package/src/middleware/index.ts +13 -0
- package/src/middleware/snapshot.ts +153 -0
- package/src/middleware/time-travel.ts +236 -0
- package/src/middleware.ts +735 -1614
- package/src/prototype_functional.ts +46 -0
- package/src/reproduce_issue.ts +26 -0
- package/dist/types/middleware.d.ts +0 -1048
- package/dist/types/middleware.d.ts.map +0 -1
- package/dist/types/runtime-extract.d.ts +0 -53
- 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 (
|
|
70
|
+
### Basic Counter (Functional Builder Pattern)
|
|
71
71
|
|
|
72
|
-
**
|
|
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
|
|
82
|
-
return
|
|
79
|
+
(next) => ({
|
|
80
|
+
// Transitions (Ī“) - `this` is automatically typed
|
|
81
|
+
increment() {
|
|
82
|
+
return next({ count: this.count + 1 });
|
|
83
83
|
},
|
|
84
|
-
add
|
|
85
|
-
return
|
|
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
|
|
@@ -145,11 +165,11 @@ The most powerful pattern: different machine types represent different states.
|
|
|
145
165
|
import { createMachine, Machine } from "@doeixd/machine";
|
|
146
166
|
|
|
147
167
|
// Define distinct machine types for each state
|
|
148
|
-
type LoggedOut = Machine<{ status: "loggedOut" }
|
|
168
|
+
type LoggedOut = Machine<{ status: "loggedOut" }, {
|
|
149
169
|
login: (username: string) => LoggedIn;
|
|
150
170
|
};
|
|
151
171
|
|
|
152
|
-
type LoggedIn = Machine<{ status: "loggedIn"; username: string }
|
|
172
|
+
type LoggedIn = Machine<{ status: "loggedIn"; username: string }, {
|
|
153
173
|
logout: () => LoggedOut;
|
|
154
174
|
viewProfile: () => LoggedIn;
|
|
155
175
|
};
|
|
@@ -216,12 +236,12 @@ logout(state); // Runtime error!
|
|
|
216
236
|
**Type-State Approach (Compile-Time Enforcement):**
|
|
217
237
|
```typescript
|
|
218
238
|
// ā
States are distinct types - compiler enforces validity
|
|
219
|
-
type LoggedOut = Machine<{ status: "loggedOut" }
|
|
239
|
+
type LoggedOut = Machine<{ status: "loggedOut" }, {
|
|
220
240
|
login: (user: string) => LoggedIn;
|
|
221
241
|
// No logout method - impossible to call
|
|
222
242
|
};
|
|
223
243
|
|
|
224
|
-
type LoggedIn = Machine<{ status: "loggedIn"; username: string }
|
|
244
|
+
type LoggedIn = Machine<{ status: "loggedIn"; username: string }, {
|
|
225
245
|
logout: () => LoggedOut;
|
|
226
246
|
// No login method - impossible to call
|
|
227
247
|
};
|
|
@@ -288,7 +308,7 @@ if (hasState(machine, "status", "success")) {
|
|
|
288
308
|
|
|
289
309
|
#### 5. Event Type Safety
|
|
290
310
|
```typescript
|
|
291
|
-
type FetchMachine = AsyncMachine<{ status: string }
|
|
311
|
+
type FetchMachine = AsyncMachine<{ status: string }, {
|
|
292
312
|
fetch: (id: number) => Promise<FetchMachine>;
|
|
293
313
|
retry: () => Promise<FetchMachine>;
|
|
294
314
|
};
|
|
@@ -350,22 +370,22 @@ This shows the full power of Type-State Programming:
|
|
|
350
370
|
|
|
351
371
|
```typescript
|
|
352
372
|
// Define the states as distinct types
|
|
353
|
-
type IdleState = Machine<{ status: "idle" }
|
|
373
|
+
type IdleState = Machine<{ status: "idle" }, {
|
|
354
374
|
fetch: (url: string) => LoadingState;
|
|
355
375
|
};
|
|
356
376
|
|
|
357
|
-
type LoadingState = Machine<{ status: "loading"; url: string }
|
|
377
|
+
type LoadingState = Machine<{ status: "loading"; url: string }, {
|
|
358
378
|
cancel: () => IdleState;
|
|
359
379
|
// Note: No fetch - can't start new request while loading
|
|
360
380
|
};
|
|
361
381
|
|
|
362
|
-
type SuccessState = Machine<{ status: "success"; data: any }
|
|
382
|
+
type SuccessState = Machine<{ status: "success"; data: any }, {
|
|
363
383
|
refetch: () => LoadingState;
|
|
364
384
|
clear: () => IdleState;
|
|
365
385
|
// Note: No cancel - nothing to cancel
|
|
366
386
|
};
|
|
367
387
|
|
|
368
|
-
type ErrorState = Machine<{ status: "error"; error: string }
|
|
388
|
+
type ErrorState = Machine<{ status: "error"; error: string }, {
|
|
369
389
|
retry: () => LoadingState;
|
|
370
390
|
clear: () => IdleState;
|
|
371
391
|
};
|
|
@@ -413,9 +433,25 @@ This is the essence of Type-State Programming: **Make illegal states unrepresent
|
|
|
413
433
|
|
|
414
434
|
### Machine Creation
|
|
415
435
|
|
|
416
|
-
#### `createMachine<C, T>(context,
|
|
436
|
+
#### `createMachine<C, T>(context, factory)`
|
|
417
437
|
|
|
418
|
-
Creates a synchronous state machine.
|
|
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)
|
|
453
|
+
|
|
454
|
+
Creates a synchronous state machine from a context and transition functions.
|
|
419
455
|
|
|
420
456
|
```typescript
|
|
421
457
|
const machine = createMachine(
|
|
@@ -428,6 +464,22 @@ const machine = createMachine(
|
|
|
428
464
|
);
|
|
429
465
|
```
|
|
430
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
|
+
|
|
431
483
|
#### `createAsyncMachine<C, T>(context, transitions)`
|
|
432
484
|
|
|
433
485
|
Creates an async state machine (for side effects, API calls, etc.).
|
|
@@ -435,16 +487,16 @@ Creates an async state machine (for side effects, API calls, etc.).
|
|
|
435
487
|
```typescript
|
|
436
488
|
const machine = createAsyncMachine(
|
|
437
489
|
{ status: "idle", data: null },
|
|
438
|
-
{
|
|
490
|
+
(next) => ({
|
|
439
491
|
async fetch() {
|
|
440
492
|
try {
|
|
441
493
|
const data = await api.getData();
|
|
442
|
-
return
|
|
494
|
+
return next({ status: "success", data });
|
|
443
495
|
} catch (error) {
|
|
444
|
-
return
|
|
496
|
+
return next({ status: "error", data: null });
|
|
445
497
|
}
|
|
446
498
|
}
|
|
447
|
-
}
|
|
499
|
+
})
|
|
448
500
|
);
|
|
449
501
|
```
|
|
450
502
|
|
|
@@ -727,7 +779,7 @@ const tracked = withAnalytics(machine, trackEvent);
|
|
|
727
779
|
```typescript
|
|
728
780
|
import { Context, Transitions, Event, TransitionArgs } from "@doeixd/machine";
|
|
729
781
|
|
|
730
|
-
type MyMachine = Machine<{ count: number }
|
|
782
|
+
type MyMachine = Machine<{ count: number }, {
|
|
731
783
|
add: (n: number) => MyMachine;
|
|
732
784
|
};
|
|
733
785
|
|