effect 2.0.2 → 2.0.4

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 (127) hide show
  1. package/Cron/package.json +6 -0
  2. package/FiberMap/package.json +6 -0
  3. package/FiberSet/package.json +6 -0
  4. package/Trie/package.json +6 -0
  5. package/dist/cjs/Cron.js +457 -0
  6. package/dist/cjs/Cron.js.map +1 -0
  7. package/dist/cjs/Fiber.js.map +1 -1
  8. package/dist/cjs/FiberMap.js +176 -0
  9. package/dist/cjs/FiberMap.js.map +1 -0
  10. package/dist/cjs/FiberSet.js +150 -0
  11. package/dist/cjs/FiberSet.js.map +1 -0
  12. package/dist/cjs/MutableHashMap.js +11 -1
  13. package/dist/cjs/MutableHashMap.js.map +1 -1
  14. package/dist/cjs/MutableHashSet.js +7 -1
  15. package/dist/cjs/MutableHashSet.js.map +1 -1
  16. package/dist/cjs/MutableList.js +8 -11
  17. package/dist/cjs/MutableList.js.map +1 -1
  18. package/dist/cjs/Schedule.js +12 -1
  19. package/dist/cjs/Schedule.js.map +1 -1
  20. package/dist/cjs/Struct.js +16 -1
  21. package/dist/cjs/Struct.js.map +1 -1
  22. package/dist/cjs/Trie.js +680 -0
  23. package/dist/cjs/Trie.js.map +1 -0
  24. package/dist/cjs/index.js +10 -2
  25. package/dist/cjs/index.js.map +1 -1
  26. package/dist/cjs/internal/hashMap/node.js +2 -2
  27. package/dist/cjs/internal/hashMap/node.js.map +1 -1
  28. package/dist/cjs/internal/pubsub.js +11 -17
  29. package/dist/cjs/internal/pubsub.js.map +1 -1
  30. package/dist/cjs/internal/redBlackTree/node.js +35 -30
  31. package/dist/cjs/internal/redBlackTree/node.js.map +1 -1
  32. package/dist/cjs/internal/redBlackTree.js +69 -13
  33. package/dist/cjs/internal/redBlackTree.js.map +1 -1
  34. package/dist/cjs/internal/schedule.js +29 -2
  35. package/dist/cjs/internal/schedule.js.map +1 -1
  36. package/dist/cjs/internal/stack.js +6 -11
  37. package/dist/cjs/internal/stack.js.map +1 -1
  38. package/dist/cjs/internal/trie.js +588 -0
  39. package/dist/cjs/internal/trie.js.map +1 -0
  40. package/dist/cjs/internal/version.js +1 -1
  41. package/dist/dts/Cron.d.ts +170 -0
  42. package/dist/dts/Cron.d.ts.map +1 -0
  43. package/dist/dts/Fiber.d.ts +6 -0
  44. package/dist/dts/Fiber.d.ts.map +1 -1
  45. package/dist/dts/FiberMap.d.ts +125 -0
  46. package/dist/dts/FiberMap.d.ts.map +1 -0
  47. package/dist/dts/FiberSet.d.ts +99 -0
  48. package/dist/dts/FiberSet.d.ts.map +1 -0
  49. package/dist/dts/MutableHashMap.d.ts +4 -0
  50. package/dist/dts/MutableHashMap.d.ts.map +1 -1
  51. package/dist/dts/MutableHashSet.d.ts +5 -0
  52. package/dist/dts/MutableHashSet.d.ts.map +1 -1
  53. package/dist/dts/MutableList.d.ts.map +1 -1
  54. package/dist/dts/Schedule.d.ts +12 -0
  55. package/dist/dts/Schedule.d.ts.map +1 -1
  56. package/dist/dts/Struct.d.ts +17 -3
  57. package/dist/dts/Struct.d.ts.map +1 -1
  58. package/dist/dts/Trie.d.ts +740 -0
  59. package/dist/dts/Trie.d.ts.map +1 -0
  60. package/dist/dts/Types.d.ts +4 -0
  61. package/dist/dts/Types.d.ts.map +1 -1
  62. package/dist/dts/index.d.ts +30 -0
  63. package/dist/dts/index.d.ts.map +1 -1
  64. package/dist/dts/internal/redBlackTree/node.d.ts +8 -0
  65. package/dist/dts/internal/redBlackTree/node.d.ts.map +1 -1
  66. package/dist/dts/internal/stack.d.ts +1 -1
  67. package/dist/dts/internal/stack.d.ts.map +1 -1
  68. package/dist/dts/internal/trie.d.ts +2 -0
  69. package/dist/dts/internal/trie.d.ts.map +1 -0
  70. package/dist/dts/internal/version.d.ts +1 -1
  71. package/dist/esm/Cron.js +418 -0
  72. package/dist/esm/Cron.js.map +1 -0
  73. package/dist/esm/Fiber.js.map +1 -1
  74. package/dist/esm/FiberMap.js +140 -0
  75. package/dist/esm/FiberMap.js.map +1 -0
  76. package/dist/esm/FiberSet.js +114 -0
  77. package/dist/esm/FiberSet.js.map +1 -0
  78. package/dist/esm/MutableHashMap.js +9 -0
  79. package/dist/esm/MutableHashMap.js.map +1 -1
  80. package/dist/esm/MutableHashSet.js +5 -0
  81. package/dist/esm/MutableHashSet.js.map +1 -1
  82. package/dist/esm/MutableList.js +8 -11
  83. package/dist/esm/MutableList.js.map +1 -1
  84. package/dist/esm/Schedule.js +11 -0
  85. package/dist/esm/Schedule.js.map +1 -1
  86. package/dist/esm/Struct.js +14 -0
  87. package/dist/esm/Struct.js.map +1 -1
  88. package/dist/esm/Trie.js +648 -0
  89. package/dist/esm/Trie.js.map +1 -0
  90. package/dist/esm/index.js +30 -0
  91. package/dist/esm/index.js.map +1 -1
  92. package/dist/esm/internal/hashMap/node.js +2 -2
  93. package/dist/esm/internal/hashMap/node.js.map +1 -1
  94. package/dist/esm/internal/pubsub.js +11 -17
  95. package/dist/esm/internal/pubsub.js.map +1 -1
  96. package/dist/esm/internal/redBlackTree/node.js +31 -25
  97. package/dist/esm/internal/redBlackTree/node.js.map +1 -1
  98. package/dist/esm/internal/redBlackTree.js +69 -13
  99. package/dist/esm/internal/redBlackTree.js.map +1 -1
  100. package/dist/esm/internal/schedule.js +26 -0
  101. package/dist/esm/internal/schedule.js.map +1 -1
  102. package/dist/esm/internal/stack.js +4 -9
  103. package/dist/esm/internal/stack.js.map +1 -1
  104. package/dist/esm/internal/trie.js +547 -0
  105. package/dist/esm/internal/trie.js.map +1 -0
  106. package/dist/esm/internal/version.js +1 -1
  107. package/package.json +33 -1
  108. package/src/Cron.ts +525 -0
  109. package/src/Fiber.ts +7 -0
  110. package/src/FiberMap.ts +269 -0
  111. package/src/FiberSet.ts +194 -0
  112. package/src/MutableHashMap.ts +10 -0
  113. package/src/MutableHashSet.ts +6 -0
  114. package/src/MutableList.ts +15 -7
  115. package/src/Schedule.ts +13 -0
  116. package/src/Struct.ts +24 -6
  117. package/src/Trie.ts +772 -0
  118. package/src/Types.ts +5 -0
  119. package/src/index.ts +34 -0
  120. package/src/internal/hashMap/node.ts +3 -3
  121. package/src/internal/pubsub.ts +15 -14
  122. package/src/internal/redBlackTree/node.ts +37 -17
  123. package/src/internal/redBlackTree.ts +73 -38
  124. package/src/internal/schedule.ts +42 -0
  125. package/src/internal/stack.ts +8 -2
  126. package/src/internal/trie.ts +721 -0
  127. package/src/internal/version.ts +1 -1
