mutts 1.0.9 → 1.0.10

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 (204) hide show
  1. package/README.md +58 -33
  2. package/dist/browser.cjs +1371 -1206
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.ts +2 -1392
  5. package/dist/browser.dev.cjs +110 -0
  6. package/dist/browser.dev.cjs.map +1 -0
  7. package/dist/browser.dev.d.ts +2 -0
  8. package/dist/browser.dev.esm.js +5 -0
  9. package/dist/browser.dev.esm.js.map +1 -0
  10. package/dist/browser.esm.js +6 -87
  11. package/dist/browser.esm.js.map +1 -1
  12. package/dist/chunks/{async-browser-lvzLOCgk.cjs → async-browser-BU_IfxYD.cjs} +4 -85
  13. package/dist/chunks/async-browser-BU_IfxYD.cjs.map +1 -0
  14. package/dist/chunks/{async-node-C3DeIb0y.cjs → async-node-3PrbVAbB.cjs} +3 -1
  15. package/dist/chunks/async-node-3PrbVAbB.cjs.map +1 -0
  16. package/dist/chunks/{index-2vea86wD.esm.js → index-CaaQQlPJ.esm.js} +1116 -953
  17. package/dist/chunks/index-CaaQQlPJ.esm.js.map +1 -0
  18. package/dist/chunks/node-nKJBk8iJ.esm.js +96 -0
  19. package/dist/chunks/node-nKJBk8iJ.esm.js.map +1 -0
  20. package/dist/chunks/{index-VTO-b2vR.cjs → proxy-Dtg-bJ3T.cjs} +2285 -2983
  21. package/dist/chunks/proxy-Dtg-bJ3T.cjs.map +1 -0
  22. package/dist/chunks/{index-CtA2AWl3.esm.js → proxy-r7lARftl.esm.js} +2273 -2948
  23. package/dist/chunks/proxy-r7lARftl.esm.js.map +1 -0
  24. package/dist/debug.cjs +973 -28
  25. package/dist/debug.cjs.map +1 -1
  26. package/dist/debug.d.ts +36 -37
  27. package/dist/debug.esm.js +949 -1
  28. package/dist/debug.esm.js.map +1 -1
  29. package/dist/devtools/manifest.json +1 -1
  30. package/dist/devtools/panel.html +1 -1
  31. package/dist/devtools/panel.js +107 -94
  32. package/dist/devtools/panel.js.map +1 -1
  33. package/dist/index.d.ts +1447 -1
  34. package/dist/mutts.umd.js +7167 -1
  35. package/dist/mutts.umd.js.map +1 -1
  36. package/dist/mutts.umd.min.js +1 -1
  37. package/dist/mutts.umd.min.js.map +1 -1
  38. package/dist/node.cjs +62 -60
  39. package/dist/node.cjs.map +1 -1
  40. package/dist/node.d.ts +2 -2
  41. package/dist/node.dev.cjs +110 -0
  42. package/dist/node.dev.cjs.map +1 -0
  43. package/dist/node.dev.d.ts +2 -0
  44. package/dist/node.dev.esm.js +6 -0
  45. package/dist/node.dev.esm.js.map +1 -0
  46. package/dist/node.esm.js +4 -97
  47. package/dist/node.esm.js.map +1 -1
  48. package/dist/{types-DaHFfhlN.d.ts → types-W5vD6m2n.d.ts} +99 -44
  49. package/docs/ai/api-reference.md +11 -18
  50. package/docs/ai/manual.md +308 -230
  51. package/docs/reactive/advanced.md +312 -2
  52. package/docs/reactive/attend.md +1 -2
  53. package/docs/reactive/collections.md +21 -39
  54. package/docs/reactive/core.md +7 -37
  55. package/docs/reactive/debugging.md +117 -10
  56. package/docs/reactive/error-handling.md +10 -10
  57. package/docs/reactive/resource.md +125 -0
  58. package/docs/reactive/scan.md +32 -1
  59. package/docs/reactive.md +3 -2
  60. package/docs/utils.md +70 -0
  61. package/package.json +59 -30
  62. package/dist/chunks/async-browser-lvzLOCgk.cjs.map +0 -1
  63. package/dist/chunks/async-node-C3DeIb0y.cjs.map +0 -1
  64. package/dist/chunks/index-2vea86wD.esm.js.map +0 -1
  65. package/dist/chunks/index-CtA2AWl3.esm.js.map +0 -1
  66. package/dist/chunks/index-VTO-b2vR.cjs.map +0 -1
  67. package/dist/debug/debug.d.ts +0 -122
  68. package/dist/debug/debug.d.ts.map +0 -1
  69. package/dist/debug/index.d.ts +0 -4
  70. package/dist/debug/index.d.ts.map +0 -1
  71. package/dist/debug/lineage-panel.d.ts +0 -5
  72. package/dist/debug/lineage-panel.d.ts.map +0 -1
  73. package/dist/debug/lineage.d.ts +0 -79
  74. package/dist/debug/lineage.d.ts.map +0 -1
  75. package/dist/src/async/browser.d.ts +0 -2
  76. package/dist/src/async/browser.d.ts.map +0 -1
  77. package/dist/src/async/index.d.ts +0 -19
  78. package/dist/src/async/index.d.ts.map +0 -1
  79. package/dist/src/async/node.d.ts +0 -2
  80. package/dist/src/async/node.d.ts.map +0 -1
  81. package/dist/src/decorator.d.ts +0 -106
  82. package/dist/src/decorator.d.ts.map +0 -1
  83. package/dist/src/destroyable.d.ts +0 -87
  84. package/dist/src/destroyable.d.ts.map +0 -1
  85. package/dist/src/entry-browser.d.ts +0 -3
  86. package/dist/src/entry-browser.d.ts.map +0 -1
  87. package/dist/src/entry-node.d.ts +0 -3
  88. package/dist/src/entry-node.d.ts.map +0 -1
  89. package/dist/src/eventful.d.ts +0 -20
  90. package/dist/src/eventful.d.ts.map +0 -1
  91. package/dist/src/flavored.d.ts +0 -33
  92. package/dist/src/flavored.d.ts.map +0 -1
  93. package/dist/src/index.d.ts +0 -14
  94. package/dist/src/index.d.ts.map +0 -1
  95. package/dist/src/indexable.d.ts +0 -243
  96. package/dist/src/indexable.d.ts.map +0 -1
  97. package/dist/src/introspection.d.ts +0 -27
  98. package/dist/src/introspection.d.ts.map +0 -1
  99. package/dist/src/iterableWeak.d.ts +0 -53
  100. package/dist/src/iterableWeak.d.ts.map +0 -1
  101. package/dist/src/mixins.d.ts +0 -25
  102. package/dist/src/mixins.d.ts.map +0 -1
  103. package/dist/src/promiseChain.d.ts +0 -20
  104. package/dist/src/promiseChain.d.ts.map +0 -1
  105. package/dist/src/reactive/array.d.ts +0 -48
  106. package/dist/src/reactive/array.d.ts.map +0 -1
  107. package/dist/src/reactive/buffer.d.ts +0 -120
  108. package/dist/src/reactive/buffer.d.ts.map +0 -1
  109. package/dist/src/reactive/change.d.ts +0 -29
  110. package/dist/src/reactive/change.d.ts.map +0 -1
  111. package/dist/src/reactive/deep-touch.d.ts +0 -28
  112. package/dist/src/reactive/deep-touch.d.ts.map +0 -1
  113. package/dist/src/reactive/deep-watch-state.d.ts +0 -25
  114. package/dist/src/reactive/deep-watch-state.d.ts.map +0 -1
  115. package/dist/src/reactive/deep-watch.d.ts +0 -20
  116. package/dist/src/reactive/deep-watch.d.ts.map +0 -1
  117. package/dist/src/reactive/describe.d.ts +0 -12
  118. package/dist/src/reactive/describe.d.ts.map +0 -1
  119. package/dist/src/reactive/effect-context.d.ts +0 -34
  120. package/dist/src/reactive/effect-context.d.ts.map +0 -1
  121. package/dist/src/reactive/effects.d.ts +0 -164
  122. package/dist/src/reactive/effects.d.ts.map +0 -1
  123. package/dist/src/reactive/index.d.ts +0 -19
  124. package/dist/src/reactive/index.d.ts.map +0 -1
  125. package/dist/src/reactive/map.d.ts +0 -28
  126. package/dist/src/reactive/map.d.ts.map +0 -1
  127. package/dist/src/reactive/memoize.d.ts +0 -28
  128. package/dist/src/reactive/memoize.d.ts.map +0 -1
  129. package/dist/src/reactive/non-reactive-state.d.ts +0 -9
  130. package/dist/src/reactive/non-reactive-state.d.ts.map +0 -1
  131. package/dist/src/reactive/non-reactive.d.ts +0 -11
  132. package/dist/src/reactive/non-reactive.d.ts.map +0 -1
  133. package/dist/src/reactive/project.d.ts +0 -40
  134. package/dist/src/reactive/project.d.ts.map +0 -1
  135. package/dist/src/reactive/proxy-state.d.ts +0 -8
  136. package/dist/src/reactive/proxy-state.d.ts.map +0 -1
  137. package/dist/src/reactive/proxy.d.ts +0 -23
  138. package/dist/src/reactive/proxy.d.ts.map +0 -1
  139. package/dist/src/reactive/record.d.ts +0 -115
  140. package/dist/src/reactive/record.d.ts.map +0 -1
  141. package/dist/src/reactive/register.d.ts +0 -125
  142. package/dist/src/reactive/register.d.ts.map +0 -1
  143. package/dist/src/reactive/registry.d.ts +0 -21
  144. package/dist/src/reactive/registry.d.ts.map +0 -1
  145. package/dist/src/reactive/set.d.ts +0 -26
  146. package/dist/src/reactive/set.d.ts.map +0 -1
  147. package/dist/src/reactive/tracking.d.ts +0 -7
  148. package/dist/src/reactive/tracking.d.ts.map +0 -1
  149. package/dist/src/reactive/types.d.ts +0 -424
  150. package/dist/src/reactive/types.d.ts.map +0 -1
  151. package/dist/src/reactive/watch.d.ts +0 -48
  152. package/dist/src/reactive/watch.d.ts.map +0 -1
  153. package/dist/src/std-decorators.d.ts +0 -45
  154. package/dist/src/std-decorators.d.ts.map +0 -1
  155. package/dist/src/utils.d.ts +0 -49
  156. package/dist/src/utils.d.ts.map +0 -1
  157. package/dist/src/zone.d.ts +0 -40
  158. package/dist/src/zone.d.ts.map +0 -1
  159. package/docs/reactive/describe.md +0 -85
  160. package/docs/reactive/project.md +0 -93
  161. package/src/async/browser.ts +0 -323
  162. package/src/async/index.ts +0 -27
  163. package/src/async/node.ts +0 -92
  164. package/src/decorator.ts +0 -272
  165. package/src/destroyable.ts +0 -199
  166. package/src/entry-browser.ts +0 -5
  167. package/src/entry-node.ts +0 -5
  168. package/src/eventful.ts +0 -110
  169. package/src/flavored.ts +0 -106
  170. package/src/index.d.ts +0 -12
  171. package/src/index.ts +0 -64
  172. package/src/indexable.ts +0 -526
  173. package/src/introspection.ts +0 -59
  174. package/src/iterableWeak.ts +0 -233
  175. package/src/mixins.ts +0 -123
  176. package/src/promiseChain.ts +0 -110
  177. package/src/reactive/array.ts +0 -500
  178. package/src/reactive/buffer.ts +0 -328
  179. package/src/reactive/change.ts +0 -131
  180. package/src/reactive/deep-touch.ts +0 -273
  181. package/src/reactive/deep-watch-state.ts +0 -82
  182. package/src/reactive/deep-watch.ts +0 -171
  183. package/src/reactive/describe.ts +0 -39
  184. package/src/reactive/effect-context.ts +0 -83
  185. package/src/reactive/effects.ts +0 -1434
  186. package/src/reactive/index.ts +0 -72
  187. package/src/reactive/map.ts +0 -142
  188. package/src/reactive/memoize.ts +0 -186
  189. package/src/reactive/non-reactive-state.ts +0 -49
  190. package/src/reactive/non-reactive.ts +0 -43
  191. package/src/reactive/project.md +0 -107
  192. package/src/reactive/project.ts +0 -430
  193. package/src/reactive/proxy-state.ts +0 -27
  194. package/src/reactive/proxy.ts +0 -282
  195. package/src/reactive/record.ts +0 -181
  196. package/src/reactive/register.ts +0 -538
  197. package/src/reactive/registry.ts +0 -72
  198. package/src/reactive/set.ts +0 -117
  199. package/src/reactive/tracking.ts +0 -41
  200. package/src/reactive/types.ts +0 -520
  201. package/src/reactive/watch.ts +0 -180
  202. package/src/std-decorators.ts +0 -256
  203. package/src/utils.ts +0 -300
  204. package/src/zone.ts +0 -142
