@pithos/core 2.3.0 → 2.5.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.
Files changed (108) hide show
  1. package/README.md +1 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/autocompletion.d.ts +135 -1
  4. package/dist/eidos/abstract-factory/abstract-factory.d.ts +125 -0
  5. package/dist/eidos/abstract-factory/abstract-factory.d.ts.map +1 -0
  6. package/dist/eidos/abstract-factory/abstract-factory.js +128 -0
  7. package/dist/eidos/abstract-factory/abstract-factory.js.map +1 -0
  8. package/dist/eidos/adapter/adapter.d.ts +97 -0
  9. package/dist/eidos/adapter/adapter.d.ts.map +1 -0
  10. package/dist/eidos/adapter/adapter.js +90 -0
  11. package/dist/eidos/adapter/adapter.js.map +1 -0
  12. package/dist/eidos/bridge/bridge.d.ts +81 -0
  13. package/dist/eidos/bridge/bridge.d.ts.map +1 -0
  14. package/dist/eidos/bridge/bridge.js +75 -0
  15. package/dist/eidos/bridge/bridge.js.map +1 -0
  16. package/dist/eidos/builder/builder.d.ts +181 -0
  17. package/dist/eidos/builder/builder.d.ts.map +1 -0
  18. package/dist/eidos/builder/builder.js +139 -0
  19. package/dist/eidos/builder/builder.js.map +1 -0
  20. package/dist/eidos/chain/chain.d.ts +99 -0
  21. package/dist/eidos/chain/chain.d.ts.map +1 -0
  22. package/dist/eidos/chain/chain.js +111 -0
  23. package/dist/eidos/chain/chain.js.map +1 -0
  24. package/dist/eidos/command/command.d.ts +267 -0
  25. package/dist/eidos/command/command.d.ts.map +1 -0
  26. package/dist/eidos/command/command.js +298 -0
  27. package/dist/eidos/command/command.js.map +1 -0
  28. package/dist/eidos/composite/composite.d.ts +168 -0
  29. package/dist/eidos/composite/composite.d.ts.map +1 -0
  30. package/dist/eidos/composite/composite.js +157 -0
  31. package/dist/eidos/composite/composite.js.map +1 -0
  32. package/dist/eidos/decorator/decorator.d.ts +138 -0
  33. package/dist/eidos/decorator/decorator.d.ts.map +1 -0
  34. package/dist/eidos/decorator/decorator.js +143 -0
  35. package/dist/eidos/decorator/decorator.js.map +1 -0
  36. package/dist/eidos/facade/facade.d.ts +61 -0
  37. package/dist/eidos/facade/facade.d.ts.map +1 -0
  38. package/dist/eidos/facade/facade.js +63 -0
  39. package/dist/eidos/facade/facade.js.map +1 -0
  40. package/dist/eidos/factory-method/factory-method.d.ts +76 -0
  41. package/dist/eidos/factory-method/factory-method.d.ts.map +1 -0
  42. package/dist/eidos/factory-method/factory-method.js +60 -0
  43. package/dist/eidos/factory-method/factory-method.js.map +1 -0
  44. package/dist/eidos/flyweight/flyweight.d.ts +40 -0
  45. package/dist/eidos/flyweight/flyweight.d.ts.map +1 -0
  46. package/dist/eidos/flyweight/flyweight.js +41 -0
  47. package/dist/eidos/flyweight/flyweight.js.map +1 -0
  48. package/dist/eidos/interpreter/interpreter.d.ts +82 -0
  49. package/dist/eidos/interpreter/interpreter.d.ts.map +1 -0
  50. package/dist/eidos/interpreter/interpreter.js +84 -0
  51. package/dist/eidos/interpreter/interpreter.js.map +1 -0
  52. package/dist/eidos/iterator/iterator.d.ts +164 -0
  53. package/dist/eidos/iterator/iterator.d.ts.map +1 -0
  54. package/dist/eidos/iterator/iterator.js +258 -0
  55. package/dist/eidos/iterator/iterator.js.map +1 -0
  56. package/dist/eidos/mediator/mediator.d.ts +102 -0
  57. package/dist/eidos/mediator/mediator.d.ts.map +1 -0
  58. package/dist/eidos/mediator/mediator.js +112 -0
  59. package/dist/eidos/mediator/mediator.js.map +1 -0
  60. package/dist/eidos/memento/memento.d.ts +103 -0
  61. package/dist/eidos/memento/memento.d.ts.map +1 -0
  62. package/dist/eidos/memento/memento.js +114 -0
  63. package/dist/eidos/memento/memento.js.map +1 -0
  64. package/dist/eidos/observer/observer-lite.d.ts +49 -0
  65. package/dist/eidos/observer/observer-lite.d.ts.map +1 -0
  66. package/dist/eidos/observer/observer-lite.js +55 -0
  67. package/dist/eidos/observer/observer-lite.js.map +1 -0
  68. package/dist/eidos/observer/observer.d.ts +96 -0
  69. package/dist/eidos/observer/observer.d.ts.map +1 -0
  70. package/dist/eidos/observer/observer.js +117 -0
  71. package/dist/eidos/observer/observer.js.map +1 -0
  72. package/dist/eidos/prototype/prototype.d.ts +32 -0
  73. package/dist/eidos/prototype/prototype.d.ts.map +1 -0
  74. package/dist/eidos/prototype/prototype.js +33 -0
  75. package/dist/eidos/prototype/prototype.js.map +1 -0
  76. package/dist/eidos/proxy/proxy.d.ts +108 -0
  77. package/dist/eidos/proxy/proxy.d.ts.map +1 -0
  78. package/dist/eidos/proxy/proxy.js +121 -0
  79. package/dist/eidos/proxy/proxy.js.map +1 -0
  80. package/dist/eidos/singleton/singleton.d.ts +76 -0
  81. package/dist/eidos/singleton/singleton.d.ts.map +1 -0
  82. package/dist/eidos/singleton/singleton.js +77 -0
  83. package/dist/eidos/singleton/singleton.js.map +1 -0
  84. package/dist/eidos/state/state-lite.d.ts +102 -0
  85. package/dist/eidos/state/state-lite.d.ts.map +1 -0
  86. package/dist/eidos/state/state-lite.js +69 -0
  87. package/dist/eidos/state/state-lite.js.map +1 -0
  88. package/dist/eidos/state/state.d.ts +152 -0
  89. package/dist/eidos/state/state.d.ts.map +1 -0
  90. package/dist/eidos/state/state.js +85 -0
  91. package/dist/eidos/state/state.js.map +1 -0
  92. package/dist/eidos/strategy/strategy.d.ts +148 -0
  93. package/dist/eidos/strategy/strategy.d.ts.map +1 -0
  94. package/dist/eidos/strategy/strategy.js +167 -0
  95. package/dist/eidos/strategy/strategy.js.map +1 -0
  96. package/dist/eidos/template/template.d.ts +95 -0
  97. package/dist/eidos/template/template.d.ts.map +1 -0
  98. package/dist/eidos/template/template.js +110 -0
  99. package/dist/eidos/template/template.js.map +1 -0
  100. package/dist/eidos/visitor/visitor.d.ts +78 -0
  101. package/dist/eidos/visitor/visitor.d.ts.map +1 -0
  102. package/dist/eidos/visitor/visitor.js +80 -0
  103. package/dist/eidos/visitor/visitor.js.map +1 -0
  104. package/dist/zygos/result/index.d.ts +19 -0
  105. package/dist/zygos/result/index.d.ts.map +1 -0
  106. package/dist/zygos/result/index.js +29 -0
  107. package/dist/zygos/result/index.js.map +1 -0
  108. package/package.json +28 -3
