@procedures/collections 0.0.0-stage → 0.2.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 (205) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +394 -2
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/async/async-queue.d.ts +155 -0
  6. package/dist/async/async-queue.d.ts.map +1 -0
  7. package/dist/async/async-queue.js +342 -0
  8. package/dist/async/async-queue.js.map +1 -0
  9. package/dist/async/channels.d.ts +188 -0
  10. package/dist/async/channels.d.ts.map +1 -0
  11. package/dist/async/channels.js +314 -0
  12. package/dist/async/channels.js.map +1 -0
  13. package/dist/behaviors/bounded.d.ts +79 -0
  14. package/dist/behaviors/bounded.d.ts.map +1 -0
  15. package/dist/behaviors/bounded.js +384 -0
  16. package/dist/behaviors/bounded.js.map +1 -0
  17. package/dist/behaviors/composite.d.ts +17 -0
  18. package/dist/behaviors/composite.d.ts.map +1 -0
  19. package/dist/behaviors/composite.js +93 -0
  20. package/dist/behaviors/composite.js.map +1 -0
  21. package/dist/behaviors/evented.d.ts +154 -0
  22. package/dist/behaviors/evented.d.ts.map +1 -0
  23. package/dist/behaviors/evented.js +299 -0
  24. package/dist/behaviors/evented.js.map +1 -0
  25. package/dist/behaviors/lru.d.ts +84 -0
  26. package/dist/behaviors/lru.d.ts.map +1 -0
  27. package/dist/behaviors/lru.js +376 -0
  28. package/dist/behaviors/lru.js.map +1 -0
  29. package/dist/behaviors/readonly.d.ts +73 -0
  30. package/dist/behaviors/readonly.d.ts.map +1 -0
  31. package/dist/behaviors/readonly.js +177 -0
  32. package/dist/behaviors/readonly.js.map +1 -0
  33. package/dist/behaviors/safe.d.ts +163 -0
  34. package/dist/behaviors/safe.d.ts.map +1 -0
  35. package/dist/behaviors/safe.js +176 -0
  36. package/dist/behaviors/safe.js.map +1 -0
  37. package/dist/behaviors/synchronized.d.ts +88 -0
  38. package/dist/behaviors/synchronized.d.ts.map +1 -0
  39. package/dist/behaviors/synchronized.js +285 -0
  40. package/dist/behaviors/synchronized.js.map +1 -0
  41. package/dist/behaviors/ttl.d.ts +118 -0
  42. package/dist/behaviors/ttl.d.ts.map +1 -0
  43. package/dist/behaviors/ttl.js +354 -0
  44. package/dist/behaviors/ttl.js.map +1 -0
  45. package/dist/contracts/model.d.ts +29 -0
  46. package/dist/contracts/model.d.ts.map +1 -0
  47. package/dist/contracts/model.js +26 -0
  48. package/dist/contracts/model.js.map +1 -0
  49. package/dist/core/effects.d.ts +176 -0
  50. package/dist/core/effects.d.ts.map +1 -0
  51. package/dist/core/effects.js +180 -0
  52. package/dist/core/effects.js.map +1 -0
  53. package/dist/core/events.d.ts +192 -0
  54. package/dist/core/events.d.ts.map +1 -0
  55. package/dist/core/events.js +291 -0
  56. package/dist/core/events.js.map +1 -0
  57. package/dist/core/middleware.d.ts +231 -0
  58. package/dist/core/middleware.d.ts.map +1 -0
  59. package/dist/core/middleware.js +161 -0
  60. package/dist/core/middleware.js.map +1 -0
  61. package/dist/core/policies.d.ts +220 -0
  62. package/dist/core/policies.d.ts.map +1 -0
  63. package/dist/core/policies.js +48 -0
  64. package/dist/core/policies.js.map +1 -0
  65. package/dist/core/traits.d.ts +142 -0
  66. package/dist/core/traits.d.ts.map +1 -0
  67. package/dist/core/traits.js +8 -0
  68. package/dist/core/traits.js.map +1 -0
  69. package/dist/fx/collectors.d.ts +193 -0
  70. package/dist/fx/collectors.d.ts.map +1 -0
  71. package/dist/fx/collectors.js +375 -0
  72. package/dist/fx/collectors.js.map +1 -0
  73. package/dist/fx/iter.d.ts +166 -0
  74. package/dist/fx/iter.d.ts.map +1 -0
  75. package/dist/fx/iter.js +421 -0
  76. package/dist/fx/iter.js.map +1 -0
  77. package/dist/impl/array-deque.d.ts +112 -0
  78. package/dist/impl/array-deque.d.ts.map +1 -0
  79. package/dist/impl/array-deque.js +380 -0
  80. package/dist/impl/array-deque.js.map +1 -0
  81. package/dist/impl/array-list.d.ts +101 -0
  82. package/dist/impl/array-list.d.ts.map +1 -0
  83. package/dist/impl/array-list.js +387 -0
  84. package/dist/impl/array-list.js.map +1 -0
  85. package/dist/impl/hash-map.d.ts +149 -0
  86. package/dist/impl/hash-map.d.ts.map +1 -0
  87. package/dist/impl/hash-map.js +473 -0
  88. package/dist/impl/hash-map.js.map +1 -0
  89. package/dist/impl/hash-set.d.ts +125 -0
  90. package/dist/impl/hash-set.d.ts.map +1 -0
  91. package/dist/impl/hash-set.js +264 -0
  92. package/dist/impl/hash-set.js.map +1 -0
  93. package/dist/impl/linked-hash-map.d.ts +141 -0
  94. package/dist/impl/linked-hash-map.d.ts.map +1 -0
  95. package/dist/impl/linked-hash-map.js +442 -0
  96. package/dist/impl/linked-hash-map.js.map +1 -0
  97. package/dist/impl/linked-list.d.ts +109 -0
  98. package/dist/impl/linked-list.d.ts.map +1 -0
  99. package/dist/impl/linked-list.js +494 -0
  100. package/dist/impl/linked-list.js.map +1 -0
  101. package/dist/impl/priority-queue.d.ts +139 -0
  102. package/dist/impl/priority-queue.d.ts.map +1 -0
  103. package/dist/impl/priority-queue.js +343 -0
  104. package/dist/impl/priority-queue.js.map +1 -0
  105. package/dist/impl/tree-map.d.ts +153 -0
  106. package/dist/impl/tree-map.d.ts.map +1 -0
  107. package/dist/impl/tree-map.js +788 -0
  108. package/dist/impl/tree-map.js.map +1 -0
  109. package/dist/impl/tree-set.d.ts +112 -0
  110. package/dist/impl/tree-set.d.ts.map +1 -0
  111. package/dist/impl/tree-set.js +374 -0
  112. package/dist/impl/tree-set.js.map +1 -0
  113. package/dist/index.d.ts +106 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/dist/index.js +139 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/interfaces/collection.d.ts +119 -0
  118. package/dist/interfaces/collection.d.ts.map +1 -0
  119. package/dist/interfaces/collection.js +8 -0
  120. package/dist/interfaces/collection.js.map +1 -0
  121. package/dist/interfaces/list.d.ts +247 -0
  122. package/dist/interfaces/list.d.ts.map +1 -0
  123. package/dist/interfaces/list.js +8 -0
  124. package/dist/interfaces/list.js.map +1 -0
  125. package/dist/interfaces/map.d.ts +344 -0
  126. package/dist/interfaces/map.d.ts.map +1 -0
  127. package/dist/interfaces/map.js +8 -0
  128. package/dist/interfaces/map.js.map +1 -0
  129. package/dist/interfaces/queue.d.ts +304 -0
  130. package/dist/interfaces/queue.d.ts.map +1 -0
  131. package/dist/interfaces/queue.js +8 -0
  132. package/dist/interfaces/queue.js.map +1 -0
  133. package/dist/interfaces/set.d.ts +137 -0
  134. package/dist/interfaces/set.d.ts.map +1 -0
  135. package/dist/interfaces/set.js +8 -0
  136. package/dist/interfaces/set.js.map +1 -0
  137. package/dist/register.d.ts +8 -0
  138. package/dist/register.d.ts.map +1 -0
  139. package/dist/register.js +8 -0
  140. package/dist/register.js.map +1 -0
  141. package/dist/storage/index.d.ts +15 -0
  142. package/dist/storage/index.d.ts.map +1 -0
  143. package/dist/storage/index.js +14 -0
  144. package/dist/storage/index.js.map +1 -0
  145. package/dist/storage/interface.d.ts +141 -0
  146. package/dist/storage/interface.d.ts.map +1 -0
  147. package/dist/storage/interface.js +23 -0
  148. package/dist/storage/interface.js.map +1 -0
  149. package/dist/storage/memory.d.ts +68 -0
  150. package/dist/storage/memory.d.ts.map +1 -0
  151. package/dist/storage/memory.js +154 -0
  152. package/dist/storage/memory.js.map +1 -0
  153. package/dist/utils/defaults.d.ts +135 -0
  154. package/dist/utils/defaults.d.ts.map +1 -0
  155. package/dist/utils/defaults.js +322 -0
  156. package/dist/utils/defaults.js.map +1 -0
  157. package/dist/utils/factories.d.ts +144 -0
  158. package/dist/utils/factories.d.ts.map +1 -0
  159. package/dist/utils/factories.js +293 -0
  160. package/dist/utils/factories.js.map +1 -0
  161. package/dist/utils/helpers.d.ts +137 -0
  162. package/dist/utils/helpers.d.ts.map +1 -0
  163. package/dist/utils/helpers.js +221 -0
  164. package/dist/utils/helpers.js.map +1 -0
  165. package/package.json +68 -3
  166. package/src/async/async-queue.ts +417 -0
  167. package/src/async/channels.ts +374 -0
  168. package/src/behaviors/bounded.ts +477 -0
  169. package/src/behaviors/composite.ts +99 -0
  170. package/src/behaviors/evented.ts +464 -0
  171. package/src/behaviors/lru.ts +447 -0
  172. package/src/behaviors/readonly.ts +224 -0
  173. package/src/behaviors/safe.ts +372 -0
  174. package/src/behaviors/synchronized.ts +316 -0
  175. package/src/behaviors/ttl.ts +462 -0
  176. package/src/contracts/model.ts +44 -0
  177. package/src/core/effects.ts +323 -0
  178. package/src/core/events.ts +356 -0
  179. package/src/core/middleware.ts +415 -0
  180. package/src/core/policies.ts +316 -0
  181. package/src/core/traits.ts +164 -0
  182. package/src/fx/collectors.ts +500 -0
  183. package/src/fx/iter.ts +536 -0
  184. package/src/impl/array-deque.ts +463 -0
  185. package/src/impl/array-list.ts +490 -0
  186. package/src/impl/hash-map.ts +623 -0
  187. package/src/impl/hash-set.ts +342 -0
  188. package/src/impl/linked-hash-map.ts +572 -0
  189. package/src/impl/linked-list.ts +606 -0
  190. package/src/impl/priority-queue.ts +448 -0
  191. package/src/impl/tree-map.ts +912 -0
  192. package/src/impl/tree-set.ts +469 -0
  193. package/src/index.ts +277 -0
  194. package/src/interfaces/collection.ts +141 -0
  195. package/src/interfaces/list.ts +281 -0
  196. package/src/interfaces/map.ts +405 -0
  197. package/src/interfaces/queue.ts +353 -0
  198. package/src/interfaces/set.ts +158 -0
  199. package/src/register.ts +8 -0
  200. package/src/storage/index.ts +16 -0
  201. package/src/storage/interface.ts +179 -0
  202. package/src/storage/memory.ts +180 -0
  203. package/src/utils/defaults.ts +345 -0
  204. package/src/utils/factories.ts +357 -0
  205. package/src/utils/helpers.ts +248 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # @procedures/collections
