@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,114 @@
|
|
|
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 { some, none } from "../../zygos/option.js";
|
|
40
|
+
/**
|
|
41
|
+
* Creates a history manager for undo/redo functionality.
|
|
42
|
+
*
|
|
43
|
+
* Tracks state changes as snapshots. Pushing a new state clears any
|
|
44
|
+
* redo history (standard undo/redo behavior).
|
|
45
|
+
*
|
|
46
|
+
* @template T - The state type
|
|
47
|
+
* @param initial - The initial state
|
|
48
|
+
* @returns A history manager
|
|
49
|
+
* @since 2.4.0
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const history = createHistory({ count: 0 });
|
|
54
|
+
*
|
|
55
|
+
* history.push({ count: 1 });
|
|
56
|
+
* history.push({ count: 2 });
|
|
57
|
+
* history.push({ count: 3 });
|
|
58
|
+
*
|
|
59
|
+
* history.undo(); // Some({ count: 2 })
|
|
60
|
+
* history.undo(); // Some({ count: 1 })
|
|
61
|
+
* history.redo(); // Some({ count: 2 })
|
|
62
|
+
*
|
|
63
|
+
* // New push clears redo stack
|
|
64
|
+
* history.push({ count: 10 });
|
|
65
|
+
* history.canRedo(); // false
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function createHistory(initial) {
|
|
69
|
+
const undoStack = [{ state: initial, timestamp: Date.now() }];
|
|
70
|
+
const redoStack = [];
|
|
71
|
+
return {
|
|
72
|
+
current() {
|
|
73
|
+
return undoStack[undoStack.length - 1].state;
|
|
74
|
+
},
|
|
75
|
+
push(state) {
|
|
76
|
+
undoStack.push({ state, timestamp: Date.now() });
|
|
77
|
+
redoStack.length = 0;
|
|
78
|
+
},
|
|
79
|
+
undo() {
|
|
80
|
+
if (undoStack.length <= 1)
|
|
81
|
+
return none;
|
|
82
|
+
const lastIndex = undoStack.length - 1;
|
|
83
|
+
const snapshot = undoStack[lastIndex];
|
|
84
|
+
undoStack.length = lastIndex;
|
|
85
|
+
redoStack.push(snapshot);
|
|
86
|
+
return some(undoStack[undoStack.length - 1].state);
|
|
87
|
+
},
|
|
88
|
+
redo() {
|
|
89
|
+
if (redoStack.length === 0)
|
|
90
|
+
return none;
|
|
91
|
+
const lastIndex = redoStack.length - 1;
|
|
92
|
+
const snapshot = redoStack[lastIndex];
|
|
93
|
+
redoStack.length = lastIndex;
|
|
94
|
+
undoStack.push(snapshot);
|
|
95
|
+
return some(undoStack[undoStack.length - 1].state);
|
|
96
|
+
},
|
|
97
|
+
canUndo() {
|
|
98
|
+
return undoStack.length > 1;
|
|
99
|
+
},
|
|
100
|
+
canRedo() {
|
|
101
|
+
return redoStack.length > 0;
|
|
102
|
+
},
|
|
103
|
+
history() {
|
|
104
|
+
return undoStack;
|
|
105
|
+
},
|
|
106
|
+
clear() {
|
|
107
|
+
const current = undoStack[undoStack.length - 1];
|
|
108
|
+
undoStack.length = 0;
|
|
109
|
+
undoStack.push(current);
|
|
110
|
+
redoStack.length = 0;
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=memento.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memento.js","sourceRoot":"","sources":["../../../src/eidos/memento/memento.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAuC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,aAAa,CAAI,OAAU;IACzC,MAAM,SAAS,GAAkB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAkB,EAAE,CAAC;IAEpC,OAAO;QACL,OAAO;YACL,OAAO,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QAC/C,CAAC;QAED,IAAI,CAAC,KAAQ;YACX,SAAS,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACjD,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACvB,CAAC;QAED,IAAI;YACF,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YACvC,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;YACtC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;YAC7B,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;QAED,IAAI;YACF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACxC,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;YACtC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;YAC7B,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzB,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC;QAED,OAAO;YACL,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO;YACL,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO;YACL,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,KAAK;YACH,MAAM,OAAO,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAChD,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;YACrB,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight Observer Pattern — zero external dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Provides the same `subscribe` / `notify` / `clear` API as
|
|
5
|
+
* {@link createObservable}, but without `safeNotify`, `once`, or `size`.
|
|
6
|
+
* This avoids pulling in `@zygos/result` and keeps the bundle minimal
|
|
7
|
+
* for consumers who only need basic pub/sub.
|
|
8
|
+
*
|
|
9
|
+
* @module eidos/observer/observer-lite
|
|
10
|
+
* @since 2.5.0
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { createLiteObservable } from "@pithos/core/eidos/observer/observer-lite";
|
|
15
|
+
*
|
|
16
|
+
* const onClick = createLiteObservable<{ x: number; y: number }>();
|
|
17
|
+
*
|
|
18
|
+
* const unsub = onClick.subscribe(({ x, y }) => console.log(x, y));
|
|
19
|
+
* onClick.notify({ x: 10, y: 20 }); // logs: 10 20
|
|
20
|
+
* unsub();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/** A listener callback that reacts to emitted values. */
|
|
24
|
+
export type Listener<T> = (value: T) => void;
|
|
25
|
+
/**
|
|
26
|
+
* A function that removes a listener when called.
|
|
27
|
+
*
|
|
28
|
+
* @since 2.5.0
|
|
29
|
+
*/
|
|
30
|
+
export type Unsubscribe = () => void;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a lightweight observable (pub/sub emitter).
|
|
33
|
+
*
|
|
34
|
+
* Only exposes `subscribe`, `notify`, and `clear`.
|
|
35
|
+
* No dependency on `@zygos/result` — ideal for size-sensitive bundles.
|
|
36
|
+
*
|
|
37
|
+
* @template T - The type of values emitted to listeners
|
|
38
|
+
* @returns Observable with `subscribe`, `notify`, `clear`
|
|
39
|
+
* @since 2.5.0
|
|
40
|
+
*/
|
|
41
|
+
export declare function createLiteObservable<T>(): {
|
|
42
|
+
/** Add a listener. Returns an unsubscribe function. */
|
|
43
|
+
subscribe: (listener: Listener<T>) => Unsubscribe;
|
|
44
|
+
/** Emit a value to all listeners (fail-fast). */
|
|
45
|
+
notify: (value: T) => void;
|
|
46
|
+
/** Remove all listeners. */
|
|
47
|
+
clear: () => void;
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=observer-lite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer-lite.d.ts","sourceRoot":"","sources":["../../../src/eidos/observer/observer-lite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,yDAAyD;AACzD,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,CAAC;IAIlC,uDAAuD;0BACjC,QAAQ,CAAC,CAAC,CAAC,KAAG,WAAW;IAO/C,iDAAiD;oBACjC,CAAC,KAAG,IAAI;IAMxB,4BAA4B;iBACjB,IAAI;EAIlB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight Observer Pattern — zero external dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Provides the same `subscribe` / `notify` / `clear` API as
|
|
5
|
+
* {@link createObservable}, but without `safeNotify`, `once`, or `size`.
|
|
6
|
+
* This avoids pulling in `@zygos/result` and keeps the bundle minimal
|
|
7
|
+
* for consumers who only need basic pub/sub.
|
|
8
|
+
*
|
|
9
|
+
* @module eidos/observer/observer-lite
|
|
10
|
+
* @since 2.5.0
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { createLiteObservable } from "@pithos/core/eidos/observer/observer-lite";
|
|
15
|
+
*
|
|
16
|
+
* const onClick = createLiteObservable<{ x: number; y: number }>();
|
|
17
|
+
*
|
|
18
|
+
* const unsub = onClick.subscribe(({ x, y }) => console.log(x, y));
|
|
19
|
+
* onClick.notify({ x: 10, y: 20 }); // logs: 10 20
|
|
20
|
+
* unsub();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Creates a lightweight observable (pub/sub emitter).
|
|
25
|
+
*
|
|
26
|
+
* Only exposes `subscribe`, `notify`, and `clear`.
|
|
27
|
+
* No dependency on `@zygos/result` — ideal for size-sensitive bundles.
|
|
28
|
+
*
|
|
29
|
+
* @template T - The type of values emitted to listeners
|
|
30
|
+
* @returns Observable with `subscribe`, `notify`, `clear`
|
|
31
|
+
* @since 2.5.0
|
|
32
|
+
*/
|
|
33
|
+
export function createLiteObservable() {
|
|
34
|
+
const listeners = new Set();
|
|
35
|
+
return {
|
|
36
|
+
/** Add a listener. Returns an unsubscribe function. */
|
|
37
|
+
subscribe: (listener) => {
|
|
38
|
+
listeners.add(listener);
|
|
39
|
+
return () => {
|
|
40
|
+
listeners.delete(listener);
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
/** Emit a value to all listeners (fail-fast). */
|
|
44
|
+
notify: (value) => {
|
|
45
|
+
for (const listener of listeners) {
|
|
46
|
+
listener(value);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
/** Remove all listeners. */
|
|
50
|
+
clear: () => {
|
|
51
|
+
listeners.clear();
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=observer-lite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer-lite.js","sourceRoot":"","sources":["../../../src/eidos/observer/observer-lite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAYH;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAe,CAAC;IAEzC,OAAO;QACL,uDAAuD;QACvD,SAAS,EAAE,CAAC,QAAqB,EAAe,EAAE;YAChD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,CAAC;QACJ,CAAC;QAED,iDAAiD;QACjD,MAAM,EAAE,CAAC,KAAQ,EAAQ,EAAE;YACzB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,KAAK,EAAE,GAAS,EAAE;YAChB,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functional Observer Pattern.
|
|
3
|
+
*
|
|
4
|
+
* In OOP, the Observer pattern requires Subject/Observer interfaces,
|
|
5
|
+
* concrete classes, and manual attach/detach management.
|
|
6
|
+
* In functional TypeScript, it's a Set of callbacks behind a closure.
|
|
7
|
+
*
|
|
8
|
+
* @module eidos/observer
|
|
9
|
+
* @since 2.4.0
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { createObservable } from "@pithos/core/eidos/observer/observer";
|
|
14
|
+
*
|
|
15
|
+
* const onClick = createObservable<{ x: number; y: number }>();
|
|
16
|
+
*
|
|
17
|
+
* const unsub = onClick.subscribe(({ x, y }) => console.log(x, y));
|
|
18
|
+
* onClick.notify({ x: 10, y: 20 }); // logs: 10 20
|
|
19
|
+
* unsub();
|
|
20
|
+
* onClick.notify({ x: 30, y: 40 }); // nothing - unsubscribed
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import type { Result } from "../../zygos/result/result.js";
|
|
24
|
+
/**
|
|
25
|
+
* A listener is a callback that reacts to emitted values.
|
|
26
|
+
* Replaces the GoF Observer interface.
|
|
27
|
+
*
|
|
28
|
+
* @template T - The value type
|
|
29
|
+
* @since 2.4.0
|
|
30
|
+
*/
|
|
31
|
+
export type Listener<T> = (value: T) => void;
|
|
32
|
+
/**
|
|
33
|
+
* A function that removes a listener when called.
|
|
34
|
+
* Replaces the GoF `detach(observer)` method.
|
|
35
|
+
*
|
|
36
|
+
* @since 2.4.0
|
|
37
|
+
*/
|
|
38
|
+
export type Unsubscribe = () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Creates an observable (pub/sub emitter).
|
|
41
|
+
* Replaces the GoF Subject class - no interface, no attach/detach ceremony,
|
|
42
|
+
* just subscribe and get back an unsubscribe function.
|
|
43
|
+
*
|
|
44
|
+
* @template T - The type of values emitted to listeners
|
|
45
|
+
* @returns Observable with `subscribe`, `notify`, `once`, `safeNotify`, `size`, `clear`
|
|
46
|
+
* @since 2.4.0
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const onUserLogin = createObservable<{ id: string; name: string }>();
|
|
51
|
+
*
|
|
52
|
+
* // Subscribe - returns an unsubscribe function
|
|
53
|
+
* const unsub = onUserLogin.subscribe((user) => {
|
|
54
|
+
* console.log(`${user.name} logged in`);
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* // One-time listener
|
|
58
|
+
* onUserLogin.once((user) => {
|
|
59
|
+
* sendWelcomeEmail(user);
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* onUserLogin.notify({ id: "1", name: "Alice" });
|
|
63
|
+
* unsub();
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function createObservable<T>(): {
|
|
67
|
+
/** Add a listener. Returns an unsubscribe function. */
|
|
68
|
+
subscribe: (listener: Listener<T>) => Unsubscribe;
|
|
69
|
+
/**
|
|
70
|
+
* Emit a value to all listeners. Fail-fast: if a listener throws,
|
|
71
|
+
* the error propagates and subsequent listeners are not called.
|
|
72
|
+
* Use `safeNotify` for resilient notification.
|
|
73
|
+
*/
|
|
74
|
+
notify: (value: T) => void;
|
|
75
|
+
/**
|
|
76
|
+
* Subscribe for a single notification, then auto-unsubscribe.
|
|
77
|
+
* The listener is wrapped internally - always use the returned
|
|
78
|
+
* `Unsubscribe` function to cancel before it fires.
|
|
79
|
+
*/
|
|
80
|
+
once: (listener: Listener<T>) => Unsubscribe;
|
|
81
|
+
/**
|
|
82
|
+
* Emit a value to all listeners with error safety.
|
|
83
|
+
* Unlike `notify`, this catches listener errors and continues
|
|
84
|
+
* notifying remaining listeners. Returns a zygos `Result`:
|
|
85
|
+
* - `Ok(void)` if all listeners succeeded
|
|
86
|
+
* - `Err(Error[])` with collected errors from failing listeners
|
|
87
|
+
*
|
|
88
|
+
* @since 2.4.0
|
|
89
|
+
*/
|
|
90
|
+
safeNotify: (value: T) => Result<void, Error[]>;
|
|
91
|
+
/** Current number of listeners. */
|
|
92
|
+
readonly size: number;
|
|
93
|
+
/** Remove all listeners. */
|
|
94
|
+
clear: () => void;
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.d.ts","sourceRoot":"","sources":["../../../src/eidos/observer/observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,CAAC;IAI9B,uDAAuD;0BACjC,QAAQ,CAAC,CAAC,CAAC,KAAG,WAAW;IAO/C;;;;OAIG;oBACa,CAAC,KAAG,IAAI;IAMxB;;;;OAIG;qBACc,QAAQ,CAAC,CAAC,CAAC,KAAG,WAAW;IAW1C;;;;;;;;OAQG;wBACiB,CAAC,KAAG,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAc7C,mCAAmC;mBACvB,MAAM;IAIlB,4BAA4B;iBACjB,IAAI;EAIlB"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functional Observer Pattern.
|
|
3
|
+
*
|
|
4
|
+
* In OOP, the Observer pattern requires Subject/Observer interfaces,
|
|
5
|
+
* concrete classes, and manual attach/detach management.
|
|
6
|
+
* In functional TypeScript, it's a Set of callbacks behind a closure.
|
|
7
|
+
*
|
|
8
|
+
* @module eidos/observer
|
|
9
|
+
* @since 2.4.0
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { createObservable } from "@pithos/core/eidos/observer/observer";
|
|
14
|
+
*
|
|
15
|
+
* const onClick = createObservable<{ x: number; y: number }>();
|
|
16
|
+
*
|
|
17
|
+
* const unsub = onClick.subscribe(({ x, y }) => console.log(x, y));
|
|
18
|
+
* onClick.notify({ x: 10, y: 20 }); // logs: 10 20
|
|
19
|
+
* unsub();
|
|
20
|
+
* onClick.notify({ x: 30, y: 40 }); // nothing - unsubscribed
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import { ok, err } from "../../zygos/result/result.js";
|
|
24
|
+
/**
|
|
25
|
+
* Creates an observable (pub/sub emitter).
|
|
26
|
+
* Replaces the GoF Subject class - no interface, no attach/detach ceremony,
|
|
27
|
+
* just subscribe and get back an unsubscribe function.
|
|
28
|
+
*
|
|
29
|
+
* @template T - The type of values emitted to listeners
|
|
30
|
+
* @returns Observable with `subscribe`, `notify`, `once`, `safeNotify`, `size`, `clear`
|
|
31
|
+
* @since 2.4.0
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const onUserLogin = createObservable<{ id: string; name: string }>();
|
|
36
|
+
*
|
|
37
|
+
* // Subscribe - returns an unsubscribe function
|
|
38
|
+
* const unsub = onUserLogin.subscribe((user) => {
|
|
39
|
+
* console.log(`${user.name} logged in`);
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // One-time listener
|
|
43
|
+
* onUserLogin.once((user) => {
|
|
44
|
+
* sendWelcomeEmail(user);
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* onUserLogin.notify({ id: "1", name: "Alice" });
|
|
48
|
+
* unsub();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export function createObservable() {
|
|
52
|
+
const listeners = new Set();
|
|
53
|
+
return {
|
|
54
|
+
/** Add a listener. Returns an unsubscribe function. */
|
|
55
|
+
subscribe: (listener) => {
|
|
56
|
+
listeners.add(listener);
|
|
57
|
+
return () => {
|
|
58
|
+
listeners.delete(listener);
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
/**
|
|
62
|
+
* Emit a value to all listeners. Fail-fast: if a listener throws,
|
|
63
|
+
* the error propagates and subsequent listeners are not called.
|
|
64
|
+
* Use `safeNotify` for resilient notification.
|
|
65
|
+
*/
|
|
66
|
+
notify: (value) => {
|
|
67
|
+
for (const listener of listeners) {
|
|
68
|
+
listener(value);
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* Subscribe for a single notification, then auto-unsubscribe.
|
|
73
|
+
* The listener is wrapped internally - always use the returned
|
|
74
|
+
* `Unsubscribe` function to cancel before it fires.
|
|
75
|
+
*/
|
|
76
|
+
once: (listener) => {
|
|
77
|
+
const wrapper = (value) => {
|
|
78
|
+
listeners.delete(wrapper);
|
|
79
|
+
listener(value);
|
|
80
|
+
};
|
|
81
|
+
listeners.add(wrapper);
|
|
82
|
+
return () => {
|
|
83
|
+
listeners.delete(wrapper);
|
|
84
|
+
};
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* Emit a value to all listeners with error safety.
|
|
88
|
+
* Unlike `notify`, this catches listener errors and continues
|
|
89
|
+
* notifying remaining listeners. Returns a zygos `Result`:
|
|
90
|
+
* - `Ok(void)` if all listeners succeeded
|
|
91
|
+
* - `Err(Error[])` with collected errors from failing listeners
|
|
92
|
+
*
|
|
93
|
+
* @since 2.4.0
|
|
94
|
+
*/
|
|
95
|
+
safeNotify: (value) => {
|
|
96
|
+
const errors = [];
|
|
97
|
+
for (const listener of listeners) {
|
|
98
|
+
try {
|
|
99
|
+
listener(value);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
errors.push(error instanceof Error ? error : new Error(String(error)));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return errors.length > 0 ? err(errors) : ok(undefined);
|
|
106
|
+
},
|
|
107
|
+
/** Current number of listeners. */
|
|
108
|
+
get size() {
|
|
109
|
+
return listeners.size;
|
|
110
|
+
},
|
|
111
|
+
/** Remove all listeners. */
|
|
112
|
+
clear: () => {
|
|
113
|
+
listeners.clear();
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.js","sourceRoot":"","sources":["../../../src/eidos/observer/observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAoB/C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAe,CAAC;IAEzC,OAAO;QACL,uDAAuD;QACvD,SAAS,EAAE,CAAC,QAAqB,EAAe,EAAE;YAChD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,CAAC;QACJ,CAAC;QAED;;;;WAIG;QACH,MAAM,EAAE,CAAC,KAAQ,EAAQ,EAAE;YACzB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED;;;;WAIG;QACH,IAAI,EAAE,CAAC,QAAqB,EAAe,EAAE;YAC3C,MAAM,OAAO,GAAgB,CAAC,KAAK,EAAE,EAAE;gBACrC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC1B,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC,CAAC;YACF,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC,CAAC;QACJ,CAAC;QAED;;;;;;;;WAQG;QACH,UAAU,EAAE,CAAC,KAAQ,EAAyB,EAAE;YAC9C,MAAM,MAAM,GAAY,EAAE,CAAC;YAC3B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,IAAI,CAAC;oBACH,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAClB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CACT,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;QACzD,CAAC;QAED,mCAAmC;QACnC,IAAI,IAAI;YACN,OAAO,SAAS,CAAC,IAAI,CAAC;QACxB,CAAC;QAED,4BAA4B;QAC5B,KAAK,EAAE,GAAS,EAAE;YAChB,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functional Prototype Pattern.
|
|
3
|
+
*
|
|
4
|
+
* In OOP, the Prototype pattern requires a `clone()` method on objects to
|
|
5
|
+
* create copies without coupling to concrete classes.
|
|
6
|
+
*
|
|
7
|
+
* In functional TypeScript with immutable data, this is covered by Arkhe:
|
|
8
|
+
* - `deepClone` for deep copies (handles circular refs, Date, Map, Set, etc.)
|
|
9
|
+
* - `deepCloneFull` for binary data (TypedArrays, ArrayBuffer, Blob, File)
|
|
10
|
+
* - Spread operator `{ ...obj }` for shallow copies
|
|
11
|
+
*
|
|
12
|
+
* This module re-exports Arkhe's clone functions for discoverability.
|
|
13
|
+
*
|
|
14
|
+
* @module eidos/prototype
|
|
15
|
+
* @since 2.4.0
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { deepClone } from "@pithos/core/eidos/prototype/prototype";
|
|
20
|
+
* // or directly from Arkhe:
|
|
21
|
+
* import { deepClone } from "../../arkhe/object/deep-clone.js";
|
|
22
|
+
*
|
|
23
|
+
* const original = { a: 1, b: { c: 2 }, d: new Map([["x", 1]]) };
|
|
24
|
+
* const cloned = deepClone(original);
|
|
25
|
+
*
|
|
26
|
+
* // For shallow copies, just use spread:
|
|
27
|
+
* const shallow = { ...original, a: 99 };
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export { deepClone } from "../../arkhe/object/deep-clone.js";
|
|
31
|
+
export { deepCloneFull } from "../../arkhe/object/deep-clone-full.js";
|
|
32
|
+
//# sourceMappingURL=prototype.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prototype.d.ts","sourceRoot":"","sources":["../../../src/eidos/prototype/prototype.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functional Prototype Pattern.
|
|
3
|
+
*
|
|
4
|
+
* In OOP, the Prototype pattern requires a `clone()` method on objects to
|
|
5
|
+
* create copies without coupling to concrete classes.
|
|
6
|
+
*
|
|
7
|
+
* In functional TypeScript with immutable data, this is covered by Arkhe:
|
|
8
|
+
* - `deepClone` for deep copies (handles circular refs, Date, Map, Set, etc.)
|
|
9
|
+
* - `deepCloneFull` for binary data (TypedArrays, ArrayBuffer, Blob, File)
|
|
10
|
+
* - Spread operator `{ ...obj }` for shallow copies
|
|
11
|
+
*
|
|
12
|
+
* This module re-exports Arkhe's clone functions for discoverability.
|
|
13
|
+
*
|
|
14
|
+
* @module eidos/prototype
|
|
15
|
+
* @since 2.4.0
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { deepClone } from "@pithos/core/eidos/prototype/prototype";
|
|
20
|
+
* // or directly from Arkhe:
|
|
21
|
+
* import { deepClone } from "../../arkhe/object/deep-clone.js";
|
|
22
|
+
*
|
|
23
|
+
* const original = { a: 1, b: { c: 2 }, d: new Map([["x", 1]]) };
|
|
24
|
+
* const cloned = deepClone(original);
|
|
25
|
+
*
|
|
26
|
+
* // For shallow copies, just use spread:
|
|
27
|
+
* const shallow = { ...original, a: 99 };
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
// Re-export from Arkhe for discoverability
|
|
31
|
+
export { deepClone } from "../../arkhe/object/deep-clone.js";
|
|
32
|
+
export { deepCloneFull } from "../../arkhe/object/deep-clone-full.js";
|
|
33
|
+
//# sourceMappingURL=prototype.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prototype.js","sourceRoot":"","sources":["../../../src/eidos/prototype/prototype.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,2CAA2C;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functional Proxy Pattern.
|
|
3
|
+
*
|
|
4
|
+
* In OOP, the Proxy pattern requires a Subject interface, a RealSubject class,
|
|
5
|
+
* and a Proxy class that wraps it to control access (lazy init, caching,
|
|
6
|
+
* access control, logging...).
|
|
7
|
+
* In functional TypeScript, Proxy provides ready-made higher-order functions
|
|
8
|
+
* for the most common proxy use cases.
|
|
9
|
+
*
|
|
10
|
+
* Compared to Decorator (generic hooks via before/after/around), Proxy
|
|
11
|
+
* offers opinionated, named wrappers for specific access-control scenarios.
|
|
12
|
+
*
|
|
13
|
+
* Several proxy use cases are already covered by arkhe utilities,
|
|
14
|
+
* re-exported here for discoverability:
|
|
15
|
+
* - `memoize` - caching proxy with custom key resolvers, cache injection (LRU, TTL)
|
|
16
|
+
* - `once` - single-use proxy, executes once then caches the result
|
|
17
|
+
* - `throttle` - rate-limiting proxy, at most one call per time window
|
|
18
|
+
* - `debounce` - debounce proxy, defers execution until inactivity
|
|
19
|
+
*
|
|
20
|
+
* @module eidos/proxy
|
|
21
|
+
* @since 2.4.0
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { lazy, memoize, once, throttle, guarded } from "@pithos/core/eidos/proxy/proxy";
|
|
26
|
+
*
|
|
27
|
+
* // Lazy initialization proxy
|
|
28
|
+
* const query = lazy(() => {
|
|
29
|
+
* const conn = createConnection();
|
|
30
|
+
* return (sql: string) => conn.execute(sql);
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // Caching proxy
|
|
34
|
+
* const fetchUser = memoize((id: string) => db.query(id));
|
|
35
|
+
*
|
|
36
|
+
* // Single-use proxy
|
|
37
|
+
* const init = once(() => bootstrap());
|
|
38
|
+
*
|
|
39
|
+
* // Rate-limiting proxy
|
|
40
|
+
* const onScroll = throttle(() => recalcLayout(), 200);
|
|
41
|
+
*
|
|
42
|
+
* // Access control proxy
|
|
43
|
+
* const deleteUser = guarded(
|
|
44
|
+
* (id: string) => db.delete(id),
|
|
45
|
+
* (id) => id !== "admin" ? true : "Cannot delete admin",
|
|
46
|
+
* );
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
import type { Result } from "../../zygos/result/result.js";
|
|
50
|
+
/** Caching proxy - re-exported from arkhe for discoverability. */
|
|
51
|
+
export { memoize } from "../../arkhe/function/memoize.js";
|
|
52
|
+
export type { MemoizedFunction, MemoizeOptions, MemoizeCache } from "../../arkhe/function/memoize.js";
|
|
53
|
+
/** Single-use proxy - re-exported from arkhe for discoverability. */
|
|
54
|
+
export { once } from "../../arkhe/function/once.js";
|
|
55
|
+
/** Rate-limiting proxy - re-exported from arkhe for discoverability. */
|
|
56
|
+
export { throttle } from "../../arkhe/function/throttle.js";
|
|
57
|
+
/** Debounce proxy - re-exported from arkhe for discoverability. */
|
|
58
|
+
export { debounce } from "../../arkhe/function/debounce.js";
|
|
59
|
+
/**
|
|
60
|
+
* Lazy proxy - defers function creation until first call.
|
|
61
|
+
* The factory is called once on the first invocation, then
|
|
62
|
+
* the created function is used directly for all subsequent calls.
|
|
63
|
+
*
|
|
64
|
+
* @template In - The input type
|
|
65
|
+
* @template Out - The output type
|
|
66
|
+
* @param factory - A function that creates the real function on demand
|
|
67
|
+
* @returns A proxy that initializes lazily
|
|
68
|
+
* @since 2.4.0
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* // Expensive connection is only created when first needed
|
|
73
|
+
* const query = lazy(() => {
|
|
74
|
+
* const conn = createConnection(); // heavy init
|
|
75
|
+
* return (sql: string) => conn.execute(sql);
|
|
76
|
+
* });
|
|
77
|
+
*
|
|
78
|
+
* // Nothing happens yet...
|
|
79
|
+
* query("SELECT 1"); // NOW the connection is created, then query runs
|
|
80
|
+
* query("SELECT 2"); // reuses the same connection
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function lazy<In, Out>(factory: () => (input: In) => Out): (input: In) => Out;
|
|
84
|
+
/**
|
|
85
|
+
* Guarded proxy - checks access before calling the function.
|
|
86
|
+
* The check returns `true` to allow, or a rejection reason string to deny.
|
|
87
|
+
* Returns a zygos `Result`: `Ok(output)` if allowed, `Err(reason)` if denied.
|
|
88
|
+
*
|
|
89
|
+
* @template In - The input type
|
|
90
|
+
* @template Out - The output type
|
|
91
|
+
* @param fn - The function to guard
|
|
92
|
+
* @param check - Access check. Return `true` to allow, or a string reason to deny.
|
|
93
|
+
* @returns A proxy returning `Result<Out, string>`
|
|
94
|
+
* @since 2.4.0
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const deleteUser = guarded(
|
|
99
|
+
* (id: string) => db.delete(id),
|
|
100
|
+
* (id) => id !== "admin" ? true : "Cannot delete admin user",
|
|
101
|
+
* );
|
|
102
|
+
*
|
|
103
|
+
* deleteUser("user-1"); // Ok(void)
|
|
104
|
+
* deleteUser("admin"); // Err("Cannot delete admin user")
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function guarded<In, Out>(fn: (input: In) => Out, check: (input: In) => true | string): (input: In) => Result<Out, string>;
|
|
108
|
+
//# sourceMappingURL=proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../src/eidos/proxy/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,kEAAkE;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE9F,qEAAqE;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C,wEAAwE;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,mEAAmE;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,IAAI,CAAC,EAAE,EAAE,GAAG,EAC1B,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,GAAG,GAChC,CAAC,KAAK,EAAE,EAAE,KAAK,GAAG,CAMpB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,GAAG,EAC7B,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,GAAG,EACtB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,IAAI,GAAG,MAAM,GAClC,CAAC,KAAK,EAAE,EAAE,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAMpC"}
|