@vidact/runtime 0.2.0-beta.0 → 0.2.0-beta.5
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/CHANGELOG.md +52 -0
- package/README.md +1 -1
- package/dist/actions.d.ts +32 -30
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +251 -266
- package/dist/actions.js.map +1 -1
- package/dist/async.d.ts +20 -17
- package/dist/async.d.ts.map +1 -1
- package/dist/async.js +18 -17
- package/dist/async.js.map +1 -1
- package/dist/compiled/async-resource.d.ts +9 -6
- package/dist/compiled/async-resource.d.ts.map +1 -1
- package/dist/compiled/async-resource.js +69 -77
- package/dist/compiled/async-resource.js.map +1 -1
- package/dist/compiled/core.d.ts +136 -147
- package/dist/compiled/core.d.ts.map +1 -1
- package/dist/compiled/core.js +2672 -2985
- package/dist/compiled/core.js.map +1 -1
- package/dist/compiled/types.d.ts +44 -56
- package/dist/compiled/types.d.ts.map +1 -1
- package/dist/compiled/types.js +10 -6
- package/dist/compiled/types.js.map +1 -1
- package/dist/compiled/validation.d.ts +4 -1
- package/dist/compiled/validation.d.ts.map +1 -1
- package/dist/compiled/validation.js +17 -20
- package/dist/compiled/validation.js.map +1 -1
- package/dist/component-spread.d.ts +5 -3
- package/dist/component-spread.d.ts.map +1 -1
- package/dist/component-spread.js +49 -67
- package/dist/component-spread.js.map +1 -1
- package/dist/concurrent.d.ts +20 -18
- package/dist/concurrent.d.ts.map +1 -1
- package/dist/concurrent.js +191 -210
- package/dist/concurrent.js.map +1 -1
- package/dist/direct-dom.d.ts +17 -12
- package/dist/direct-dom.d.ts.map +1 -1
- package/dist/direct-dom.js +187 -221
- package/dist/direct-dom.js.map +1 -1
- package/dist/dom/attributes.d.ts +9 -6
- package/dist/dom/attributes.d.ts.map +1 -1
- package/dist/dom/attributes.js +65 -47
- package/dist/dom/attributes.js.map +1 -1
- package/dist/dom/events.d.ts +5 -2
- package/dist/dom/events.d.ts.map +1 -1
- package/dist/dom/events.js +53 -65
- package/dist/dom/events.js.map +1 -1
- package/dist/dom/forms.d.ts +9 -6
- package/dist/dom/forms.d.ts.map +1 -1
- package/dist/dom/forms.js +152 -198
- package/dist/dom/forms.js.map +1 -1
- package/dist/dom/intrinsic.d.ts +17 -15
- package/dist/dom/intrinsic.d.ts.map +1 -1
- package/dist/dom/intrinsic.js +48 -50
- package/dist/dom/intrinsic.js.map +1 -1
- package/dist/dom/namespace.d.ts +4 -1
- package/dist/dom/namespace.d.ts.map +1 -1
- package/dist/dom/namespace.js +25 -28
- package/dist/dom/namespace.js.map +1 -1
- package/dist/dom/namespaces.d.ts +11 -8
- package/dist/dom/namespaces.d.ts.map +1 -1
- package/dist/dom/namespaces.js +14 -12
- package/dist/dom/namespaces.js.map +1 -1
- package/dist/dom/properties.d.ts +18 -16
- package/dist/dom/properties.d.ts.map +1 -1
- package/dist/dom/properties.js +273 -296
- package/dist/dom/properties.js.map +1 -1
- package/dist/dom/style-properties.d.ts +4 -1
- package/dist/dom/style-properties.d.ts.map +1 -1
- package/dist/dom/style-properties.js +49 -45
- package/dist/dom/style-properties.js.map +1 -1
- package/dist/dom/styles.d.ts +5 -2
- package/dist/dom/styles.d.ts.map +1 -1
- package/dist/dom/styles.js +47 -67
- package/dist/dom/styles.js.map +1 -1
- package/dist/dom-forms.d.ts +4 -1
- package/dist/dom-forms.d.ts.map +1 -1
- package/dist/dom-forms.js +16 -13
- package/dist/dom-forms.js.map +1 -1
- package/dist/dom-styles.d.ts +4 -1
- package/dist/dom-styles.d.ts.map +1 -1
- package/dist/dom-styles.js +10 -7
- package/dist/dom-styles.js.map +1 -1
- package/dist/framework-hydrate.d.ts +20 -17
- package/dist/framework-hydrate.d.ts.map +1 -1
- package/dist/framework-hydrate.js +128 -146
- package/dist/framework-hydrate.js.map +1 -1
- package/dist/framework-protocol.d.ts +27 -25
- package/dist/framework-protocol.d.ts.map +1 -1
- package/dist/framework-protocol.js +173 -211
- package/dist/framework-protocol.js.map +1 -1
- package/dist/framework.d.ts +34 -32
- package/dist/framework.d.ts.map +1 -1
- package/dist/framework.js +74 -93
- package/dist/framework.js.map +1 -1
- package/dist/hydrate.d.ts +11 -8
- package/dist/hydrate.d.ts.map +1 -1
- package/dist/hydrate.js +13 -9
- package/dist/hydrate.js.map +1 -1
- package/dist/hydration-bridge.d.ts +70 -58
- package/dist/hydration-bridge.d.ts.map +1 -1
- package/dist/hydration-bridge.js +77 -66
- package/dist/hydration-bridge.js.map +1 -1
- package/dist/hydration.d.ts +54 -28
- package/dist/hydration.d.ts.map +1 -1
- package/dist/hydration.js +450 -463
- package/dist/hydration.js.map +1 -1
- package/dist/index.d.ts +13 -13
- package/dist/index.js +11 -13
- package/dist/indexed-list.d.ts +8 -5
- package/dist/indexed-list.d.ts.map +1 -1
- package/dist/indexed-list.js +14 -7
- package/dist/indexed-list.js.map +1 -1
- package/dist/jsx-runtime.d.ts +10 -8
- package/dist/jsx-runtime.d.ts.map +1 -1
- package/dist/jsx-runtime.js +28 -23
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/keyed-list.d.ts +13 -14
- package/dist/keyed-list.d.ts.map +1 -1
- package/dist/keyed-list.js +132 -160
- package/dist/keyed-list.js.map +1 -1
- package/dist/metadata.d.ts +6 -3
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +131 -164
- package/dist/metadata.js.map +1 -1
- package/dist/nested-prop.d.ts +4 -2
- package/dist/nested-prop.d.ts.map +1 -1
- package/dist/nested-prop.js +17 -16
- package/dist/nested-prop.js.map +1 -1
- package/dist/profiling.d.ts +11 -8
- package/dist/profiling.d.ts.map +1 -1
- package/dist/profiling.js +17 -17
- package/dist/profiling.js.map +1 -1
- package/dist/protocol.d.ts +5 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +8 -5
- package/dist/protocol.js.map +1 -1
- package/dist/raw-html.d.ts +5 -2
- package/dist/raw-html.d.ts.map +1 -1
- package/dist/raw-html.js +86 -146
- package/dist/raw-html.js.map +1 -1
- package/dist/ref.d.ts +8 -3
- package/dist/ref.d.ts.map +1 -1
- package/dist/ref.js +10 -2
- package/dist/ref.js.map +1 -1
- package/dist/renderable-protocol.d.ts +26 -8
- package/dist/renderable-protocol.d.ts.map +1 -1
- package/dist/renderable-protocol.js +30 -9
- package/dist/renderable-protocol.js.map +1 -1
- package/dist/renderable.d.ts +27 -22
- package/dist/renderable.d.ts.map +1 -1
- package/dist/renderable.js +141 -133
- package/dist/renderable.js.map +1 -1
- package/dist/retained-ui.d.ts +9 -6
- package/dist/retained-ui.d.ts.map +1 -1
- package/dist/retained-ui.js +12 -10
- package/dist/retained-ui.js.map +1 -1
- package/dist/root.d.ts +18 -15
- package/dist/root.d.ts.map +1 -1
- package/dist/root.js +73 -85
- package/dist/root.js.map +1 -1
- package/dist/scheduler.d.ts +10 -8
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/scheduler.js +97 -105
- package/dist/scheduler.js.map +1 -1
- package/dist/server-framework.d.ts +45 -42
- package/dist/server-framework.d.ts.map +1 -1
- package/dist/server-framework.js +209 -217
- package/dist/server-framework.js.map +1 -1
- package/dist/server.d.ts +130 -128
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +603 -710
- package/dist/server.js.map +1 -1
- package/dist/shared/promise.d.ts +6 -3
- package/dist/shared/promise.d.ts.map +1 -1
- package/dist/shared/promise.js +21 -19
- package/dist/shared/promise.js.map +1 -1
- package/dist/source-mask.d.ts +9 -6
- package/dist/source-mask.d.ts.map +1 -1
- package/dist/source-mask.js +45 -63
- package/dist/source-mask.js.map +1 -1
- package/dist/spread.d.ts +5 -2
- package/dist/spread.d.ts.map +1 -1
- package/dist/spread.js +79 -99
- package/dist/spread.js.map +1 -1
- package/dist/state-slot.d.ts +18 -15
- package/dist/state-slot.d.ts.map +1 -1
- package/dist/state-slot.js +43 -42
- package/dist/state-slot.js.map +1 -1
- package/dist/testing.d.ts +9 -6
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +16 -12
- package/dist/testing.js.map +1 -1
- package/package.json +8 -7
- package/src/actions.ts +415 -0
- package/src/async.ts +78 -0
- package/src/compiled/async-resource.ts +113 -0
- package/src/compiled/core.ts +4041 -0
- package/src/compiled/types.ts +96 -0
- package/src/compiled/validation.ts +23 -0
- package/src/component-spread.ts +86 -0
- package/src/concurrent.ts +310 -0
- package/src/direct-dom.ts +365 -0
- package/src/dom/attributes.ts +55 -0
- package/src/dom/events.ts +93 -0
- package/src/dom/forms.ts +220 -0
- package/src/dom/intrinsic.ts +94 -0
- package/src/dom/namespace.ts +30 -0
- package/src/dom/namespaces.ts +14 -0
- package/src/dom/properties.ts +355 -0
- package/src/dom/style-properties.ts +46 -0
- package/src/dom/styles.ts +86 -0
- package/src/dom-forms.ts +23 -0
- package/src/dom-styles.ts +11 -0
- package/src/env.d.ts +6 -0
- package/src/framework-hydrate.ts +224 -0
- package/src/framework-protocol.ts +335 -0
- package/src/framework.ts +161 -0
- package/src/hydrate.ts +38 -0
- package/src/hydration-bridge.ts +196 -0
- package/src/hydration.ts +642 -0
- package/src/index.ts +92 -0
- package/src/indexed-list.ts +20 -0
- package/src/jsx-runtime.ts +55 -0
- package/src/keyed-list.ts +233 -0
- package/src/metadata.ts +212 -0
- package/src/nested-prop.ts +27 -0
- package/src/profiling.ts +43 -0
- package/src/protocol.ts +8 -0
- package/src/raw-html.ts +206 -0
- package/src/ref.ts +13 -0
- package/src/renderable-protocol.ts +63 -0
- package/src/renderable.ts +283 -0
- package/src/retained-ui.ts +19 -0
- package/src/root.ts +122 -0
- package/src/scheduler.ts +136 -0
- package/src/server-framework.ts +397 -0
- package/src/server.ts +1160 -0
- package/src/shared/promise.ts +28 -0
- package/src/source-mask.ts +83 -0
- package/src/spread.ts +131 -0
- package/src/state-slot.ts +76 -0
- package/src/testing.ts +27 -0
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function abortReason(signal: AbortSignal): unknown {
|
|
2
|
+
return signal.reason ?? new DOMException('The operation was aborted', 'AbortError')
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function isPromiseLike<Value>(value: unknown): value is PromiseLike<Value> {
|
|
6
|
+
return (
|
|
7
|
+
((typeof value === 'object' && value !== null) || typeof value === 'function') &&
|
|
8
|
+
typeof (value as PromiseLike<Value>).then === 'function'
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function withAbort<Value>(operation: Promise<Value>, signal: AbortSignal): Promise<Value> {
|
|
13
|
+
if (signal.aborted) return Promise.reject(abortReason(signal))
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const onAbort = (): void => reject(abortReason(signal))
|
|
16
|
+
signal.addEventListener('abort', onAbort, { once: true })
|
|
17
|
+
void operation.then(
|
|
18
|
+
(value) => {
|
|
19
|
+
signal.removeEventListener('abort', onAbort)
|
|
20
|
+
resolve(value)
|
|
21
|
+
},
|
|
22
|
+
(error: unknown) => {
|
|
23
|
+
signal.removeEventListener('abort', onAbort)
|
|
24
|
+
reject(error)
|
|
25
|
+
},
|
|
26
|
+
)
|
|
27
|
+
})
|
|
28
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const BITS_PER_WORD = 32
|
|
2
|
+
const DEV = typeof __VIDACT_DEV__ === 'undefined' || __VIDACT_DEV__
|
|
3
|
+
|
|
4
|
+
export type SourceMask = number | Uint32Array
|
|
5
|
+
|
|
6
|
+
export function source(index: number): SourceMask {
|
|
7
|
+
if (!Number.isSafeInteger(index) || index < 0) {
|
|
8
|
+
throw new RangeError(
|
|
9
|
+
DEV ? `source index must be a non-negative safe integer, received ${index}` : 'V701',
|
|
10
|
+
)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const word = Math.floor(index / BITS_PER_WORD)
|
|
14
|
+
const bit = (1 << (index % BITS_PER_WORD)) >>> 0
|
|
15
|
+
if (word === 0) return bit
|
|
16
|
+
|
|
17
|
+
const words = new Uint32Array(word + 1)
|
|
18
|
+
words[word] = bit
|
|
19
|
+
return words
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function combineSources(...masks: readonly SourceMask[]): SourceMask {
|
|
23
|
+
const length = masks.reduce<number>((maximum, mask) => Math.max(maximum, wordLength(mask)), 1)
|
|
24
|
+
if (length === 1) {
|
|
25
|
+
let combined = 0
|
|
26
|
+
for (const mask of masks) combined = (combined | wordAt(mask, 0)) >>> 0
|
|
27
|
+
return combined
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const combined = new Uint32Array(length)
|
|
31
|
+
for (const mask of masks) {
|
|
32
|
+
for (let index = 0; index < wordLength(mask); index += 1) {
|
|
33
|
+
combined[index] = ((combined[index] ?? 0) | wordAt(mask, index)) >>> 0
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return combined
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function intersectsSources(left: SourceMask, right: SourceMask): boolean {
|
|
40
|
+
if (typeof left === 'number' && typeof right === 'number') {
|
|
41
|
+
return (left & right) >>> 0 !== 0
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const leftLength = wordLength(left)
|
|
45
|
+
const rightLength = wordLength(right)
|
|
46
|
+
const length = Math.min(leftLength, rightLength)
|
|
47
|
+
for (let index = 0; index < length; index += 1) {
|
|
48
|
+
if ((wordAt(left, index) & wordAt(right, index)) >>> 0 !== 0) return true
|
|
49
|
+
}
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function isEmptySources(mask: SourceMask): boolean {
|
|
54
|
+
if (typeof mask === 'number') return mask === 0
|
|
55
|
+
for (const word of mask) {
|
|
56
|
+
if (word !== 0) return false
|
|
57
|
+
}
|
|
58
|
+
return true
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function unionSources(left: SourceMask, right: SourceMask): SourceMask {
|
|
62
|
+
if (typeof left === 'number' && typeof right === 'number') {
|
|
63
|
+
return (left | right) >>> 0
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const leftLength = wordLength(left)
|
|
67
|
+
const rightLength = wordLength(right)
|
|
68
|
+
const length = Math.max(leftLength, rightLength)
|
|
69
|
+
const words = new Uint32Array(length)
|
|
70
|
+
for (let index = 0; index < length; index += 1) {
|
|
71
|
+
words[index] = (wordAt(left, index) | wordAt(right, index)) >>> 0
|
|
72
|
+
}
|
|
73
|
+
return words
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function wordAt(mask: SourceMask, index: number): number {
|
|
77
|
+
if (typeof mask === 'number') return index === 0 ? mask : 0
|
|
78
|
+
return mask[index] ?? 0
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function wordLength(mask: SourceMask): number {
|
|
82
|
+
return typeof mask === 'number' ? 1 : mask.length
|
|
83
|
+
}
|
package/src/spread.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import {
|
|
2
|
+
binding as createBinding,
|
|
3
|
+
mountCompiledPropTransition,
|
|
4
|
+
mountCompiledRef,
|
|
5
|
+
registerCompiledCleanup,
|
|
6
|
+
} from './compiled/core.ts'
|
|
7
|
+
import type { CompiledBinding } from './compiled/types.ts'
|
|
8
|
+
import { attachEventProp, isEventProp } from './dom/events.ts'
|
|
9
|
+
import { INTERNAL_NAMESPACE_PROP } from './dom/intrinsic.ts'
|
|
10
|
+
import {
|
|
11
|
+
applyDomProp,
|
|
12
|
+
ensureControlledFormRestoration,
|
|
13
|
+
isControlledFormProp,
|
|
14
|
+
} from './dom/properties.ts'
|
|
15
|
+
|
|
16
|
+
const DEV = typeof __VIDACT_DEV__ === 'undefined' || __VIDACT_DEV__
|
|
17
|
+
let spreadId = 0
|
|
18
|
+
|
|
19
|
+
export function compiledSpread(
|
|
20
|
+
binding: CompiledBinding<unknown>,
|
|
21
|
+
overriddenNames: readonly string[],
|
|
22
|
+
): Record<string, (element: Element) => boolean> {
|
|
23
|
+
return {
|
|
24
|
+
[`__vidactSpread${spreadId++}`]: (element) =>
|
|
25
|
+
mountReactiveSpread(element, binding, overriddenNames),
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function mountReactiveSpread(
|
|
30
|
+
element: Element,
|
|
31
|
+
binding: CompiledBinding<unknown>,
|
|
32
|
+
overriddenNames: readonly string[],
|
|
33
|
+
): boolean {
|
|
34
|
+
const overrides = new Set(overriddenNames)
|
|
35
|
+
const cleanups = new Map<string, () => void>()
|
|
36
|
+
let controlledCleanup: (() => void) | undefined
|
|
37
|
+
let restoreAfterChildren = false
|
|
38
|
+
const active = (value: unknown): Record<string, unknown> => {
|
|
39
|
+
if (value === null || value === undefined) return {}
|
|
40
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
41
|
+
throw new TypeError(DEV ? 'reactive JSX spread value must be an object or nullish' : 'V105')
|
|
42
|
+
}
|
|
43
|
+
return value as Record<string, unknown>
|
|
44
|
+
}
|
|
45
|
+
if (!overrides.has('ref')) {
|
|
46
|
+
mountCompiledRef(
|
|
47
|
+
element,
|
|
48
|
+
createBinding(binding[2], binding[3], () => active(binding[1]()).ref, binding[4], binding[5]),
|
|
49
|
+
)
|
|
50
|
+
overrides.add('ref')
|
|
51
|
+
}
|
|
52
|
+
const apply = (name: string, value: unknown): (() => void) => {
|
|
53
|
+
if (
|
|
54
|
+
name === 'children' ||
|
|
55
|
+
name === 'key' ||
|
|
56
|
+
name === 'dangerouslySetInnerHTML' ||
|
|
57
|
+
name === INTERNAL_NAMESPACE_PROP
|
|
58
|
+
) {
|
|
59
|
+
throw new TypeError(
|
|
60
|
+
DEV
|
|
61
|
+
? `reactive JSX spread property ${name} requires dedicated ownership semantics`
|
|
62
|
+
: 'V105',
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
if (isControlledFormProp(element, name) && controlledCleanup === undefined) {
|
|
66
|
+
controlledCleanup = ensureControlledFormRestoration(element)
|
|
67
|
+
}
|
|
68
|
+
if (name === 'value' && element instanceof HTMLSelectElement) restoreAfterChildren = true
|
|
69
|
+
if (isEventProp(name)) return attachEventProp(element, name, value)
|
|
70
|
+
applyDomProp(element, name, value)
|
|
71
|
+
return () => {}
|
|
72
|
+
}
|
|
73
|
+
const visibleEntries = (value: Record<string, unknown>): Array<[string, unknown]> =>
|
|
74
|
+
Object.entries(value).filter(([name]) => !overrides.has(name))
|
|
75
|
+
|
|
76
|
+
mountCompiledPropTransition(
|
|
77
|
+
binding,
|
|
78
|
+
(initial) => {
|
|
79
|
+
for (const [name, value] of visibleEntries(active(initial))) {
|
|
80
|
+
cleanups.set(name, apply(name, value))
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
(nextValue, previousValue) => {
|
|
84
|
+
const next = active(nextValue)
|
|
85
|
+
const previous = active(previousValue)
|
|
86
|
+
const names = new Set([...Object.keys(previous), ...Object.keys(next)])
|
|
87
|
+
const changes = [...names]
|
|
88
|
+
.filter((name) => !overrides.has(name) && !Object.is(next[name], previous[name]))
|
|
89
|
+
.map((name) => ({ name, next: next[name], previous: previous[name] }))
|
|
90
|
+
const undo: Array<() => void> = []
|
|
91
|
+
return [
|
|
92
|
+
() => {
|
|
93
|
+
for (const change of changes) {
|
|
94
|
+
const previousCleanup = cleanups.get(change.name)
|
|
95
|
+
let nextCleanup: () => void
|
|
96
|
+
try {
|
|
97
|
+
nextCleanup = apply(change.name, change.next)
|
|
98
|
+
} catch (error) {
|
|
99
|
+
try {
|
|
100
|
+
apply(change.name, change.previous)
|
|
101
|
+
} catch {
|
|
102
|
+
// Preserve the spread property error that aborted publication.
|
|
103
|
+
}
|
|
104
|
+
throw error
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
previousCleanup?.()
|
|
108
|
+
} catch (error) {
|
|
109
|
+
nextCleanup()
|
|
110
|
+
throw error
|
|
111
|
+
}
|
|
112
|
+
cleanups.set(change.name, nextCleanup)
|
|
113
|
+
undo.push(() => {
|
|
114
|
+
nextCleanup()
|
|
115
|
+
cleanups.set(change.name, apply(change.name, change.previous))
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
() => {
|
|
120
|
+
for (let index = undo.length - 1; index >= 0; index -= 1) undo[index]?.()
|
|
121
|
+
undo.length = 0
|
|
122
|
+
},
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
)
|
|
126
|
+
registerCompiledCleanup(() => {
|
|
127
|
+
controlledCleanup?.()
|
|
128
|
+
for (const cleanup of cleanups.values()) cleanup()
|
|
129
|
+
})
|
|
130
|
+
return restoreAfterChildren
|
|
131
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { SourceMask } from './source-mask.ts'
|
|
2
|
+
|
|
3
|
+
export type StateUpdate<T> = T | ((previous: T) => T)
|
|
4
|
+
|
|
5
|
+
export interface DeferredStateWrite<T> {
|
|
6
|
+
readonly slot: object
|
|
7
|
+
readonly revision: number
|
|
8
|
+
readonly update: StateUpdate<T>
|
|
9
|
+
readonly commit: (update: StateUpdate<T>) => void
|
|
10
|
+
readonly currentRevision: () => number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type StateWriteInterceptor = <T>(write: DeferredStateWrite<T>) => boolean
|
|
14
|
+
|
|
15
|
+
let stateWriteInterceptor: StateWriteInterceptor | undefined
|
|
16
|
+
|
|
17
|
+
export function installStateWriteInterceptor(interceptor: StateWriteInterceptor): void {
|
|
18
|
+
stateWriteInterceptor = interceptor
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface StateSlot<T> {
|
|
22
|
+
readonly get: () => T
|
|
23
|
+
readonly set: (update: StateUpdate<T>) => void
|
|
24
|
+
readonly replace: (value: T) => void
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createStateSlot<T>(
|
|
28
|
+
invalidate: (sources: SourceMask) => void,
|
|
29
|
+
source: SourceMask,
|
|
30
|
+
initialValue: T,
|
|
31
|
+
assertWritable?: () => void,
|
|
32
|
+
): StateSlot<T> {
|
|
33
|
+
let value = initialValue
|
|
34
|
+
let revision = 0
|
|
35
|
+
const token = {}
|
|
36
|
+
|
|
37
|
+
const commit = (next: T): void => {
|
|
38
|
+
if (Object.is(value, next)) return
|
|
39
|
+
|
|
40
|
+
value = next
|
|
41
|
+
revision += 1
|
|
42
|
+
invalidate(source)
|
|
43
|
+
}
|
|
44
|
+
const commitUpdate = (update: StateUpdate<T>): void => {
|
|
45
|
+
const next = typeof update === 'function' ? (update as (previous: T) => T)(value) : update
|
|
46
|
+
commit(next)
|
|
47
|
+
}
|
|
48
|
+
const commitReplacement = (replacement: StateUpdate<T>): void => commit(replacement as T)
|
|
49
|
+
const write = (update: StateUpdate<T>, commitWrite: (update: StateUpdate<T>) => void): void => {
|
|
50
|
+
if (
|
|
51
|
+
stateWriteInterceptor?.({
|
|
52
|
+
slot: token,
|
|
53
|
+
revision,
|
|
54
|
+
update,
|
|
55
|
+
commit: commitWrite,
|
|
56
|
+
currentRevision: () => revision,
|
|
57
|
+
})
|
|
58
|
+
) {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
commitWrite(update)
|
|
62
|
+
}
|
|
63
|
+
const replace = (next: T): void => {
|
|
64
|
+
assertWritable?.()
|
|
65
|
+
write(next, commitReplacement)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
get: () => value,
|
|
70
|
+
set: (update) => {
|
|
71
|
+
assertWritable?.()
|
|
72
|
+
write(update, commitUpdate)
|
|
73
|
+
},
|
|
74
|
+
replace,
|
|
75
|
+
}
|
|
76
|
+
}
|
package/src/testing.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { readCompiledOwnerMetrics as readOwnerMetrics } from './compiled/core.ts'
|
|
2
|
+
import {
|
|
3
|
+
beginActScope as beginSchedulerActScope,
|
|
4
|
+
endActScope as endSchedulerActScope,
|
|
5
|
+
flushScheduledTasks as flushSchedulerTasks,
|
|
6
|
+
hasScheduledTasks as schedulerHasTasks,
|
|
7
|
+
} from './scheduler.ts'
|
|
8
|
+
|
|
9
|
+
export function beginActScope(): void {
|
|
10
|
+
beginSchedulerActScope()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function endActScope(): void {
|
|
14
|
+
endSchedulerActScope()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function flushScheduledTasks(): number {
|
|
18
|
+
return flushSchedulerTasks()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function hasScheduledTasks(): boolean {
|
|
22
|
+
return schedulerHasTasks()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function readCompiledOwnerMetrics(): ReturnType<typeof readOwnerMetrics> {
|
|
26
|
+
return readOwnerMetrics()
|
|
27
|
+
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,OAAO,EACP,MAAM,EACN,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,yBAAyB,EACzB,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,OAAO,EACP,KAAK,EACL,aAAa,EACb,gBAAgB,EAChB,GAAG,EACH,WAAW,EACX,UAAU,EACV,SAAS,EACT,cAAc,EACd,KAAK,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,oBAAoB,EACpB,IAAI,EACJ,KAAK,UAAU,EACf,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,UAAU,EACV,iBAAiB,GAClB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EACL,aAAa,EACb,QAAQ,EACR,CAAC,EACD,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,GACjB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC9E,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAA;AACxF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H,mCAAmC;AAEnC,OAAO,EACL,OAAO,EACP,MAAM,EACN,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,yBAAyB,EACzB,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,OAAO,EACP,KAAK,EACL,aAAa,EACb,gBAAgB,EAChB,GAAG,EACH,WAAW,EACX,UAAU,EACV,SAAS,EACT,cAAc,EACd,KAAK,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,OAAO,EACP,oBAAoB,EACpB,IAAI,GAGL,MAAM,oBAAoB,CAAA;AAW3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EACL,aAAa,EACb,QAAQ,EACR,CAAC,GAIF,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AAC9E,OAAO,EAAE,MAAM,EAAmB,MAAM,UAAU,CAAA;AAClD,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,iBAAiB,GAGlB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAsC,MAAM,WAAW,CAAA;AACxF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,EAAmB,MAAM,kBAAkB,CAAA;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA"}
|