@rotorsoft/act 0.11.1 → 0.12.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.
@@ -1,3 +1,4 @@
1
+ import type { Projection } from "./projection-builder.js";
1
2
  import type { Committed, Dispatcher, EventRegister, ReactionOptions, ReactionResolver, Schema, SchemaRegister, Schemas, Snapshot, State } from "./types/index.js";
2
3
  /**
3
4
  * A self-contained functional slice grouping partial states with their
@@ -13,6 +14,7 @@ export type Slice<S extends SchemaRegister<A>, E extends Schemas, A extends Sche
13
14
  readonly _tag: "Slice";
14
15
  readonly states: Map<string, State<any, any, any>>;
15
16
  readonly events: EventRegister<E>;
17
+ readonly projections: ReadonlyArray<Projection<any>>;
16
18
  /** @internal phantom field for type-level state schema tracking */
17
19
  readonly _S?: S;
18
20
  /** @internal phantom field for type-level state name tracking */
@@ -48,6 +50,14 @@ export type SliceBuilder<S extends SchemaRegister<A>, E extends Schemas, A exten
48
50
  }, E & EX, A & AX, M & {
49
51
  [K in NX]: SX;
50
52
  }>;
53
+ /**
54
+ * Embeds a built Projection within this slice for encapsulated
55
+ * feature composition. The projection's events must be a subset
56
+ * of events from states already registered via `.with()`.
57
+ * Projection handlers preserve their `(event, stream)` signature
58
+ * and do not receive a Dispatcher.
59
+ */
60
+ projection: <EP extends Schemas>(proj: [Exclude<keyof EP, keyof E>] extends [never] ? Projection<EP> : never) => SliceBuilder<S, E, A, M>;
51
61
  /**
52
62
  * Begins defining a reaction scoped to this slice's events.
53
63
  */
@@ -103,5 +113,5 @@ export type SliceBuilder<S extends SchemaRegister<A>, E extends Schemas, A exten
103
113
  * @see {@link SliceBuilder} for builder methods
104
114
  * @see {@link Slice} for the output type
105
115
  */
106
- export declare function slice<S extends SchemaRegister<A> = {}, E extends Schemas = {}, A extends Schemas = {}, M extends Record<string, Schema> = {}>(states?: Map<string, State<any, any, any>>, actions?: Record<string, any>, events?: EventRegister<E>): SliceBuilder<S, E, A, M>;
116
+ export declare function slice<S extends SchemaRegister<A> = {}, E extends Schemas = {}, A extends Schemas = {}, M extends Record<string, Schema> = {}>(states?: Map<string, State<any, any, any>>, actions?: Record<string, any>, events?: EventRegister<E>, projections?: Projection<any>[]): SliceBuilder<S, E, A, M>;
107
117
  //# sourceMappingURL=slice-builder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"slice-builder.d.ts","sourceRoot":"","sources":["../../src/slice-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slice-builder.d.ts","sourceRoot":"","sources":["../../src/slice-builder.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1424,6 +1424,24 @@ function registerState(state2, states, actions, events) {
1424
1424
  }
1425
1425
  }
1426
1426
  }
1427
+ function mergeProjection(proj, events) {
1428
+ for (const eventName of Object.keys(proj.events)) {
1429
+ const projRegister = proj.events[eventName];
1430
+ const existing = events[eventName];
1431
+ if (!existing) {
1432
+ events[eventName] = {
1433
+ schema: projRegister.schema,
1434
+ reactions: new Map(projRegister.reactions)
1435
+ };
1436
+ } else {
1437
+ for (const [name, reaction] of projRegister.reactions) {
1438
+ let key = name;
1439
+ while (existing.reactions.has(key)) key = `${key}_p`;
1440
+ existing.reactions.set(key, reaction);
1441
+ }
1442
+ }
1443
+ }
1444
+ }
1427
1445
  var _this_ = ({ stream }) => ({
1428
1446
  source: stream,
1429
1447
  target: stream
@@ -1498,11 +1516,20 @@ function projection(target, events = {}) {
1498
1516
  function isSlice(x) {
1499
1517
  return x != null && x._tag === "Slice";
1500
1518
  }
1501
- function slice(states = /* @__PURE__ */ new Map(), actions = {}, events = {}) {
1519
+ function slice(states = /* @__PURE__ */ new Map(), actions = {}, events = {}, projections = []) {
1502
1520
  const builder = {
1503
1521
  with: (state2) => {
1504
1522
  registerState(state2, states, actions, events);
1505
- return slice(states, actions, events);
1523
+ return slice(
1524
+ states,
1525
+ actions,
1526
+ events,
1527
+ projections
1528
+ );
1529
+ },
1530
+ projection: (proj) => {
1531
+ projections.push(proj);
1532
+ return slice(states, actions, events, projections);
1506
1533
  },
1507
1534
  on: (event) => ({
1508
1535
  do: (handler, options) => {
@@ -1538,7 +1565,8 @@ function slice(states = /* @__PURE__ */ new Map(), actions = {}, events = {}) {
1538
1565
  build: () => ({
1539
1566
  _tag: "Slice",
1540
1567
  states,
1541
- events
1568
+ events,
1569
+ projections
1542
1570
  }),
1543
1571
  events
1544
1572
  };
@@ -1549,27 +1577,16 @@ function slice(states = /* @__PURE__ */ new Map(), actions = {}, events = {}) {
1549
1577
  function act(states = /* @__PURE__ */ new Map(), registry = {
1550
1578
  actions: {},
1551
1579
  events: {}
1552
- }) {
1580
+ }, pendingProjections = []) {
1553
1581
  const builder = {
1554
1582
  with: ((input) => {
1555
1583
  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
- }
1571
- }
1572
- return act(states, registry);
1584
+ mergeProjection(input, registry.events);
1585
+ return act(
1586
+ states,
1587
+ registry,
1588
+ pendingProjections
1589
+ );
1573
1590
  }
1574
1591
  if (isSlice(input)) {
1575
1592
  for (const s of input.states.values()) {
@@ -1581,10 +1598,19 @@ function act(states = /* @__PURE__ */ new Map(), registry = {
1581
1598
  registry.events[eventName].reactions.set(name, reaction);
1582
1599
  }
1583
1600
  }
1584
- return act(states, registry);
1601
+ pendingProjections.push(...input.projections);
1602
+ return act(
1603
+ states,
1604
+ registry,
1605
+ pendingProjections
1606
+ );
1585
1607
  }
1586
1608
  registerState(input, states, registry.actions, registry.events);
1587
- return act(states, registry);
1609
+ return act(
1610
+ states,
1611
+ registry,
1612
+ pendingProjections
1613
+ );
1588
1614
  }),
1589
1615
  /**
1590
1616
  * Adds a reaction to an event.
@@ -1624,7 +1650,12 @@ function act(states = /* @__PURE__ */ new Map(), registry = {
1624
1650
  };
1625
1651
  }
1626
1652
  }),
1627
- build: () => new Act(registry, states),
1653
+ build: () => {
1654
+ for (const proj of pendingProjections) {
1655
+ mergeProjection(proj, registry.events);
1656
+ }
1657
+ return new Act(registry, states);
1658
+ },
1628
1659
  events: registry.events
1629
1660
  };
1630
1661
  return builder;