@pithos/core 2.3.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +1 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/autocompletion.d.ts +135 -1
  4. package/dist/eidos/abstract-factory/abstract-factory.d.ts +125 -0
  5. package/dist/eidos/abstract-factory/abstract-factory.d.ts.map +1 -0
  6. package/dist/eidos/abstract-factory/abstract-factory.js +128 -0
  7. package/dist/eidos/abstract-factory/abstract-factory.js.map +1 -0
  8. package/dist/eidos/adapter/adapter.d.ts +97 -0
  9. package/dist/eidos/adapter/adapter.d.ts.map +1 -0
  10. package/dist/eidos/adapter/adapter.js +90 -0
  11. package/dist/eidos/adapter/adapter.js.map +1 -0
  12. package/dist/eidos/bridge/bridge.d.ts +81 -0
  13. package/dist/eidos/bridge/bridge.d.ts.map +1 -0
  14. package/dist/eidos/bridge/bridge.js +75 -0
  15. package/dist/eidos/bridge/bridge.js.map +1 -0
  16. package/dist/eidos/builder/builder.d.ts +181 -0
  17. package/dist/eidos/builder/builder.d.ts.map +1 -0
  18. package/dist/eidos/builder/builder.js +139 -0
  19. package/dist/eidos/builder/builder.js.map +1 -0
  20. package/dist/eidos/chain/chain.d.ts +99 -0
  21. package/dist/eidos/chain/chain.d.ts.map +1 -0
  22. package/dist/eidos/chain/chain.js +111 -0
  23. package/dist/eidos/chain/chain.js.map +1 -0
  24. package/dist/eidos/command/command.d.ts +267 -0
  25. package/dist/eidos/command/command.d.ts.map +1 -0
  26. package/dist/eidos/command/command.js +298 -0
  27. package/dist/eidos/command/command.js.map +1 -0
  28. package/dist/eidos/composite/composite.d.ts +168 -0
  29. package/dist/eidos/composite/composite.d.ts.map +1 -0
  30. package/dist/eidos/composite/composite.js +157 -0
  31. package/dist/eidos/composite/composite.js.map +1 -0
  32. package/dist/eidos/decorator/decorator.d.ts +138 -0
  33. package/dist/eidos/decorator/decorator.d.ts.map +1 -0
  34. package/dist/eidos/decorator/decorator.js +143 -0
  35. package/dist/eidos/decorator/decorator.js.map +1 -0
  36. package/dist/eidos/facade/facade.d.ts +61 -0
  37. package/dist/eidos/facade/facade.d.ts.map +1 -0
  38. package/dist/eidos/facade/facade.js +63 -0
  39. package/dist/eidos/facade/facade.js.map +1 -0
  40. package/dist/eidos/factory-method/factory-method.d.ts +76 -0
  41. package/dist/eidos/factory-method/factory-method.d.ts.map +1 -0
  42. package/dist/eidos/factory-method/factory-method.js +60 -0
  43. package/dist/eidos/factory-method/factory-method.js.map +1 -0
  44. package/dist/eidos/flyweight/flyweight.d.ts +40 -0
  45. package/dist/eidos/flyweight/flyweight.d.ts.map +1 -0
  46. package/dist/eidos/flyweight/flyweight.js +41 -0
  47. package/dist/eidos/flyweight/flyweight.js.map +1 -0
  48. package/dist/eidos/interpreter/interpreter.d.ts +82 -0
  49. package/dist/eidos/interpreter/interpreter.d.ts.map +1 -0
  50. package/dist/eidos/interpreter/interpreter.js +84 -0
  51. package/dist/eidos/interpreter/interpreter.js.map +1 -0
  52. package/dist/eidos/iterator/iterator.d.ts +164 -0
  53. package/dist/eidos/iterator/iterator.d.ts.map +1 -0
  54. package/dist/eidos/iterator/iterator.js +258 -0
  55. package/dist/eidos/iterator/iterator.js.map +1 -0
  56. package/dist/eidos/mediator/mediator.d.ts +102 -0
  57. package/dist/eidos/mediator/mediator.d.ts.map +1 -0
  58. package/dist/eidos/mediator/mediator.js +112 -0
  59. package/dist/eidos/mediator/mediator.js.map +1 -0
  60. package/dist/eidos/memento/memento.d.ts +103 -0
  61. package/dist/eidos/memento/memento.d.ts.map +1 -0
  62. package/dist/eidos/memento/memento.js +114 -0
  63. package/dist/eidos/memento/memento.js.map +1 -0
  64. package/dist/eidos/observer/observer-lite.d.ts +49 -0
  65. package/dist/eidos/observer/observer-lite.d.ts.map +1 -0
  66. package/dist/eidos/observer/observer-lite.js +55 -0
  67. package/dist/eidos/observer/observer-lite.js.map +1 -0
  68. package/dist/eidos/observer/observer.d.ts +96 -0
  69. package/dist/eidos/observer/observer.d.ts.map +1 -0
  70. package/dist/eidos/observer/observer.js +117 -0
  71. package/dist/eidos/observer/observer.js.map +1 -0
  72. package/dist/eidos/prototype/prototype.d.ts +32 -0
  73. package/dist/eidos/prototype/prototype.d.ts.map +1 -0
  74. package/dist/eidos/prototype/prototype.js +33 -0
  75. package/dist/eidos/prototype/prototype.js.map +1 -0
  76. package/dist/eidos/proxy/proxy.d.ts +108 -0
  77. package/dist/eidos/proxy/proxy.d.ts.map +1 -0
  78. package/dist/eidos/proxy/proxy.js +121 -0
  79. package/dist/eidos/proxy/proxy.js.map +1 -0
  80. package/dist/eidos/singleton/singleton.d.ts +76 -0
  81. package/dist/eidos/singleton/singleton.d.ts.map +1 -0
  82. package/dist/eidos/singleton/singleton.js +77 -0
  83. package/dist/eidos/singleton/singleton.js.map +1 -0
  84. package/dist/eidos/state/state-lite.d.ts +102 -0
  85. package/dist/eidos/state/state-lite.d.ts.map +1 -0
  86. package/dist/eidos/state/state-lite.js +69 -0
  87. package/dist/eidos/state/state-lite.js.map +1 -0
  88. package/dist/eidos/state/state.d.ts +152 -0
  89. package/dist/eidos/state/state.d.ts.map +1 -0
  90. package/dist/eidos/state/state.js +85 -0
  91. package/dist/eidos/state/state.js.map +1 -0
  92. package/dist/eidos/strategy/strategy.d.ts +148 -0
  93. package/dist/eidos/strategy/strategy.d.ts.map +1 -0
  94. package/dist/eidos/strategy/strategy.js +167 -0
  95. package/dist/eidos/strategy/strategy.js.map +1 -0
  96. package/dist/eidos/template/template.d.ts +95 -0
  97. package/dist/eidos/template/template.d.ts.map +1 -0
  98. package/dist/eidos/template/template.js +110 -0
  99. package/dist/eidos/template/template.js.map +1 -0
  100. package/dist/eidos/visitor/visitor.d.ts +78 -0
  101. package/dist/eidos/visitor/visitor.d.ts.map +1 -0
  102. package/dist/eidos/visitor/visitor.js +80 -0
  103. package/dist/eidos/visitor/visitor.js.map +1 -0
  104. package/dist/zygos/result/index.d.ts +19 -0
  105. package/dist/zygos/result/index.d.ts.map +1 -0
  106. package/dist/zygos/result/index.js +29 -0
  107. package/dist/zygos/result/index.js.map +1 -0
  108. package/package.json +28 -3
