@rotorsoft/act 0.8.0 → 0.10.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/dist/.tsbuildinfo +1 -1
- package/dist/@types/act-builder.d.ts +37 -220
- package/dist/@types/act-builder.d.ts.map +1 -1
- package/dist/@types/act.d.ts +2 -2
- package/dist/@types/act.d.ts.map +1 -1
- package/dist/@types/index.d.ts +2 -0
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/@types/merge.d.ts +38 -0
- package/dist/@types/merge.d.ts.map +1 -0
- package/dist/@types/projection-builder.d.ts +123 -0
- package/dist/@types/projection-builder.d.ts.map +1 -0
- package/dist/@types/slice-builder.d.ts +107 -0
- package/dist/@types/slice-builder.d.ts.map +1 -0
- package/dist/@types/state-builder.d.ts +26 -21
- package/dist/@types/state-builder.d.ts.map +1 -1
- package/dist/@types/types/action.d.ts +46 -1
- package/dist/@types/types/action.d.ts.map +1 -1
- package/dist/@types/types/reaction.d.ts +1 -1
- package/dist/@types/types/reaction.d.ts.map +1 -1
- package/dist/@types/utils.d.ts +1 -1
- package/dist/index.cjs +216 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +212 -71
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -53,10 +53,14 @@ __export(index_exports, {
|
|
|
53
53
|
dispose: () => dispose,
|
|
54
54
|
disposeAndExit: () => disposeAndExit,
|
|
55
55
|
extend: () => extend,
|
|
56
|
+
isProjection: () => isProjection,
|
|
57
|
+
isSlice: () => isSlice,
|
|
56
58
|
logger: () => logger,
|
|
57
59
|
patch: () => patch,
|
|
58
60
|
port: () => port,
|
|
61
|
+
projection: () => projection,
|
|
59
62
|
sleep: () => sleep,
|
|
63
|
+
slice: () => slice,
|
|
60
64
|
state: () => state,
|
|
61
65
|
store: () => store,
|
|
62
66
|
validate: () => validate
|
|
@@ -629,9 +633,6 @@ process.once("unhandledRejection", async (arg) => {
|
|
|
629
633
|
await disposeAndExit("ERROR");
|
|
630
634
|
});
|
|
631
635
|
|
|
632
|
-
// src/act-builder.ts
|
|
633
|
-
var import_zod4 = require("zod");
|
|
634
|
-
|
|
635
636
|
// src/act.ts
|
|
636
637
|
var import_crypto2 = require("crypto");
|
|
637
638
|
var import_events = __toESM(require("events"), 1);
|
|
@@ -872,7 +873,6 @@ var Act = class {
|
|
|
872
873
|
action2,
|
|
873
874
|
target,
|
|
874
875
|
payload,
|
|
875
|
-
// @ts-expect-error type lost
|
|
876
876
|
reactingTo,
|
|
877
877
|
skipValidation
|
|
878
878
|
);
|
|
@@ -1000,7 +1000,7 @@ var Act = class {
|
|
|
1000
1000
|
for (const payload of payloads) {
|
|
1001
1001
|
const { event, handler, options } = payload;
|
|
1002
1002
|
try {
|
|
1003
|
-
await handler(event, stream);
|
|
1003
|
+
await handler(event, stream, this);
|
|
1004
1004
|
at = event.id;
|
|
1005
1005
|
handled++;
|
|
1006
1006
|
} catch (error) {
|
|
@@ -1129,7 +1129,6 @@ var Act = class {
|
|
|
1129
1129
|
retry: 0,
|
|
1130
1130
|
lagging: lagging2
|
|
1131
1131
|
},
|
|
1132
|
-
// @ts-expect-error indexed by key
|
|
1133
1132
|
payloads
|
|
1134
1133
|
});
|
|
1135
1134
|
});
|
|
@@ -1346,7 +1345,8 @@ var Act = class {
|
|
|
1346
1345
|
}
|
|
1347
1346
|
};
|
|
1348
1347
|
|
|
1349
|
-
// src/
|
|
1348
|
+
// src/merge.ts
|
|
1349
|
+
var import_zod4 = require("zod");
|
|
1350
1350
|
function baseTypeName(zodType) {
|
|
1351
1351
|
let t = zodType;
|
|
1352
1352
|
while (typeof t.unwrap === "function") {
|
|
@@ -1376,80 +1376,216 @@ function mergeSchemas(existing, incoming, stateName) {
|
|
|
1376
1376
|
function mergeInits(existing, incoming) {
|
|
1377
1377
|
return () => ({ ...existing(), ...incoming() });
|
|
1378
1378
|
}
|
|
1379
|
+
function registerState(state2, states, actions, events) {
|
|
1380
|
+
if (states.has(state2.name)) {
|
|
1381
|
+
const existing = states.get(state2.name);
|
|
1382
|
+
for (const name of Object.keys(state2.actions)) {
|
|
1383
|
+
if (existing.actions[name] === state2.actions[name]) continue;
|
|
1384
|
+
if (actions[name]) throw new Error(`Duplicate action "${name}"`);
|
|
1385
|
+
}
|
|
1386
|
+
for (const name of Object.keys(state2.events)) {
|
|
1387
|
+
if (existing.events[name] === state2.events[name]) continue;
|
|
1388
|
+
if (events[name]) throw new Error(`Duplicate event "${name}"`);
|
|
1389
|
+
}
|
|
1390
|
+
const merged = {
|
|
1391
|
+
...existing,
|
|
1392
|
+
state: mergeSchemas(existing.state, state2.state, state2.name),
|
|
1393
|
+
init: mergeInits(existing.init, state2.init),
|
|
1394
|
+
events: { ...existing.events, ...state2.events },
|
|
1395
|
+
actions: { ...existing.actions, ...state2.actions },
|
|
1396
|
+
patch: { ...existing.patch, ...state2.patch },
|
|
1397
|
+
on: { ...existing.on, ...state2.on },
|
|
1398
|
+
given: { ...existing.given, ...state2.given },
|
|
1399
|
+
snap: state2.snap || existing.snap
|
|
1400
|
+
};
|
|
1401
|
+
states.set(state2.name, merged);
|
|
1402
|
+
for (const name of Object.keys(merged.actions)) {
|
|
1403
|
+
actions[name] = merged;
|
|
1404
|
+
}
|
|
1405
|
+
for (const name of Object.keys(state2.events)) {
|
|
1406
|
+
if (events[name]) continue;
|
|
1407
|
+
events[name] = {
|
|
1408
|
+
schema: state2.events[name],
|
|
1409
|
+
reactions: /* @__PURE__ */ new Map()
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
} else {
|
|
1413
|
+
states.set(state2.name, state2);
|
|
1414
|
+
for (const name of Object.keys(state2.actions)) {
|
|
1415
|
+
if (actions[name]) throw new Error(`Duplicate action "${name}"`);
|
|
1416
|
+
actions[name] = state2;
|
|
1417
|
+
}
|
|
1418
|
+
for (const name of Object.keys(state2.events)) {
|
|
1419
|
+
if (events[name]) throw new Error(`Duplicate event "${name}"`);
|
|
1420
|
+
events[name] = {
|
|
1421
|
+
schema: state2.events[name],
|
|
1422
|
+
reactions: /* @__PURE__ */ new Map()
|
|
1423
|
+
};
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1379
1427
|
var _this_ = ({ stream }) => ({
|
|
1380
1428
|
source: stream,
|
|
1381
1429
|
target: stream
|
|
1382
1430
|
});
|
|
1383
1431
|
var _void_ = () => void 0;
|
|
1432
|
+
|
|
1433
|
+
// src/projection-builder.ts
|
|
1434
|
+
function isProjection(x) {
|
|
1435
|
+
return x != null && x._tag === "Projection";
|
|
1436
|
+
}
|
|
1437
|
+
function projection(target, events = {}) {
|
|
1438
|
+
const defaultResolver = target ? { target } : void 0;
|
|
1439
|
+
const builder = {
|
|
1440
|
+
on: (entry) => {
|
|
1441
|
+
const keys = Object.keys(entry);
|
|
1442
|
+
if (keys.length !== 1) throw new Error(".on() requires exactly one key");
|
|
1443
|
+
const event = keys[0];
|
|
1444
|
+
const schema = entry[event];
|
|
1445
|
+
if (!(event in events)) {
|
|
1446
|
+
events[event] = {
|
|
1447
|
+
schema,
|
|
1448
|
+
reactions: /* @__PURE__ */ new Map()
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
return {
|
|
1452
|
+
do: (handler) => {
|
|
1453
|
+
const reaction = {
|
|
1454
|
+
handler,
|
|
1455
|
+
resolver: defaultResolver ?? _this_,
|
|
1456
|
+
options: {
|
|
1457
|
+
blockOnError: true,
|
|
1458
|
+
maxRetries: 3
|
|
1459
|
+
}
|
|
1460
|
+
};
|
|
1461
|
+
const register = events[event];
|
|
1462
|
+
const name = handler.name || `${event}_${register.reactions.size}`;
|
|
1463
|
+
register.reactions.set(name, reaction);
|
|
1464
|
+
const nextBuilder = projection(
|
|
1465
|
+
target,
|
|
1466
|
+
events
|
|
1467
|
+
);
|
|
1468
|
+
return {
|
|
1469
|
+
...nextBuilder,
|
|
1470
|
+
to(resolver) {
|
|
1471
|
+
register.reactions.set(name, {
|
|
1472
|
+
...reaction,
|
|
1473
|
+
resolver: typeof resolver === "string" ? { target: resolver } : resolver
|
|
1474
|
+
});
|
|
1475
|
+
return nextBuilder;
|
|
1476
|
+
},
|
|
1477
|
+
void() {
|
|
1478
|
+
register.reactions.set(name, {
|
|
1479
|
+
...reaction,
|
|
1480
|
+
resolver: _void_
|
|
1481
|
+
});
|
|
1482
|
+
return nextBuilder;
|
|
1483
|
+
}
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
};
|
|
1487
|
+
},
|
|
1488
|
+
build: () => ({
|
|
1489
|
+
_tag: "Projection",
|
|
1490
|
+
events
|
|
1491
|
+
}),
|
|
1492
|
+
events
|
|
1493
|
+
};
|
|
1494
|
+
return builder;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
// src/slice-builder.ts
|
|
1498
|
+
function isSlice(x) {
|
|
1499
|
+
return x != null && x._tag === "Slice";
|
|
1500
|
+
}
|
|
1501
|
+
function slice(states = /* @__PURE__ */ new Map(), actions = {}, events = {}) {
|
|
1502
|
+
const builder = {
|
|
1503
|
+
with: (state2) => {
|
|
1504
|
+
registerState(state2, states, actions, events);
|
|
1505
|
+
return slice(states, actions, events);
|
|
1506
|
+
},
|
|
1507
|
+
on: (event) => ({
|
|
1508
|
+
do: (handler, options) => {
|
|
1509
|
+
const reaction = {
|
|
1510
|
+
handler,
|
|
1511
|
+
resolver: _this_,
|
|
1512
|
+
options: {
|
|
1513
|
+
blockOnError: options?.blockOnError ?? true,
|
|
1514
|
+
maxRetries: options?.maxRetries ?? 3
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
const name = handler.name || `${String(event)}_${events[event].reactions.size}`;
|
|
1518
|
+
events[event].reactions.set(name, reaction);
|
|
1519
|
+
return {
|
|
1520
|
+
...builder,
|
|
1521
|
+
to(resolver) {
|
|
1522
|
+
events[event].reactions.set(name, {
|
|
1523
|
+
...reaction,
|
|
1524
|
+
resolver: typeof resolver === "string" ? { target: resolver } : resolver
|
|
1525
|
+
});
|
|
1526
|
+
return builder;
|
|
1527
|
+
},
|
|
1528
|
+
void() {
|
|
1529
|
+
events[event].reactions.set(name, {
|
|
1530
|
+
...reaction,
|
|
1531
|
+
resolver: _void_
|
|
1532
|
+
});
|
|
1533
|
+
return builder;
|
|
1534
|
+
}
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
}),
|
|
1538
|
+
build: () => ({
|
|
1539
|
+
_tag: "Slice",
|
|
1540
|
+
states,
|
|
1541
|
+
events
|
|
1542
|
+
}),
|
|
1543
|
+
events
|
|
1544
|
+
};
|
|
1545
|
+
return builder;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
// src/act-builder.ts
|
|
1384
1549
|
function act(states = /* @__PURE__ */ new Map(), registry = {
|
|
1385
1550
|
actions: {},
|
|
1386
1551
|
events: {}
|
|
1387
1552
|
}) {
|
|
1388
1553
|
const builder = {
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
}
|
|
1407
|
-
for (const name of Object.keys(state2.events)) {
|
|
1408
|
-
if (registry.events[name])
|
|
1409
|
-
throw new Error(`Duplicate event "${name}"`);
|
|
1410
|
-
}
|
|
1411
|
-
const merged = {
|
|
1412
|
-
...existing,
|
|
1413
|
-
state: mergeSchemas(existing.state, state2.state, state2.name),
|
|
1414
|
-
init: mergeInits(existing.init, state2.init),
|
|
1415
|
-
events: { ...existing.events, ...state2.events },
|
|
1416
|
-
actions: { ...existing.actions, ...state2.actions },
|
|
1417
|
-
patch: { ...existing.patch, ...state2.patch },
|
|
1418
|
-
on: { ...existing.on, ...state2.on },
|
|
1419
|
-
given: { ...existing.given, ...state2.given },
|
|
1420
|
-
snap: state2.snap || existing.snap
|
|
1421
|
-
};
|
|
1422
|
-
states.set(state2.name, merged);
|
|
1423
|
-
for (const name of Object.keys(merged.actions)) {
|
|
1424
|
-
registry.actions[name] = merged;
|
|
1425
|
-
}
|
|
1426
|
-
for (const name of Object.keys(state2.events)) {
|
|
1427
|
-
registry.events[name] = {
|
|
1428
|
-
schema: state2.events[name],
|
|
1429
|
-
reactions: /* @__PURE__ */ new Map()
|
|
1430
|
-
};
|
|
1554
|
+
with: ((input) => {
|
|
1555
|
+
if (isProjection(input)) {
|
|
1556
|
+
for (const eventName of Object.keys(input.events)) {
|
|
1557
|
+
const projRegister = input.events[eventName];
|
|
1558
|
+
const existing = registry.events[eventName];
|
|
1559
|
+
if (!existing) {
|
|
1560
|
+
registry.events[eventName] = {
|
|
1561
|
+
schema: projRegister.schema,
|
|
1562
|
+
reactions: new Map(projRegister.reactions)
|
|
1563
|
+
};
|
|
1564
|
+
} else {
|
|
1565
|
+
for (const [name, reaction] of projRegister.reactions) {
|
|
1566
|
+
let key = name;
|
|
1567
|
+
while (existing.reactions.has(key)) key = `${key}_p`;
|
|
1568
|
+
existing.reactions.set(key, reaction);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1431
1571
|
}
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
registry.actions[name] = state2;
|
|
1572
|
+
return act(states, registry);
|
|
1573
|
+
}
|
|
1574
|
+
if (isSlice(input)) {
|
|
1575
|
+
for (const s of input.states.values()) {
|
|
1576
|
+
registerState(s, states, registry.actions, registry.events);
|
|
1438
1577
|
}
|
|
1439
|
-
for (const
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
reactions: /* @__PURE__ */ new Map()
|
|
1445
|
-
};
|
|
1578
|
+
for (const eventName of Object.keys(input.events)) {
|
|
1579
|
+
const sliceRegister = input.events[eventName];
|
|
1580
|
+
for (const [name, reaction] of sliceRegister.reactions) {
|
|
1581
|
+
registry.events[eventName].reactions.set(name, reaction);
|
|
1582
|
+
}
|
|
1446
1583
|
}
|
|
1584
|
+
return act(states, registry);
|
|
1447
1585
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
);
|
|
1452
|
-
},
|
|
1586
|
+
registerState(input, states, registry.actions, registry.events);
|
|
1587
|
+
return act(states, registry);
|
|
1588
|
+
}),
|
|
1453
1589
|
/**
|
|
1454
1590
|
* Adds a reaction to an event.
|
|
1455
1591
|
*
|
|
@@ -1467,18 +1603,19 @@ function act(states = /* @__PURE__ */ new Map(), registry = {
|
|
|
1467
1603
|
maxRetries: options?.maxRetries ?? 3
|
|
1468
1604
|
}
|
|
1469
1605
|
};
|
|
1470
|
-
registry.events[event].reactions.
|
|
1606
|
+
const name = handler.name || `${String(event)}_${registry.events[event].reactions.size}`;
|
|
1607
|
+
registry.events[event].reactions.set(name, reaction);
|
|
1471
1608
|
return {
|
|
1472
1609
|
...builder,
|
|
1473
1610
|
to(resolver) {
|
|
1474
|
-
registry.events[event].reactions.set(
|
|
1611
|
+
registry.events[event].reactions.set(name, {
|
|
1475
1612
|
...reaction,
|
|
1476
1613
|
resolver: typeof resolver === "string" ? { target: resolver } : resolver
|
|
1477
1614
|
});
|
|
1478
1615
|
return builder;
|
|
1479
1616
|
},
|
|
1480
1617
|
void() {
|
|
1481
|
-
registry.events[event].reactions.set(
|
|
1618
|
+
registry.events[event].reactions.set(name, {
|
|
1482
1619
|
...reaction,
|
|
1483
1620
|
resolver: _void_
|
|
1484
1621
|
});
|
|
@@ -1519,7 +1656,11 @@ function state(name, state2) {
|
|
|
1519
1656
|
}
|
|
1520
1657
|
function action_builder(state2) {
|
|
1521
1658
|
return {
|
|
1522
|
-
on(
|
|
1659
|
+
on(entry) {
|
|
1660
|
+
const keys = Object.keys(entry);
|
|
1661
|
+
if (keys.length !== 1) throw new Error(".on() requires exactly one key");
|
|
1662
|
+
const action2 = keys[0];
|
|
1663
|
+
const schema = entry[action2];
|
|
1523
1664
|
if (action2 in state2.actions)
|
|
1524
1665
|
throw new Error(`Duplicate action "${action2}"`);
|
|
1525
1666
|
const actions = { ...state2.actions, [action2]: schema };
|
|
@@ -1573,10 +1714,14 @@ function action_builder(state2) {
|
|
|
1573
1714
|
dispose,
|
|
1574
1715
|
disposeAndExit,
|
|
1575
1716
|
extend,
|
|
1717
|
+
isProjection,
|
|
1718
|
+
isSlice,
|
|
1576
1719
|
logger,
|
|
1577
1720
|
patch,
|
|
1578
1721
|
port,
|
|
1722
|
+
projection,
|
|
1579
1723
|
sleep,
|
|
1724
|
+
slice,
|
|
1580
1725
|
state,
|
|
1581
1726
|
store,
|
|
1582
1727
|
validate
|