@pithos/core 2.3.0 → 2.4.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 (99) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/autocompletion.d.ts +129 -1
  3. package/dist/eidos/abstract-factory/abstract-factory.d.ts +125 -0
  4. package/dist/eidos/abstract-factory/abstract-factory.d.ts.map +1 -0
  5. package/dist/eidos/abstract-factory/abstract-factory.js +128 -0
  6. package/dist/eidos/abstract-factory/abstract-factory.js.map +1 -0
  7. package/dist/eidos/adapter/adapter.d.ts +97 -0
  8. package/dist/eidos/adapter/adapter.d.ts.map +1 -0
  9. package/dist/eidos/adapter/adapter.js +90 -0
  10. package/dist/eidos/adapter/adapter.js.map +1 -0
  11. package/dist/eidos/bridge/bridge.d.ts +81 -0
  12. package/dist/eidos/bridge/bridge.d.ts.map +1 -0
  13. package/dist/eidos/bridge/bridge.js +75 -0
  14. package/dist/eidos/bridge/bridge.js.map +1 -0
  15. package/dist/eidos/builder/builder.d.ts +181 -0
  16. package/dist/eidos/builder/builder.d.ts.map +1 -0
  17. package/dist/eidos/builder/builder.js +139 -0
  18. package/dist/eidos/builder/builder.js.map +1 -0
  19. package/dist/eidos/chain/chain.d.ts +99 -0
  20. package/dist/eidos/chain/chain.d.ts.map +1 -0
  21. package/dist/eidos/chain/chain.js +111 -0
  22. package/dist/eidos/chain/chain.js.map +1 -0
  23. package/dist/eidos/command/command.d.ts +267 -0
  24. package/dist/eidos/command/command.d.ts.map +1 -0
  25. package/dist/eidos/command/command.js +298 -0
  26. package/dist/eidos/command/command.js.map +1 -0
  27. package/dist/eidos/composite/composite.d.ts +168 -0
  28. package/dist/eidos/composite/composite.d.ts.map +1 -0
  29. package/dist/eidos/composite/composite.js +157 -0
  30. package/dist/eidos/composite/composite.js.map +1 -0
  31. package/dist/eidos/decorator/decorator.d.ts +138 -0
  32. package/dist/eidos/decorator/decorator.d.ts.map +1 -0
  33. package/dist/eidos/decorator/decorator.js +143 -0
  34. package/dist/eidos/decorator/decorator.js.map +1 -0
  35. package/dist/eidos/facade/facade.d.ts +61 -0
  36. package/dist/eidos/facade/facade.d.ts.map +1 -0
  37. package/dist/eidos/facade/facade.js +63 -0
  38. package/dist/eidos/facade/facade.js.map +1 -0
  39. package/dist/eidos/factory-method/factory-method.d.ts +76 -0
  40. package/dist/eidos/factory-method/factory-method.d.ts.map +1 -0
  41. package/dist/eidos/factory-method/factory-method.js +60 -0
  42. package/dist/eidos/factory-method/factory-method.js.map +1 -0
  43. package/dist/eidos/flyweight/flyweight.d.ts +40 -0
  44. package/dist/eidos/flyweight/flyweight.d.ts.map +1 -0
  45. package/dist/eidos/flyweight/flyweight.js +41 -0
  46. package/dist/eidos/flyweight/flyweight.js.map +1 -0
  47. package/dist/eidos/interpreter/interpreter.d.ts +82 -0
  48. package/dist/eidos/interpreter/interpreter.d.ts.map +1 -0
  49. package/dist/eidos/interpreter/interpreter.js +84 -0
  50. package/dist/eidos/interpreter/interpreter.js.map +1 -0
  51. package/dist/eidos/iterator/iterator.d.ts +164 -0
  52. package/dist/eidos/iterator/iterator.d.ts.map +1 -0
  53. package/dist/eidos/iterator/iterator.js +258 -0
  54. package/dist/eidos/iterator/iterator.js.map +1 -0
  55. package/dist/eidos/mediator/mediator.d.ts +102 -0
  56. package/dist/eidos/mediator/mediator.d.ts.map +1 -0
  57. package/dist/eidos/mediator/mediator.js +112 -0
  58. package/dist/eidos/mediator/mediator.js.map +1 -0
  59. package/dist/eidos/memento/memento.d.ts +103 -0
  60. package/dist/eidos/memento/memento.d.ts.map +1 -0
  61. package/dist/eidos/memento/memento.js +114 -0
  62. package/dist/eidos/memento/memento.js.map +1 -0
  63. package/dist/eidos/observer/observer.d.ts +96 -0
  64. package/dist/eidos/observer/observer.d.ts.map +1 -0
  65. package/dist/eidos/observer/observer.js +117 -0
  66. package/dist/eidos/observer/observer.js.map +1 -0
  67. package/dist/eidos/prototype/prototype.d.ts +32 -0
  68. package/dist/eidos/prototype/prototype.d.ts.map +1 -0
  69. package/dist/eidos/prototype/prototype.js +33 -0
  70. package/dist/eidos/prototype/prototype.js.map +1 -0
  71. package/dist/eidos/proxy/proxy.d.ts +108 -0
  72. package/dist/eidos/proxy/proxy.d.ts.map +1 -0
  73. package/dist/eidos/proxy/proxy.js +121 -0
  74. package/dist/eidos/proxy/proxy.js.map +1 -0
  75. package/dist/eidos/singleton/singleton.d.ts +76 -0
  76. package/dist/eidos/singleton/singleton.d.ts.map +1 -0
  77. package/dist/eidos/singleton/singleton.js +77 -0
  78. package/dist/eidos/singleton/singleton.js.map +1 -0
  79. package/dist/eidos/state/state.d.ts +152 -0
  80. package/dist/eidos/state/state.d.ts.map +1 -0
  81. package/dist/eidos/state/state.js +85 -0
  82. package/dist/eidos/state/state.js.map +1 -0
  83. package/dist/eidos/strategy/strategy.d.ts +148 -0
  84. package/dist/eidos/strategy/strategy.d.ts.map +1 -0
  85. package/dist/eidos/strategy/strategy.js +167 -0
  86. package/dist/eidos/strategy/strategy.js.map +1 -0
  87. package/dist/eidos/template/template.d.ts +95 -0
  88. package/dist/eidos/template/template.d.ts.map +1 -0
  89. package/dist/eidos/template/template.js +110 -0
  90. package/dist/eidos/template/template.js.map +1 -0
  91. package/dist/eidos/visitor/visitor.d.ts +78 -0
  92. package/dist/eidos/visitor/visitor.d.ts.map +1 -0
  93. package/dist/eidos/visitor/visitor.js +80 -0
  94. package/dist/eidos/visitor/visitor.js.map +1 -0
  95. package/dist/zygos/result/index.d.ts +19 -0
  96. package/dist/zygos/result/index.d.ts.map +1 -0
  97. package/dist/zygos/result/index.js +29 -0
  98. package/dist/zygos/result/index.js.map +1 -0
  99. package/package.json +28 -3
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Functional Singleton Pattern.
3
+ *
4
+ * In OOP, the Singleton pattern requires a class with a private constructor
5
+ * and a static `getInstance()` method to ensure only one instance exists.
6
+ *
7
+ * In functional TypeScript, this is absorbed by the ES module system:
8
+ * - A module is evaluated exactly once
9
+ * - `export const instance = create()` is a singleton by default
10
+ * - No pattern needed — it's native module behavior
11
+ *
12
+ * For lazy initialization, Arkhe provides `once` which caches the first call.
13
+ *
14
+ * ## Why Singleton is considered an anti-pattern
15
+ *
16
+ * The Singleton appears in the GoF book (1994), but the community has since
17
+ * largely recognized it as an anti-pattern:
18
+ *
19
+ * - **Global state in disguise** — A singleton is just a global variable with
20
+ * extra steps. It creates implicit coupling throughout your codebase.
21
+ *
22
+ * - **Testability nightmare** — You can't easily mock a singleton. Every test
23
+ * shares the same instance and its state, leading to flaky tests.
24
+ *
25
+ * - **Hidden dependencies** — Code using `getInstance()` has invisible deps.
26
+ * You can't tell what a function needs just by looking at its signature.
27
+ *
28
+ * - **Concurrency issues** — Lazy initialization is a race condition waiting
29
+ * to happen (less relevant in single-threaded JS, but still a code smell).
30
+ *
31
+ * ## The modern alternative: Dependency Injection
32
+ *
33
+ * Instead of reaching for a global singleton, pass dependencies explicitly:
34
+ *
35
+ * ```ts
36
+ * // ❌ Singleton — hidden dependency
37
+ * const fetchUsers = () => {
38
+ * const db = Database.getInstance();
39
+ * return db.query("SELECT * FROM users");
40
+ * };
41
+ *
42
+ * // ✅ Dependency injection — explicit, testable
43
+ * const fetchUsers = (db: Database) => {
44
+ * return db.query("SELECT * FROM users");
45
+ * };
46
+ * ```
47
+ *
48
+ * This module re-exports `once` from Arkhe for discoverability.
49
+ *
50
+ * @module eidos/singleton
51
+ * @since 2.4.0
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { once } from "@pithos/core/eidos/singleton/singleton";
56
+ * // or directly from Arkhe:
57
+ * import { once } from "../../arkhe/function/once.js";
58
+ *
59
+ * // Lazy singleton initialization
60
+ * const getDb = once(() => connectToDatabase());
61
+ *
62
+ * getDb(); // connects
63
+ * getDb(); // returns cached connection
64
+ *
65
+ * // But consider: could this be passed as a parameter instead?
66
+ * ```
67
+ */
68
+ export { once } from "../../arkhe/function/once.js";
69
+ /**
70
+ * Alias for `once` — creates a lazy singleton from a factory function.
71
+ * Re-exported for discoverability when searching for "singleton".
72
+ *
73
+ * @see once
74
+ */
75
+ export { once as singleton } from "../../arkhe/function/once.js";
76
+ //# sourceMappingURL=singleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../../../src/eidos/singleton/singleton.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAGH,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C;;;;;GAKG;AACH,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Functional Singleton Pattern.
3
+ *
4
+ * In OOP, the Singleton pattern requires a class with a private constructor
5
+ * and a static `getInstance()` method to ensure only one instance exists.
6
+ *
7
+ * In functional TypeScript, this is absorbed by the ES module system:
8
+ * - A module is evaluated exactly once
9
+ * - `export const instance = create()` is a singleton by default
10
+ * - No pattern needed — it's native module behavior
11
+ *
12
+ * For lazy initialization, Arkhe provides `once` which caches the first call.
13
+ *
14
+ * ## Why Singleton is considered an anti-pattern
15
+ *
16
+ * The Singleton appears in the GoF book (1994), but the community has since
17
+ * largely recognized it as an anti-pattern:
18
+ *
19
+ * - **Global state in disguise** — A singleton is just a global variable with
20
+ * extra steps. It creates implicit coupling throughout your codebase.
21
+ *
22
+ * - **Testability nightmare** — You can't easily mock a singleton. Every test
23
+ * shares the same instance and its state, leading to flaky tests.
24
+ *
25
+ * - **Hidden dependencies** — Code using `getInstance()` has invisible deps.
26
+ * You can't tell what a function needs just by looking at its signature.
27
+ *
28
+ * - **Concurrency issues** — Lazy initialization is a race condition waiting
29
+ * to happen (less relevant in single-threaded JS, but still a code smell).
30
+ *
31
+ * ## The modern alternative: Dependency Injection
32
+ *
33
+ * Instead of reaching for a global singleton, pass dependencies explicitly:
34
+ *
35
+ * ```ts
36
+ * // ❌ Singleton — hidden dependency
37
+ * const fetchUsers = () => {
38
+ * const db = Database.getInstance();
39
+ * return db.query("SELECT * FROM users");
40
+ * };
41
+ *
42
+ * // ✅ Dependency injection — explicit, testable
43
+ * const fetchUsers = (db: Database) => {
44
+ * return db.query("SELECT * FROM users");
45
+ * };
46
+ * ```
47
+ *
48
+ * This module re-exports `once` from Arkhe for discoverability.
49
+ *
50
+ * @module eidos/singleton
51
+ * @since 2.4.0
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { once } from "@pithos/core/eidos/singleton/singleton";
56
+ * // or directly from Arkhe:
57
+ * import { once } from "../../arkhe/function/once.js";
58
+ *
59
+ * // Lazy singleton initialization
60
+ * const getDb = once(() => connectToDatabase());
61
+ *
62
+ * getDb(); // connects
63
+ * getDb(); // returns cached connection
64
+ *
65
+ * // But consider: could this be passed as a parameter instead?
66
+ * ```
67
+ */
68
+ // Re-export from Arkhe for discoverability
69
+ export { once } from "../../arkhe/function/once.js";
70
+ /**
71
+ * Alias for `once` — creates a lazy singleton from a factory function.
72
+ * Re-exported for discoverability when searching for "singleton".
73
+ *
74
+ * @see once
75
+ */
76
+ export { once as singleton } from "../../arkhe/function/once.js";
77
+ //# sourceMappingURL=singleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleton.js","sourceRoot":"","sources":["../../../src/eidos/singleton/singleton.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAEH,2CAA2C;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAE5C;;;;;GAKG;AACH,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Functional State Pattern.
3
+ *
4
+ * In OOP, the State pattern requires a Context class, a State interface,
5
+ * and concrete State subclasses that the Context delegates to.
6
+ * In functional TypeScript, a state machine is a record of transitions
7
+ * keyed by state, where each transition maps an event to the next state
8
+ * (and optionally updates context).
9
+ *
10
+ * @module eidos/state
11
+ * @since 2.4.0
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { createMachine } from "@pithos/core/eidos/state/state";
16
+ *
17
+ * const light = createMachine({
18
+ * green: { timer: { to: "yellow" } },
19
+ * yellow: { timer: { to: "red" } },
20
+ * red: { timer: { to: "green" } },
21
+ * }, "green");
22
+ *
23
+ * light.current(); // "green"
24
+ * light.send("timer"); // "yellow"
25
+ * light.send("timer"); // "red"
26
+ * ```
27
+ */
28
+ import type { Option } from "../../zygos/option.js";
29
+ /**
30
+ * A simple transition to a target state.
31
+ *
32
+ * @template S - Union of state names
33
+ * @since 2.4.0
34
+ */
35
+ export interface SimpleTransition<S extends string> {
36
+ readonly to: S;
37
+ }
38
+ /**
39
+ * A transition that updates context.
40
+ *
41
+ * @template S - Union of state names
42
+ * @template C - Context type
43
+ * @since 2.4.0
44
+ */
45
+ export interface ContextTransition<S extends string, C> {
46
+ readonly to: S;
47
+ readonly update: (ctx: C) => C;
48
+ }
49
+ /**
50
+ * A transition is either simple (just target) or with context update.
51
+ *
52
+ * @template S - Union of state names
53
+ * @template C - Context type
54
+ * @since 2.4.0
55
+ */
56
+ export type Transition<S extends string, C> = SimpleTransition<S> | ContextTransition<S, C>;
57
+ /**
58
+ * A transition map for a single state.
59
+ *
60
+ * @template S - Union of state names
61
+ * @template E - Union of event names
62
+ * @template C - Context type
63
+ * @since 2.4.0
64
+ */
65
+ export type Transitions<S extends string, E extends string, C> = {
66
+ readonly [K in E]?: Transition<S, C>;
67
+ };
68
+ /**
69
+ * Full state machine definition.
70
+ *
71
+ * @template S - Union of state names
72
+ * @template E - Union of event names
73
+ * @template C - Context type
74
+ * @since 2.4.0
75
+ */
76
+ export type MachineDefinition<S extends string, E extends string, C> = {
77
+ readonly [K in S]: Transitions<S, E, C>;
78
+ };
79
+ /**
80
+ * A transition listener receives the previous state, the event, and the new state.
81
+ *
82
+ * @template S - Union of state names
83
+ * @template E - Union of event names
84
+ * @since 2.4.0
85
+ */
86
+ export type TransitionListener<S extends string, E extends string> = (from: S, event: E, to: S) => void;
87
+ /**
88
+ * Creates a finite state machine.
89
+ *
90
+ * @template S - Union of state names
91
+ * @template E - Union of event names
92
+ * @param definition - The state/transition map
93
+ * @param initial - The initial state
94
+ * @returns A machine with `current`, `send`, `matches`, `trySend`, `onTransition`, `reset`
95
+ * @since 2.4.0
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * const door = createMachine({
100
+ * locked: { unlock: { to: "closed" } },
101
+ * closed: { open: { to: "opened" }, lock: { to: "locked" } },
102
+ * opened: { close: { to: "closed" } },
103
+ * }, "locked");
104
+ *
105
+ * door.send("unlock"); // "closed"
106
+ * door.send("open"); // "opened"
107
+ * door.matches("opened"); // true
108
+ * ```
109
+ */
110
+ export declare function createMachine<S extends string, E extends string>(definition: MachineDefinition<S, E, undefined>, initial: S): {
111
+ current: () => S;
112
+ send: (event: E) => S;
113
+ matches: (state: S) => boolean;
114
+ trySend: (event: E) => Option<S>;
115
+ onTransition: (listener: TransitionListener<S, E>) => () => void;
116
+ reset: () => void;
117
+ };
118
+ /**
119
+ * Creates a finite state machine with context.
120
+ *
121
+ * @template S - Union of state names
122
+ * @template E - Union of event names
123
+ * @template C - Context type
124
+ * @param definition - The state/transition map
125
+ * @param initial - The initial state
126
+ * @param initialContext - The initial context value
127
+ * @returns A machine with `current`, `context`, `send`, `matches`, `trySend`, `onTransition`, `reset`
128
+ * @since 2.4.0
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * const counter = createMachine({
133
+ * active: {
134
+ * increment: { to: "active", update: (ctx: number) => ctx + 1 },
135
+ * reset: { to: "active", update: () => 0 },
136
+ * },
137
+ * }, "active", 0);
138
+ *
139
+ * counter.send("increment"); // "active"
140
+ * counter.context(); // 1
141
+ * ```
142
+ */
143
+ export declare function createMachine<S extends string, E extends string, C>(definition: MachineDefinition<S, E, C>, initial: S, initialContext: C): {
144
+ current: () => S;
145
+ context: () => C;
146
+ send: (event: E) => S;
147
+ matches: (state: S) => boolean;
148
+ trySend: (event: E) => Option<S>;
149
+ onTransition: (listener: TransitionListener<S, E>) => () => void;
150
+ reset: () => void;
151
+ };
152
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/eidos/state/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Functional State Pattern.
3
+ *
4
+ * In OOP, the State pattern requires a Context class, a State interface,
5
+ * and concrete State subclasses that the Context delegates to.
6
+ * In functional TypeScript, a state machine is a record of transitions
7
+ * keyed by state, where each transition maps an event to the next state
8
+ * (and optionally updates context).
9
+ *
10
+ * @module eidos/state
11
+ * @since 2.4.0
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { createMachine } from "@pithos/core/eidos/state/state";
16
+ *
17
+ * const light = createMachine({
18
+ * green: { timer: { to: "yellow" } },
19
+ * yellow: { timer: { to: "red" } },
20
+ * red: { timer: { to: "green" } },
21
+ * }, "green");
22
+ *
23
+ * light.current(); // "green"
24
+ * light.send("timer"); // "yellow"
25
+ * light.send("timer"); // "red"
26
+ * ```
27
+ */
28
+ import { some, none } from "../../zygos/option.js";
29
+ /**
30
+ * Type guard for context transitions.
31
+ */
32
+ function hasUpdate(t) {
33
+ return "update" in t;
34
+ }
35
+ export function createMachine(definition, initial, initialContext) {
36
+ let state = initial;
37
+ let ctx = initialContext;
38
+ const listeners = new Set();
39
+ const send = (event) => {
40
+ const transitions = definition[state];
41
+ const transition = transitions[event];
42
+ if (transition === undefined)
43
+ return state;
44
+ const from = state;
45
+ state = transition.to;
46
+ // Stryker disable next-line ConditionalExpression: ctx check is defensive - TypeScript prevents update on machines without context
47
+ if (hasUpdate(transition) && ctx !== undefined) {
48
+ ctx = transition.update(ctx);
49
+ }
50
+ for (const listener of listeners) {
51
+ listener(from, event, state);
52
+ }
53
+ return state;
54
+ };
55
+ const trySend = (event) => {
56
+ const transitions = definition[state];
57
+ if (transitions[event] === undefined)
58
+ return none;
59
+ return some(send(event));
60
+ };
61
+ const onTransition = (listener) => {
62
+ listeners.add(listener);
63
+ return () => { listeners.delete(listener); };
64
+ };
65
+ const base = {
66
+ current: () => state,
67
+ send,
68
+ matches: (s) => state === s,
69
+ trySend,
70
+ onTransition,
71
+ reset: () => {
72
+ state = initial;
73
+ ctx = initialContext;
74
+ },
75
+ };
76
+ if (initialContext !== undefined) {
77
+ return {
78
+ ...base,
79
+ // INTENTIONAL: ctx is guaranteed to be C when initialContext is provided
80
+ context: () => ctx,
81
+ };
82
+ }
83
+ return base;
84
+ }
85
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/eidos/state/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAyE3C;;GAEG;AACH,SAAS,SAAS,CAChB,CAAmB;IAEnB,OAAO,QAAQ,IAAI,CAAC,CAAC;AACvB,CAAC;AA4ED,MAAM,UAAU,aAAa,CAC3B,UAAsC,EACtC,OAAU,EACV,cAAkB;IAElB,IAAI,KAAK,GAAM,OAAO,CAAC;IACvB,IAAI,GAAG,GAAkB,cAAc,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,GAAG,EAA4B,CAAC;IAEtD,MAAM,IAAI,GAAG,CAAC,KAAQ,EAAK,EAAE;QAC3B,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAE3C,MAAM,IAAI,GAAG,KAAK,CAAC;QACnB,KAAK,GAAG,UAAU,CAAC,EAAE,CAAC;QAEtB,mIAAmI;QACnI,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAC/C,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,KAAQ,EAAa,EAAE;QACtC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAClD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,QAAkC,EAAgB,EAAE;QACxE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG;QACX,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK;QACpB,IAAI;QACJ,OAAO,EAAE,CAAC,CAAI,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC;QAC9B,OAAO;QACP,YAAY;QACZ,KAAK,EAAE,GAAG,EAAE;YACV,KAAK,GAAG,OAAO,CAAC;YAChB,GAAG,GAAG,cAAc,CAAC;QACvB,CAAC;KACF,CAAC;IAEF,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO;YACL,GAAG,IAAI;YACP,yEAAyE;YACzE,OAAO,EAAE,GAAG,EAAE,CAAC,GAAQ;SACxB,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Functional Strategy Pattern.
3
+ *
4
+ * In OOP, the Strategy pattern requires an interface, concrete classes, and a
5
+ * context class to swap algorithms at runtime. In functional TypeScript, a
6
+ * strategy is simply a function - the pattern becomes composition.
7
+ *
8
+ * @module eidos/strategy
9
+ * @since 2.4.0
10
+ *
11
+ * @see {@link https://pithos.dev/api/eidos/strategy/ | Explanations, examples and live demo}
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { type Strategy, createStrategies, safeStrategy } from "@pithos/core/eidos/strategy";
16
+ *
17
+ * const sorting = createStrategies({
18
+ * asc: (data: number[]) => [...data].sort((a, b) => a - b),
19
+ * desc: (data: number[]) => [...data].sort((a, b) => b - a),
20
+ * });
21
+ *
22
+ * sorting.execute("asc", [3, 1, 2]); // [1, 2, 3]
23
+ * sorting.use("desc")([3, 1, 2]); // [3, 2, 1]
24
+ * ```
25
+ */
26
+ import type { Result } from "../../zygos/result/result.js";
27
+ import type { Option } from "../../zygos/option.js";
28
+ import type { GenericSchema, Infer } from "../../kanon/types/base.js";
29
+ /**
30
+ * A Strategy is a function that transforms an input into an output.
31
+ * This replaces the GoF Strategy interface + concrete classes.
32
+ *
33
+ * @template In - The input type
34
+ * @template Out - The output type
35
+ * @since 2.4.0
36
+ */
37
+ export type Strategy<In, Out> = (input: In) => Out;
38
+ /**
39
+ * Creates a strategy resolver from a record of named strategies.
40
+ * Replaces the GoF Context class - instead of `setStrategy()` + `execute()`,
41
+ * you simply pick a function by key and call it.
42
+ *
43
+ * @template K - Union of strategy keys
44
+ * @template In - The input type
45
+ * @template Out - The output type
46
+ * @param strategies - Record mapping keys to strategy functions
47
+ * @returns Resolver with `use` (get fn) and `execute` (run by key)
48
+ * @since 2.4.0
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * const pricing = createStrategies({
53
+ * regular: (price: number) => price,
54
+ * vip: (price: number) => price * 0.8,
55
+ * premium: (price: number) => price * 0.7,
56
+ * });
57
+ *
58
+ * const applyVip = pricing.use("vip");
59
+ * applyVip(100); // 80
60
+ *
61
+ * pricing.execute("premium", 100); // 70
62
+ *
63
+ * // Safe lookup for dynamic keys (e.g. from config)
64
+ * const key: string = getFromConfig();
65
+ * pricing.get(key); // Option<Strategy<number, number>>
66
+ * ```
67
+ */
68
+ export declare function createStrategies<K extends string, In, Out>(strategies: Record<K, Strategy<In, Out>>): {
69
+ /** Get a strategy by key. Typed keys only. */
70
+ use: (key: K) => Strategy<In, Out>;
71
+ /** Execute a strategy by key with the given input. */
72
+ execute: (key: K, input: In) => Out;
73
+ /** Safe lookup for dynamic/runtime keys. Returns `Option<Strategy>`. */
74
+ get: (key: string) => Option<Strategy<In, Out>>;
75
+ };
76
+ /**
77
+ * Wraps a strategy to return a zygos `Result` instead of throwing.
78
+ * Catches any exception and wraps it in `Err<Error>`.
79
+ *
80
+ * @deprecated Use `Result.fromThrowable` from `@zygos/result/result` instead.
81
+ *
82
+ * ```ts
83
+ * import { Result } from "../../zygos/result/result.js";
84
+ *
85
+ * const safeParseJson = Result.fromThrowable(
86
+ * (input: string) => JSON.parse(input),
87
+ * (e) => e instanceof Error ? e : new Error(String(e)),
88
+ * );
89
+ * safeParseJson('{"ok":true}'); // Ok({ ok: true })
90
+ * safeParseJson("invalid"); // Err(SyntaxError(...))
91
+ * ```
92
+ *
93
+ * @see {@link https://pithos.dev/api/eidos/strategy/ | Full explanation, examples and live demo}
94
+ * @template In - The input type
95
+ * @template Out - The output type
96
+ * @param strategy - The strategy to make safe
97
+ * @returns A new strategy returning `Result<Out, Error>`
98
+ * @since 2.4.0
99
+ */
100
+ export declare function safeStrategy<In, Out>(strategy: Strategy<In, Out>): Strategy<In, Result<Out, Error>>;
101
+ /**
102
+ * Composes a primary strategy with a fallback.
103
+ * If the primary throws, the fallback is executed instead.
104
+ *
105
+ * @template In - The input type
106
+ * @template Out - The output type
107
+ * @param primary - The strategy to try first
108
+ * @param fallback - The strategy to use if primary throws
109
+ * @returns A new combined strategy
110
+ * @since 2.4.0
111
+ *
112
+ * @example
113
+ * ```ts
114
+ * const fromCache: Strategy<string, Data> = (key) => cache.get(key);
115
+ * const fromApi: Strategy<string, Data> = (key) => api.fetch(key);
116
+ *
117
+ * const fetchData = withFallback(fromCache, fromApi);
118
+ * fetchData("user:123"); // tries cache, falls back to API
119
+ * ```
120
+ */
121
+ export declare function withFallback<In, Out>(primary: Strategy<In, Out>, fallback: Strategy<In, Out>): Strategy<In, Out>;
122
+ /**
123
+ * Validates input against a kanon schema before executing the strategy.
124
+ * Bridges kanon validation, zygos Result, and the strategy pattern.
125
+ *
126
+ * @template S - The kanon schema type
127
+ * @template Out - The output type of the strategy
128
+ * @param schema - Kanon schema to validate input against
129
+ * @param strategy - Strategy to execute on validated input
130
+ * @returns A function accepting unknown input and returning `Result<Out, string>`
131
+ * @since 2.4.0
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * import { number } from "@pithos/core/kanon";
136
+ *
137
+ * const double = withValidation(
138
+ * number().min(0),
139
+ * (n) => n * 2,
140
+ * );
141
+ *
142
+ * double(5); // Ok(10)
143
+ * double(-1); // Err("Number must be >= 0")
144
+ * double("hello"); // Err("Expected number")
145
+ * ```
146
+ */
147
+ export declare function withValidation<S extends GenericSchema, Out>(schema: S, strategy: Strategy<Infer<S>, Out>): (input: unknown) => Result<Out, string>;
148
+ //# sourceMappingURL=strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../../src/eidos/strategy/strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,GAAG,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,EAAE,GAAG,EACxD,UAAU,EAAE,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAGtC,8CAA8C;eACnC,CAAC,KAAG,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC;IAChC,sDAAsD;mBACvC,CAAC,SAAS,EAAE,KAAG,GAAG;IACjC,wEAAwE;eAC7D,MAAM,KAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;EAQhD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,GAAG,EAClC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,GAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAQlC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,GAAG,EAClC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,EAC1B,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,GAC1B,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAQnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,aAAa,EAAE,GAAG,EACzD,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,GAChC,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAEzC"}