mutts 1.0.9 → 1.0.11
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.
- package/README.md +60 -35
- package/dist/browser.cjs +1333 -1760
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +2 -1392
- package/dist/browser.dev.cjs +114 -0
- package/dist/browser.dev.cjs.map +1 -0
- package/dist/browser.dev.d.ts +2 -0
- package/dist/browser.dev.esm.js +5 -0
- package/dist/browser.dev.esm.js.map +1 -0
- package/dist/browser.esm.js +18 -97
- package/dist/browser.esm.js.map +1 -1
- package/dist/chunks/{async-browser-lvzLOCgk.cjs → async-browser-Dgr5CreQ.cjs} +16 -95
- package/dist/chunks/async-browser-Dgr5CreQ.cjs.map +1 -0
- package/dist/chunks/{async-node-C3DeIb0y.cjs → async-node-3PrbVAbB.cjs} +3 -1
- package/dist/chunks/async-node-3PrbVAbB.cjs.map +1 -0
- package/dist/chunks/index-Sf74wXTV.esm.js +2577 -0
- package/dist/chunks/index-Sf74wXTV.esm.js.map +1 -0
- package/dist/chunks/node-Bo7WU5S2.esm.js +96 -0
- package/dist/chunks/node-Bo7WU5S2.esm.js.map +1 -0
- package/dist/chunks/{index-VTO-b2vR.cjs → proxy-Cc79Lrzj.cjs} +2593 -3216
- package/dist/chunks/proxy-Cc79Lrzj.cjs.map +1 -0
- package/dist/chunks/{index-CtA2AWl3.esm.js → proxy-D2C49sXH.esm.js} +2570 -3174
- package/dist/chunks/proxy-D2C49sXH.esm.js.map +1 -0
- package/dist/debug.cjs +987 -28
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.d.ts +37 -38
- package/dist/debug.esm.js +963 -1
- package/dist/debug.esm.js.map +1 -1
- package/dist/devtools/manifest.json +1 -1
- package/dist/devtools/panel.html +1 -1
- package/dist/devtools/panel.js +107 -94
- package/dist/devtools/panel.js.map +1 -1
- package/dist/index.d.ts +1322 -1
- package/dist/mutts.umd.js +6647 -1
- package/dist/mutts.umd.js.map +1 -1
- package/dist/mutts.umd.min.js +1 -1
- package/dist/mutts.umd.min.js.map +1 -1
- package/dist/node.cjs +69 -63
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.dev.cjs +114 -0
- package/dist/node.dev.cjs.map +1 -0
- package/dist/node.dev.d.ts +2 -0
- package/dist/node.dev.esm.js +6 -0
- package/dist/node.dev.esm.js.map +1 -0
- package/dist/node.esm.js +4 -97
- package/dist/node.esm.js.map +1 -1
- package/dist/{types-DaHFfhlN.d.ts → types-Bx2PhORg.d.ts} +134 -88
- package/docs/ai/api-reference.md +11 -32
- package/docs/ai/manual.md +297 -239
- package/docs/reactive/advanced.md +318 -9
- package/docs/reactive/attend.md +2 -4
- package/docs/reactive/collections.md +22 -187
- package/docs/reactive/core.md +223 -131
- package/docs/reactive/debugging.md +119 -12
- package/docs/reactive/error-handling.md +10 -10
- package/docs/reactive/resource.md +125 -0
- package/docs/reactive.md +3 -4
- package/docs/utils.md +70 -0
- package/docs/zone.md +1 -1
- package/package.json +76 -38
- package/dist/chunks/async-browser-lvzLOCgk.cjs.map +0 -1
- package/dist/chunks/async-node-C3DeIb0y.cjs.map +0 -1
- package/dist/chunks/index-2vea86wD.esm.js +0 -3011
- package/dist/chunks/index-2vea86wD.esm.js.map +0 -1
- package/dist/chunks/index-CtA2AWl3.esm.js.map +0 -1
- package/dist/chunks/index-VTO-b2vR.cjs.map +0 -1
- package/dist/debug/debug.d.ts +0 -122
- package/dist/debug/debug.d.ts.map +0 -1
- package/dist/debug/index.d.ts +0 -4
- package/dist/debug/index.d.ts.map +0 -1
- package/dist/debug/lineage-panel.d.ts +0 -5
- package/dist/debug/lineage-panel.d.ts.map +0 -1
- package/dist/debug/lineage.d.ts +0 -79
- package/dist/debug/lineage.d.ts.map +0 -1
- package/dist/src/async/browser.d.ts +0 -2
- package/dist/src/async/browser.d.ts.map +0 -1
- package/dist/src/async/index.d.ts +0 -19
- package/dist/src/async/index.d.ts.map +0 -1
- package/dist/src/async/node.d.ts +0 -2
- package/dist/src/async/node.d.ts.map +0 -1
- package/dist/src/decorator.d.ts +0 -106
- package/dist/src/decorator.d.ts.map +0 -1
- package/dist/src/destroyable.d.ts +0 -87
- package/dist/src/destroyable.d.ts.map +0 -1
- package/dist/src/entry-browser.d.ts +0 -3
- package/dist/src/entry-browser.d.ts.map +0 -1
- package/dist/src/entry-node.d.ts +0 -3
- package/dist/src/entry-node.d.ts.map +0 -1
- package/dist/src/eventful.d.ts +0 -20
- package/dist/src/eventful.d.ts.map +0 -1
- package/dist/src/flavored.d.ts +0 -33
- package/dist/src/flavored.d.ts.map +0 -1
- package/dist/src/index.d.ts +0 -14
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/indexable.d.ts +0 -243
- package/dist/src/indexable.d.ts.map +0 -1
- package/dist/src/introspection.d.ts +0 -27
- package/dist/src/introspection.d.ts.map +0 -1
- package/dist/src/iterableWeak.d.ts +0 -53
- package/dist/src/iterableWeak.d.ts.map +0 -1
- package/dist/src/mixins.d.ts +0 -25
- package/dist/src/mixins.d.ts.map +0 -1
- package/dist/src/promiseChain.d.ts +0 -20
- package/dist/src/promiseChain.d.ts.map +0 -1
- package/dist/src/reactive/array.d.ts +0 -48
- package/dist/src/reactive/array.d.ts.map +0 -1
- package/dist/src/reactive/buffer.d.ts +0 -120
- package/dist/src/reactive/buffer.d.ts.map +0 -1
- package/dist/src/reactive/change.d.ts +0 -29
- package/dist/src/reactive/change.d.ts.map +0 -1
- package/dist/src/reactive/deep-touch.d.ts +0 -28
- package/dist/src/reactive/deep-touch.d.ts.map +0 -1
- package/dist/src/reactive/deep-watch-state.d.ts +0 -25
- package/dist/src/reactive/deep-watch-state.d.ts.map +0 -1
- package/dist/src/reactive/deep-watch.d.ts +0 -20
- package/dist/src/reactive/deep-watch.d.ts.map +0 -1
- package/dist/src/reactive/describe.d.ts +0 -12
- package/dist/src/reactive/describe.d.ts.map +0 -1
- package/dist/src/reactive/effect-context.d.ts +0 -34
- package/dist/src/reactive/effect-context.d.ts.map +0 -1
- package/dist/src/reactive/effects.d.ts +0 -164
- package/dist/src/reactive/effects.d.ts.map +0 -1
- package/dist/src/reactive/index.d.ts +0 -19
- package/dist/src/reactive/index.d.ts.map +0 -1
- package/dist/src/reactive/map.d.ts +0 -28
- package/dist/src/reactive/map.d.ts.map +0 -1
- package/dist/src/reactive/memoize.d.ts +0 -28
- package/dist/src/reactive/memoize.d.ts.map +0 -1
- package/dist/src/reactive/non-reactive-state.d.ts +0 -9
- package/dist/src/reactive/non-reactive-state.d.ts.map +0 -1
- package/dist/src/reactive/non-reactive.d.ts +0 -11
- package/dist/src/reactive/non-reactive.d.ts.map +0 -1
- package/dist/src/reactive/project.d.ts +0 -40
- package/dist/src/reactive/project.d.ts.map +0 -1
- package/dist/src/reactive/proxy-state.d.ts +0 -8
- package/dist/src/reactive/proxy-state.d.ts.map +0 -1
- package/dist/src/reactive/proxy.d.ts +0 -23
- package/dist/src/reactive/proxy.d.ts.map +0 -1
- package/dist/src/reactive/record.d.ts +0 -115
- package/dist/src/reactive/record.d.ts.map +0 -1
- package/dist/src/reactive/register.d.ts +0 -125
- package/dist/src/reactive/register.d.ts.map +0 -1
- package/dist/src/reactive/registry.d.ts +0 -21
- package/dist/src/reactive/registry.d.ts.map +0 -1
- package/dist/src/reactive/set.d.ts +0 -26
- package/dist/src/reactive/set.d.ts.map +0 -1
- package/dist/src/reactive/tracking.d.ts +0 -7
- package/dist/src/reactive/tracking.d.ts.map +0 -1
- package/dist/src/reactive/types.d.ts +0 -424
- package/dist/src/reactive/types.d.ts.map +0 -1
- package/dist/src/reactive/watch.d.ts +0 -48
- package/dist/src/reactive/watch.d.ts.map +0 -1
- package/dist/src/std-decorators.d.ts +0 -45
- package/dist/src/std-decorators.d.ts.map +0 -1
- package/dist/src/utils.d.ts +0 -49
- package/dist/src/utils.d.ts.map +0 -1
- package/dist/src/zone.d.ts +0 -40
- package/dist/src/zone.d.ts.map +0 -1
- package/docs/reactive/describe.md +0 -85
- package/docs/reactive/project.md +0 -93
- package/docs/reactive/scan.md +0 -293
- package/src/async/browser.ts +0 -323
- package/src/async/index.ts +0 -27
- package/src/async/node.ts +0 -92
- package/src/decorator.ts +0 -272
- package/src/destroyable.ts +0 -199
- package/src/entry-browser.ts +0 -5
- package/src/entry-node.ts +0 -5
- package/src/eventful.ts +0 -110
- package/src/flavored.ts +0 -106
- package/src/index.d.ts +0 -12
- package/src/index.ts +0 -64
- package/src/indexable.ts +0 -526
- package/src/introspection.ts +0 -59
- package/src/iterableWeak.ts +0 -233
- package/src/mixins.ts +0 -123
- package/src/promiseChain.ts +0 -110
- package/src/reactive/array.ts +0 -500
- package/src/reactive/buffer.ts +0 -328
- package/src/reactive/change.ts +0 -131
- package/src/reactive/deep-touch.ts +0 -273
- package/src/reactive/deep-watch-state.ts +0 -82
- package/src/reactive/deep-watch.ts +0 -171
- package/src/reactive/describe.ts +0 -39
- package/src/reactive/effect-context.ts +0 -83
- package/src/reactive/effects.ts +0 -1434
- package/src/reactive/index.ts +0 -72
- package/src/reactive/map.ts +0 -142
- package/src/reactive/memoize.ts +0 -186
- package/src/reactive/non-reactive-state.ts +0 -49
- package/src/reactive/non-reactive.ts +0 -43
- package/src/reactive/project.md +0 -107
- package/src/reactive/project.ts +0 -430
- package/src/reactive/proxy-state.ts +0 -27
- package/src/reactive/proxy.ts +0 -282
- package/src/reactive/record.ts +0 -181
- package/src/reactive/register.ts +0 -538
- package/src/reactive/registry.ts +0 -72
- package/src/reactive/set.ts +0 -117
- package/src/reactive/tracking.ts +0 -41
- package/src/reactive/types.ts +0 -520
- package/src/reactive/watch.ts +0 -180
- package/src/std-decorators.ts +0 -256
- package/src/utils.ts +0 -300
- 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
|
-
})
|