@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.
- package/README.md +1 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/autocompletion.d.ts +135 -1
- package/dist/eidos/abstract-factory/abstract-factory.d.ts +125 -0
- package/dist/eidos/abstract-factory/abstract-factory.d.ts.map +1 -0
- package/dist/eidos/abstract-factory/abstract-factory.js +128 -0
- package/dist/eidos/abstract-factory/abstract-factory.js.map +1 -0
- package/dist/eidos/adapter/adapter.d.ts +97 -0
- package/dist/eidos/adapter/adapter.d.ts.map +1 -0
- package/dist/eidos/adapter/adapter.js +90 -0
- package/dist/eidos/adapter/adapter.js.map +1 -0
- package/dist/eidos/bridge/bridge.d.ts +81 -0
- package/dist/eidos/bridge/bridge.d.ts.map +1 -0
- package/dist/eidos/bridge/bridge.js +75 -0
- package/dist/eidos/bridge/bridge.js.map +1 -0
- package/dist/eidos/builder/builder.d.ts +181 -0
- package/dist/eidos/builder/builder.d.ts.map +1 -0
- package/dist/eidos/builder/builder.js +139 -0
- package/dist/eidos/builder/builder.js.map +1 -0
- package/dist/eidos/chain/chain.d.ts +99 -0
- package/dist/eidos/chain/chain.d.ts.map +1 -0
- package/dist/eidos/chain/chain.js +111 -0
- package/dist/eidos/chain/chain.js.map +1 -0
- package/dist/eidos/command/command.d.ts +267 -0
- package/dist/eidos/command/command.d.ts.map +1 -0
- package/dist/eidos/command/command.js +298 -0
- package/dist/eidos/command/command.js.map +1 -0
- package/dist/eidos/composite/composite.d.ts +168 -0
- package/dist/eidos/composite/composite.d.ts.map +1 -0
- package/dist/eidos/composite/composite.js +157 -0
- package/dist/eidos/composite/composite.js.map +1 -0
- package/dist/eidos/decorator/decorator.d.ts +138 -0
- package/dist/eidos/decorator/decorator.d.ts.map +1 -0
- package/dist/eidos/decorator/decorator.js +143 -0
- package/dist/eidos/decorator/decorator.js.map +1 -0
- package/dist/eidos/facade/facade.d.ts +61 -0
- package/dist/eidos/facade/facade.d.ts.map +1 -0
- package/dist/eidos/facade/facade.js +63 -0
- package/dist/eidos/facade/facade.js.map +1 -0
- package/dist/eidos/factory-method/factory-method.d.ts +76 -0
- package/dist/eidos/factory-method/factory-method.d.ts.map +1 -0
- package/dist/eidos/factory-method/factory-method.js +60 -0
- package/dist/eidos/factory-method/factory-method.js.map +1 -0
- package/dist/eidos/flyweight/flyweight.d.ts +40 -0
- package/dist/eidos/flyweight/flyweight.d.ts.map +1 -0
- package/dist/eidos/flyweight/flyweight.js +41 -0
- package/dist/eidos/flyweight/flyweight.js.map +1 -0
- package/dist/eidos/interpreter/interpreter.d.ts +82 -0
- package/dist/eidos/interpreter/interpreter.d.ts.map +1 -0
- package/dist/eidos/interpreter/interpreter.js +84 -0
- package/dist/eidos/interpreter/interpreter.js.map +1 -0
- package/dist/eidos/iterator/iterator.d.ts +164 -0
- package/dist/eidos/iterator/iterator.d.ts.map +1 -0
- package/dist/eidos/iterator/iterator.js +258 -0
- package/dist/eidos/iterator/iterator.js.map +1 -0
- package/dist/eidos/mediator/mediator.d.ts +102 -0
- package/dist/eidos/mediator/mediator.d.ts.map +1 -0
- package/dist/eidos/mediator/mediator.js +112 -0
- package/dist/eidos/mediator/mediator.js.map +1 -0
- package/dist/eidos/memento/memento.d.ts +103 -0
- package/dist/eidos/memento/memento.d.ts.map +1 -0
- package/dist/eidos/memento/memento.js +114 -0
- package/dist/eidos/memento/memento.js.map +1 -0
- package/dist/eidos/observer/observer-lite.d.ts +49 -0
- package/dist/eidos/observer/observer-lite.d.ts.map +1 -0
- package/dist/eidos/observer/observer-lite.js +55 -0
- package/dist/eidos/observer/observer-lite.js.map +1 -0
- package/dist/eidos/observer/observer.d.ts +96 -0
- package/dist/eidos/observer/observer.d.ts.map +1 -0
- package/dist/eidos/observer/observer.js +117 -0
- package/dist/eidos/observer/observer.js.map +1 -0
- package/dist/eidos/prototype/prototype.d.ts +32 -0
- package/dist/eidos/prototype/prototype.d.ts.map +1 -0
- package/dist/eidos/prototype/prototype.js +33 -0
- package/dist/eidos/prototype/prototype.js.map +1 -0
- package/dist/eidos/proxy/proxy.d.ts +108 -0
- package/dist/eidos/proxy/proxy.d.ts.map +1 -0
- package/dist/eidos/proxy/proxy.js +121 -0
- package/dist/eidos/proxy/proxy.js.map +1 -0
- package/dist/eidos/singleton/singleton.d.ts +76 -0
- package/dist/eidos/singleton/singleton.d.ts.map +1 -0
- package/dist/eidos/singleton/singleton.js +77 -0
- package/dist/eidos/singleton/singleton.js.map +1 -0
- package/dist/eidos/state/state-lite.d.ts +102 -0
- package/dist/eidos/state/state-lite.d.ts.map +1 -0
- package/dist/eidos/state/state-lite.js +69 -0
- package/dist/eidos/state/state-lite.js.map +1 -0
- package/dist/eidos/state/state.d.ts +152 -0
- package/dist/eidos/state/state.d.ts.map +1 -0
- package/dist/eidos/state/state.js +85 -0
- package/dist/eidos/state/state.js.map +1 -0
- package/dist/eidos/strategy/strategy.d.ts +148 -0
- package/dist/eidos/strategy/strategy.d.ts.map +1 -0
- package/dist/eidos/strategy/strategy.js +167 -0
- package/dist/eidos/strategy/strategy.js.map +1 -0
- package/dist/eidos/template/template.d.ts +95 -0
- package/dist/eidos/template/template.d.ts.map +1 -0
- package/dist/eidos/template/template.js +110 -0
- package/dist/eidos/template/template.js.map +1 -0
- package/dist/eidos/visitor/visitor.d.ts +78 -0
- package/dist/eidos/visitor/visitor.d.ts.map +1 -0
- package/dist/eidos/visitor/visitor.js +80 -0
- package/dist/eidos/visitor/visitor.js.map +1 -0
- package/dist/zygos/result/index.d.ts +19 -0
- package/dist/zygos/result/index.d.ts.map +1 -0
- package/dist/zygos/result/index.js +29 -0
- package/dist/zygos/result/index.js.map +1 -0
- 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"}
|