2
+
3
+ ## 0.2.0
4
+
5
+ No changes in this release.
6
+
7
+ ## 0.1.0
8
+
9
+ The first release on npm. The packages of the client monorepo have one version together.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 Mark Russell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,395 @@
1
- # Temporary Holding Version
1
+ # @procedures/collections
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![npm](https://img.shields.io/npm/v/@procedures/collections?color=2346c4&label=npm)](https://www.npmjs.com/package/@procedures/collections)
4
+
5
+ A comprehensive, transport-agnostic collections framework for TypeScript. Provides unified abstractions for data structures with pluggable storage backends, enabling seamless switching between local and remote storage.
6
+
7
+ ## Architecture Overview
8
+
9
+ ```
10
+ ┌─────────────────────────────────────────────────────────────────────────────┐
11
+ │ Application Layer │
12
+ │ │
13
+ │ ArrayList<T> HashMap<K,V> TreeSet<T> PriorityQueue<T> ... │
14
+ └─────────────────────────────────┬───────────────────────────────────────────┘
15
+ │
16
+ ┌─────────────────────────────────▼───────────────────────────────────────────┐
17
+ │ Behavior Decorators │
18
+ │ │
19
+ │ Bounded LRU TTL Evented Synchronized ReadOnly Safe │
20
+ └─────────────────────────────────┬───────────────────────────────────────────┘
21
+ │
22
+ ┌─────────────────────────────────▼───────────────────────────────────────────┐
23
+ │ CollectionStorage<T> │
24
+ │ │
25
+ │ get() set() delete() find() getAll() setBatch() deleteBatch() ... │
26
+ └─────────────────────────────────┬───────────────────────────────────────────┘
27
+ │
28
+ ┌───────────────────────┼───────────────────────┐
29
+ │ │ │
30
+ ▼ ▼ ▼
31
+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
32
+ │ MemoryStorage │ │ ApiStorage │ │ HybridStorage │
33
+ │ │ │ │ │ │
34
+ │ In-memory Map │ │ Remote via RPC │ │ Local + Remote │
35
+ │ Fast, volatile │ │ Persistent │ │ With sync │
36
+ └─────────────────┘ └─────────────────┘ └─────────────────┘
37
+ ```
38
+
39
+ ## Key Design Principles
40
+
41
+ ### Transport Agnosticism
42
+
43
+ All storage methods return `Promise<T>`, ensuring client code cannot distinguish between local and remote storage:
44
+
45
+ ```typescript
46
+ // This code works identically whether storage is local or remote
47
+ const user = await storage.get("user-123");
48
+ await storage.set("user-456", { name: "Alice" });
49
+ const active = await storage.find(u => u.status === "active");
50
+ ```
51
+
52
+ ### Composable Behaviors
53
+
54
+ Behaviors can be stacked to add functionality:
55
+
56
+ ```typescript
57
+ import { ArrayList, withBounded, withLRU, withEvented } from "@procedures/collections";
58
+
59
+ // Create a bounded, LRU-evicting, event-emitting list
60
+ const list = withEvented(
61
+ withLRU(
62
+ withBounded(new ArrayList<User>(), { maxSize: 1000 }),
63
+ { maxAge: 3600000 }
64
+ )
65
+ );
66
+
67
+ list.on("add", (item) => console.log("Added:", item));
68
+ list.on("evict", (item) => console.log("Evicted:", item));
69
+ ```
70
+
71
+ ## Installation
72
+
73
+ ```bash
74
+ pnpm add @procedures/collections
75
+ ```
76
+
77
+ ## Core Interfaces
78
+
79
+ ### CollectionStorage<T>
80
+
81
+ The foundational storage interface that all backends implement:
82
+
83
+ ```typescript
84
+ interface CollectionStorage<T> {
85
+ // Read Operations
86
+ get(id: string): Promise<T | undefined>;
87
+ getAll(): Promise<T[]>;
88
+ find(predicate: (item: T) => boolean): Promise<T[]>;
89
+ has(id: string): Promise<boolean>;
90
+ size(): Promise<number>;
91
+
92
+ // Write Operations
93
+ set(id: string, value: T): Promise<void>;
94
+ delete(id: string): Promise<boolean>;
95
+ clear(): Promise<void>;
96
+
97
+ // Bulk Operations
98
+ setBatch(items: Array<[string, T]>): Promise<void>;
99
+ deleteBatch(ids: string[]): Promise<number>;
100
+ getBatch(ids: string[]): Promise<Map<string, T>>;
101
+
102
+ // Lifecycle
103
+ close(): Promise<void>;
104
+ getMetadata?(): Promise<StorageMetadata>;
105
+ }
106
+ ```
107
+
108
+ ## Storage Backends
109
+
110
+ ### MemoryStorage
111
+
112
+ Fast, in-memory storage using JavaScript Map:
113
+
114
+ ```typescript
115
+ import { MemoryStorage } from "@procedures/collections";
116
+
117
+ const storage = new MemoryStorage<User>();
118
+ await storage.set("user-1", { name: "Alice", age: 30 });
119
+ const user = await storage.get("user-1");
120
+ ```
121
+
122
+ ### ApiStorage
123
+
124
+ Remote storage via RPC client:
125
+
126
+ ```typescript
127
+ import { ApiStorage } from "@procedures/collections";
128
+ import { Client } from "@procedures/client";
129
+
130
+ const client = new Client({ transport });
131
+ const storage = new ApiStorage<User>(client, {
132
+ collection: "users",
133
+ endpoints: {
134
+ get: { service: "users", operation: "get" },
135
+ set: { service: "users", operation: "set" },
136
+ // ... other endpoints
137
+ }
138
+ });
139
+ ```
140
+
141
+ ### HybridStorage
142
+
143
+ Local cache with remote synchronization:
144
+
145
+ ```typescript
146
+ import { HybridStorage, MemoryStorage, ApiStorage } from "@procedures/collections";
147
+
148
+ const hybrid = new HybridStorage<User>({
149
+ local: new MemoryStorage<User>(),
150
+ remote: apiStorage,
151
+ syncStrategy: "write-through", // or "write-behind"
152
+ conflictResolver: (local, remote) => remote.updatedAt > local.updatedAt ? remote : local
153
+ });
154
+ ```
155
+
156
+ ## Collection Implementations
157
+
158
+ ### Lists
159
+
160
+ ```typescript
161
+ import { ArrayList, LinkedList } from "@procedures/collections";
162
+
163
+ const arrayList = new ArrayList<number>(); // O(1) random access
164
+ const linkedList = new LinkedList<number>(); // O(1) insertions
165
+ ```
166
+
167
+ ### Maps
168
+
169
+ ```typescript
170
+ import { HashMap, TreeMap, LinkedHashMap } from "@procedures/collections";
171
+
172
+ const hashMap = new HashMap<string, User>(); // O(1) access
173
+ const treeMap = new TreeMap<string, User>(); // Sorted keys
174
+ const linkedHashMap = new LinkedHashMap<string, User>(); // Insertion order
175
+ ```
176
+
177
+ ### Sets
178
+
179
+ ```typescript
180
+ import { HashSet, TreeSet } from "@procedures/collections";
181
+
182
+ const hashSet = new HashSet<string>(); // O(1) membership
183
+ const treeSet = new TreeSet<number>(); // Sorted, O(log n)
184
+ ```
185
+
186
+ ### Queues
187
+
188
+ ```typescript
189
+ import { PriorityQueue, ArrayDeque } from "@procedures/collections";
190
+
191
+ const pq = new PriorityQueue<Task>((a, b) => a.priority - b.priority);
192
+ const deque = new ArrayDeque<Message>(); // Double-ended queue
193
+ ```
194
+
195
+ ## Behavior Decorators
196
+
197
+ ### Bounded Collections
198
+
199
+ ```typescript
200
+ import { withBounded } from "@procedures/collections";
201
+
202
+ const bounded = withBounded(new ArrayList<Log>(), {
203
+ maxSize: 10000,
204
+ evictionPolicy: "oldest" // or "newest", "random"
205
+ });
206
+ ```
207
+
208
+ ### LRU Cache
209
+
210
+ ```typescript
211
+ import { withLRU } from "@procedures/collections";
212
+
213
+ const lru = withLRU(new HashMap<string, Session>(), {
214
+ maxSize: 1000,
215
+ maxAge: 3600000 // 1 hour TTL
216
+ });
217
+ ```
218
+
219
+ ### TTL (Time-To-Live)
220
+
221
+ ```typescript
222
+ import { withTTL } from "@procedures/collections";
223
+
224
+ const ttl = withTTL(new HashMap<string, Token>(), {
225
+ defaultTTL: 300000, // 5 minutes
226
+ checkInterval: 60000 // Check every minute
227
+ });
228
+ ```
229
+
230
+ ### Event Emission
231
+
232
+ ```typescript
233
+ import { withEvented } from "@procedures/collections";
234
+
235
+ const evented = withEvented(new ArrayList<Order>());
236
+
237
+ evented.on("add", (item, index) => audit.log("order_added", item));
238
+ evented.on("remove", (item) => audit.log("order_removed", item));
239
+ evented.on("clear", () => audit.log("orders_cleared"));
240
+ ```
241
+
242
+ ### Thread Safety (Synchronized)
243
+
244
+ ```typescript
245
+ import { withSynchronized } from "@procedures/collections";
246
+
247
+ const sync = withSynchronized(new HashMap<string, Counter>());
248
+ // All operations are automatically locked
249
+ ```
250
+
251
+ ## Async Utilities
252
+
253
+ ### AsyncQueue
254
+
255
+ ```typescript
256
+ import { AsyncQueue } from "@procedures/collections";
257
+
258
+ const queue = new AsyncQueue<Job>();
259
+
260
+ // Producer
261
+ await queue.enqueue({ id: 1, task: "process" });
262
+
263
+ // Consumer (blocks until item available)
264
+ const job = await queue.dequeue();
265
+ ```
266
+
267
+ ### Channels (Go-style)
268
+
269
+ ```typescript
270
+ import { Channel } from "@procedures/collections";
271
+
272
+ const ch = new Channel<Message>(10); // Buffered channel
273
+
274
+ // Send (blocks if buffer full)
275
+ await ch.send({ type: "hello" });
276
+
277
+ // Receive (blocks if empty)
278
+ const msg = await ch.receive();
279
+
280
+ // Close channel
281
+ ch.close();
282
+ ```
283
+
284
+ ## Functional Utilities
285
+
286
+ ### Iteration
287
+
288
+ ```typescript
289
+ import { iter } from "@procedures/collections";
290
+
291
+ const result = iter([1, 2, 3, 4, 5])
292
+ .filter(n => n % 2 === 0)
293
+ .map(n => n * 2)
294
+ .take(2)
295
+ .collect();
296
+ // [4, 8]
297
+ ```
298
+
299
+ ### Collectors
300
+
301
+ ```typescript
302
+ import { collect, toMap, groupBy, partition } from "@procedures/collections";
303
+
304
+ const users = [/* ... */];
305
+
306
+ const byId = collect(users, toMap(u => u.id));
307
+ const byRole = collect(users, groupBy(u => u.role));
308
+ const [admins, others] = collect(users, partition(u => u.isAdmin));
309
+ ```
310
+
311
+ ## Data Flow Diagram
312
+
313
+ ```
314
+ ┌──────────────────────────────────────────────────────────────────┐
315
+ │ Client Application │
316
+ │ │
317
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
318
+ │ │ Users │ │ Orders │ │ Products │ │
319
+ │ │ Collection │ │ Collection │ │ Collection │ │
320
+ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
321
+ │ │ │ │ │
322
+ │ └────────────────┼────────────────┘ │
323
+ │ │ │
324
+ │ ▼ │
325
+ │ ┌───────────────────────┐ │
326
+ │ │ HybridStorage<T> │ │
327
+ │ │ ┌─────────────────┐ │ │
328
+ │ │ │ MemoryStorage │◄─┼── Fast reads │
329
+ │ │ │ (L1 Cache) │ │ │
330
+ │ │ └────────┬────────┘ │ │
331
+ │ │ │ sync │ │
332
+ │ │ ┌────────▼────────┐ │ │
333
+ │ │ │ ApiStorage │◄─┼── Persistent writes │
334
+ │ │ │ (Remote) │ │ │
335
+ │ │ └─────────────────┘ │ │
336
+ │ └───────────────────────┘ │
337
+ └──────────────────────────────────────────────────────────────────┘
338
+ │
339
+ │ HTTP/WebSocket
340
+ ▼
341
+ ┌──────────────────────────────────────────────────────────────────┐
342
+ │ Remote Server │
343
+ │ │
344
+ │ ┌───────────────────────┐ │
345
+ │ │ MongoStorage<T> │ (from client-mongo) │
346
+ │ │ │ │
347
+ │ │ Implements │ │
348
+ │ │ CollectionStorage<T> │ │
349
+ │ └───────────┬───────────┘ │
350
+ │ │ │
351
+ │ ▼ │
352
+ │ ┌───────────────────────┐ │
353
+ │ │ MongoDB │ │
354
+ │ └───────────────────────┘ │
355
+ └──────────────────────────────────────────────────────────────────┘
356
+ ```
357
+
358
+ ## Integration with MongoDB
359
+
360
+ The `client-mongo` package provides `MongoStorage<T>` implementing `CollectionStorage<T>`:
361
+
362
+ ```typescript
363
+ import { MongoStorage } from "@procedures/mongo";
364
+ import { HybridStorage, MemoryStorage } from "@procedures/collections";
365
+
366
+ // MongoDB-backed storage
367
+ const mongoStorage = new MongoStorage<User>({ collection: "users" });
368
+
369
+ // Or hybrid with local cache
370
+ const hybrid = new HybridStorage<User>({
371
+ local: new MemoryStorage<User>(),
372
+ remote: mongoStorage
373
+ });
374
+ ```
375
+
376
+ ## API Reference
377
+
378
+ ### StorageMetadata
379
+
380
+ ```typescript
381
+ interface StorageMetadata {
382
+ type: "memory" | "api" | "hybrid" | "synced" | "custom";
383
+ size: number;
384
+ stats?: {
385
+ hitRate?: number; // Cache hit rate
386
+ lastSync?: number; // Last sync timestamp
387
+ pendingOps?: number; // Pending sync operations
388
+ memoryUsage?: number; // Memory in bytes
389
+ };
390
+ }
391
+ ```
392
+
393
+ ## License
394
+
395
+ MIT