mutts 1.0.8 → 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.
- package/README.md +77 -35
- package/dist/browser.cjs +2144 -5355
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +2 -1655
- package/dist/browser.dev.cjs +110 -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 +20 -107
- package/dist/browser.esm.js.map +1 -1
- package/dist/chunks/{async-browser-CA0jPWIi.cjs → async-browser-BU_IfxYD.cjs} +19 -107
- package/dist/chunks/async-browser-BU_IfxYD.cjs.map +1 -0
- package/dist/chunks/{async-core-UqHzvJ-S.cjs → async-core-CRLKP3l-.cjs} +8 -4
- package/dist/chunks/async-core-CRLKP3l-.cjs.map +1 -0
- package/dist/chunks/{async-node-BYHuGTni.cjs → async-node-3PrbVAbB.cjs} +7 -12
- package/dist/chunks/async-node-3PrbVAbB.cjs.map +1 -0
- package/dist/chunks/index-CaaQQlPJ.esm.js +3174 -0
- package/dist/chunks/index-CaaQQlPJ.esm.js.map +1 -0
- package/dist/chunks/node-nKJBk8iJ.esm.js +96 -0
- package/dist/chunks/node-nKJBk8iJ.esm.js.map +1 -0
- package/dist/chunks/proxy-Dtg-bJ3T.cjs +3763 -0
- package/dist/chunks/proxy-Dtg-bJ3T.cjs.map +1 -0
- package/dist/chunks/proxy-r7lARftl.esm.js +3701 -0
- package/dist/chunks/proxy-r7lARftl.esm.js.map +1 -0
- package/dist/debug.cjs +980 -0
- package/dist/debug.cjs.map +1 -0
- package/dist/debug.d.ts +208 -0
- package/dist/debug.esm.js +950 -0
- package/dist/debug.esm.js.map +1 -0
- 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 +1447 -13
- package/dist/mutts.umd.js +7167 -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 +70 -66
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +2 -1
- package/dist/node.dev.cjs +110 -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 -103
- package/dist/node.esm.js.map +1 -1
- package/dist/{reactive/types.d.ts → types-W5vD6m2n.d.ts} +186 -93
- package/docs/ai/api-reference.md +12 -19
- package/docs/ai/manual.md +521 -17
- package/docs/events.md +57 -2
- package/docs/flavored.md +210 -0
- package/docs/reactive/advanced.md +314 -5
- package/docs/reactive/attend.md +142 -0
- package/docs/reactive/collections.md +76 -39
- package/docs/reactive/core.md +100 -14
- package/docs/reactive/debugging.md +123 -18
- package/docs/reactive/error-handling.md +121 -0
- package/docs/reactive/resource.md +125 -0
- package/docs/reactive/scan.md +247 -1
- package/docs/reactive.md +4 -1
- package/docs/std-decorators.md +102 -51
- package/docs/utils.md +70 -0
- package/docs/zone.md +3 -7
- package/package.json +64 -30
- package/dist/async/browser.d.ts +0 -2
- package/dist/async/browser.d.ts.map +0 -1
- package/dist/async/index.d.ts +0 -18
- package/dist/async/index.d.ts.map +0 -1
- package/dist/async/node.d.ts +0 -2
- package/dist/async/node.d.ts.map +0 -1
- package/dist/chunks/async-browser-CA0jPWIi.cjs.map +0 -1
- package/dist/chunks/async-core-UqHzvJ-S.cjs.map +0 -1
- package/dist/chunks/async-node-BYHuGTni.cjs.map +0 -1
- package/dist/chunks/index-DhaOVusv.esm.js +0 -6411
- package/dist/chunks/index-DhaOVusv.esm.js.map +0 -1
- package/dist/decorator.d.ts +0 -106
- package/dist/decorator.d.ts.map +0 -1
- package/dist/destroyable.d.ts +0 -87
- package/dist/destroyable.d.ts.map +0 -1
- package/dist/entry-browser.d.ts +0 -3
- package/dist/entry-browser.d.ts.map +0 -1
- package/dist/entry-node.d.ts +0 -3
- package/dist/entry-node.d.ts.map +0 -1
- package/dist/eventful.d.ts +0 -18
- package/dist/eventful.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/indexable.d.ts +0 -243
- package/dist/indexable.d.ts.map +0 -1
- package/dist/introspection.d.ts +0 -27
- package/dist/introspection.d.ts.map +0 -1
- package/dist/iterableWeak.d.ts +0 -53
- package/dist/iterableWeak.d.ts.map +0 -1
- package/dist/mixins.d.ts +0 -25
- package/dist/mixins.d.ts.map +0 -1
- package/dist/promiseChain.d.ts +0 -20
- package/dist/promiseChain.d.ts.map +0 -1
- package/dist/reactive/array.d.ts +0 -49
- package/dist/reactive/array.d.ts.map +0 -1
- package/dist/reactive/buffer.d.ts +0 -44
- package/dist/reactive/buffer.d.ts.map +0 -1
- package/dist/reactive/change.d.ts +0 -29
- package/dist/reactive/change.d.ts.map +0 -1
- package/dist/reactive/debug.d.ts +0 -111
- package/dist/reactive/debug.d.ts.map +0 -1
- package/dist/reactive/deep-touch.d.ts +0 -28
- package/dist/reactive/deep-touch.d.ts.map +0 -1
- package/dist/reactive/deep-watch-state.d.ts +0 -25
- package/dist/reactive/deep-watch-state.d.ts.map +0 -1
- package/dist/reactive/deep-watch.d.ts +0 -19
- package/dist/reactive/deep-watch.d.ts.map +0 -1
- package/dist/reactive/effect-context.d.ts +0 -7
- package/dist/reactive/effect-context.d.ts.map +0 -1
- package/dist/reactive/effects.d.ts +0 -151
- package/dist/reactive/effects.d.ts.map +0 -1
- package/dist/reactive/index.d.ts +0 -20
- package/dist/reactive/index.d.ts.map +0 -1
- package/dist/reactive/interface.d.ts +0 -64
- package/dist/reactive/interface.d.ts.map +0 -1
- package/dist/reactive/map.d.ts +0 -30
- package/dist/reactive/map.d.ts.map +0 -1
- package/dist/reactive/memoize.d.ts +0 -5
- package/dist/reactive/memoize.d.ts.map +0 -1
- package/dist/reactive/non-reactive-state.d.ts +0 -9
- package/dist/reactive/non-reactive-state.d.ts.map +0 -1
- package/dist/reactive/non-reactive.d.ts +0 -11
- package/dist/reactive/non-reactive.d.ts.map +0 -1
- package/dist/reactive/project.d.ts +0 -41
- package/dist/reactive/project.d.ts.map +0 -1
- package/dist/reactive/proxy-state.d.ts +0 -8
- package/dist/reactive/proxy-state.d.ts.map +0 -1
- package/dist/reactive/proxy.d.ts +0 -23
- package/dist/reactive/proxy.d.ts.map +0 -1
- package/dist/reactive/record.d.ts +0 -116
- package/dist/reactive/record.d.ts.map +0 -1
- package/dist/reactive/register.d.ts +0 -64
- package/dist/reactive/register.d.ts.map +0 -1
- package/dist/reactive/registry.d.ts +0 -20
- package/dist/reactive/registry.d.ts.map +0 -1
- package/dist/reactive/set.d.ts +0 -28
- package/dist/reactive/set.d.ts.map +0 -1
- package/dist/reactive/tracking.d.ts +0 -7
- package/dist/reactive/tracking.d.ts.map +0 -1
- package/dist/reactive/types.d.ts.map +0 -1
- package/dist/std-decorators.d.ts +0 -50
- package/dist/std-decorators.d.ts.map +0 -1
- package/dist/utils.d.ts +0 -49
- package/dist/utils.d.ts.map +0 -1
- package/dist/zone.d.ts +0 -40
- package/dist/zone.d.ts.map +0 -1
- package/docs/reactive/project.md +0 -93
- package/src/async/browser.ts +0 -319
- package/src/async/index.ts +0 -23
- package/src/async/node.ts +0 -104
- 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 -77
- 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 -507
- package/src/reactive/buffer.ts +0 -168
- package/src/reactive/change.ts +0 -138
- package/src/reactive/debug.ts +0 -517
- package/src/reactive/deep-touch.ts +0 -268
- package/src/reactive/deep-watch-state.ts +0 -82
- package/src/reactive/deep-watch.ts +0 -168
- package/src/reactive/effect-context.ts +0 -18
- package/src/reactive/effects.ts +0 -1382
- package/src/reactive/index.ts +0 -75
- package/src/reactive/interface.ts +0 -210
- package/src/reactive/map.ts +0 -158
- package/src/reactive/memoize.ts +0 -163
- package/src/reactive/non-reactive-state.ts +0 -49
- package/src/reactive/non-reactive.ts +0 -43
- package/src/reactive/project.ts +0 -453
- package/src/reactive/proxy-state.ts +0 -27
- package/src/reactive/proxy.ts +0 -264
- package/src/reactive/record.ts +0 -196
- package/src/reactive/register.ts +0 -419
- package/src/reactive/registry.ts +0 -59
- package/src/reactive/set.ts +0 -130
- package/src/reactive/tracking.ts +0 -44
- package/src/reactive/types.ts +0 -440
- package/src/std-decorators.ts +0 -217
- package/src/utils.ts +0 -301
- package/src/zone.ts +0 -138
package/src/reactive/project.ts
DELETED
|
@@ -1,453 +0,0 @@
|
|
|
1
|
-
import { FoolProof } from '../utils'
|
|
2
|
-
import { setEffectName } from './debug'
|
|
3
|
-
import { getActiveEffect } from './effect-context'
|
|
4
|
-
import { effect, untracked } from './effects'
|
|
5
|
-
import { cleanedBy, cleanup } from './interface'
|
|
6
|
-
import { reactive } from './proxy'
|
|
7
|
-
import { Register } from './register'
|
|
8
|
-
import { type ProjectionContext, projectionInfo, type ScopedCallback } from './types'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Maps projection effects (item effects) to their projection context
|
|
12
|
-
*/
|
|
13
|
-
export const effectProjectionMetadata = new WeakMap<ScopedCallback, ProjectionContext>()
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Returns the projection context of the currently running effect, if any.
|
|
17
|
-
*/
|
|
18
|
-
export function getActiveProjection(): ProjectionContext | undefined {
|
|
19
|
-
const active = getActiveEffect()
|
|
20
|
-
return active ? effectProjectionMetadata.get(active) : undefined
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/* TODO
|
|
24
|
-
It seems to work and I feel like it's correct but I couldn't validate theoretically that `ascend`
|
|
25
|
-
is the correct way to deal with nested effects.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
type ProjectOldValue<Target> = Target extends readonly (infer Item)[]
|
|
29
|
-
? Item
|
|
30
|
-
: Target extends Map<any, infer Item>
|
|
31
|
-
? Item
|
|
32
|
-
: Target extends Record<PropertyKey, infer Item>
|
|
33
|
-
? Item
|
|
34
|
-
: unknown
|
|
35
|
-
|
|
36
|
-
export type ProjectAccess<SourceValue, Key, SourceType, Target> = {
|
|
37
|
-
readonly key: Key
|
|
38
|
-
get(): SourceValue
|
|
39
|
-
set(value: SourceValue): boolean
|
|
40
|
-
readonly source: SourceType
|
|
41
|
-
readonly old?: ProjectOldValue<Target>
|
|
42
|
-
value: SourceValue
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export type ProjectCallback<SourceValue, Key, Target extends object, SourceType, Result> = (
|
|
46
|
-
access: ProjectAccess<SourceValue, Key, SourceType, Target>,
|
|
47
|
-
target: Target
|
|
48
|
-
) => Result
|
|
49
|
-
|
|
50
|
-
export type ProjectResult<Target extends object> = Target & { [cleanup]: ScopedCallback }
|
|
51
|
-
|
|
52
|
-
function defineAccessValue<Access extends { get(): unknown; set(value: unknown): boolean }>(
|
|
53
|
-
access: Access
|
|
54
|
-
) {
|
|
55
|
-
Object.defineProperty(access, 'value', {
|
|
56
|
-
get: access.get,
|
|
57
|
-
set: access.set,
|
|
58
|
-
configurable: true,
|
|
59
|
-
enumerable: true,
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function makeCleanup<Result extends object>(
|
|
64
|
-
target: Result,
|
|
65
|
-
effectMap: Map<unknown, ScopedCallback>,
|
|
66
|
-
onDispose: () => void,
|
|
67
|
-
metadata?: any
|
|
68
|
-
): ProjectResult<Result> {
|
|
69
|
-
if (metadata) {
|
|
70
|
-
Object.defineProperty(target, projectionInfo, {
|
|
71
|
-
value: metadata,
|
|
72
|
-
writable: false,
|
|
73
|
-
enumerable: false,
|
|
74
|
-
configurable: true,
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
return cleanedBy(target, () => {
|
|
78
|
-
onDispose()
|
|
79
|
-
for (const stop of effectMap.values()) stop?.()
|
|
80
|
-
effectMap.clear()
|
|
81
|
-
}) as ProjectResult<Result>
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function projectArray<SourceValue, ResultValue>(
|
|
85
|
-
source: readonly SourceValue[],
|
|
86
|
-
apply: ProjectCallback<SourceValue, number, ResultValue[], readonly SourceValue[], ResultValue>
|
|
87
|
-
): ProjectResult<ResultValue[]> {
|
|
88
|
-
source = reactive(source)
|
|
89
|
-
const target = reactive([] as ResultValue[])
|
|
90
|
-
const indexEffects = new Map<number, ScopedCallback>()
|
|
91
|
-
|
|
92
|
-
function normalizeTargetLength(length: number) {
|
|
93
|
-
FoolProof.set(target as unknown as object, 'length', length, target)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function disposeIndex(index: number) {
|
|
97
|
-
const stopEffect = indexEffects.get(index)
|
|
98
|
-
if (stopEffect) {
|
|
99
|
-
indexEffects.delete(index)
|
|
100
|
-
stopEffect()
|
|
101
|
-
Reflect.deleteProperty(target as unknown as object, index)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const parent = getActiveProjection()
|
|
106
|
-
const depth = parent ? parent.depth + 1 : 0
|
|
107
|
-
|
|
108
|
-
const cleanupLength = effect(function projectArrayLengthEffect({ ascend }) {
|
|
109
|
-
const length = source.length
|
|
110
|
-
normalizeTargetLength(length)
|
|
111
|
-
const existing = Array.from(indexEffects.keys())
|
|
112
|
-
for (let i = 0; i < length; i++) {
|
|
113
|
-
if (indexEffects.has(i)) continue
|
|
114
|
-
ascend(() => {
|
|
115
|
-
const index = i
|
|
116
|
-
const stop = effect(function projectArrayIndexEffect() {
|
|
117
|
-
const previous = untracked(() => target[index])
|
|
118
|
-
const accessBase = {
|
|
119
|
-
key: index,
|
|
120
|
-
source,
|
|
121
|
-
get: () => FoolProof.get(source as any, index, source),
|
|
122
|
-
set: (value: SourceValue) =>
|
|
123
|
-
FoolProof.set(source as any, index, value, source),
|
|
124
|
-
old: previous,
|
|
125
|
-
} as ProjectAccess<SourceValue, number, readonly SourceValue[], ResultValue[]>
|
|
126
|
-
defineAccessValue(accessBase)
|
|
127
|
-
const produced = apply(accessBase, target)
|
|
128
|
-
target[index] = produced
|
|
129
|
-
})
|
|
130
|
-
setEffectName(stop, `project[${depth}]:${index}`)
|
|
131
|
-
effectProjectionMetadata.set(stop, {
|
|
132
|
-
source,
|
|
133
|
-
key: index,
|
|
134
|
-
target,
|
|
135
|
-
depth,
|
|
136
|
-
parent,
|
|
137
|
-
})
|
|
138
|
-
indexEffects.set(i, stop)
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
for (const index of existing) if (index >= length) disposeIndex(index)
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
return makeCleanup(target, indexEffects, () => cleanupLength(), {
|
|
145
|
-
source,
|
|
146
|
-
target,
|
|
147
|
-
apply,
|
|
148
|
-
depth,
|
|
149
|
-
parent,
|
|
150
|
-
} as ProjectionContext)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function projectRegister<Key extends PropertyKey, SourceValue, ResultValue>(
|
|
154
|
-
source: Register<SourceValue, Key>,
|
|
155
|
-
apply: ProjectCallback<
|
|
156
|
-
SourceValue,
|
|
157
|
-
Key,
|
|
158
|
-
Map<Key, ResultValue>,
|
|
159
|
-
Register<SourceValue, Key>,
|
|
160
|
-
ResultValue
|
|
161
|
-
>
|
|
162
|
-
): ProjectResult<Map<Key, ResultValue>> {
|
|
163
|
-
const observedSource = reactive(source) as Register<SourceValue, Key>
|
|
164
|
-
const rawTarget = new Map<Key, ResultValue>()
|
|
165
|
-
const target = reactive(rawTarget) as Map<Key, ResultValue>
|
|
166
|
-
const keyEffects = new Map<Key, ScopedCallback>()
|
|
167
|
-
|
|
168
|
-
function disposeKey(key: Key) {
|
|
169
|
-
const stopEffect = keyEffects.get(key)
|
|
170
|
-
if (stopEffect) {
|
|
171
|
-
stopEffect()
|
|
172
|
-
keyEffects.delete(key)
|
|
173
|
-
target.delete(key)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const parent = getActiveProjection()
|
|
178
|
-
const depth = parent ? parent.depth + 1 : 0
|
|
179
|
-
|
|
180
|
-
const cleanupKeys = effect(function projectRegisterEffect({ ascend }) {
|
|
181
|
-
const keys = new Set<Key>()
|
|
182
|
-
for (const key of observedSource.mapKeys()) keys.add(key)
|
|
183
|
-
|
|
184
|
-
for (const key of keys) {
|
|
185
|
-
if (keyEffects.has(key)) continue
|
|
186
|
-
ascend(() => {
|
|
187
|
-
const stop = effect(function projectRegisterKeyEffect() {
|
|
188
|
-
const previous = untracked(() => target.get(key))
|
|
189
|
-
const accessBase = {
|
|
190
|
-
key,
|
|
191
|
-
source: observedSource,
|
|
192
|
-
get: () => observedSource.get(key) as SourceValue,
|
|
193
|
-
set: (value: SourceValue) => {
|
|
194
|
-
observedSource.set(key, value)
|
|
195
|
-
return true
|
|
196
|
-
},
|
|
197
|
-
old: previous,
|
|
198
|
-
} as ProjectAccess<SourceValue, Key, Register<SourceValue, Key>, Map<Key, ResultValue>>
|
|
199
|
-
defineAccessValue(accessBase)
|
|
200
|
-
const produced = apply(accessBase, target)
|
|
201
|
-
target.set(key, produced)
|
|
202
|
-
})
|
|
203
|
-
setEffectName(stop, `project[${depth}]:${String(key)}`)
|
|
204
|
-
effectProjectionMetadata.set(stop, {
|
|
205
|
-
source: observedSource,
|
|
206
|
-
key,
|
|
207
|
-
target,
|
|
208
|
-
depth,
|
|
209
|
-
parent,
|
|
210
|
-
})
|
|
211
|
-
keyEffects.set(key, stop)
|
|
212
|
-
})
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
for (const key of Array.from(keyEffects.keys())) if (!keys.has(key)) disposeKey(key)
|
|
216
|
-
})
|
|
217
|
-
|
|
218
|
-
return makeCleanup(target, keyEffects, () => cleanupKeys(), {
|
|
219
|
-
source: observedSource,
|
|
220
|
-
target,
|
|
221
|
-
apply,
|
|
222
|
-
depth,
|
|
223
|
-
parent,
|
|
224
|
-
} as ProjectionContext)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
function projectRecord<Source extends Record<PropertyKey, any>, ResultValue>(
|
|
228
|
-
source: Source,
|
|
229
|
-
apply: ProjectCallback<
|
|
230
|
-
Source[keyof Source],
|
|
231
|
-
keyof Source,
|
|
232
|
-
Record<keyof Source, ResultValue>,
|
|
233
|
-
Source,
|
|
234
|
-
ResultValue
|
|
235
|
-
>
|
|
236
|
-
): ProjectResult<Record<keyof Source, ResultValue>> {
|
|
237
|
-
const observedSource = reactive(source) as Source
|
|
238
|
-
const target = reactive({} as Record<keyof Source, ResultValue>)
|
|
239
|
-
const keyEffects = new Map<PropertyKey, ScopedCallback>()
|
|
240
|
-
|
|
241
|
-
function disposeKey(key: PropertyKey) {
|
|
242
|
-
const stopEffect = keyEffects.get(key)
|
|
243
|
-
if (stopEffect) {
|
|
244
|
-
stopEffect()
|
|
245
|
-
keyEffects.delete(key)
|
|
246
|
-
Reflect.deleteProperty(target as Record<PropertyKey, unknown>, key)
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const parent = getActiveProjection()
|
|
251
|
-
const depth = parent ? parent.depth + 1 : 0
|
|
252
|
-
|
|
253
|
-
const cleanupKeys = effect(function projectRecordEffect({ ascend }) {
|
|
254
|
-
const keys = new Set<PropertyKey>()
|
|
255
|
-
for (const key in observedSource) keys.add(key)
|
|
256
|
-
const observed = Reflect.ownKeys(observedSource)
|
|
257
|
-
for (const key of observed) keys.add(key)
|
|
258
|
-
|
|
259
|
-
for (const key of keys) {
|
|
260
|
-
if (keyEffects.has(key)) continue
|
|
261
|
-
ascend(() => {
|
|
262
|
-
const stop = effect(function projectRecordKeyEffect() {
|
|
263
|
-
const sourceKey = key as keyof Source
|
|
264
|
-
const previous = untracked(
|
|
265
|
-
() => (target as Record<PropertyKey, ResultValue | undefined>)[key]
|
|
266
|
-
)
|
|
267
|
-
const accessBase = {
|
|
268
|
-
key: sourceKey,
|
|
269
|
-
source: observedSource,
|
|
270
|
-
get: () => FoolProof.get(observedSource, sourceKey, observedSource),
|
|
271
|
-
set: (value: Source[typeof sourceKey]) =>
|
|
272
|
-
FoolProof.set(observedSource, sourceKey, value, observedSource),
|
|
273
|
-
old: previous,
|
|
274
|
-
} as ProjectAccess<
|
|
275
|
-
Source[typeof sourceKey],
|
|
276
|
-
keyof Source,
|
|
277
|
-
Source,
|
|
278
|
-
Record<keyof Source, ResultValue>
|
|
279
|
-
>
|
|
280
|
-
defineAccessValue(accessBase)
|
|
281
|
-
const produced = apply(accessBase, target)
|
|
282
|
-
;(target as any)[sourceKey] = produced
|
|
283
|
-
})
|
|
284
|
-
setEffectName(stop, `project[${depth}]:${String(key)}`)
|
|
285
|
-
effectProjectionMetadata.set(stop, {
|
|
286
|
-
source: observedSource,
|
|
287
|
-
key,
|
|
288
|
-
target,
|
|
289
|
-
depth,
|
|
290
|
-
parent,
|
|
291
|
-
})
|
|
292
|
-
keyEffects.set(key, stop)
|
|
293
|
-
})
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
for (const key of Array.from(keyEffects.keys())) if (!keys.has(key)) disposeKey(key)
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
return makeCleanup(target, keyEffects, () => cleanupKeys(), {
|
|
300
|
-
source: observedSource,
|
|
301
|
-
target,
|
|
302
|
-
apply,
|
|
303
|
-
depth,
|
|
304
|
-
parent,
|
|
305
|
-
} as ProjectionContext)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
function projectMap<Key, Value, ResultValue>(
|
|
309
|
-
source: Map<Key, Value>,
|
|
310
|
-
apply: ProjectCallback<Value, Key, Map<Key, ResultValue>, Map<Key, Value>, ResultValue>
|
|
311
|
-
): ProjectResult<Map<Key, ResultValue>> {
|
|
312
|
-
const observedSource = reactive(source) as Map<Key, Value>
|
|
313
|
-
const rawTarget = new Map<Key, ResultValue>()
|
|
314
|
-
const target = reactive(rawTarget) as Map<Key, ResultValue>
|
|
315
|
-
const keyEffects = new Map<Key, ScopedCallback>()
|
|
316
|
-
|
|
317
|
-
function disposeKey(key: Key) {
|
|
318
|
-
const stopEffect = keyEffects.get(key)
|
|
319
|
-
if (stopEffect) {
|
|
320
|
-
stopEffect()
|
|
321
|
-
keyEffects.delete(key)
|
|
322
|
-
target.delete(key)
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
const parent = getActiveProjection()
|
|
327
|
-
const depth = parent ? parent.depth + 1 : 0
|
|
328
|
-
|
|
329
|
-
const cleanupKeys = effect(function projectMapEffect({ ascend }) {
|
|
330
|
-
const keys = new Set<Key>()
|
|
331
|
-
for (const key of observedSource.keys()) keys.add(key)
|
|
332
|
-
|
|
333
|
-
for (const key of keys) {
|
|
334
|
-
if (keyEffects.has(key)) continue
|
|
335
|
-
ascend(() => {
|
|
336
|
-
const stop = effect(function projectMapKeyEffect() {
|
|
337
|
-
const previous = untracked(() => target.get(key))
|
|
338
|
-
const accessBase = {
|
|
339
|
-
key,
|
|
340
|
-
source: observedSource,
|
|
341
|
-
get: () => observedSource.get(key) as Value,
|
|
342
|
-
set: (value: Value) => {
|
|
343
|
-
observedSource.set(key, value)
|
|
344
|
-
return true
|
|
345
|
-
},
|
|
346
|
-
old: previous,
|
|
347
|
-
} as ProjectAccess<Value, Key, Map<Key, Value>, Map<Key, ResultValue>>
|
|
348
|
-
defineAccessValue(accessBase)
|
|
349
|
-
const produced = apply(accessBase, target)
|
|
350
|
-
target.set(key, produced)
|
|
351
|
-
})
|
|
352
|
-
setEffectName(stop, `project[${depth}]:${String(key)}`)
|
|
353
|
-
effectProjectionMetadata.set(stop, {
|
|
354
|
-
source: observedSource,
|
|
355
|
-
key,
|
|
356
|
-
target,
|
|
357
|
-
depth,
|
|
358
|
-
parent,
|
|
359
|
-
})
|
|
360
|
-
keyEffects.set(key, stop)
|
|
361
|
-
})
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
for (const key of Array.from(keyEffects.keys())) if (!keys.has(key)) disposeKey(key)
|
|
365
|
-
})
|
|
366
|
-
|
|
367
|
-
return makeCleanup(target, keyEffects, () => cleanupKeys(), {
|
|
368
|
-
source: observedSource,
|
|
369
|
-
target,
|
|
370
|
-
apply,
|
|
371
|
-
depth,
|
|
372
|
-
parent,
|
|
373
|
-
} as ProjectionContext)
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
type ProjectOverload = {
|
|
377
|
-
<SourceValue, ResultValue>(
|
|
378
|
-
source: readonly SourceValue[],
|
|
379
|
-
apply: ProjectCallback<SourceValue, number, ResultValue[], readonly SourceValue[], ResultValue>
|
|
380
|
-
): ProjectResult<ResultValue[]>
|
|
381
|
-
<Key extends PropertyKey, SourceValue, ResultValue>(
|
|
382
|
-
source: Register<SourceValue, Key>,
|
|
383
|
-
apply: ProjectCallback<
|
|
384
|
-
SourceValue,
|
|
385
|
-
Key,
|
|
386
|
-
Map<Key, ResultValue>,
|
|
387
|
-
Register<SourceValue, Key>,
|
|
388
|
-
ResultValue
|
|
389
|
-
>
|
|
390
|
-
): ProjectResult<Map<Key, ResultValue>>
|
|
391
|
-
<Source extends Record<PropertyKey, any>, ResultValue>(
|
|
392
|
-
source: Source,
|
|
393
|
-
apply: ProjectCallback<
|
|
394
|
-
Source[keyof Source],
|
|
395
|
-
keyof Source,
|
|
396
|
-
Record<keyof Source, ResultValue>,
|
|
397
|
-
Source,
|
|
398
|
-
ResultValue
|
|
399
|
-
>
|
|
400
|
-
): ProjectResult<Record<keyof Source, ResultValue>>
|
|
401
|
-
<Key, Value, ResultValue>(
|
|
402
|
-
source: Map<Key, Value>,
|
|
403
|
-
apply: ProjectCallback<Value, Key, Map<Key, ResultValue>, Map<Key, Value>, ResultValue>
|
|
404
|
-
): ProjectResult<Map<Key, ResultValue>>
|
|
405
|
-
array: typeof projectArray
|
|
406
|
-
register: typeof projectRegister
|
|
407
|
-
record: typeof projectRecord
|
|
408
|
-
map: typeof projectMap
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
function projectCore<SourceValue, ResultValue>(
|
|
412
|
-
source: readonly SourceValue[],
|
|
413
|
-
apply: ProjectCallback<SourceValue, number, ResultValue[], readonly SourceValue[], ResultValue>
|
|
414
|
-
): ProjectResult<ResultValue[]>
|
|
415
|
-
function projectCore<Key extends PropertyKey, SourceValue, ResultValue>(
|
|
416
|
-
source: Register<SourceValue, Key>,
|
|
417
|
-
apply: ProjectCallback<
|
|
418
|
-
SourceValue,
|
|
419
|
-
Key,
|
|
420
|
-
Map<Key, ResultValue>,
|
|
421
|
-
Register<SourceValue, Key>,
|
|
422
|
-
ResultValue
|
|
423
|
-
>
|
|
424
|
-
): ProjectResult<Map<Key, ResultValue>>
|
|
425
|
-
function projectCore<Source extends Record<PropertyKey, any>, ResultValue>(
|
|
426
|
-
source: Source,
|
|
427
|
-
apply: ProjectCallback<
|
|
428
|
-
Source[keyof Source],
|
|
429
|
-
keyof Source,
|
|
430
|
-
Record<keyof Source, ResultValue>,
|
|
431
|
-
Source,
|
|
432
|
-
ResultValue
|
|
433
|
-
>
|
|
434
|
-
): ProjectResult<Record<keyof Source, ResultValue>>
|
|
435
|
-
function projectCore<Key, Value, ResultValue>(
|
|
436
|
-
source: Map<Key, Value>,
|
|
437
|
-
apply: ProjectCallback<Value, Key, Map<Key, ResultValue>, Map<Key, Value>, ResultValue>
|
|
438
|
-
): ProjectResult<Map<Key, ResultValue>>
|
|
439
|
-
function projectCore(source: any, apply: any): ProjectResult<any> {
|
|
440
|
-
if (Array.isArray(source)) return projectArray(source, apply)
|
|
441
|
-
if (source instanceof Map) return projectMap(source, apply)
|
|
442
|
-
if (source instanceof Register) return projectRegister(source, apply)
|
|
443
|
-
if (source && (source.constructor === Object || source.constructor === undefined))
|
|
444
|
-
return projectRecord(source, apply)
|
|
445
|
-
throw new Error('Unsupported source type')
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
export const project: ProjectOverload = Object.assign(projectCore, {
|
|
449
|
-
array: projectArray,
|
|
450
|
-
register: projectRegister,
|
|
451
|
-
record: projectRecord,
|
|
452
|
-
map: projectMap,
|
|
453
|
-
})
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export const objectToProxy = new WeakMap<object, object>()
|
|
2
|
-
export const proxyToObject = new WeakMap<object, object>()
|
|
3
|
-
|
|
4
|
-
export function storeProxyRelationship(target: object, proxy: object) {
|
|
5
|
-
objectToProxy.set(target, proxy)
|
|
6
|
-
proxyToObject.set(proxy, target)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function getExistingProxy<T extends object>(target: T): T | undefined {
|
|
10
|
-
return objectToProxy.get(target) as T | undefined
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function trackProxyObject(proxy: object, target: object) {
|
|
14
|
-
proxyToObject.set(proxy, target)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function unwrap<T>(obj: T): T {
|
|
18
|
-
let current = obj
|
|
19
|
-
while (current && typeof current === 'object' && current !== null && proxyToObject.has(current)) {
|
|
20
|
-
current = proxyToObject.get(current) as T
|
|
21
|
-
}
|
|
22
|
-
return current
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function isReactive(obj: any): boolean {
|
|
26
|
-
return proxyToObject.has(obj)
|
|
27
|
-
}
|