@procedures/store 0.0.0-stage → 0.1.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 (115) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +65 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/errors.d.ts +16 -0
  6. package/dist/errors.d.ts.map +1 -0
  7. package/dist/errors.js +18 -0
  8. package/dist/errors.js.map +1 -0
  9. package/dist/index.d.ts +19 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +19 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/module.d.ts +15 -0
  14. package/dist/module.d.ts.map +1 -0
  15. package/dist/module.js +16 -0
  16. package/dist/module.js.map +1 -0
  17. package/dist/procedures.d.ts +13 -0
  18. package/dist/procedures.d.ts.map +1 -0
  19. package/dist/procedures.js +14 -0
  20. package/dist/procedures.js.map +1 -0
  21. package/dist/program-store/attach.d.ts +20 -0
  22. package/dist/program-store/attach.d.ts.map +1 -0
  23. package/dist/program-store/attach.js +36 -0
  24. package/dist/program-store/attach.js.map +1 -0
  25. package/dist/program-store/collection.d.ts +19 -0
  26. package/dist/program-store/collection.d.ts.map +1 -0
  27. package/dist/program-store/collection.js +34 -0
  28. package/dist/program-store/collection.js.map +1 -0
  29. package/dist/program-store/file.d.ts +29 -0
  30. package/dist/program-store/file.d.ts.map +1 -0
  31. package/dist/program-store/file.js +156 -0
  32. package/dist/program-store/file.js.map +1 -0
  33. package/dist/program-store/index.d.ts +11 -0
  34. package/dist/program-store/index.d.ts.map +1 -0
  35. package/dist/program-store/index.js +10 -0
  36. package/dist/program-store/index.js.map +1 -0
  37. package/dist/program-store/memory.d.ts +15 -0
  38. package/dist/program-store/memory.d.ts.map +1 -0
  39. package/dist/program-store/memory.js +25 -0
  40. package/dist/program-store/memory.js.map +1 -0
  41. package/dist/program-store/procedures.d.ts +23 -0
  42. package/dist/program-store/procedures.d.ts.map +1 -0
  43. package/dist/program-store/procedures.js +221 -0
  44. package/dist/program-store/procedures.js.map +1 -0
  45. package/dist/program-store/types.d.ts +50 -0
  46. package/dist/program-store/types.d.ts.map +1 -0
  47. package/dist/program-store/types.js +41 -0
  48. package/dist/program-store/types.js.map +1 -0
  49. package/dist/register.d.ts +8 -0
  50. package/dist/register.d.ts.map +1 -0
  51. package/dist/register.js +15 -0
  52. package/dist/register.js.map +1 -0
  53. package/dist/storage/adapter.d.ts +148 -0
  54. package/dist/storage/adapter.d.ts.map +1 -0
  55. package/dist/storage/adapter.js +214 -0
  56. package/dist/storage/adapter.js.map +1 -0
  57. package/dist/storage/api.d.ts +125 -0
  58. package/dist/storage/api.d.ts.map +1 -0
  59. package/dist/storage/api.js +220 -0
  60. package/dist/storage/api.js.map +1 -0
  61. package/dist/storage/factory.d.ts +134 -0
  62. package/dist/storage/factory.d.ts.map +1 -0
  63. package/dist/storage/factory.js +166 -0
  64. package/dist/storage/factory.js.map +1 -0
  65. package/dist/storage/hybrid.d.ts +193 -0
  66. package/dist/storage/hybrid.d.ts.map +1 -0
  67. package/dist/storage/hybrid.js +519 -0
  68. package/dist/storage/hybrid.js.map +1 -0
  69. package/dist/storage/index.d.ts +21 -0
  70. package/dist/storage/index.d.ts.map +1 -0
  71. package/dist/storage/index.js +20 -0
  72. package/dist/storage/index.js.map +1 -0
  73. package/dist/storage/procedures.d.ts +14 -0
  74. package/dist/storage/procedures.d.ts.map +1 -0
  75. package/dist/storage/procedures.js +98 -0
  76. package/dist/storage/procedures.js.map +1 -0
  77. package/dist/storage/serialization.d.ts +123 -0
  78. package/dist/storage/serialization.d.ts.map +1 -0
  79. package/dist/storage/serialization.js +216 -0
  80. package/dist/storage/serialization.js.map +1 -0
  81. package/dist/storage/synced-registry.d.ts +246 -0
  82. package/dist/storage/synced-registry.d.ts.map +1 -0
  83. package/dist/storage/synced-registry.js +575 -0
  84. package/dist/storage/synced-registry.js.map +1 -0
  85. package/dist/storage/types.d.ts +130 -0
  86. package/dist/storage/types.d.ts.map +1 -0
  87. package/dist/storage/types.js +8 -0
  88. package/dist/storage/types.js.map +1 -0
  89. package/dist/types.d.ts +7 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +7 -0
  92. package/dist/types.js.map +1 -0
  93. package/package.json +79 -3
  94. package/src/errors.ts +20 -0
  95. package/src/index.ts +19 -0
  96. package/src/module.ts +18 -0
  97. package/src/procedures.ts +17 -0
  98. package/src/program-store/attach.ts +46 -0
  99. package/src/program-store/collection.ts +39 -0
  100. package/src/program-store/file.ts +157 -0
  101. package/src/program-store/index.ts +17 -0
  102. package/src/program-store/memory.ts +30 -0
  103. package/src/program-store/procedures.ts +344 -0
  104. package/src/program-store/types.ts +78 -0
  105. package/src/register.ts +18 -0
  106. package/src/storage/adapter.ts +273 -0
  107. package/src/storage/api.ts +335 -0
  108. package/src/storage/factory.ts +268 -0
  109. package/src/storage/hybrid.ts +676 -0
  110. package/src/storage/index.ts +61 -0
  111. package/src/storage/procedures.ts +146 -0
  112. package/src/storage/serialization.ts +283 -0
  113. package/src/storage/synced-registry.ts +698 -0
  114. package/src/storage/types.ts +180 -0
  115. package/src/types.ts +7 -0
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Procedure Storage Adapter
3
+ *
4
+ * Wraps CollectionStorage<SerializedProcedure> to provide procedure-specific
5
+ * storage operations with serialization/deserialization.
6
+ */
7
+ import { pathToKey } from "@procedures/client";
8
+ import { serializeProcedure, deserializeProcedure, getProcedureKey, } from "./serialization.js";
9
+ /**
10
+ * Adapter that wraps CollectionStorage for procedure-specific operations.
11
+ *
12
+ * Handles serialization/deserialization of procedures and provides
13
+ * convenience methods for common operations.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const storage = new InMemoryStorage<SerializedProcedure>();
18
+ * const adapter = new ProcedureStorageAdapter(storage, {
19
+ * handlerLoader: createDynamicHandlerLoader(),
20
+ * });
21
+ *
22
+ * // Store a procedure
23
+ * await adapter.store(myProcedure);
24
+ *
25
+ * // Load a procedure
26
+ * const proc = await adapter.load(['lib', 'scan']);
27
+ * ```
28
+ */
29
+ export class ProcedureStorageAdapter {
30
+ storage;
31
+ handlerLoader;
32
+ serializeOptions;
33
+ constructor(storage, options = {}) {
34
+ this.storage = storage;
35
+ this.handlerLoader = options.handlerLoader;
36
+ this.serializeOptions = options.serializeOptions ?? {};
37
+ }
38
+ // ===========================================================================
39
+ // Single Item Operations
40
+ // ===========================================================================
41
+ /**
42
+ * Store a procedure.
43
+ *
44
+ * @param procedure - Procedure to store
45
+ * @param options - Override default serialization options
46
+ * @returns The record that the storage got
47
+ */
48
+ async store(procedure, options) {
49
+ const key = getProcedureKey(procedure);
50
+ const serialized = serializeProcedure(procedure, {
51
+ ...this.serializeOptions,
52
+ ...options,
53
+ });
54
+ await this.storage.set(key, serialized);
55
+ return serialized;
56
+ }
57
+ /**
58
+ * Load a procedure by path.
59
+ *
60
+ * @param path - Procedure path
61
+ * @returns Procedure or undefined if not found
62
+ */
63
+ async load(path) {
64
+ const key = pathToKey(path);
65
+ const data = await this.storage.get(key);
66
+ if (!data)
67
+ return undefined;
68
+ return deserializeProcedure(data, {
69
+ handlerLoader: this.handlerLoader,
70
+ });
71
+ }
72
+ /**
73
+ * Check if a procedure exists in storage.
74
+ *
75
+ * @param path - Procedure path
76
+ * @returns True if procedure exists
77
+ */
78
+ async has(path) {
79
+ const key = pathToKey(path);
80
+ return this.storage.has(key);
81
+ }
82
+ /**
83
+ * Remove a procedure from storage.
84
+ *
85
+ * @param path - Procedure path
86
+ * @returns True if procedure was removed
87
+ */
88
+ async remove(path) {
89
+ const key = pathToKey(path);
90
+ return this.storage.delete(key);
91
+ }
92
+ // ===========================================================================
93
+ // Bulk Operations
94
+ // ===========================================================================
95
+ /**
96
+ * Load all procedures from storage.
97
+ *
98
+ * @returns Array of all procedures
99
+ */
100
+ async loadAll() {
101
+ const items = await this.storage.getAll();
102
+ return Promise.all(items.map((item) => deserializeProcedure(item, { handlerLoader: this.handlerLoader })));
103
+ }
104
+ /**
105
+ * Load procedures matching a path prefix.
106
+ *
107
+ * @param prefix - Path prefix to match
108
+ * @returns Array of matching procedures
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // Load all lib.* procedures
113
+ * const libProcedures = await adapter.loadByPrefix(['lib']);
114
+ * ```
115
+ */
116
+ async loadByPrefix(prefix) {
117
+ const prefixKey = pathToKey(prefix);
118
+ const items = await this.storage.find((item) => {
119
+ const itemKey = pathToKey(item.path);
120
+ return itemKey === prefixKey || itemKey.startsWith(prefixKey + ".");
121
+ });
122
+ return Promise.all(items.map((item) => deserializeProcedure(item, { handlerLoader: this.handlerLoader })));
123
+ }
124
+ /**
125
+ * Store multiple procedures.
126
+ *
127
+ * @param procedures - Procedures to store
128
+ * @param options - Override default serialization options, or a function that gives the
129
+ * options of each procedure (for example, its handler reference)
130
+ * @returns The records that the storage got
131
+ */
132
+ async storeAll(procedures, options) {
133
+ const items = procedures.map((proc) => [
134
+ getProcedureKey(proc),
135
+ serializeProcedure(proc, {
136
+ ...this.serializeOptions,
137
+ ...(typeof options === "function" ? options(proc) : options),
138
+ }),
139
+ ]);
140
+ await this.storage.setBatch(items);
141
+ return items.map(([, serialized]) => serialized);
142
+ }
143
+ /**
144
+ * Remove multiple procedures.
145
+ *
146
+ * @param paths - Procedure paths to remove
147
+ * @returns Number of procedures removed
148
+ */
149
+ async removeAll(paths) {
150
+ const keys = paths.map(pathToKey);
151
+ return this.storage.deleteBatch(keys);
152
+ }
153
+ /**
154
+ * Clear all procedures from storage.
155
+ */
156
+ async clear() {
157
+ await this.storage.clear();
158
+ }
159
+ // ===========================================================================
160
+ // Info Operations
161
+ // ===========================================================================
162
+ /**
163
+ * Get the number of stored procedures.
164
+ */
165
+ async size() {
166
+ return this.storage.size();
167
+ }
168
+ /**
169
+ * List all stored procedure paths.
170
+ *
171
+ * @returns Array of procedure paths
172
+ */
173
+ async listPaths() {
174
+ const items = await this.storage.getAll();
175
+ return items.map((item) => item.path);
176
+ }
177
+ /**
178
+ * Get the raw serialized data for a procedure.
179
+ * Useful for debugging or custom processing.
180
+ *
181
+ * @param path - Procedure path
182
+ * @returns Serialized procedure data or undefined
183
+ */
184
+ async getRaw(path) {
185
+ const key = pathToKey(path);
186
+ return this.storage.get(key);
187
+ }
188
+ /**
189
+ * Get all raw serialized data.
190
+ * Useful for debugging or backup.
191
+ *
192
+ * @returns Array of serialized procedures
193
+ */
194
+ async getAllRaw() {
195
+ return this.storage.getAll();
196
+ }
197
+ // ===========================================================================
198
+ // Lifecycle
199
+ // ===========================================================================
200
+ /**
201
+ * Close the underlying storage.
202
+ */
203
+ async close() {
204
+ await this.storage.close();
205
+ }
206
+ /**
207
+ * Get the underlying storage instance.
208
+ * Use for advanced operations or testing.
209
+ */
210
+ getStorage() {
211
+ return this.storage;
212
+ }
213
+ }
214
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/storage/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,GAEhB,MAAM,oBAAoB,CAAC;AAiB5B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,uBAAuB;IACjB,OAAO,CAAyC;IAChD,aAAa,CAA4B;IACzC,gBAAgB,CAAmB;IAEpD,YACE,OAA+C,EAC/C,OAAO,GAAmC,EAAE;QAE5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QAC3C,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAAC;IACzD,CAAC;IAED,8EAA8E;IAC9E,yBAAyB;IACzB,8EAA8E;IAE9E;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CAAC,SAAuB,EAAE,OAA0B;QAC7D,MAAM,GAAG,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,EAAE;YAC/C,GAAG,IAAI,CAAC,gBAAgB;YACxB,GAAG,OAAO;SACX,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACxC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CAAC,IAAmB;QAC5B,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAE5B,OAAO,oBAAoB,CAAC,IAAI,EAAE;YAChC,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAC,IAAmB;QAC3B,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,IAAmB;QAC9B,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E;;;;OAIG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1C,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACjB,oBAAoB,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAClE,CACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,YAAY,CAAC,MAAqB;QACtC,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrC,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC,GAAG,CAChB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACjB,oBAAoB,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAClE,CACF,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,CACZ,UAA0B,EAC1B,OAAwF;QAExF,MAAM,KAAK,GAAyC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3E,eAAe,CAAC,IAAI,CAAC;YACrB,kBAAkB,CAAC,IAAI,EAAE;gBACvB,GAAG,IAAI,CAAC,gBAAgB;gBACxB,GAAG,CAAC,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;aAC7D,CAAC;SACH,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACnC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CAAC,KAAsB;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,SAAS;QACb,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,CAAC,IAAmB;QAC9B,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,SAAS;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC;IAED,8EAA8E;IAC9E,YAAY;IACZ,8EAA8E;IAE9E;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * API Storage Implementation
3
+ *
4
+ * Remote storage backed by universal client.
5
+ * Enables collections to be persisted on a server.
6
+ *
7
+ * This is the KEY integration between Collections and Universal Client!
8
+ */
9
+ import type { CollectionStorage, StorageMetadata } from "@procedures/collections";
10
+ import type { Client } from "@procedures/client";
11
+ /**
12
+ * API storage configuration options.
13
+ */
14
+ export interface ApiStorageOptions {
15
+ /**
16
+ * The collection of the core collection procedures. The calls go to
17
+ * `collections.<collection>.<operation>`, as `createCollectionProcedures(collection)` registers them.
18
+ * @example "users", "procedures"
19
+ */
20
+ collection?: string;
21
+ /**
22
+ * Service name for RPC calls. The default is `collections.<collection>`. Give a service only
23
+ * for a server with other paths.
24
+ * @example "users", "orders", "products"
25
+ */
26
+ service?: string;
27
+ /**
28
+ * Optional API version
29
+ * @example "v1", "v2"
30
+ */
31
+ version?: string;
32
+ /**
33
+ * Custom operation names (override defaults)
34
+ */
35
+ operations?: {
36
+ get?: string;
37
+ getAll?: string;
38
+ find?: string;
39
+ has?: string;
40
+ size?: string;
41
+ set?: string;
42
+ delete?: string;
43
+ clear?: string;
44
+ setBatch?: string;
45
+ deleteBatch?: string;
46
+ getBatch?: string;
47
+ };
48
+ /**
49
+ * Request timeout in milliseconds. A call that takes longer fails. 0: no timeout.
50
+ * @default 30000 (30 seconds)
51
+ */
52
+ timeout?: number;
53
+ /**
54
+ * Retry a call that fails with a retryable error: true (3 attempts), false (1 attempt), or the
55
+ * number of attempts.
56
+ * @default true
57
+ */
58
+ retry?: boolean | number;
59
+ /**
60
+ * The first delay between attempts in milliseconds. Each later delay is two times longer.
61
+ * @default 100
62
+ */
63
+ retryDelay?: number;
64
+ /**
65
+ * AbortSignal for cancelling requests
66
+ */
67
+ signal?: AbortSignal;
68
+ /**
69
+ * True: `close()` closes the client. The default is false: the client belongs to the caller.
70
+ * @default false
71
+ */
72
+ closeClient?: boolean;
73
+ }
74
+ /**
75
+ * API storage backed by universal client.
76
+ *
77
+ * Maps collection operations to the core collection procedures
78
+ * (`createCollectionProcedures`), which take and return raw values:
79
+ * - get(id) → `collections.<collection>.get` with `{ id }`
80
+ * - set(id, value) → `collections.<collection>.set` with `{ id, value }`
81
+ * - setBatch(items) → `collections.<collection>.setBatch` with `{ items: [{ id, value }] }`
82
+ * - etc.
83
+ *
84
+ * Before, the class expected a `{ data }` envelope and called `<service>.get`: no core
85
+ * procedure matched, and every read was undefined (deep dive CORE-9, DATA-9).
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * // Create API storage
90
+ * const client = new Client({
91
+ * transport: new HttpTransport({ baseUrl: "https://api.example.com" })
92
+ * });
93
+ *
94
+ * const storage = new ApiStorage(client, { collection: "users" });
95
+ *
96
+ * // Operations are automatically sent to server
97
+ * await storage.set("123", { name: "John" });
98
+ * const user = await storage.get("123"); // Fetched from server
99
+ * ```
100
+ */
101
+ export declare class ApiStorage<T> implements CollectionStorage<T> {
102
+ private client;
103
+ private options;
104
+ constructor(client: Client, options: ApiStorageOptions);
105
+ get(id: string): Promise<T | undefined>;
106
+ getAll(): Promise<T[]>;
107
+ find(predicate: (item: T) => boolean): Promise<T[]>;
108
+ has(id: string): Promise<boolean>;
109
+ size(): Promise<number>;
110
+ set(id: string, value: T): Promise<void>;
111
+ delete(id: string): Promise<boolean>;
112
+ clear(): Promise<void>;
113
+ setBatch(items: Array<[string, T]>): Promise<void>;
114
+ deleteBatch(ids: string[]): Promise<number>;
115
+ getBatch(ids: string[]): Promise<Map<string, T>>;
116
+ close(): Promise<void>;
117
+ getMetadata(): Promise<StorageMetadata>;
118
+ /**
119
+ * Make an RPC call via the universal client, with the timeout, the signal and the retries.
120
+ */
121
+ private call;
122
+ /** One attempt: the call ends at the timeout, or when the signal of the options aborts. */
123
+ private attempt;
124
+ }
125
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/storage/api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAIjD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAEzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA+BD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,UAAU,CAAC,CAAC,CAAE,YAAW,iBAAiB,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CASb;IAEF,YAAY,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EA8BrD;IAMK,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAG5C;IAEK,MAAM,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAM3B;IAEK,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAIxD;IAEK,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEtC;IAEK,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAE5B;IAMK,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7C;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzC;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAMK,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;IAEK,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAEhD;IAEK,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CASrD;IAMK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAK3B;IAEK,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC,CAY5C;IAMD;;OAEG;YACW,IAAI;IAqBlB,2FAA2F;IAC3F,OAAO,CAAC,OAAO;CAsBhB"}
@@ -0,0 +1,220 @@
1
+ /**
2
+ * API Storage Implementation
3
+ *
4
+ * Remote storage backed by universal client.
5
+ * Enables collections to be persisted on a server.
6
+ *
7
+ * This is the KEY integration between Collections and Universal Client!
8
+ */
9
+ /** An error that says whether another attempt can succeed (a ClientError does). */
10
+ function isRetryable(error) {
11
+ return (typeof error === "object" &&
12
+ error !== null &&
13
+ error.retryable === true);
14
+ }
15
+ /** A promise that rejects when the signal aborts first. */
16
+ function untilAborted(promise, signal, describe) {
17
+ if (!signal)
18
+ return promise;
19
+ if (signal.aborted)
20
+ return Promise.reject(describe());
21
+ return new Promise((resolve, reject) => {
22
+ const onAbort = () => reject(describe());
23
+ signal.addEventListener("abort", onAbort, { once: true });
24
+ promise.then((value) => {
25
+ signal.removeEventListener("abort", onAbort);
26
+ resolve(value);
27
+ }, (error) => {
28
+ signal.removeEventListener("abort", onAbort);
29
+ reject(error);
30
+ });
31
+ });
32
+ }
33
+ /**
34
+ * API storage backed by universal client.
35
+ *
36
+ * Maps collection operations to the core collection procedures
37
+ * (`createCollectionProcedures`), which take and return raw values:
38
+ * - get(id) → `collections.<collection>.get` with `{ id }`
39
+ * - set(id, value) → `collections.<collection>.set` with `{ id, value }`
40
+ * - setBatch(items) → `collections.<collection>.setBatch` with `{ items: [{ id, value }] }`
41
+ * - etc.
42
+ *
43
+ * Before, the class expected a `{ data }` envelope and called `<service>.get`: no core
44
+ * procedure matched, and every read was undefined (deep dive CORE-9, DATA-9).
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * // Create API storage
49
+ * const client = new Client({
50
+ * transport: new HttpTransport({ baseUrl: "https://api.example.com" })
51
+ * });
52
+ *
53
+ * const storage = new ApiStorage(client, { collection: "users" });
54
+ *
55
+ * // Operations are automatically sent to server
56
+ * await storage.set("123", { name: "John" });
57
+ * const user = await storage.get("123"); // Fetched from server
58
+ * ```
59
+ */
60
+ export class ApiStorage {
61
+ client;
62
+ options;
63
+ constructor(client, options) {
64
+ const service = options.service ?? (options.collection !== undefined ? `collections.${options.collection}` : undefined);
65
+ if (!service) {
66
+ throw new Error("ApiStorage requires a collection or a service");
67
+ }
68
+ this.client = client;
69
+ this.options = {
70
+ service,
71
+ ...(options.version !== undefined && { version: options.version }),
72
+ operations: {
73
+ get: "get",
74
+ getAll: "getAll",
75
+ find: "find",
76
+ has: "has",
77
+ size: "size",
78
+ set: "set",
79
+ delete: "delete",
80
+ clear: "clear",
81
+ setBatch: "setBatch",
82
+ deleteBatch: "deleteBatch",
83
+ getBatch: "getBatch",
84
+ ...options.operations,
85
+ },
86
+ timeout: options.timeout ?? 30000,
87
+ attempts: options.retry === false ? 1 : options.retry === true || options.retry === undefined ? 3 : Math.max(1, options.retry),
88
+ retryDelay: options.retryDelay ?? 100,
89
+ ...(options.signal !== undefined && { signal: options.signal }),
90
+ closeClient: options.closeClient ?? false,
91
+ };
92
+ }
93
+ //
94
+ // ═══ Read Operations ═══
95
+ //
96
+ async get(id) {
97
+ const value = await this.call("get", { id });
98
+ return value ?? undefined;
99
+ }
100
+ async getAll() {
101
+ const values = await this.call("getAll", {});
102
+ if (!Array.isArray(values)) {
103
+ throw new Error(`${this.options.service}.getAll did not return an array`);
104
+ }
105
+ return values;
106
+ }
107
+ async find(predicate) {
108
+ // A predicate cannot go over the network: read all items, then filter here
109
+ const all = await this.getAll();
110
+ return all.filter(predicate);
111
+ }
112
+ async has(id) {
113
+ return (await this.call("has", { id })) === true;
114
+ }
115
+ async size() {
116
+ return Number(await this.call("size", {}));
117
+ }
118
+ //
119
+ // ═══ Write Operations ═══
120
+ //
121
+ async set(id, value) {
122
+ await this.call("set", { id, value });
123
+ }
124
+ async delete(id) {
125
+ return (await this.call("delete", { id })) === true;
126
+ }
127
+ async clear() {
128
+ await this.call("clear", {});
129
+ }
130
+ //
131
+ // ═══ Bulk Operations ═══
132
+ //
133
+ async setBatch(items) {
134
+ // The collection procedure takes objects, not tuples
135
+ await this.call("setBatch", { items: items.map(([id, value]) => ({ id, value })) });
136
+ }
137
+ async deleteBatch(ids) {
138
+ return Number(await this.call("deleteBatch", { ids }));
139
+ }
140
+ async getBatch(ids) {
141
+ const values = (await this.call("getBatch", { ids })) ?? {};
142
+ // Convert object to Map
143
+ const result = new Map();
144
+ for (const [id, value] of Object.entries(values)) {
145
+ result.set(id, value);
146
+ }
147
+ return result;
148
+ }
149
+ //
150
+ // ═══ Lifecycle & Metadata ═══
151
+ //
152
+ async close() {
153
+ // The client belongs to the caller, unless the caller gave it to this storage
154
+ if (this.options.closeClient) {
155
+ await this.client.close();
156
+ }
157
+ }
158
+ async getMetadata() {
159
+ const storageSize = await this.size();
160
+ return {
161
+ type: "api",
162
+ size: storageSize,
163
+ stats: {
164
+ service: this.options.service,
165
+ version: this.options.version,
166
+ timeout: this.options.timeout,
167
+ },
168
+ };
169
+ }
170
+ //
171
+ // ═══ Internal Helpers ═══
172
+ //
173
+ /**
174
+ * Make an RPC call via the universal client, with the timeout, the signal and the retries.
175
+ */
176
+ async call(operation, payload) {
177
+ const method = {
178
+ service: this.options.service,
179
+ operation: this.options.operations[operation] ?? operation,
180
+ ...(this.options.version !== undefined && { version: this.options.version }),
181
+ };
182
+ const label = `${method.service}.${method.operation}`;
183
+ for (let attempt = 1;; attempt++) {
184
+ try {
185
+ return await this.attempt(method, payload, label);
186
+ }
187
+ catch (error) {
188
+ if (attempt >= this.options.attempts || !isRetryable(error) || this.options.signal?.aborted) {
189
+ throw error;
190
+ }
191
+ const delay = this.options.retryDelay * 2 ** (attempt - 1);
192
+ await untilAborted(new Promise((resolve) => setTimeout(resolve, delay)), this.options.signal, () => error);
193
+ }
194
+ }
195
+ }
196
+ /** One attempt: the call ends at the timeout, or when the signal of the options aborts. */
197
+ attempt(method, payload, label) {
198
+ const signals = [];
199
+ if (this.options.signal)
200
+ signals.push(this.options.signal);
201
+ const timer = this.options.timeout > 0 ? new AbortController() : undefined;
202
+ let timeoutHandle;
203
+ if (timer) {
204
+ timeoutHandle = setTimeout(() => timer.abort(), this.options.timeout);
205
+ signals.push(timer.signal);
206
+ }
207
+ const signal = signals.length === 0 ? undefined : signals.length === 1 ? signals[0] : AbortSignal.any(signals);
208
+ // The signal goes in the call options, so the transport can stop the request too. (Before,
209
+ // it went into the metadata, and the timeout was dropped: deep dive CORE-9.)
210
+ const callOptions = {};
211
+ if (signal)
212
+ callOptions.signal = signal;
213
+ const call = this.client.call(method, payload, callOptions);
214
+ return untilAborted(call, signal, () => timer?.signal.aborted ? new Error(`${label} timed out after ${this.options.timeout} ms`) : new Error(`${label} was aborted`)).finally(() => {
215
+ if (timeoutHandle !== undefined)
216
+ clearTimeout(timeoutHandle);
217
+ });
218
+ }
219
+ }
220
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/storage/api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA+EH,mFAAmF;AACnF,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACb,KAAiC,CAAC,SAAS,KAAK,IAAI,CACtD,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,SAAS,YAAY,CAAI,OAAmB,EAAE,MAA+B,EAAE,QAAqB;IAClG,IAAI,CAAC,MAAM;QAAE,OAAO,OAAO,CAAC;IAC5B,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IACtD,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,MAAM,OAAO,GAAG,GAAS,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/C,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CACV,CAAC,KAAK,EAAE,EAAE;YACR,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YACjB,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,OAAO,UAAU;IACb,MAAM,CAAS;IACf,OAAO,CASb;IAEF,YAAY,MAAc,EAAE,OAA0B;QACpD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACxH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG;YACb,OAAO;YACP,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,UAAU,EAAE;gBACV,GAAG,EAAE,KAAK;gBACV,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,KAAK;gBACV,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,KAAK;gBACV,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,UAAU;gBACpB,WAAW,EAAE,aAAa;gBAC1B,QAAQ,EAAE,UAAU;gBACpB,GAAG,OAAO,CAAC,UAAU;aACtB;YACD,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;YACjC,QAAQ,EACN,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC;YACtH,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,GAAG;YACrC,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YAC/D,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK;SAC1C,CAAC;IACJ,CAAC;IAED,EAAE;IACF,0BAA0B;IAC1B,EAAE;IAEF,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAuB,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACnE,OAAO,KAAK,IAAI,SAAS,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAM,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,iCAAiC,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAA+B;QACxC,2EAA2E;QAC3E,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAU,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAS,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,EAAE;IACF,2BAA2B;IAC3B,EAAE;IAEF,KAAK,CAAC,GAAG,CAAC,EAAU,EAAE,KAAQ;QAC5B,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAU,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,EAAE;IACF,0BAA0B;IAC1B,EAAE;IAEF,KAAK,CAAC,QAAQ,CAAC,KAAyB;QACtC,qDAAqD;QACrD,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACtF,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,GAAa;QAC7B,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAS,aAAa,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAa;QAC1B,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAA2B,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAEtF,wBAAwB;QACxB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAa,CAAC;QACpC,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACjD,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,EAAE;IACF,+BAA+B;IAC/B,EAAE;IAEF,KAAK,CAAC,KAAK;QACT,8EAA8E;QAC9E,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAEtC,OAAO;YACL,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE;gBACL,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;gBAC7B,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;gBAC7B,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;aAC9B;SACF,CAAC;IACJ,CAAC;IAED,EAAE;IACF,2BAA2B;IAC3B,EAAE;IAEF;;OAEG;IACK,KAAK,CAAC,IAAI,CAAO,SAA0D,EAAE,OAAgB;QACnG,MAAM,MAAM,GAAW;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,SAAS;YAC1D,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;SAC7E,CAAC;QACF,MAAM,KAAK,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QAEtD,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAO,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAC1D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;oBAC5F,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;gBAC3D,MAAM,YAAY,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,KAAc,CAAC,CAAC;YACtH,CAAC;QACH,CAAC;IACH,CAAC;IAED,2FAA2F;IACnF,OAAO,CAAO,MAAc,EAAE,OAAgB,EAAE,KAAa;QACnE,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3E,IAAI,aAAwD,CAAC;QAC7D,IAAI,KAAK,EAAE,CAAC;YACV,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE/G,2FAA2F;QAC3F,6EAA6E;QAC7E,MAAM,WAAW,GAAyB,EAAE,CAAC;QAC7C,IAAI,MAAM;YAAE,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAgB,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAC3E,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CACrC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,cAAc,CAAC,CAC7H,CAAC,OAAO,CAAC,GAAG,EAAE;YACb,IAAI,aAAa,KAAK,SAAS;gBAAE,YAAY,CAAC,aAAa,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}