@@ -10,7 +10,7 @@
10
10
  * ❌ const distance = math.geometry.distance; // from autocompletion
11
11
  * ✅ import { distance } from 'pithos/math/geometry';
12
12
  *
13
- * Generated on: 2026-03-11T01:54:32.385Z
13
+ * Generated on: 2026-04-03T14:52:39.923Z
14
14
  * */
15
15
 
16
16
  /**
@@ -568,6 +568,117 @@ declare const _autocompletion: {
568
568
  ensurePromise: typeof import('./bridges/ensurePromise.js')['ensurePromise'];
569
569
  };
570
570
  };
571
+ eidos: {
572
+ abstract_factory: {
573
+ createAbstractFactory: typeof import('./eidos/abstract-factory/abstract-factory.js')['createAbstractFactory'];
574
+ };
575
+ adapter: {
576
+ adapt: typeof import('./eidos/adapter/adapter.js')['adapt'];
577
+ createAdapter: typeof import('./eidos/adapter/adapter.js')['createAdapter'];
578
+ };
579
+ bridge: {
580
+ composeBridges: typeof import('./eidos/bridge/bridge.js')['composeBridges'];
581
+ createBridge: typeof import('./eidos/bridge/bridge.js')['createBridge'];
582
+ };
583
+ builder: {
584
+ createBuilder: typeof import('./eidos/builder/builder.js')['createBuilder'];
585
+ createValidatedBuilder: typeof import('./eidos/builder/builder.js')['createValidatedBuilder'];
586
+ };
587
+ chain: {
588
+ createChain: typeof import('./eidos/chain/chain.js')['createChain'];
589
+ safeChain: typeof import('./eidos/chain/chain.js')['safeChain'];
590
+ };
591
+ command: {
592
+ createCommandStack: typeof import('./eidos/command/command.js')['createCommandStack'];
593
+ createReactiveCommandStack: typeof import('./eidos/command/command.js')['createReactiveCommandStack'];
594
+ safeExecute: typeof import('./eidos/command/command.js')['safeExecute'];
595
+ undoable: typeof import('./eidos/command/command.js')['undoable'];
596
+ undoableState: typeof import('./eidos/command/command.js')['undoableState'];
597
+ };
598
+ composite: {
599
+ branch: typeof import('./eidos/composite/composite.js')['branch'];
600
+ find: typeof import('./eidos/composite/composite.js')['find'];
601
+ flatten: typeof import('./eidos/composite/composite.js')['flatten'];
602
+ fold: typeof import('./eidos/composite/composite.js')['fold'];
603
+ leaf: typeof import('./eidos/composite/composite.js')['leaf'];
604
+ map: typeof import('./eidos/composite/composite.js')['map'];
605
+ };
606
+ decorator: {
607
+ after: typeof import('./eidos/decorator/decorator.js')['after'];
608
+ around: typeof import('./eidos/decorator/decorator.js')['around'];
609
+ before: typeof import('./eidos/decorator/decorator.js')['before'];
610
+ decorate: typeof import('./eidos/decorator/decorator.js')['decorate'];
611
+ };
612
+ facade: {
613
+ createFacade: typeof import('./eidos/facade/facade.js')['createFacade'];
614
+ };
615
+ factory_method: {
616
+ createFactoryMethod: typeof import('./eidos/factory-method/factory-method.js')['createFactoryMethod'];
617
+ };
618
+ flyweight: {
619
+ memoize: typeof import('./eidos/flyweight/flyweight.js')['memoize'];
620
+ };
621
+ interpreter: {
622
+ interpret: typeof import('./eidos/interpreter/interpreter.js')['interpret'];
623
+ };
624
+ iterator: {
625
+ createIterable: typeof import('./eidos/iterator/iterator.js')['createIterable'];
626
+ filter: typeof import('./eidos/iterator/iterator.js')['filter'];
627
+ iterate: typeof import('./eidos/iterator/iterator.js')['iterate'];
628
+ lazyRange: typeof import('./eidos/iterator/iterator.js')['lazyRange'];
629
+ map: typeof import('./eidos/iterator/iterator.js')['map'];
630
+ reduce: typeof import('./eidos/iterator/iterator.js')['reduce'];
631
+ take: typeof import('./eidos/iterator/iterator.js')['take'];
632
+ toArray: typeof import('./eidos/iterator/iterator.js')['toArray'];
633
+ };
634
+ mediator: {
635
+ createMediator: typeof import('./eidos/mediator/mediator.js')['createMediator'];
636
+ };
637
+ memento: {
638
+ createHistory: typeof import('./eidos/memento/memento.js')['createHistory'];
639
+ };
640
+ observer: {
641
+ createObservable: typeof import('./eidos/observer/observer.js')['createObservable'];
642
+ };
643
+ observer_lite: {
644
+ createLiteObservable: typeof import('./eidos/observer/observer-lite.js')['createLiteObservable'];
645
+ };
646
+ prototype: {
647
+ deepClone: typeof import('./eidos/prototype/prototype.js')['deepClone'];
648
+ deepCloneFull: typeof import('./eidos/prototype/prototype.js')['deepCloneFull'];
649
+ };
650
+ proxy: {
651
+ debounce: typeof import('./eidos/proxy/proxy.js')['debounce'];
652
+ guarded: typeof import('./eidos/proxy/proxy.js')['guarded'];
653
+ lazy: typeof import('./eidos/proxy/proxy.js')['lazy'];
654
+ memoize: typeof import('./eidos/proxy/proxy.js')['memoize'];
655
+ once: typeof import('./eidos/proxy/proxy.js')['once'];
656
+ throttle: typeof import('./eidos/proxy/proxy.js')['throttle'];
657
+ };
658
+ singleton: {
659
+ once: typeof import('./eidos/singleton/singleton.js')['once'];
660
+ singleton: typeof import('./eidos/singleton/singleton.js')['singleton'];
661
+ };
662
+ state: {
663
+ createMachine: typeof import('./eidos/state/state.js')['createMachine'];
664
+ };
665
+ state_lite: {
666
+ createLiteMachine: typeof import('./eidos/state/state-lite.js')['createLiteMachine'];
667
+ };
668
+ strategy: {
669
+ createStrategies: typeof import('./eidos/strategy/strategy.js')['createStrategies'];
670
+ safeStrategy: typeof import('./eidos/strategy/strategy.js')['safeStrategy'];
671
+ withFallback: typeof import('./eidos/strategy/strategy.js')['withFallback'];
672
+ withValidation: typeof import('./eidos/strategy/strategy.js')['withValidation'];
673
+ };
674
+ template: {
675
+ template: typeof import('./eidos/template/template.js')['template'];
676
+ templateWithDefaults: typeof import('./eidos/template/template.js')['templateWithDefaults'];
677
+ };
678
+ visitor: {
679
+ visit: typeof import('./eidos/visitor/visitor.js')['visit'];
680
+ };
681
+ };
571
682
  kanon: {
572
683
  index: {
573
684
  any: typeof import('./kanon/index.js')['any'];
@@ -1559,6 +1670,20 @@ declare const _autocompletion: {
1559
1670
  map: typeof import('./zygos/task.js')['map'];
1560
1671
  of: typeof import('./zygos/task.js')['of'];
1561
1672
  };
1673
+ index: {
1674
+ err: typeof import('./zygos/result/index.js')['err'];
1675
+ Err: typeof import('./zygos/result/index.js')['Err'];
1676
+ errAsync: typeof import('./zygos/result/index.js')['errAsync'];
1677
+ fromEither: typeof import('./zygos/result/index.js')['fromEither'];
1678
+ fromOption: typeof import('./zygos/result/index.js')['fromOption'];
1679
+ ok: typeof import('./zygos/result/index.js')['ok'];
1680
+ Ok: typeof import('./zygos/result/index.js')['Ok'];
1681
+ okAsync: typeof import('./zygos/result/index.js')['okAsync'];
1682
+ ResultAsync: typeof import('./zygos/result/index.js')['ResultAsync'];
1683
+ safeAsyncTry: typeof import('./zygos/result/index.js')['safeAsyncTry'];
1684
+ safeTry: typeof import('./zygos/result/index.js')['safeTry'];
1685
+ toEither: typeof import('./zygos/result/index.js')['toEither'];
1686
+ };
1562
1687
  result: {
1563
1688
  err: typeof import('./zygos/result/result.js')['err'];
1564
1689
  Err: typeof import('./zygos/result/result.js')['Err'];
@@ -1611,6 +1736,15 @@ export { arkhe };
1611
1736
  declare const bridges: typeof _autocompletion.bridges;
1612
1737
  export { bridges };
1613
1738
 
1739
+ /**
1740
+ * @deprecated ⚠️ For autocompletion only.
1741
+ * Use direct imports from 'eidos/...' to preserve tree-shaking.
1742
+ * @example
1743
+ * import { createAbstractFactory } from 'pithos/eidos/abstract-factory/abstract-factory';
1744
+ */
1745
+ declare const eidos: typeof _autocompletion.eidos;
1746
+ export { eidos };
1747
+
1614
1748
  /**
1615
1749
  * @deprecated ⚠️ For autocompletion only.
1616
1750
  * Use direct imports from 'kanon/...' to preserve tree-shaking.
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Functional Abstract Factory Pattern.
3
+ *
4
+ * In OOP, the Abstract Factory pattern requires an AbstractFactory interface,
5
+ * concrete factory classes, abstract product interfaces, and concrete product
6
+ * classes — a deep hierarchy just to produce families of related objects.
7
+ * In functional TypeScript, an abstract factory is a function that returns
8
+ * a record of creator functions. Swapping families is just swapping the factory.
9
+ *
10
+ * The core value of the pattern is intra-family consistency: products created
11
+ * by the same family are guaranteed to be compatible and can collaborate.
12
+ * A single `create("variant")` call returns a coherent record where every
13
+ * creator shares the same family context.
14
+ *
15
+ * @module eidos/abstract-factory
16
+ * @since 2.4.0
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { createAbstractFactory } from "@pithos/core/eidos/abstract-factory/abstract-factory";
21
+ *
22
+ * // Products collaborate: renderForm uses both button and input from the
23
+ * // same family, guaranteeing visual consistency.
24
+ * type UIKit = {
25
+ * button: (label: string) => string;
26
+ * input: (placeholder: string) => string;
27
+ * renderForm: (action: string) => string;
28
+ * };
29
+ *
30
+ * const factory = createAbstractFactory<"light" | "dark", UIKit>({
31
+ * light: () => {
32
+ * const button = (label: string) => `<button class="light">${label}</button>`;
33
+ * const input = (ph: string) => `<input class="light" placeholder="${ph}" />`;
34
+ * return {
35
+ * button,
36
+ * input,
37
+ * renderForm: (action) => `${input(action)}${button("Submit")}`,
38
+ * };
39
+ * },
40
+ * dark: () => {
41
+ * const button = (label: string) => `<button class="dark">${label}</button>`;
42
+ * const input = (ph: string) => `<input class="dark" placeholder="${ph}" />`;
43
+ * return {
44
+ * button,
45
+ * input,
46
+ * renderForm: (action) => `${input(action)}${button("Submit")}`,
47
+ * };
48
+ * },
49
+ * });
50
+ *
51
+ * const ui = factory.create("dark");
52
+ * ui.renderForm("search");
53
+ * // `<input class="dark" ...><button class="dark">Submit</button>`
54
+ * ```
55
+ */
56
+ import type { Option } from "../../zygos/option.js";
57
+ /**
58
+ * A Factory is a zero-arg function that produces a product record.
59
+ * Each key in the record is a creator function for one product of the family.
60
+ *
61
+ * @template Products - The record of creator functions
62
+ * @since 2.4.0
63
+ */
64
+ export type Factory<Products extends Record<string, (...args: never[]) => unknown>> = () => Products;
65
+ /**
66
+ * Creates an abstract factory from a record of named family factories.
67
+ *
68
+ * Each key is a family name, each value is a factory function that produces
69
+ * the product record for that family. All families must produce the same
70
+ * product shape (same keys, same signatures).
71
+ *
72
+ * The real power is intra-family collaboration: since `create` returns a
73
+ * coherent record, products from the same family can reference each other
74
+ * via closure, guaranteeing compatibility without type gymnastics.
75
+ *
76
+ * @template K - Union of family keys
77
+ * @template Products - The record of creator functions each family produces
78
+ * @param families - Record mapping family keys to factory functions
79
+ * @returns An abstract factory with `create`, `get`, and `keys`
80
+ * @since 2.4.0
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * // Products that collaborate: encoder uses the separator from its family
85
+ * type Codec = {
86
+ * encode: (parts: string[]) => string;
87
+ * decode: (raw: string) => string[];
88
+ * };
89
+ *
90
+ * const codecs = createAbstractFactory<"csv" | "tsv", Codec>({
91
+ * csv: () => {
92
+ * const sep = ",";
93
+ * return {
94
+ * encode: (parts) => parts.join(sep),
95
+ * decode: (raw) => raw.split(sep),
96
+ * };
97
+ * },
98
+ * tsv: () => {
99
+ * const sep = "\t";
100
+ * return {
101
+ * encode: (parts) => parts.join(sep),
102
+ * decode: (raw) => raw.split(sep),
103
+ * };
104
+ * },
105
+ * });
106
+ *
107
+ * const csv = codecs.create("csv");
108
+ * csv.decode(csv.encode(["a", "b"])); // ["a", "b"] — round-trip guaranteed
109
+ * ```
110
+ */
111
+ export declare function createAbstractFactory<K extends string, Products extends Record<string, (...args: never[]) => unknown>>(families: Record<K, Factory<Products>>): {
112
+ /**
113
+ * Create a product family by key. The factory is called each time,
114
+ * producing a fresh product record.
115
+ */
116
+ create: (key: K) => Products;
117
+ /**
118
+ * Safe lookup for dynamic/runtime keys.
119
+ * Returns `Some(factory)` if the key exists, `None` otherwise.
120
+ */
121
+ get: (key: string) => Option<Factory<Products>>;
122
+ /** Returns all registered family keys. */
123
+ keys: () => K[];
124
+ };
125
+ //# sourceMappingURL=abstract-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abstract-factory.d.ts","sourceRoot":"","sources":["../../../src/eidos/abstract-factory/abstract-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,MAAM,OAAO,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,IAChF,MAAM,QAAQ,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,qBAAqB,CACnC,CAAC,SAAS,MAAM,EAChB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAC9D,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEpC;;;OAGG;kBACW,CAAC,KAAG,QAAQ;IAE1B;;;OAGG;eACQ,MAAM,KAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAQ7C,0CAA0C;gBAChC,CAAC,EAAE;EAKhB"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Functional Abstract Factory Pattern.
3
+ *
4
+ * In OOP, the Abstract Factory pattern requires an AbstractFactory interface,
5
+ * concrete factory classes, abstract product interfaces, and concrete product
6
+ * classes — a deep hierarchy just to produce families of related objects.
7
+ * In functional TypeScript, an abstract factory is a function that returns
8
+ * a record of creator functions. Swapping families is just swapping the factory.
9
+ *
10
+ * The core value of the pattern is intra-family consistency: products created
11
+ * by the same family are guaranteed to be compatible and can collaborate.
12
+ * A single `create("variant")` call returns a coherent record where every
13
+ * creator shares the same family context.
14
+ *
15
+ * @module eidos/abstract-factory
16
+ * @since 2.4.0
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { createAbstractFactory } from "@pithos/core/eidos/abstract-factory/abstract-factory";
21
+ *
22
+ * // Products collaborate: renderForm uses both button and input from the
23
+ * // same family, guaranteeing visual consistency.
24
+ * type UIKit = {
25
+ * button: (label: string) => string;
26
+ * input: (placeholder: string) => string;
27
+ * renderForm: (action: string) => string;
28
+ * };
29
+ *
30
+ * const factory = createAbstractFactory<"light" | "dark", UIKit>({
31
+ * light: () => {
32
+ * const button = (label: string) => `<button class="light">${label}</button>`;
33
+ * const input = (ph: string) => `<input class="light" placeholder="${ph}" />`;
34
+ * return {
35
+ * button,
36
+ * input,
37
+ * renderForm: (action) => `${input(action)}${button("Submit")}`,
38
+ * };
39
+ * },
40
+ * dark: () => {
41
+ * const button = (label: string) => `<button class="dark">${label}</button>`;
42
+ * const input = (ph: string) => `<input class="dark" placeholder="${ph}" />`;
43
+ * return {
44
+ * button,
45
+ * input,
46
+ * renderForm: (action) => `${input(action)}${button("Submit")}`,
47
+ * };
48
+ * },
49
+ * });
50
+ *
51
+ * const ui = factory.create("dark");
52
+ * ui.renderForm("search");
53
+ * // `<input class="dark" ...><button class="dark">Submit</button>`
54
+ * ```
55
+ */
56
+ import { some, none } from "../../zygos/option.js";
57
+ /**
58
+ * Creates an abstract factory from a record of named family factories.
59
+ *
60
+ * Each key is a family name, each value is a factory function that produces
61
+ * the product record for that family. All families must produce the same
62
+ * product shape (same keys, same signatures).
63
+ *
64
+ * The real power is intra-family collaboration: since `create` returns a
65
+ * coherent record, products from the same family can reference each other
66
+ * via closure, guaranteeing compatibility without type gymnastics.
67
+ *
68
+ * @template K - Union of family keys
69
+ * @template Products - The record of creator functions each family produces
70
+ * @param families - Record mapping family keys to factory functions
71
+ * @returns An abstract factory with `create`, `get`, and `keys`
72
+ * @since 2.4.0
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * // Products that collaborate: encoder uses the separator from its family
77
+ * type Codec = {
78
+ * encode: (parts: string[]) => string;
79
+ * decode: (raw: string) => string[];
80
+ * };
81
+ *
82
+ * const codecs = createAbstractFactory<"csv" | "tsv", Codec>({
83
+ * csv: () => {
84
+ * const sep = ",";
85
+ * return {
86
+ * encode: (parts) => parts.join(sep),
87
+ * decode: (raw) => raw.split(sep),
88
+ * };
89
+ * },
90
+ * tsv: () => {
91
+ * const sep = "\t";
92
+ * return {
93
+ * encode: (parts) => parts.join(sep),
94
+ * decode: (raw) => raw.split(sep),
95
+ * };
96
+ * },
97
+ * });
98
+ *
99
+ * const csv = codecs.create("csv");
100
+ * csv.decode(csv.encode(["a", "b"])); // ["a", "b"] — round-trip guaranteed
101
+ * ```
102
+ */
103
+ export function createAbstractFactory(families) {
104
+ return {
105
+ /**
106
+ * Create a product family by key. The factory is called each time,
107
+ * producing a fresh product record.
108
+ */
109
+ create: (key) => families[key](),
110
+ /**
111
+ * Safe lookup for dynamic/runtime keys.
112
+ * Returns `Some(factory)` if the key exists, `None` otherwise.
113
+ */
114
+ get: (key) => {
115
+ if (key in families) {
116
+ // INTENTIONAL: key validated by `in` check, TS can't narrow string to K
117
+ return some(families[key]);
118
+ }
119
+ return none;
120
+ },
121
+ /** Returns all registered family keys. */
122
+ keys: () => {
123
+ // INTENTIONAL: Object.keys returns string[], but we know they're K
124
+ return Object.keys(families);
125
+ },
126
+ };
127
+ }
128
+ //# sourceMappingURL=abstract-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abstract-factory.js","sourceRoot":"","sources":["../../../src/eidos/abstract-factory/abstract-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAa3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,MAAM,UAAU,qBAAqB,CAGnC,QAAsC;IACtC,OAAO;QACL;;;WAGG;QACH,MAAM,EAAE,CAAC,GAAM,EAAY,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QAE7C;;;WAGG;QACH,GAAG,EAAE,CAAC,GAAW,EAA6B,EAAE;YAC9C,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;gBACpB,wEAAwE;gBACxE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAQ,CAAC,CAAC,CAAC;YAClC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,0CAA0C;QAC1C,IAAI,EAAE,GAAQ,EAAE;YACd,mEAAmE;YACnE,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAQ,CAAC;QACtC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Functional Adapter Pattern.
3
+ *
4
+ * In OOP, the Adapter pattern requires a Target class, an Adaptee class with
5
+ * an incompatible interface, and an Adapter class that extends/wraps both.
6
+ * In functional TypeScript, an adapter is a pair of mapping functions
7
+ * that transform one function signature into another.
8
+ *
9
+ * @module eidos/adapter
10
+ * @since 2.4.0
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { adapt, createAdapter } from "@pithos/core/eidos/adapter/adapter";
15
+ *
16
+ * // Legacy API returns XML string
17
+ * const legacyFetch = (id: number) => `<user><name>Alice</name></user>`;
18
+ *
19
+ * // Adapt to new API shape: string id in, object out
20
+ * const fetchUser = adapt(
21
+ * legacyFetch,
22
+ * (id: string) => parseInt(id), // map input
23
+ * (xml) => ({ name: "Alice", xml }), // map output
24
+ * );
25
+ *
26
+ * fetchUser("42"); // { name: "Alice", xml: "<user>..." }
27
+ * ```
28
+ */
29
+ /**
30
+ * An Adapter transforms a function with one signature into a function
31
+ * with a different signature. Replaces the GoF Adapter class hierarchy.
32
+ *
33
+ * @template FromIn - The source function's input type
34
+ * @template FromOut - The source function's output type
35
+ * @template ToIn - The target input type
36
+ * @template ToOut - The target output type
37
+ * @since 2.4.0
38
+ */
39
+ export type Adapter<FromIn, FromOut, ToIn, ToOut> = (source: (input: FromIn) => FromOut) => (input: ToIn) => ToOut;
40
+ /**
41
+ * Creates a reusable adapter from input/output mappers.
42
+ * The adapter can then be applied to any source function
43
+ * with the matching signature.
44
+ *
45
+ * @template FromIn - The source function's input type
46
+ * @template FromOut - The source function's output type
47
+ * @template ToIn - The target input type
48
+ * @template ToOut - The target output type
49
+ * @param mapInput - Transforms target input into source input
50
+ * @param mapOutput - Transforms source output into target output
51
+ * @returns A reusable Adapter
52
+ * @since 2.4.0
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * // Adapter from Celsius to Fahrenheit API
57
+ * const celsiusToFahrenheit = createAdapter<number, string, number, string>(
58
+ * (fahrenheit) => (fahrenheit - 32) * 5 / 9, // °F -> °C input
59
+ * (label) => label.replace("°C", "°F"), // output label
60
+ * );
61
+ *
62
+ * const describeCelsius = (temp: number) => `${temp.toFixed(1)}°C`;
63
+ * const describeFahrenheit = celsiusToFahrenheit(describeCelsius);
64
+ *
65
+ * describeFahrenheit(212); // "100.0°F"
66
+ * ```
67
+ */
68
+ export declare function createAdapter<FromIn, FromOut, ToIn, ToOut>(mapInput: (input: ToIn) => FromIn, mapOutput: (output: FromOut) => ToOut): Adapter<FromIn, FromOut, ToIn, ToOut>;
69
+ /**
70
+ * Adapts a source function in one shot by mapping both input and output.
71
+ *
72
+ * @template FromIn - The source function's input type
73
+ * @template FromOut - The source function's output type
74
+ * @template ToIn - The target input type
75
+ * @template ToOut - The target output type
76
+ * @param source - The function to adapt
77
+ * @param mapInput - Transforms target input into source input
78
+ * @param mapOutput - Transforms source output into target output
79
+ * @returns The adapted function
80
+ * @since 2.4.0
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * // Adapt a sorting function to work with strings instead of numbers
85
+ * const sortNumbers = (nums: number[]) => [...nums].sort((a, b) => a - b);
86
+ *
87
+ * const sortStrings = adapt(
88
+ * sortNumbers,
89
+ * (strs: string[]) => strs.map(Number),
90
+ * (nums) => nums.map(String),
91
+ * );
92
+ *
93
+ * sortStrings(["3", "1", "2"]); // ["1", "2", "3"]
94
+ * ```
95
+ */
96
+ export declare function adapt<FromIn, FromOut, ToIn, ToOut>(source: (input: FromIn) => FromOut, mapInput: (input: ToIn) => FromIn, mapOutput: (output: FromOut) => ToOut): (input: ToIn) => ToOut;
97
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/eidos/adapter/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,CAClD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,KAC/B,CAAC,KAAK,EAAE,IAAI,KAAK,KAAK,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EACxD,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,MAAM,EACjC,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,KAAK,GACpC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAEvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAChD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,EAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,MAAM,EACjC,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,KAAK,GACpC,CAAC,KAAK,EAAE,IAAI,KAAK,KAAK,CAExB"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Functional Adapter Pattern.
3
+ *
4
+ * In OOP, the Adapter pattern requires a Target class, an Adaptee class with
5
+ * an incompatible interface, and an Adapter class that extends/wraps both.
6
+ * In functional TypeScript, an adapter is a pair of mapping functions
7
+ * that transform one function signature into another.
8
+ *
9
+ * @module eidos/adapter
10
+ * @since 2.4.0
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { adapt, createAdapter } from "@pithos/core/eidos/adapter/adapter";
15
+ *
16
+ * // Legacy API returns XML string
17
+ * const legacyFetch = (id: number) => `<user><name>Alice</name></user>`;
18
+ *
19
+ * // Adapt to new API shape: string id in, object out
20
+ * const fetchUser = adapt(
21
+ * legacyFetch,
22
+ * (id: string) => parseInt(id), // map input
23
+ * (xml) => ({ name: "Alice", xml }), // map output
24
+ * );
25
+ *
26
+ * fetchUser("42"); // { name: "Alice", xml: "<user>..." }
27
+ * ```
28
+ */
29
+ /**
30
+ * Creates a reusable adapter from input/output mappers.
31
+ * The adapter can then be applied to any source function
32
+ * with the matching signature.
33
+ *
34
+ * @template FromIn - The source function's input type
35
+ * @template FromOut - The source function's output type
36
+ * @template ToIn - The target input type
37
+ * @template ToOut - The target output type
38
+ * @param mapInput - Transforms target input into source input
39
+ * @param mapOutput - Transforms source output into target output
40
+ * @returns A reusable Adapter
41
+ * @since 2.4.0
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * // Adapter from Celsius to Fahrenheit API
46
+ * const celsiusToFahrenheit = createAdapter<number, string, number, string>(
47
+ * (fahrenheit) => (fahrenheit - 32) * 5 / 9, // °F -> °C input
48
+ * (label) => label.replace("°C", "°F"), // output label
49
+ * );
50
+ *
51
+ * const describeCelsius = (temp: number) => `${temp.toFixed(1)}°C`;
52
+ * const describeFahrenheit = celsiusToFahrenheit(describeCelsius);
53
+ *
54
+ * describeFahrenheit(212); // "100.0°F"
55
+ * ```
56
+ */
57
+ export function createAdapter(mapInput, mapOutput) {
58
+ return (source) => (input) => mapOutput(source(mapInput(input)));
59
+ }
60
+ /**
61
+ * Adapts a source function in one shot by mapping both input and output.
62
+ *
63
+ * @template FromIn - The source function's input type
64
+ * @template FromOut - The source function's output type
65
+ * @template ToIn - The target input type
66
+ * @template ToOut - The target output type
67
+ * @param source - The function to adapt
68
+ * @param mapInput - Transforms target input into source input
69
+ * @param mapOutput - Transforms source output into target output
70
+ * @returns The adapted function
71
+ * @since 2.4.0
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * // Adapt a sorting function to work with strings instead of numbers
76
+ * const sortNumbers = (nums: number[]) => [...nums].sort((a, b) => a - b);
77
+ *
78
+ * const sortStrings = adapt(
79
+ * sortNumbers,
80
+ * (strs: string[]) => strs.map(Number),
81
+ * (nums) => nums.map(String),
82
+ * );
83
+ *
84
+ * sortStrings(["3", "1", "2"]); // ["1", "2", "3"]
85
+ * ```
86
+ */
87
+ export function adapt(source, mapInput, mapOutput) {
88
+ return (input) => mapOutput(source(mapInput(input)));
89
+ }
90
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/eidos/adapter/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAgBH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAiC,EACjC,SAAqC;IAErC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,KAAK,CACnB,MAAkC,EAClC,QAAiC,EACjC,SAAqC;IAErC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC"}