@@ -0,0 +1,258 @@
1
+ /**
2
+ * Functional Iterator Pattern.
3
+ *
4
+ * In OOP, the Iterator pattern requires a Collection interface, an Iterator
5
+ * interface, and concrete implementations that decouple traversal from the
6
+ * underlying data structure.
7
+ * In functional TypeScript, iterators are lazy sequences built on the native
8
+ * `Iterable` protocol, created via `createIterable` which decouples traversal
9
+ * logic from data sources.
10
+ *
11
+ * JavaScript already has the Iterator protocol (`Symbol.iterator`, `for...of`).
12
+ * The core of this module is the **constructor** layer:
13
+ * - `createIterable` - the GoF concept: decouple traversal from structure
14
+ * - `lazyRange` - lazy numeric sequences (finite or infinite)
15
+ * - `iterate` - unfold from a seed function
16
+ *
17
+ * A minimal set of **companion operators** (`map`, `filter`, `take`) and
18
+ * **consumers** (`toArray`, `reduce`) is included to make the constructors
19
+ * usable in practice (e.g. bounding an infinite `lazyRange` with `take`).
20
+ * These are not general-purpose collection utilities - they exist to serve
21
+ * the pattern.
22
+ *
23
+ * @module eidos/iterator
24
+ * @since 2.4.0
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { lazyRange, map, filter, take, toArray } from "@pithos/core/eidos/iterator/iterator";
29
+ *
30
+ * const result = toArray(
31
+ * take(5)(
32
+ * filter((n: number) => n % 2 === 0)(
33
+ * lazyRange(0, Infinity)
34
+ * )
35
+ * )
36
+ * );
37
+ * // [0, 2, 4, 6, 8]
38
+ * ```
39
+ */
40
+ import { some, none } from "../../zygos/option.js";
41
+ // -------------------------------------------------------------------------------------
42
+ // Constructors
43
+ // -------------------------------------------------------------------------------------
44
+ /**
45
+ * Creates a lazy, re-iterable sequence from a factory that produces a "next" function.
46
+ *
47
+ * The factory is called each time `[Symbol.iterator]()` is invoked, ensuring
48
+ * the iterable can be traversed multiple times. Each "next" call returns
49
+ * `Some(value)` for the next element or `None` to signal completion.
50
+ *
51
+ * This is the core of the GoF Iterator pattern: it decouples traversal logic
52
+ * (the `next` function) from the data source.
53
+ *
54
+ * @template T - The element type
55
+ * @param factory - A function that creates a stateful "next" supplier
56
+ * @returns A lazy Iterable
57
+ * @since 2.4.0
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * // Iterate over a tree in depth-first order
62
+ * const treeIter = createIterable(() => {
63
+ * const stack = [rootNode];
64
+ * return () => {
65
+ * if (stack.length === 0) return none;
66
+ * const node = stack.pop();
67
+ * if (!node) return none;
68
+ * stack.push(...node.children);
69
+ * return some(node.value);
70
+ * };
71
+ * });
72
+ *
73
+ * for (const value of treeIter) { ... }
74
+ * ```
75
+ */
76
+ export function createIterable(factory) {
77
+ return {
78
+ [Symbol.iterator]() {
79
+ const next = factory();
80
+ return {
81
+ next() {
82
+ const result = next();
83
+ if (result._tag === "None")
84
+ return { done: true, value: undefined };
85
+ return { done: false, value: result.value };
86
+ },
87
+ };
88
+ },
89
+ };
90
+ }
91
+ /**
92
+ * Creates a lazy numeric range.
93
+ *
94
+ * Supports both ascending and descending ranges, as well as infinite ranges
95
+ * (use `take` to bound them).
96
+ *
97
+ * @param start - Start value (inclusive)
98
+ * @param end - End value (exclusive), defaults to Infinity
99
+ * @param step - Step increment, defaults to 1
100
+ * @returns A lazy Iterable of numbers
101
+ * @since 2.4.0
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * toArray(lazyRange(0, 5)); // [0, 1, 2, 3, 4]
106
+ * toArray(lazyRange(0, 10, 3)); // [0, 3, 6, 9]
107
+ * toArray(lazyRange(5, 0, -1)); // [5, 4, 3, 2, 1]
108
+ * ```
109
+ */
110
+ export function lazyRange(start, end = Infinity, step = 1) {
111
+ return createIterable(() => {
112
+ let current = start;
113
+ return () => {
114
+ if (step > 0 ? current >= end : current <= end)
115
+ return none;
116
+ const value = current;
117
+ current += step;
118
+ return some(value);
119
+ };
120
+ });
121
+ }
122
+ /**
123
+ * Creates an infinite iterable by repeatedly applying a function to a seed.
124
+ *
125
+ * Produces: seed, f(seed), f(f(seed)), ...
126
+ *
127
+ * @template T - The element type
128
+ * @param seed - The initial value
129
+ * @param f - The function to apply repeatedly
130
+ * @returns An infinite lazy Iterable
131
+ * @since 2.4.0
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * // Powers of 2
136
+ * toArray(take(5)(iterate(1, (n) => n * 2))); // [1, 2, 4, 8, 16]
137
+ * ```
138
+ */
139
+ export function iterate(seed, f) {
140
+ return createIterable(() => {
141
+ let current = seed;
142
+ let started = false;
143
+ return () => {
144
+ if (!started) {
145
+ started = true;
146
+ return some(current);
147
+ }
148
+ current = f(current);
149
+ return some(current);
150
+ };
151
+ });
152
+ }
153
+ // -------------------------------------------------------------------------------------
154
+ // Companion operators (minimal set to make constructors usable)
155
+ // -------------------------------------------------------------------------------------
156
+ /**
157
+ * Lazily transforms each element.
158
+ *
159
+ * @template A - Input element type
160
+ * @template B - Output element type
161
+ * @param f - The mapping function
162
+ * @returns A function that transforms an iterable
163
+ * @since 2.4.0
164
+ */
165
+ export function map(f) {
166
+ return (source) => createIterable(() => {
167
+ const iter = source[Symbol.iterator]();
168
+ return () => {
169
+ const { done, value } = iter.next();
170
+ if (done)
171
+ return none;
172
+ return some(f(value));
173
+ };
174
+ });
175
+ }
176
+ /**
177
+ * Lazily filters elements by a predicate.
178
+ *
179
+ * @template A - Element type
180
+ * @param predicate - The filter predicate
181
+ * @returns A function that filters an iterable
182
+ * @since 2.4.0
183
+ */
184
+ export function filter(predicate) {
185
+ return (source) => createIterable(() => {
186
+ const iter = source[Symbol.iterator]();
187
+ return () => {
188
+ while (true) {
189
+ const { done, value } = iter.next();
190
+ if (done)
191
+ return none;
192
+ if (predicate(value))
193
+ return some(value);
194
+ }
195
+ };
196
+ });
197
+ }
198
+ /**
199
+ * Lazily takes the first n elements.
200
+ *
201
+ * Essential for bounding infinite iterables.
202
+ *
203
+ * @template A - Element type
204
+ * @param n - Number of elements to take
205
+ * @returns A function that limits an iterable
206
+ * @since 2.4.0
207
+ */
208
+ export function take(n) {
209
+ return (source) => createIterable(() => {
210
+ const iter = source[Symbol.iterator]();
211
+ let remaining = n;
212
+ return () => {
213
+ if (remaining <= 0)
214
+ return none;
215
+ const { done, value } = iter.next();
216
+ if (done)
217
+ return none;
218
+ remaining--;
219
+ return some(value);
220
+ };
221
+ });
222
+ }
223
+ // -------------------------------------------------------------------------------------
224
+ // Consumers
225
+ // -------------------------------------------------------------------------------------
226
+ /**
227
+ * Collects all elements into an array.
228
+ *
229
+ * Do not use on infinite iterables without `take` first.
230
+ *
231
+ * @template A - Element type
232
+ * @param source - The iterable to collect
233
+ * @returns An array of all elements
234
+ * @since 2.4.0
235
+ */
236
+ export function toArray(source) {
237
+ return [...source];
238
+ }
239
+ /**
240
+ * Reduces an iterable to a single value.
241
+ *
242
+ * @template A - Element type
243
+ * @template B - Accumulator type
244
+ * @param f - The reducer function
245
+ * @param seed - The initial accumulator
246
+ * @returns A function that reduces an iterable
247
+ * @since 2.4.0
248
+ */
249
+ export function reduce(f, seed) {
250
+ return (source) => {
251
+ let acc = seed;
252
+ for (const item of source) {
253
+ acc = f(acc, item);
254
+ }
255
+ return acc;
256
+ };
257
+ }
258
+ //# sourceMappingURL=iterator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iterator.js","sourceRoot":"","sources":["../../../src/eidos/iterator/iterator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Functional Mediator Pattern.
3
+ *
4
+ * In OOP, the Mediator pattern requires a Mediator interface, concrete mediator
5
+ * classes, and components that communicate through the mediator instead of
6
+ * directly with each other.
7
+ *
8
+ * In functional TypeScript, a mediator is an event hub that routes messages
9
+ * between decoupled handlers. Components emit events, the mediator dispatches
10
+ * to registered handlers based on event type.
11
+ *
12
+ * The key difference from Observer: Observer broadcasts to all subscribers,
13
+ * Mediator routes to specific handlers based on event type and can orchestrate
14
+ * complex interactions.
15
+ *
16
+ * @module eidos/mediator
17
+ * @since 2.4.0
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { createMediator } from "@pithos/core/eidos/mediator/mediator";
22
+ *
23
+ * type Events = {
24
+ * userLoggedIn: { userId: string };
25
+ * orderPlaced: { orderId: string; total: number };
26
+ * paymentReceived: { orderId: string };
27
+ * };
28
+ *
29
+ * const mediator = createMediator<Events>();
30
+ *
31
+ * // Register handlers
32
+ * mediator.on("userLoggedIn", ({ userId }) => {
33
+ * console.log(`Welcome ${userId}`);
34
+ * loadUserPreferences(userId);
35
+ * });
36
+ *
37
+ * mediator.on("orderPlaced", ({ orderId, total }) => {
38
+ * sendConfirmationEmail(orderId);
39
+ * if (total > 100) mediator.emit("paymentReceived", { orderId });
40
+ * });
41
+ *
42
+ * // Components emit events without knowing who handles them
43
+ * mediator.emit("userLoggedIn", { userId: "alice" });
44
+ * ```
45
+ */
46
+ /**
47
+ * Event handler function type.
48
+ * Replaces the GoF Colleague callback interface.
49
+ *
50
+ * @template T - The event payload type
51
+ * @since 2.4.0
52
+ */
53
+ export type Handler<T> = (payload: T) => void;
54
+ /**
55
+ * Mediator interface for typed event routing.
56
+ * Replaces the GoF Mediator abstract class.
57
+ *
58
+ * @template Events - Record mapping event names to payload types
59
+ * @since 2.4.0
60
+ */
61
+ export type Mediator<Events extends Record<string, unknown>> = {
62
+ /** Register a handler for an event type. Returns unsubscribe function. */
63
+ on: <K extends keyof Events>(event: K, handler: Handler<Events[K]>) => () => void;
64
+ /** Emit an event to all registered handlers. */
65
+ emit: <K extends keyof Events>(event: K, payload: Events[K]) => void;
66
+ /** Remove all handlers for an event type, or all handlers if no event specified. */
67
+ clear: (event?: keyof Events) => void;
68
+ };
69
+ /**
70
+ * Creates a typed mediator for decoupled component communication.
71
+ *
72
+ * Components emit events without knowing who handles them. The mediator
73
+ * routes events to registered handlers, enabling loose coupling.
74
+ *
75
+ * @template Events - Record mapping event names to payload types
76
+ * @returns A mediator with `on`, `emit`, and `clear` methods
77
+ * @since 2.4.0
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * type UIEvents = {
82
+ * buttonClicked: { buttonId: string };
83
+ * formSubmitted: { data: FormData };
84
+ * modalClosed: { modalId: string };
85
+ * };
86
+ *
87
+ * const ui = createMediator<UIEvents>();
88
+ *
89
+ * // Dialog component
90
+ * ui.on("buttonClicked", ({ buttonId }) => {
91
+ * if (buttonId === "confirm") ui.emit("modalClosed", { modalId: "dialog" });
92
+ * });
93
+ *
94
+ * // Form component
95
+ * ui.on("formSubmitted", ({ data }) => {
96
+ * validate(data);
97
+ * ui.emit("buttonClicked", { buttonId: "confirm" });
98
+ * });
99
+ * ```
100
+ */
101
+ export declare function createMediator<Events extends Record<string, unknown>>(): Mediator<Events>;
102
+ //# sourceMappingURL=mediator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mediator.d.ts","sourceRoot":"","sources":["../../../src/eidos/mediator/mediator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAC7D,0EAA0E;IAC1E,EAAE,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC;IAClF,gDAAgD;IAChD,IAAI,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACrE,oFAAoF;IACpF,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,cAAc,CAC5B,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACnC,QAAQ,CAAC,MAAM,CAAC,CAoCpB"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Functional Mediator Pattern.
3
+ *
4
+ * In OOP, the Mediator pattern requires a Mediator interface, concrete mediator
5
+ * classes, and components that communicate through the mediator instead of
6
+ * directly with each other.
7
+ *
8
+ * In functional TypeScript, a mediator is an event hub that routes messages
9
+ * between decoupled handlers. Components emit events, the mediator dispatches
10
+ * to registered handlers based on event type.
11
+ *
12
+ * The key difference from Observer: Observer broadcasts to all subscribers,
13
+ * Mediator routes to specific handlers based on event type and can orchestrate
14
+ * complex interactions.
15
+ *
16
+ * @module eidos/mediator
17
+ * @since 2.4.0
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { createMediator } from "@pithos/core/eidos/mediator/mediator";
22
+ *
23
+ * type Events = {
24
+ * userLoggedIn: { userId: string };
25
+ * orderPlaced: { orderId: string; total: number };
26
+ * paymentReceived: { orderId: string };
27
+ * };
28
+ *
29
+ * const mediator = createMediator<Events>();
30
+ *
31
+ * // Register handlers
32
+ * mediator.on("userLoggedIn", ({ userId }) => {
33
+ * console.log(`Welcome ${userId}`);
34
+ * loadUserPreferences(userId);
35
+ * });
36
+ *
37
+ * mediator.on("orderPlaced", ({ orderId, total }) => {
38
+ * sendConfirmationEmail(orderId);
39
+ * if (total > 100) mediator.emit("paymentReceived", { orderId });
40
+ * });
41
+ *
42
+ * // Components emit events without knowing who handles them
43
+ * mediator.emit("userLoggedIn", { userId: "alice" });
44
+ * ```
45
+ */
46
+ /**
47
+ * Creates a typed mediator for decoupled component communication.
48
+ *
49
+ * Components emit events without knowing who handles them. The mediator
50
+ * routes events to registered handlers, enabling loose coupling.
51
+ *
52
+ * @template Events - Record mapping event names to payload types
53
+ * @returns A mediator with `on`, `emit`, and `clear` methods
54
+ * @since 2.4.0
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * type UIEvents = {
59
+ * buttonClicked: { buttonId: string };
60
+ * formSubmitted: { data: FormData };
61
+ * modalClosed: { modalId: string };
62
+ * };
63
+ *
64
+ * const ui = createMediator<UIEvents>();
65
+ *
66
+ * // Dialog component
67
+ * ui.on("buttonClicked", ({ buttonId }) => {
68
+ * if (buttonId === "confirm") ui.emit("modalClosed", { modalId: "dialog" });
69
+ * });
70
+ *
71
+ * // Form component
72
+ * ui.on("formSubmitted", ({ data }) => {
73
+ * validate(data);
74
+ * ui.emit("buttonClicked", { buttonId: "confirm" });
75
+ * });
76
+ * ```
77
+ */
78
+ export function createMediator() {
79
+ const handlers = {};
80
+ return {
81
+ on(event, handler) {
82
+ let set = handlers[event];
83
+ if (!set) {
84
+ set = new Set();
85
+ handlers[event] = set;
86
+ }
87
+ set.add(handler);
88
+ return () => {
89
+ set.delete(handler);
90
+ };
91
+ },
92
+ emit(event, payload) {
93
+ const set = handlers[event];
94
+ if (set) {
95
+ for (const handler of set) {
96
+ handler(payload);
97
+ }
98
+ }
99
+ },
100
+ clear(event) {
101
+ if (event) {
102
+ delete handlers[event];
103
+ }
104
+ else {
105
+ for (const key in handlers) {
106
+ delete handlers[key];
107
+ }
108
+ }
109
+ },
110
+ };
111
+ }
112
+ //# sourceMappingURL=mediator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mediator.js","sourceRoot":"","sources":["../../../src/eidos/mediator/mediator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AA2BH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,cAAc;IAG5B,MAAM,QAAQ,GAAsD,EAAE,CAAC;IAEvE,OAAO;QACL,EAAE,CAAyB,KAAQ,EAAE,OAA2B;YAC9D,IAAI,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;gBAChB,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;YACxB,CAAC;YACD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAEjB,OAAO,GAAG,EAAE;gBACV,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,CAAyB,KAAQ,EAAE,OAAkB;YACvD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,GAAG,EAAE,CAAC;gBACR,KAAK,MAAM,OAAO,IAAI,GAAG,EAAE,CAAC;oBAC1B,OAAO,CAAC,OAAO,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,CAAC,KAAoB;YACxB,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;oBAC3B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Functional Memento Pattern.
3
+ *
4
+ * In OOP, the Memento pattern requires an Originator class that creates
5
+ * snapshots, a Memento class that stores state, and a Caretaker that manages
6
+ * the history.
7
+ *
8
+ * In functional TypeScript with immutable data, state is already a snapshot.
9
+ * The pattern simplifies to a history manager that tracks state changes
10
+ * and enables undo/redo.
11
+ *
12
+ * ## Memento vs Command for undo/redo
13
+ *
14
+ * - **Memento** (`createHistory`): stores *state snapshots*.
15
+ * Undo restores the previous state. Use when state is cheap to copy.
16
+ *
17
+ * - **Command** (`createCommandStack`): stores *actions* with their inverses.
18
+ * Undo calls the command's undo function. Use when you have reversible operations.
19
+ *
20
+ * @module eidos/memento
21
+ * @since 2.4.0
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import { createHistory } from "@pithos/core/eidos/memento/memento";
26
+ *
27
+ * type EditorState = { content: string; cursor: number };
28
+ *
29
+ * const history = createHistory<EditorState>({ content: "", cursor: 0 });
30
+ *
31
+ * history.push({ content: "Hello", cursor: 5 });
32
+ * history.push({ content: "Hello World", cursor: 11 });
33
+ *
34
+ * history.current(); // { content: "Hello World", cursor: 11 }
35
+ * history.undo(); // Some({ content: "Hello", cursor: 5 })
36
+ * history.redo(); // Some({ content: "Hello World", cursor: 11 })
37
+ * ```
38
+ */
39
+ import type { Option } from "../../zygos/option.js";
40
+ /**
41
+ * A snapshot with metadata.
42
+ *
43
+ * @template T - The state type
44
+ * @since 2.4.0
45
+ */
46
+ export type Snapshot<T> = {
47
+ readonly state: T;
48
+ readonly timestamp: number;
49
+ };
50
+ /**
51
+ * History manager for undo/redo functionality.
52
+ *
53
+ * @template T - The state type
54
+ * @since 2.4.0
55
+ */
56
+ export type History<T> = {
57
+ /** Returns the current state. */
58
+ current: () => T;
59
+ /** Pushes a new state, clearing any redo history. */
60
+ push: (state: T) => void;
61
+ /** Undoes to previous state. Returns the new current state, or None if at beginning. */
62
+ undo: () => Option<T>;
63
+ /** Redoes to next state. Returns the new current state, or None if at end. */
64
+ redo: () => Option<T>;
65
+ /** Returns true if undo is possible. */
66
+ canUndo: () => boolean;
67
+ /** Returns true if redo is possible. */
68
+ canRedo: () => boolean;
69
+ /** Returns all snapshots in the undo stack (oldest first). */
70
+ history: () => ReadonlyArray<Snapshot<T>>;
71
+ /** Clears all history, keeping only current state. */
72
+ clear: () => void;
73
+ };
74
+ /**
75
+ * Creates a history manager for undo/redo functionality.
76
+ *
77
+ * Tracks state changes as snapshots. Pushing a new state clears any
78
+ * redo history (standard undo/redo behavior).
79
+ *
80
+ * @template T - The state type
81
+ * @param initial - The initial state
82
+ * @returns A history manager
83
+ * @since 2.4.0
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * const history = createHistory({ count: 0 });
88
+ *
89
+ * history.push({ count: 1 });
90
+ * history.push({ count: 2 });
91
+ * history.push({ count: 3 });
92
+ *
93
+ * history.undo(); // Some({ count: 2 })
94
+ * history.undo(); // Some({ count: 1 })
95
+ * history.redo(); // Some({ count: 2 })
96
+ *
97
+ * // New push clears redo stack
98
+ * history.push({ count: 10 });
99
+ * history.canRedo(); // false
100
+ * ```
101
+ */
102
+ export declare function createHistory<T>(initial: T): History<T>;
103
+ //# sourceMappingURL=memento.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memento.d.ts","sourceRoot":"","sources":["../../../src/eidos/memento/memento.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI;IACvB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC,CAAC;IACjB,qDAAqD;IACrD,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACzB,wFAAwF;IACxF,IAAI,EAAE,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;IACtB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;IACtB,wCAAwC;IACxC,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,wCAAwC;IACxC,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,sDAAsD;IACtD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAmDvD"}