package/src/utils.ts DELETED
@@ -1,300 +0,0 @@
1
- type ElementTypes<T extends readonly unknown[]> = {
2
- [K in keyof T]: T[K] extends readonly (infer U)[] ? U : T[K]
3
- }
4
-
5
- /**
6
- * Combines multiple arrays into an array of tuples, stopping at the shortest array length
7
- * @param args - Arrays to zip together
8
- * @returns Array of tuples containing elements from each input array
9
- */
10
- export function zip<T extends (readonly unknown[])[]>(...args: T): ElementTypes<T>[] {
11
- if (!args.length) return []
12
- const minLength = Math.min(...args.map((arr) => arr.length))
13
- const result: ElementTypes<T>[] = []
14
-
15
- for (let i = 0; i < minLength; i++) {
16
- const tuple = args.map((arr) => arr[i]) as ElementTypes<T>
17
- result.push(tuple)
18
- }
19
-
20
- return result
21
- }
22
-
23
- /**
24
- * Checks if two arrays are strictly equal (shallow comparison)
25
- * @param a - First value
26
- * @param b - Second value
27
- * @returns True if arrays are equal or values are strictly equal
28
- */
29
- export function arrayEquals(a: any, b: any): boolean {
30
- if (a === b) return true
31
- if (!Array.isArray(a) || !Array.isArray(b)) return false
32
- if (a.length !== b.length) return false
33
- for (let i = 0; i < a.length; i++) {
34
- if (a[i] !== b[i]) return false
35
- }
36
- return true
37
- }
38
-
39
- const nativeConstructors = new Set<Function>([
40
- Object,
41
- Array,
42
- Date,
43
- Function,
44
- Set,
45
- Map,
46
- WeakMap,
47
- WeakSet,
48
- Promise,
49
- Error,
50
- TypeError,
51
- ReferenceError,
52
- SyntaxError,
53
- RangeError,
54
- URIError,
55
- EvalError,
56
- Reflect,
57
- Proxy,
58
- RegExp,
59
- String,
60
- Number,
61
- Boolean,
62
- ] as Function[])
63
- /**
64
- * Checks if a function is a constructor (class or constructor function)
65
- * @param fn - The function to check
66
- * @returns True if the function is a constructor
67
- */
68
- export function isConstructor(fn: Function): boolean {
69
- return (
70
- fn &&
71
- typeof fn === 'function' &&
72
- (nativeConstructors.has(fn) || fn.toString?.().startsWith('class '))
73
- )
74
- }
75
-
76
- /**
77
- * Renames a function with a new name
78
- * @param fct - The function to rename
79
- * @param name - The new name for the function
80
- * @returns The function with the new name
81
- */
82
- export function renamed<F extends Function>(fct: F, name: string): F {
83
- return Object.defineProperties(fct, {
84
- name: {
85
- value: name,
86
- },
87
- })
88
- }
89
- export const FoolProof = {
90
- get(obj: any, prop: any, receiver: any) {
91
- // Check if Node is available and obj is an instance of Node
92
- if (typeof Node !== 'undefined' && obj instanceof Node) return (obj as any)[prop]
93
- return Reflect.get(obj, prop, receiver)
94
- },
95
- set(obj: any, prop: any, value: any, receiver: any) {
96
- // Check if Node is available and obj is an instance of Node
97
- if (typeof Node !== 'undefined' && obj instanceof Node) {
98
- ;(obj as any)[prop] = value
99
- return true
100
- }
101
- if (!(obj instanceof Object) && !Reflect.has(obj, prop)) {
102
- Object.defineProperty(obj, prop, {
103
- value,
104
- configurable: true,
105
- writable: true,
106
- enumerable: true,
107
- })
108
- return true
109
- }
110
- return Reflect.set(obj, prop, value, receiver)
111
- },
112
- }
113
-
114
- export function isOwnAccessor(obj: any, prop: any) {
115
- const opd = Object.getOwnPropertyDescriptor(obj, prop)
116
- return !!(opd?.get || opd?.set)
117
- }
118
-
119
- /**
120
- * Deeply compares two values.
121
- * For objects, compares prototypes with === and then own properties recursively.
122
- * Uses a cache to handle circular references.
123
- * @param a - First value
124
- * @param b - Second value
125
- * @param cache - Map for circular reference protection (internal use)
126
- * @returns True if values are deeply equal
127
- */
128
- export function deepCompare(a: any, b: any, cache = new Map<object, Set<object>>()): boolean {
129
- if (a === b) return true
130
-
131
- if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
132
- return a === b
133
- }
134
-
135
- // Prototype check
136
- const protoA = Object.getPrototypeOf(a)
137
- const protoB = Object.getPrototypeOf(b)
138
- if (protoA !== protoB) {
139
- console.warn(`[deepCompare] prototype mismatch:`, {
140
- nameA: a?.constructor?.name,
141
- nameB: b?.constructor?.name,
142
- })
143
- return false
144
- }
145
- // Circular reference protection
146
- let compared = cache.get(a)
147
- if (compared?.has(b)) return true
148
- if (!compared) {
149
- compared = new Set()
150
- cache.set(a, compared)
151
- }
152
- compared.add(b)
153
-
154
- // Handle specific object types
155
- if (Array.isArray(a)) {
156
- if (!Array.isArray(b)) {
157
- console.warn(`[deepCompare] B is not an array`)
158
- return false
159
- }
160
- if (a.length !== b.length) {
161
- console.warn(`[deepCompare] array length mismatch:`, { lenA: a.length, lenB: b.length })
162
- return false
163
- }
164
- for (let i = 0; i < a.length; i++) {
165
- if (!deepCompare(a[i], b[i], cache)) {
166
- console.warn(`[deepCompare] array element mismatch at index ${i}`)
167
- return false
168
- }
169
- }
170
- return true
171
- }
172
-
173
- if (a instanceof Date) {
174
- const match = b instanceof Date && a.getTime() === b.getTime()
175
- if (!match) console.warn(`[deepCompare] Date mismatch`)
176
- return match
177
- }
178
- if (a instanceof RegExp) {
179
- const match = b instanceof RegExp && a.toString() === b.toString()
180
- if (!match) console.warn(`[deepCompare] RegExp mismatch`)
181
- return match
182
- }
183
- if (a instanceof Set) {
184
- if (!(b instanceof Set) || a.size !== b.size) {
185
- console.warn(`[deepCompare] Set size mismatch`)
186
- return false
187
- }
188
- for (const val of a) {
189
- let found = false
190
- for (const bVal of b) {
191
- if (deepCompare(val, bVal, cache)) {
192
- found = true
193
- break
194
- }
195
- }
196
- if (!found) {
197
- console.warn(`[deepCompare] missing Set element`)
198
- return false
199
- }
200
- }
201
- return true
202
- }
203
- if (a instanceof Map) {
204
- if (!(b instanceof Map) || a.size !== b.size) {
205
- console.warn(`[deepCompare] Map size mismatch`)
206
- return false
207
- }
208
- for (const [key, val] of a) {
209
- if (!b.has(key)) {
210
- let foundMatch = false
211
- for (const [bKey, bVal] of b) {
212
- if (deepCompare(key, bKey, cache) && deepCompare(val, bVal, cache)) {
213
- foundMatch = true
214
- break
215
- }
216
- }
217
- if (!foundMatch) {
218
- console.warn(`[deepCompare] missing Map key`)
219
- return false
220
- }
221
- } else {
222
- if (!deepCompare(val, b.get(key), cache)) {
223
- console.warn(`[deepCompare] Map value mismatch for key`)
224
- return false
225
- }
226
- }
227
- }
228
- return true
229
- }
230
-
231
- // Compare own properties
232
- const keysA = Object.keys(a)
233
- const keysB = Object.keys(b)
234
- if (keysA.length !== keysB.length) {
235
- console.warn(`[deepCompare] keys length mismatch:`, {
236
- lenA: keysA.length,
237
- lenB: keysB.length,
238
- keysA,
239
- keysB,
240
- a,
241
- b,
242
- })
243
- return false
244
- }
245
-
246
- for (const key of keysA) {
247
- if (!Object.hasOwn(b, key)) {
248
- console.warn(`[deepCompare] missing key ${String(key)} in B`)
249
- return false
250
- }
251
- if (!deepCompare(a[key], b[key], cache)) {
252
- console.warn(`[deepCompare] value mismatch for key ${String(key)}:`, {
253
- valA: a[key],
254
- valB: b[key],
255
- })
256
- return false
257
- }
258
- }
259
-
260
- return true
261
- }
262
-
263
- const contentRefs = new WeakMap<object, any>()
264
- export function contentRef(container: object) {
265
- if (!contentRefs.has(container))
266
- contentRefs.set(
267
- container,
268
- Object.seal(
269
- Object.create(null, {
270
- contentOf: { value: container, writable: false, configurable: false },
271
- })
272
- )
273
- )
274
- return contentRefs.get(container)
275
- }
276
-
277
- export function tag<T extends object>(name: string, obj: T): T {
278
- Object.defineProperties(obj, {
279
- [Symbol.toStringTag]: {
280
- value: name,
281
- writable: false,
282
- configurable: false,
283
- },
284
- toString: {
285
- value: () => name,
286
- writable: false,
287
- configurable: false,
288
- },
289
- })
290
- return obj
291
- }
292
-
293
- export function named<T extends Function>(name: string, fn: T): T {
294
- Object.defineProperty(fn, 'name', {
295
- value: fn.name ? `${fn.name}::${name}` : name,
296
- writable: false,
297
- configurable: true,
298
- })
299
- return fn
300
- }
package/src/zone.ts DELETED
@@ -1,142 +0,0 @@
1
- import { asyncHooks } from './async'
2
- import { named, tag } from './utils'
3
-
4
- interface InternalZoneUse<T> {
5
- enter(value?: T): unknown
6
- leave(entered: unknown): void
7
- }
8
- function isu<T>(z: AZone<T> | InternalZoneUse<T>): InternalZoneUse<T> {
9
- return z as InternalZoneUse<T>
10
- }
11
- export abstract class AZone<T> {
12
- abstract active?: T
13
- protected enter(value?: T): unknown {
14
- const prev = this.active
15
- this.active = value
16
- return prev
17
- }
18
- protected leave(entered: unknown): void {
19
- this.active = entered as T | undefined
20
- }
21
- with<R>(value: T | undefined, fn: () => R): R {
22
- const entered = this.enter(value)
23
- let res: R
24
- try {
25
- res = fn()
26
- } finally {
27
- this.leave(entered)
28
- }
29
- // [HACK]: Sanitization
30
- // See BROWSER_ASYNC_POLYFILL.md
31
- return asyncHooks.sanitizePromise(res) as R
32
- }
33
- root<R>(fn: () => R): R {
34
- const prev = this.enter()
35
- try {
36
- return fn()
37
- } finally {
38
- this.leave(prev)
39
- }
40
- }
41
- get zoned(): FunctionWrapper {
42
- const active = this.active
43
- return named(`${this}@${active}`, (fn) => this.with(active, fn))
44
- }
45
- }
46
-
47
- export type FunctionWrapper = <R>(fn: () => R) => R
48
-
49
- export class Zone<T> extends AZone<T> {
50
- active: T | undefined
51
- }
52
-
53
- type HistoryValue<T> = { present: T | undefined; history: Set<T> }
54
- export class ZoneHistory<T> extends AZone<HistoryValue<T>> {
55
- private history = new Set<T>()
56
- public readonly present: AZone<T>
57
- public has(value: T): boolean {
58
- return this.history.has(value)
59
- }
60
- public some(predicate: (value: T) => boolean): boolean {
61
- for (const value of this.history) if (predicate(value)) return true
62
- return false
63
- }
64
- constructor(private controlled: AZone<T> = new Zone<T>()) {
65
- super()
66
- const self = this
67
- this.present = Object.create(
68
- controlled,
69
- Object.getOwnPropertyDescriptors({
70
- get active() {
71
- return controlled.active
72
- },
73
- set active(value: T | undefined) {
74
- controlled.active = value
75
- },
76
- enter(value?: T) {
77
- if (value && self.history.has(value))
78
- throw new Error('ZoneHistory: re-entering historical zone')
79
- if (value !== undefined) self.history.add(value)
80
- return { added: value, entered: isu(controlled).enter(value) }
81
- },
82
- leave(entered: { added: T | undefined; entered: unknown }) {
83
- if (entered.added !== undefined) self.history.delete(entered.added)
84
- return isu(controlled).leave(entered.entered)
85
- },
86
- })
87
- )
88
- }
89
- get active() {
90
- return { present: this.controlled.active, history: new Set(this.history) }
91
- }
92
- set active(value: HistoryValue<T> | undefined) {
93
- this.history = value?.history ? new Set(value.history) : new Set()
94
- this.controlled.active = value?.present
95
- }
96
- }
97
-
98
- export class ZoneAggregator extends AZone<Map<AZone<unknown>, unknown>> {
99
- #zones = new Set<AZone<unknown>>()
100
- constructor(...zones: AZone<unknown>[]) {
101
- super()
102
- for (const z of zones) this.#zones.add(z)
103
- }
104
- get active(): Map<AZone<unknown>, unknown> | undefined {
105
- const rv = new Map<AZone<unknown>, unknown>()
106
- for (const z of this.#zones) if (z.active !== undefined) rv.set(z, z.active)
107
- return rv
108
- }
109
- set active(value: Map<AZone<unknown>, unknown> | undefined) {
110
- for (const z of this.#zones) z.active = value?.get(z)
111
- }
112
- enter(value?: Map<AZone<unknown>, unknown> | undefined) {
113
- const entered = new Map<AZone<unknown>, unknown>()
114
- for (const z of this.#zones) {
115
- const v = value?.get(z)
116
- entered.set(z, isu(z).enter(v))
117
- }
118
- return entered
119
- }
120
- leave(entered: Map<AZone<unknown>, unknown>): void {
121
- for (const z of this.#zones) isu(z).leave(entered.get(z))
122
- }
123
- add(z: AZone<unknown>) {
124
- this.#zones.add(z)
125
- }
126
- delete(z: AZone<unknown>) {
127
- this.#zones.delete(z)
128
- }
129
- clear() {
130
- this.#zones.clear()
131
- }
132
- }
133
-
134
- export const asyncZone = tag('async', new ZoneAggregator())
135
- asyncHooks.addHook(() => {
136
- const zone = asyncZone.active
137
- return () => {
138
- const prev = asyncZone.active
139
- asyncZone.active = zone
140
- return () => (asyncZone.active = prev)
141
- }
142
- })