@rotorsoft/act 0.18.0 → 0.19.1
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/dist/.tsbuildinfo +1 -1
- package/dist/@types/event-sourcing.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +1 -7
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/@types/utils.d.ts +1 -90
- package/dist/@types/utils.d.ts.map +1 -1
- package/dist/index.cjs +3 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -35
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/@types/utils.d.ts
CHANGED
|
@@ -1,102 +1,13 @@
|
|
|
1
1
|
import { type ZodType } from "zod";
|
|
2
|
-
import type { Patch, Schema } from "./types/index.js";
|
|
3
2
|
/**
|
|
4
3
|
* @module utils
|
|
5
4
|
* @category Utilities
|
|
6
|
-
* Utility functions for
|
|
5
|
+
* Utility functions for validation, extending objects, and async helpers.
|
|
7
6
|
*
|
|
8
|
-
* - Use `patch()` to immutably update state with patches.
|
|
9
7
|
* - Use `validate()` to validate payloads against Zod schemas.
|
|
10
8
|
* - Use `extend()` to merge and validate configuration objects.
|
|
11
9
|
* - Use `sleep()` for async delays.
|
|
12
10
|
*/
|
|
13
|
-
/**
|
|
14
|
-
* Immutably applies patches to a state object, creating a new copy.
|
|
15
|
-
*
|
|
16
|
-
* This function performs deep merging for plain objects while preserving
|
|
17
|
-
* immutability. Special types (Arrays, Dates, Maps, etc.) are replaced
|
|
18
|
-
* entirely rather than merged. Setting a property to `undefined` or `null`
|
|
19
|
-
* removes it from the resulting object.
|
|
20
|
-
*
|
|
21
|
-
* Used internally by the framework to apply event patches to state, but
|
|
22
|
-
* can also be used directly for state transformations.
|
|
23
|
-
*
|
|
24
|
-
* **Merging rules:**
|
|
25
|
-
* - Plain objects: Deep merge recursively
|
|
26
|
-
* - Arrays, Dates, RegExp, Maps, Sets, TypedArrays: Replace entirely
|
|
27
|
-
* - `undefined` or `null` values: Delete the property
|
|
28
|
-
* - Primitives: Replace with patch value
|
|
29
|
-
*
|
|
30
|
-
* @param original - The original state object to patch
|
|
31
|
-
* @param patches - The patches to apply (partial state)
|
|
32
|
-
* @returns A new state object with patches applied
|
|
33
|
-
*
|
|
34
|
-
* @example Simple property update
|
|
35
|
-
* ```typescript
|
|
36
|
-
* import { patch } from "@rotorsoft/act";
|
|
37
|
-
*
|
|
38
|
-
* const state = { count: 0, name: "Alice" };
|
|
39
|
-
* const updated = patch(state, { count: 5 });
|
|
40
|
-
* // Result: { count: 5, name: "Alice" }
|
|
41
|
-
* // Original unchanged: { count: 0, name: "Alice" }
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* @example Nested object patching
|
|
45
|
-
* ```typescript
|
|
46
|
-
* const state = {
|
|
47
|
-
* user: { id: 1, name: "Alice", email: "alice@example.com" },
|
|
48
|
-
* settings: { theme: "dark" }
|
|
49
|
-
* };
|
|
50
|
-
*
|
|
51
|
-
* const updated = patch(state, {
|
|
52
|
-
* user: { email: "newemail@example.com" }
|
|
53
|
-
* });
|
|
54
|
-
* // Result: {
|
|
55
|
-
* // user: { id: 1, name: "Alice", email: "newemail@example.com" },
|
|
56
|
-
* // settings: { theme: "dark" }
|
|
57
|
-
* // }
|
|
58
|
-
* ```
|
|
59
|
-
*
|
|
60
|
-
* @example Property deletion
|
|
61
|
-
* ```typescript
|
|
62
|
-
* const state = { count: 5, temp: "value", flag: true };
|
|
63
|
-
*
|
|
64
|
-
* const updated = patch(state, {
|
|
65
|
-
* temp: undefined, // Delete temp
|
|
66
|
-
* flag: null // Delete flag
|
|
67
|
-
* });
|
|
68
|
-
* // Result: { count: 5 }
|
|
69
|
-
* ```
|
|
70
|
-
*
|
|
71
|
-
* @example Array replacement (not merged)
|
|
72
|
-
* ```typescript
|
|
73
|
-
* const state = { items: [1, 2, 3], meta: { count: 3 } };
|
|
74
|
-
*
|
|
75
|
-
* const updated = patch(state, {
|
|
76
|
-
* items: [4, 5] // Arrays are replaced, not merged
|
|
77
|
-
* });
|
|
78
|
-
* // Result: { items: [4, 5], meta: { count: 3 } }
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
* @example In event handlers
|
|
82
|
-
* ```typescript
|
|
83
|
-
* import { state } from "@rotorsoft/act";
|
|
84
|
-
* import { z } from "zod";
|
|
85
|
-
*
|
|
86
|
-
* const Counter = state({ Counter: z.object({ count: z.number() }) })
|
|
87
|
-
* .init(() => ({ count: 0 }))
|
|
88
|
-
* .emits({ Incremented: z.object({ by: z.number() }) })
|
|
89
|
-
* .patch({
|
|
90
|
-
* Incremented: (event, state) => {
|
|
91
|
-
* // patch() is called internally here
|
|
92
|
-
* return { count: state.count + event.data.by };
|
|
93
|
-
* }
|
|
94
|
-
* });
|
|
95
|
-
* ```
|
|
96
|
-
*
|
|
97
|
-
* @see {@link Patch} for the patch type definition
|
|
98
|
-
*/
|
|
99
|
-
export declare const patch: <S extends Schema>(original: Readonly<S>, patches: Readonly<Patch<S>>) => Readonly<S>;
|
|
100
11
|
/**
|
|
101
12
|
* Validates a payload against a Zod schema.
|
|
102
13
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAAiB,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,OAAO,EAAiB,MAAM,KAAK,CAAC;AAIjE;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmGG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,EACxB,QAAQ,MAAM,EACd,SAAS,QAAQ,CAAC,CAAC,CAAC,EACpB,SAAS,OAAO,CAAC,CAAC,CAAC,KAClB,QAAQ,CAAC,CAAC,CAaZ,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwHG;AACH,eAAO,MAAM,MAAM,GACjB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAEjC,QAAQ,QAAQ,CAAC,CAAC,CAAC,EACnB,QAAQ,OAAO,CAAC,CAAC,CAAC,EAClB,SAAS,QAAQ,CAAC,CAAC,CAAC,KACnB,QAAQ,CAAC,CAAC,GAAG,CAAC,CAGhB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuFG;AACH,wBAAsB,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,oBAEtC"}
|
package/dist/index.cjs
CHANGED
|
@@ -54,7 +54,6 @@ __export(index_exports, {
|
|
|
54
54
|
disposeAndExit: () => disposeAndExit,
|
|
55
55
|
extend: () => extend,
|
|
56
56
|
logger: () => logger,
|
|
57
|
-
patch: () => patch,
|
|
58
57
|
port: () => port,
|
|
59
58
|
projection: () => projection,
|
|
60
59
|
sleep: () => sleep,
|
|
@@ -206,40 +205,6 @@ var config = () => {
|
|
|
206
205
|
};
|
|
207
206
|
|
|
208
207
|
// src/utils.ts
|
|
209
|
-
var UNMERGEABLES = [
|
|
210
|
-
RegExp,
|
|
211
|
-
Date,
|
|
212
|
-
Array,
|
|
213
|
-
Map,
|
|
214
|
-
Set,
|
|
215
|
-
WeakMap,
|
|
216
|
-
WeakSet,
|
|
217
|
-
ArrayBuffer,
|
|
218
|
-
SharedArrayBuffer,
|
|
219
|
-
DataView,
|
|
220
|
-
Int8Array,
|
|
221
|
-
Uint8Array,
|
|
222
|
-
Uint8ClampedArray,
|
|
223
|
-
Int16Array,
|
|
224
|
-
Uint16Array,
|
|
225
|
-
Int32Array,
|
|
226
|
-
Uint32Array,
|
|
227
|
-
Float32Array,
|
|
228
|
-
Float64Array
|
|
229
|
-
];
|
|
230
|
-
var is_mergeable = (value) => !!value && typeof value === "object" && !UNMERGEABLES.some((t) => value instanceof t);
|
|
231
|
-
var patch = (original, patches) => {
|
|
232
|
-
const copy = {};
|
|
233
|
-
Object.keys({ ...original, ...patches }).forEach((key) => {
|
|
234
|
-
const patched_value = patches[key];
|
|
235
|
-
const original_value = original[key];
|
|
236
|
-
const patched = patches && key in patches;
|
|
237
|
-
const deleted = patched && (typeof patched_value === "undefined" || patched_value === null);
|
|
238
|
-
const value = patched && !deleted ? patched_value : original_value;
|
|
239
|
-
!deleted && (copy[key] = is_mergeable(value) ? patch(original_value || {}, patched_value || {}) : value);
|
|
240
|
-
});
|
|
241
|
-
return copy;
|
|
242
|
-
};
|
|
243
208
|
var validate = (target, payload, schema) => {
|
|
244
209
|
try {
|
|
245
210
|
return schema ? schema.parse(payload) : payload;
|
|
@@ -636,6 +601,7 @@ var import_crypto2 = require("crypto");
|
|
|
636
601
|
var import_events = __toESM(require("events"), 1);
|
|
637
602
|
|
|
638
603
|
// src/event-sourcing.ts
|
|
604
|
+
var import_act_patch = require("@rotorsoft/act-patch");
|
|
639
605
|
var import_crypto = require("crypto");
|
|
640
606
|
async function snap(snapshot) {
|
|
641
607
|
try {
|
|
@@ -668,7 +634,7 @@ async function load(me, stream, callback) {
|
|
|
668
634
|
snaps++;
|
|
669
635
|
patches = 0;
|
|
670
636
|
} else if (me.patch[e.name]) {
|
|
671
|
-
state2 = patch(state2, me.patch[e.name](event, state2));
|
|
637
|
+
state2 = (0, import_act_patch.patch)(state2, me.patch[e.name](event, state2));
|
|
672
638
|
patches++;
|
|
673
639
|
}
|
|
674
640
|
callback && callback({ event, state: state2, patches, snaps });
|
|
@@ -741,7 +707,7 @@ async function action(me, action2, target, payload, reactingTo, skipValidation =
|
|
|
741
707
|
let { state: state2, patches } = snapshot;
|
|
742
708
|
const snapshots = committed.map((event) => {
|
|
743
709
|
const p = me.patch[event.name](event, state2);
|
|
744
|
-
state2 = patch(state2, p);
|
|
710
|
+
state2 = (0, import_act_patch.patch)(state2, p);
|
|
745
711
|
patches++;
|
|
746
712
|
return { event, state: state2, patches, snaps: snapshot.snaps, patch: p };
|
|
747
713
|
});
|
|
@@ -1821,7 +1787,6 @@ function action_builder(state2) {
|
|
|
1821
1787
|
disposeAndExit,
|
|
1822
1788
|
extend,
|
|
1823
1789
|
logger,
|
|
1824
|
-
patch,
|
|
1825
1790
|
port,
|
|
1826
1791
|
projection,
|
|
1827
1792
|
sleep,
|