@@ -0,0 +1,721 @@
1
+ import * as Equal from "../Equal.js"
2
+ import { dual, identity, pipe } from "../Function.js"
3
+ import * as Hash from "../Hash.js"
4
+ import { format, NodeInspectSymbol, toJSON } from "../Inspectable.js"
5
+ import * as Option from "../Option.js"
6
+ import type * as Ordering from "../Ordering.js"
7
+ import { pipeArguments } from "../Pipeable.js"
8
+ import { hasProperty } from "../Predicate.js"
9
+ import type * as TR from "../Trie.js"
10
+
11
+ const TrieSymbolKey = "effect/Trie"
12
+
13
+ /** @internal */
14
+ export const TrieTypeId: TR.TypeId = Symbol.for(TrieSymbolKey) as TR.TypeId
15
+
16
+ type TraversalMap<K, V, A> = (k: K, v: V) => A
17
+
18
+ type TraversalFilter<K, V> = (k: K, v: V) => boolean
19
+
20
+ /** @internal */
21
+ export interface TrieImpl<in out V> extends TR.Trie<V> {
22
+ readonly _root: Node<V> | undefined
23
+ readonly _count: number
24
+ }
25
+
26
+ const trieVariance = {
27
+ /* c8 ignore next */
28
+ _Value: (_: never) => _
29
+ }
30
+
31
+ const TrieProto: TR.Trie<unknown> = {
32
+ [TrieTypeId]: trieVariance,
33
+ [Symbol.iterator]<V>(this: TrieImpl<V>): Iterator<[string, V]> {
34
+ return new TrieIterator(this, (k, v) => [k, v], () => true)
35
+ },
36
+ [Hash.symbol](): number {
37
+ let hash = Hash.hash(TrieSymbolKey)
38
+ for (const item of this) {
39
+ hash ^= pipe(Hash.hash(item[0]), Hash.combine(Hash.hash(item[1])))
40
+ }
41
+ return hash
42
+ },
43
+ [Equal.symbol]<V>(this: TrieImpl<V>, that: unknown): boolean {
44
+ if (isTrie(that)) {
45
+ const entries = Array.from(that)
46
+ return Array.from(this).every((itemSelf, i) => {
47
+ const itemThat = entries[i]
48
+ return Equal.equals(itemSelf[0], itemThat[0]) && Equal.equals(itemSelf[1], itemThat[1])
49
+ })
50
+ }
51
+ return false
52
+ },
53
+ toString() {
54
+ return format(this.toJSON())
55
+ },
56
+ toJSON() {
57
+ return {
58
+ _id: "Trie",
59
+ values: Array.from(this).map(toJSON)
60
+ }
61
+ },
62
+ [NodeInspectSymbol]() {
63
+ return this.toJSON()
64
+ },
65
+ pipe() {
66
+ return pipeArguments(this, arguments)
67
+ }
68
+ }
69
+
70
+ const makeImpl = <V>(root: Node<V> | undefined): TrieImpl<V> => {
71
+ const trie = Object.create(TrieProto)
72
+ trie._root = root
73
+ trie._count = root?.count ?? 0
74
+ return trie
75
+ }
76
+
77
+ class TrieIterator<in out V, out T> implements IterableIterator<T> {
78
+ stack: Array<[Node<V>, string, boolean]> = []
79
+
80
+ constructor(
81
+ readonly trie: TrieImpl<V>,
82
+ readonly f: TraversalMap<string, V, T>,
83
+ readonly filter: TraversalFilter<string, V>
84
+ ) {
85
+ const root = trie._root !== undefined ? trie._root : undefined
86
+ if (root !== undefined) {
87
+ this.stack.push([root, "", false])
88
+ }
89
+ }
90
+
91
+ next(): IteratorResult<T> {
92
+ while (this.stack.length > 0) {
93
+ const [node, keyString, isAdded] = this.stack.pop()!
94
+
95
+ if (isAdded) {
96
+ const value = node.value
97
+ if (value !== undefined) {
98
+ const key = keyString + node.key
99
+ if (this.filter(key, value)) {
100
+ return { done: false, value: this.f(key, value) }
101
+ }
102
+ }
103
+ } else {
104
+ this.addToStack(node, keyString)
105
+ }
106
+ }
107
+
108
+ return { done: true, value: undefined }
109
+ }
110
+
111
+ addToStack(node: Node<V>, keyString: string) {
112
+ if (node.right !== undefined) {
113
+ this.stack.push([node.right, keyString, false])
114
+ }
115
+ if (node.mid !== undefined) {
116
+ this.stack.push([node.mid, keyString + node.key, false])
117
+ }
118
+ this.stack.push([node, keyString, true])
119
+ if (node.left !== undefined) {
120
+ this.stack.push([node.left, keyString, false])
121
+ }
122
+ }
123
+
124
+ [Symbol.iterator](): IterableIterator<T> {
125
+ return new TrieIterator(this.trie, this.f, this.filter)
126
+ }
127
+ }
128
+
129
+ /** @internal */
130
+ export const isTrie: {
131
+ <V>(u: Iterable<readonly [string, V]>): u is TR.Trie<V>
132
+ (u: unknown): u is TR.Trie<unknown>
133
+ } = (u: unknown): u is TR.Trie<unknown> => hasProperty(u, TrieTypeId)
134
+
135
+ /** @internal */
136
+ export const empty = <V = never>(): TR.Trie<V> => makeImpl<V>(undefined)
137
+
138
+ /** @internal */
139
+ export const fromIterable = <V>(entries: Iterable<readonly [string, V]>) => {
140
+ let trie = empty<V>()
141
+ for (const [key, value] of entries) {
142
+ trie = insert(trie, key, value)
143
+ }
144
+ return trie
145
+ }
146
+
147
+ /** @internal */
148
+ export const make = <Entries extends Array<readonly [string, any]>>(...entries: Entries): TR.Trie<
149
+ Entries[number] extends readonly [any, infer V] ? V : never
150
+ > => {
151
+ return fromIterable(entries)
152
+ }
153
+
154
+ /** @internal */
155
+ export const insert = dual<
156
+ <V>(key: string, value: V) => (self: TR.Trie<V>) => TR.Trie<V>,
157
+ <V>(self: TR.Trie<V>, key: string, value: V) => TR.Trie<V>
158
+ >(3, <V>(self: TR.Trie<V>, key: string, value: V) => {
159
+ if (key.length === 0) return self
160
+
161
+ // -1:left | 0:mid | 1:right
162
+ const dStack: Array<Ordering.Ordering> = []
163
+ const nStack: Array<Node<V>> = []
164
+ let n: Node<V> = (self as TrieImpl<V>)._root ?? {
165
+ key: key[0],
166
+ count: 0
167
+ }
168
+ const count = n.count + 1
169
+ let cIndex = 0
170
+
171
+ while (cIndex < key.length) {
172
+ const c = key[cIndex]
173
+ nStack.push(n)
174
+ if (c > n.key) {
175
+ dStack.push(1)
176
+ if (n.right === undefined) {
177
+ n = { key: c, count }
178
+ } else {
179
+ n = n.right
180
+ }
181
+ } else if (c < n.key) {
182
+ dStack.push(-1)
183
+ if (n.left === undefined) {
184
+ n = { key: c, count }
185
+ } else {
186
+ n = n.left
187
+ }
188
+ } else {
189
+ if (cIndex === key.length - 1) {
190
+ n.value = value
191
+ } else if (n.mid === undefined) {
192
+ dStack.push(0)
193
+ n = { key: key[cIndex + 1], count }
194
+ } else {
195
+ dStack.push(0)
196
+ n = n.mid
197
+ }
198
+
199
+ cIndex += 1
200
+ }
201
+ }
202
+
203
+ // Rebuild path to leaf node (Path-copying immutability)
204
+ for (let s = nStack.length - 2; s >= 0; --s) {
205
+ const n2 = nStack[s]
206
+ const d = dStack[s]
207
+ if (d === -1) {
208
+ // left
209
+ nStack[s] = {
210
+ key: n2.key,
211
+ count,
212
+ value: n2.value,
213
+ left: nStack[s + 1],
214
+ mid: n2.mid,
215
+ right: n2.right
216
+ }
217
+ } else if (d === 1) {
218
+ // right
219
+ nStack[s] = {
220
+ key: n2.key,
221
+ count,
222
+ value: n2.value,
223
+ left: n2.left,
224
+ mid: n2.mid,
225
+ right: nStack[s + 1]
226
+ }
227
+ } else {
228
+ // mid
229
+ nStack[s] = {
230
+ key: n2.key,
231
+ count,
232
+ value: n2.value,
233
+ left: n2.left,
234
+ mid: nStack[s + 1],
235
+ right: n2.right
236
+ }
237
+ }
238
+ }
239
+
240
+ nStack[0].count = count
241
+ return makeImpl(nStack[0])
242
+ })
243
+
244
+ /** @internal */
245
+ export const size = <V>(self: TR.Trie<V>): number => (self as TrieImpl<V>)._root?.count ?? 0
246
+
247
+ /** @internal */
248
+ export const isEmpty = <V>(self: TR.Trie<V>): boolean => size(self) === 0
249
+
250
+ /** @internal */
251
+ export const keys = <V>(self: TR.Trie<V>): IterableIterator<string> =>
252
+ new TrieIterator(self as TrieImpl<V>, (key) => key, () => true)
253
+
254
+ /** @internal */
255
+ export const values = <V>(self: TR.Trie<V>): IterableIterator<V> =>
256
+ new TrieIterator(self as TrieImpl<V>, (_, value) => value, () => true)
257
+
258
+ /** @internal */
259
+ export const entries = <V>(self: TR.Trie<V>): IterableIterator<[string, V]> =>
260
+ new TrieIterator(self as TrieImpl<V>, (key, value) => [key, value], () => true)
261
+
262
+ /** @internal */
263
+ export const reduce = dual<
264
+ <Z, V>(
265
+ zero: Z,
266
+ f: (accumulator: Z, value: V, key: string) => Z
267
+ ) => (self: TR.Trie<V>) => Z,
268
+ <Z, V>(self: TR.Trie<V>, zero: Z, f: (accumulator: Z, value: V, key: string) => Z) => Z
269
+ >(3, (self, zero, f) => {
270
+ let accumulator = zero
271
+ for (const entry of self) {
272
+ accumulator = f(accumulator, entry[1], entry[0])
273
+ }
274
+ return accumulator
275
+ })
276
+
277
+ /** @internal */
278
+ export const map = dual<
279
+ <A, V>(f: (value: V, key: string) => A) => (self: TR.Trie<V>) => TR.Trie<A>,
280
+ <V, A>(self: TR.Trie<V>, f: (value: V, key: string) => A) => TR.Trie<A>
281
+ >(2, (self, f) =>
282
+ reduce(
283
+ self,
284
+ empty(),
285
+ (trie, value, key) => insert(trie, key, f(value, key))
286
+ ))
287
+
288
+ /** @internal */
289
+ export const filter: {
290
+ <A, B extends A>(f: (a: A, k: string) => a is B): (self: TR.Trie<A>) => TR.Trie<B>
291
+ <B extends A, A = B>(f: (a: A, k: string) => boolean): (self: TR.Trie<B>) => TR.Trie<B>
292
+ <A, B extends A>(self: TR.Trie<A>, f: (a: A, k: string) => a is B): TR.Trie<B>
293
+ <A>(self: TR.Trie<A>, f: (a: A, k: string) => boolean): TR.Trie<A>
294
+ } = dual(
295
+ 2,
296
+ <A>(self: TR.Trie<A>, f: (a: A, k: string) => boolean): TR.Trie<A> =>
297
+ reduce(
298
+ self,
299
+ empty(),
300
+ (trie, value, key) => f(value, key) ? insert(trie, key, value) : trie
301
+ )
302
+ )
303
+
304
+ /** @internal */
305
+ export const filterMap = dual<
306
+ <A, B>(
307
+ f: (value: A, key: string) => Option.Option<B>
308
+ ) => (self: TR.Trie<A>) => TR.Trie<B>,
309
+ <A, B>(self: TR.Trie<A>, f: (value: A, key: string) => Option.Option<B>) => TR.Trie<B>
310
+ >(2, (self, f) =>
311
+ reduce(
312
+ self,
313
+ empty(),
314
+ (trie, value, key) => {
315
+ const option = f(value, key)
316
+ return Option.isSome(option) ? insert(trie, key, option.value) : trie
317
+ }
318
+ ))
319
+
320
+ /** @internal */
321
+ export const compact = <A>(self: TR.Trie<Option.Option<A>>) => filterMap(self, identity)
322
+
323
+ /** @internal */
324
+ export const forEach = dual<
325
+ <V>(f: (value: V, key: string) => void) => (self: TR.Trie<V>) => void,
326
+ <V>(self: TR.Trie<V>, f: (value: V, key: string) => void) => void
327
+ >(2, (self, f) => reduce(self, void 0 as void, (_, value, key) => f(value, key)))
328
+
329
+ /** @internal */
330
+ export const keysWithPrefix = dual<
331
+ (prefix: string) => <V>(self: TR.Trie<V>) => IterableIterator<string>,
332
+ <V>(self: TR.Trie<V>, prefix: string) => IterableIterator<string>
333
+ >(
334
+ 2,
335
+ <V>(self: TR.Trie<V>, prefix: string): IterableIterator<string> =>
336
+ new TrieIterator(self as TrieImpl<V>, (key) => key, (key) => key.startsWith(prefix))
337
+ )
338
+
339
+ /** @internal */
340
+ export const valuesWithPrefix = dual<
341
+ (prefix: string) => <V>(self: TR.Trie<V>) => IterableIterator<V>,
342
+ <V>(self: TR.Trie<V>, prefix: string) => IterableIterator<V>
343
+ >(
344
+ 2,
345
+ <V>(self: TR.Trie<V>, prefix: string): IterableIterator<V> =>
346
+ new TrieIterator(self as TrieImpl<V>, (_, value) => value, (key) => key.startsWith(prefix))
347
+ )
348
+
349
+ /** @internal */
350
+ export const entriesWithPrefix = dual<
351
+ (prefix: string) => <V>(self: TR.Trie<V>) => IterableIterator<[string, V]>,
352
+ <V>(self: TR.Trie<V>, prefix: string) => IterableIterator<[string, V]>
353
+ >(
354
+ 2,
355
+ <V>(self: TR.Trie<V>, prefix: string): IterableIterator<[string, V]> =>
356
+ new TrieIterator(self as TrieImpl<V>, (key, value) => [key, value], (key) => key.startsWith(prefix))
357
+ )
358
+
359
+ /** @internal */
360
+ export const toEntriesWithPrefix = dual<
361
+ (prefix: string) => <V>(self: TR.Trie<V>) => Array<[string, V]>,
362
+ <V>(self: TR.Trie<V>, prefix: string) => Array<[string, V]>
363
+ >(
364
+ 2,
365
+ <V>(self: TR.Trie<V>, prefix: string): Array<[string, V]> => Array.from(entriesWithPrefix(self, prefix))
366
+ )
367
+
368
+ /** @internal */
369
+ export const get = dual<
370
+ (key: string) => <V>(self: TR.Trie<V>) => Option.Option<V>,
371
+ <V>(self: TR.Trie<V>, key: string) => Option.Option<V>
372
+ >(
373
+ 2,
374
+ <V>(self: TR.Trie<V>, key: string) => {
375
+ let n: Node<V> | undefined = (self as TrieImpl<V>)._root
376
+ if (n === undefined || key.length === 0) return Option.none()
377
+ let cIndex = 0
378
+ while (cIndex < key.length) {
379
+ const c = key[cIndex]
380
+ if (c > n.key) {
381
+ if (n.right === undefined) {
382
+ return Option.none()
383
+ } else {
384
+ n = n.right
385
+ }
386
+ } else if (c < n.key) {
387
+ if (n.left === undefined) {
388
+ return Option.none()
389
+ } else {
390
+ n = n.left
391
+ }
392
+ } else {
393
+ if (cIndex === key.length - 1) {
394
+ return Option.fromNullable(n.value)
395
+ } else {
396
+ if (n.mid === undefined) {
397
+ return Option.none()
398
+ } else {
399
+ n = n.mid
400
+ cIndex += 1
401
+ }
402
+ }
403
+ }
404
+ }
405
+ return Option.none()
406
+ }
407
+ )
408
+
409
+ /** @internal */
410
+ export const has = dual<
411
+ (key: string) => <V>(self: TR.Trie<V>) => boolean,
412
+ <V>(self: TR.Trie<V>, key: string) => boolean
413
+ >(2, (self, key) => Option.isSome(get(self, key)))
414
+
415
+ /** @internal */
416
+ export const unsafeGet = dual<
417
+ (key: string) => <V>(self: TR.Trie<V>) => V,
418
+ <V>(self: TR.Trie<V>, key: string) => V
419
+ >(2, (self, key) => {
420
+ const element = get(self, key)
421
+ if (Option.isNone(element)) {
422
+ throw new Error("Error: Expected trie to contain key")
423
+ }
424
+ return element.value
425
+ })
426
+
427
+ /** @internal */
428
+ export const remove = dual<
429
+ (key: string) => <V>(self: TR.Trie<V>) => TR.Trie<V>,
430
+ <V>(self: TR.Trie<V>, key: string) => TR.Trie<V>
431
+ >(
432
+ 2,
433
+ <V>(self: TR.Trie<V>, key: string) => {
434
+ let n: Node<V> | undefined = (self as TrieImpl<V>)._root
435
+ if (n === undefined || key.length === 0) return self
436
+
437
+ const count = n.count - 1
438
+ // -1:left | 0:mid | 1:right
439
+ const dStack: Array<Ordering.Ordering> = []
440
+ const nStack: Array<Node<V>> = []
441
+
442
+ let cIndex = 0
443
+ while (cIndex < key.length) {
444
+ const c = key[cIndex]
445
+ if (c > n.key) {
446
+ if (n.right === undefined) {
447
+ return self
448
+ } else {
449
+ nStack.push(n)
450
+ dStack.push(1)
451
+ n = n.right
452
+ }
453
+ } else if (c < n.key) {
454
+ if (n.left === undefined) {
455
+ return self
456
+ } else {
457
+ nStack.push(n)
458
+ dStack.push(-1)
459
+ n = n.left
460
+ }
461
+ } else {
462
+ if (cIndex === key.length - 1) {
463
+ if (n.value !== undefined) {
464
+ nStack.push(n)
465
+ dStack.push(0)
466
+ cIndex += 1
467
+ } else {
468
+ return self
469
+ }
470
+ } else {
471
+ if (n.mid === undefined) {
472
+ return self
473
+ } else {
474
+ nStack.push(n)
475
+ dStack.push(0)
476
+ n = n.mid
477
+ cIndex += 1
478
+ }
479
+ }
480
+ }
481
+ }
482
+
483
+ const removeNode = nStack[nStack.length - 1]
484
+ nStack[nStack.length - 1] = {
485
+ key: removeNode.key,
486
+ count,
487
+ left: removeNode.left,
488
+ mid: removeNode.mid,
489
+ right: removeNode.right
490
+ }
491
+
492
+ // Rebuild path to leaf node (Path-copying immutability)
493
+ for (let s = nStack.length - 2; s >= 0; --s) {
494
+ const n2 = nStack[s]
495
+ const d = dStack[s]
496
+ const child = nStack[s + 1]
497
+ const nc = child.left === undefined && child.mid === undefined && child.right === undefined ? undefined : child
498
+ if (d === -1) {
499
+ // left
500
+ nStack[s] = {
501
+ key: n2.key,
502
+ count,
503
+ value: n2.value,
504
+ left: nc,
505
+ mid: n2.mid,
506
+ right: n2.right
507
+ }
508
+ } else if (d === 1) {
509
+ // right
510
+ nStack[s] = {
511
+ key: n2.key,
512
+ count,
513
+ value: n2.value,
514
+ left: n2.left,
515
+ mid: n2.mid,
516
+ right: nc
517
+ }
518
+ } else {
519
+ // mid
520
+ nStack[s] = {
521
+ key: n2.key,
522
+ count,
523
+ value: n2.value,
524
+ left: n2.left,
525
+ mid: nc,
526
+ right: n2.right
527
+ }
528
+ }
529
+ }
530
+
531
+ nStack[0].count = count
532
+ return makeImpl(nStack[0])
533
+ }
534
+ )
535
+
536
+ /** @internal */
537
+ export const removeMany = dual<
538
+ (keys: Iterable<string>) => <V>(self: TR.Trie<V>) => TR.Trie<V>,
539
+ <V>(self: TR.Trie<V>, keys: Iterable<string>) => TR.Trie<V>
540
+ >(2, (self, keys) => {
541
+ let trie = self
542
+ for (const key of keys) {
543
+ trie = remove(key)(trie)
544
+ }
545
+ return trie
546
+ })
547
+
548
+ /** @internal */
549
+ export const insertMany = dual<
550
+ <V>(iter: Iterable<[string, V]>) => (self: TR.Trie<V>) => TR.Trie<V>,
551
+ <V>(self: TR.Trie<V>, iter: Iterable<[string, V]>) => TR.Trie<V>
552
+ >(2, (self, iter) => {
553
+ let trie = self
554
+ for (const [key, value] of iter) {
555
+ trie = insert(key, value)(trie)
556
+ }
557
+ return trie
558
+ })
559
+
560
+ /** @internal */
561
+ export const modify = dual<
562
+ <V>(key: string, f: (v: V) => V) => (self: TR.Trie<V>) => TR.Trie<V>,
563
+ <V>(self: TR.Trie<V>, key: string, f: (v: V) => V) => TR.Trie<V>
564
+ >(
565
+ 3,
566
+ <V>(self: TR.Trie<V>, key: string, f: (v: V) => V): TR.Trie<V> => {
567
+ let n: Node<V> | undefined = (self as TrieImpl<V>)._root
568
+ if (n === undefined || key.length === 0) return self
569
+
570
+ // -1:left | 0:mid | 1:right
571
+ const dStack: Array<Ordering.Ordering> = []
572
+ const nStack: Array<Node<V>> = []
573
+
574
+ let cIndex = 0
575
+ while (cIndex < key.length) {
576
+ const c = key[cIndex]
577
+ if (c > n.key) {
578
+ if (n.right === undefined) {
579
+ return self
580
+ } else {
581
+ nStack.push(n)
582
+ dStack.push(1)
583
+ n = n.right
584
+ }
585
+ } else if (c < n.key) {
586
+ if (n.left === undefined) {
587
+ return self
588
+ } else {
589
+ nStack.push(n)
590
+ dStack.push(-1)
591
+ n = n.left
592
+ }
593
+ } else {
594
+ if (cIndex === key.length - 1) {
595
+ if (n.value !== undefined) {
596
+ nStack.push(n)
597
+ dStack.push(0)
598
+ cIndex += 1
599
+ } else {
600
+ return self
601
+ }
602
+ } else {
603
+ if (n.mid === undefined) {
604
+ return self
605
+ } else {
606
+ nStack.push(n)
607
+ dStack.push(0)
608
+ n = n.mid
609
+ cIndex += 1
610
+ }
611
+ }
612
+ }
613
+ }
614
+
615
+ const updateNode = nStack[nStack.length - 1]
616
+ if (updateNode.value === undefined) {
617
+ return self
618
+ }
619
+
620
+ nStack[nStack.length - 1] = {
621
+ key: updateNode.key,
622
+ count: updateNode.count,
623
+ value: f(updateNode.value), // Update
624
+ left: updateNode.left,
625
+ mid: updateNode.mid,
626
+ right: updateNode.right
627
+ }
628
+
629
+ // Rebuild path to leaf node (Path-copying immutability)
630
+ for (let s = nStack.length - 2; s >= 0; --s) {
631
+ const n2 = nStack[s]
632
+ const d = dStack[s]
633
+ const child = nStack[s + 1]
634
+ if (d === -1) {
635
+ // left
636
+ nStack[s] = {
637
+ key: n2.key,
638
+ count: n2.count,
639
+ value: n2.value,
640
+ left: child,
641
+ mid: n2.mid,
642
+ right: n2.right
643
+ }
644
+ } else if (d === 1) {
645
+ // right
646
+ nStack[s] = {
647
+ key: n2.key,
648
+ count: n2.count,
649
+ value: n2.value,
650
+ left: n2.left,
651
+ mid: n2.mid,
652
+ right: child
653
+ }
654
+ } else {
655
+ // mid
656
+ nStack[s] = {
657
+ key: n2.key,
658
+ count: n2.count,
659
+ value: n2.value,
660
+ left: n2.left,
661
+ mid: child,
662
+ right: n2.right
663
+ }
664
+ }
665
+ }
666
+
667
+ return makeImpl(nStack[0])
668
+ }
669
+ )
670
+
671
+ /** @internal */
672
+ export const longestPrefixOf = dual<
673
+ (key: string) => <V>(self: TR.Trie<V>) => Option.Option<[string, V]>,
674
+ <V>(self: TR.Trie<V>, key: string) => Option.Option<[string, V]>
675
+ >(
676
+ 2,
677
+ <V>(self: TR.Trie<V>, key: string) => {
678
+ let n: Node<V> | undefined = (self as TrieImpl<V>)._root
679
+ if (n === undefined || key.length === 0) return Option.none()
680
+ let longestPrefixNode: [string, V] | undefined = undefined
681
+ let cIndex = 0
682
+ while (cIndex < key.length) {
683
+ const c = key[cIndex]
684
+ if (n.value !== undefined) {
685
+ longestPrefixNode = [key.slice(0, cIndex + 1), n.value]
686
+ }
687
+
688
+ if (c > n.key) {
689
+ if (n.right === undefined) {
690
+ break
691
+ } else {
692
+ n = n.right
693
+ }
694
+ } else if (c < n.key) {
695
+ if (n.left === undefined) {
696
+ break
697
+ } else {
698
+ n = n.left
699
+ }
700
+ } else {
701
+ if (n.mid === undefined) {
702
+ break
703
+ } else {
704
+ n = n.mid
705
+ cIndex += 1
706
+ }
707
+ }
708
+ }
709
+
710
+ return Option.fromNullable(longestPrefixNode)
711
+ }
712
+ )
713
+
714
+ interface Node<V> {
715
+ key: string
716
+ count: number
717
+ value?: V | undefined
718
+ left?: Node<V> | undefined
719
+ mid?: Node<V> | undefined
720
+ right?: Node<V> | undefined
721
+ }
@@ -1 +1 @@
1
- export const moduleVersion = "2.0.2"
1
+ export const moduleVersion = "2.0.4"