+175
-103
@@ -60,5 +60,3 @@ 'use strict'; | ||
| registry: undefined, | ||
| done: false, | ||
| isHydrationInProgress, | ||
| onHydrationEnd | ||
| done: false | ||
| }; | ||
@@ -118,9 +116,7 @@ function hydrationGetNextContextId() { | ||
| let _createErrorBoundary; | ||
| let _createOptimistic; | ||
| let _createProjection; | ||
| let _createStore; | ||
| let _createOptimisticStore; | ||
| let _createRenderEffect; | ||
| let _createEffect; | ||
| let _createLoadingBoundary; | ||
| let _hydrateSignalLike; | ||
| let _hydrateStoreLike; | ||
| let _lazyHydrationLookup; | ||
@@ -168,5 +164,8 @@ // it in EVERY client bundle even with zero references; the PURE-annotated | ||
| } | ||
| function readHydratedValue(initP, refresh) { | ||
| function readHydratedValue(initP, refresh, options) { | ||
| refresh(); | ||
| if (initP != null && typeof initP === "object") { | ||
| if (hasLoadingWindow(options) && typeof initP.then === "function") return { | ||
| then: initP.then.bind(initP) | ||
| }; | ||
| if (initP.s === 2) throw initP.v; | ||
@@ -177,7 +176,18 @@ if (initP.s === 1) return initP.v; | ||
| } | ||
| function readSerializedOrCompute(compute, prev) { | ||
| function readSerializedOrCompute(compute, prev, options) { | ||
| const o = signals.getOwner(); | ||
| if (sharedConfig.done || !sharedConfig.has(o.id)) return compute(prev); | ||
| return readHydratedValue(sharedConfig.load(o.id), () => subFetch(compute, prev)); | ||
| return readHydratedValue(sharedConfig.load(o.id), () => subFetch(compute, prev), options); | ||
| } | ||
| function assertClientCommitZero(fn, options, seed) { | ||
| if (typeof fn !== "function" || options?.ssrSource !== "client") return; | ||
| if (seed ? options.seedLoadingValue === true : "loadingValue" in options) return; | ||
| throw new Error(`ssrSource: "client" requires ${seed ? "seedLoadingValue: true" : "a loadingValue"} — the server cannot run this source, so you must declare what it renders (commit #0).`); | ||
| } | ||
| const UNASKED = { | ||
| then() {} | ||
| }; | ||
| function hasLoadingWindow(options) { | ||
| return options != null && typeof options === "object" && ("loadingValue" in options || options.seedLoadingValue === true); | ||
| } | ||
| function forwardIteratorReturn(it, value) { | ||
@@ -190,3 +200,3 @@ const returned = it.return?.(value); | ||
| } | ||
| function normalizeIterator(it) { | ||
| function normalizeIterator(it, deferFirst) { | ||
| let first = true; | ||
@@ -199,3 +209,4 @@ let buffered = null; | ||
| const r = it.next(); | ||
| return r && typeof r.then === "function" ? r : syncThenable(r); | ||
| if (r && typeof r.then === "function") return r; | ||
| return deferFirst ? Promise.resolve(r) : syncThenable(r); | ||
| } | ||
@@ -209,2 +220,3 @@ if (buffered) { | ||
| if (latest && typeof latest.then === "function") return latest; | ||
| let result = latest; | ||
| while (!latest.done) { | ||
@@ -217,4 +229,5 @@ const peek = it.next(); | ||
| latest = peek; | ||
| if (!latest.done) result = latest;else if (result !== latest) buffered = Promise.resolve(latest); | ||
| } | ||
| return Promise.resolve(latest); | ||
| return Promise.resolve(result); | ||
| }, | ||
@@ -315,3 +328,3 @@ return(value) { | ||
| if (!isAsyncIterable(loaded)) return null; | ||
| const it = normalizeIterator(loaded[Symbol.asyncIterator]()); | ||
| const it = normalizeIterator(loaded[Symbol.asyncIterator](), hasLoadingWindow(options)); | ||
| const iterable = { | ||
@@ -334,2 +347,3 @@ [Symbol.asyncIterator]() { | ||
| const srcIt = loaded[Symbol.asyncIterator](); | ||
| const loading = hasLoadingWindow(options); | ||
| let isFirst = true; | ||
@@ -377,7 +391,13 @@ let buffered = null; | ||
| const r = srcIt.next(); | ||
| return r && typeof r.then === "function" ? { | ||
| if (r && typeof r.then === "function") return { | ||
| then(fn, rej) { | ||
| r.then(v => fn(process(v)), rej); | ||
| } | ||
| } : syncThenable(process(r)); | ||
| }; | ||
| if (loading) { | ||
| return new Promise(resolvePull => { | ||
| onHydrationEnd(() => resolvePull(process(r))); | ||
| }); | ||
| } | ||
| return syncThenable(process(r)); | ||
| } | ||
@@ -393,13 +413,17 @@ if (buffered) { | ||
| } | ||
| let result = process(r); | ||
| while (!r.done) { | ||
| const peek = srcIt.next(); | ||
| if (peek && typeof peek.then === "function") { | ||
| buffered = peek; | ||
| break; | ||
| } | ||
| r = peek; | ||
| if (!r.done) result = process(r); | ||
| } | ||
| return Promise.resolve(result); | ||
| return new Promise(resolvePull => { | ||
| onHydrationEnd(() => { | ||
| let result = process(r); | ||
| while (!r.done) { | ||
| const peek = srcIt.next(); | ||
| if (peek && typeof peek.then === "function") { | ||
| buffered = peek; | ||
| break; | ||
| } | ||
| r = peek; | ||
| if (!r.done) result = process(r); | ||
| } | ||
| resolvePull(result); | ||
| }); | ||
| }); | ||
| }, | ||
@@ -415,41 +439,63 @@ return(value) { | ||
| } | ||
| function hydratedCreateMemo(compute, options) { | ||
| if (!sharedConfig.hydrating || options?.transparent) { | ||
| return signals.createMemo(compute, options); | ||
| } | ||
| function materializeContainerTrace(marker) { | ||
| const src = marker.$tr; | ||
| return signals.createRoot(() => createProjection(draft => ({ | ||
| [Symbol.asyncIterator]() { | ||
| const srcIt = src[Symbol.asyncIterator](); | ||
| let first = true; | ||
| return { | ||
| next: () => Promise.resolve(srcIt.next()).then(res => { | ||
| if (res.done) return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| if (first) { | ||
| first = false; | ||
| if (Array.isArray(res.value)) { | ||
| for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i]; | ||
| draft.length = res.value.length; | ||
| } else { | ||
| Object.assign(draft, res.value); | ||
| } | ||
| } else { | ||
| applyPatches(draft, res.value); | ||
| } | ||
| return { | ||
| done: false, | ||
| value: undefined | ||
| }; | ||
| }), | ||
| return: value => forwardIteratorReturn(srcIt, value) | ||
| }; | ||
| } | ||
| }), marker.$ta ? [] : {})); | ||
| } | ||
| function hydrateSignalLike(coreFn, fn, options) { | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = options?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const windowed = hasLoadingWindow(options); | ||
| const [hydrated, setHydrated] = signals.createSignal(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const memo = signals.createMemo(prev => { | ||
| if (!hydrated()) return prev; | ||
| return compute(prev); | ||
| const sig = coreFn(prev => { | ||
| if (!hydrated()) return windowed ? UNASKED : prev; | ||
| return fn(prev); | ||
| }, options); | ||
| setHydrated(true); | ||
| return memo; | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(signals.createMemo, compute, options); | ||
| const aiResult = hydrateSignalFromAsyncIterable(coreFn, fn, options); | ||
| if (aiResult !== null) return aiResult; | ||
| return signals.createMemo(prev => readSerializedOrCompute(compute, prev), options); | ||
| return coreFn(prev => readSerializedOrCompute(fn, prev, options), options); | ||
| } | ||
| function hydratedCreateMemo(compute, options) { | ||
| if (!sharedConfig.hydrating || options?.transparent) { | ||
| return signals.createMemo(compute, options); | ||
| } | ||
| return hydrateSignalLike(signals.createMemo, compute, options); | ||
| } | ||
| function hydratedCreateSignal(fn, second) { | ||
| if (typeof fn !== "function" || !sharedConfig.hydrating) return signals.createSignal(fn, second); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = second?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const [hydrated, setHydrated] = signals.createSignal(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const sig = signals.createSignal(prev => { | ||
| if (!hydrated()) return prev; | ||
| return fn(prev); | ||
| }, second); | ||
| setHydrated(true); | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(signals.createSignal, fn, second); | ||
| if (aiResult !== null) return aiResult; | ||
| return signals.createSignal(prev => readSerializedOrCompute(fn, prev), second); | ||
| return hydrateSignalLike(signals.createSignal, fn, second); | ||
| } | ||
@@ -476,26 +522,8 @@ function hydratedCreateErrorBoundary(fn, fallback) { | ||
| } | ||
| function hydratedCreateOptimistic(fn, second) { | ||
| if (typeof fn !== "function" || !sharedConfig.hydrating) return signals.createOptimistic(fn, second); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = second?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const [hydrated, setHydrated] = signals.createSignal(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const sig = signals.createOptimistic(prev => { | ||
| if (!hydrated()) return prev; | ||
| return fn(prev); | ||
| }, second); | ||
| setHydrated(true); | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(signals.createOptimistic, fn, second); | ||
| if (aiResult !== null) return aiResult; | ||
| return signals.createOptimistic(prev => readSerializedOrCompute(fn, prev), second); | ||
| function wrapStoreFn(fn, options) { | ||
| return draft => readSerializedOrCompute(() => fn(draft), draft, options); | ||
| } | ||
| function wrapStoreFn(fn) { | ||
| return draft => readSerializedOrCompute(() => fn(draft), draft); | ||
| } | ||
| function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) { | ||
| if (ssrSource === "client") { | ||
| const windowed = hasLoadingWindow(options); | ||
| const [hydrated, setHydrated] = signals.createSignal(false, { | ||
@@ -505,3 +533,3 @@ ownedWrite: true | ||
| const result = coreFn(draft => { | ||
| if (!hydrated()) return; | ||
| if (!hydrated()) return windowed ? UNASKED : undefined; | ||
| return fn(draft); | ||
@@ -519,3 +547,3 @@ }, initialValue, options); | ||
| if (!hydrated()) { | ||
| if (sharedConfig.has(o.id)) return readHydratedValue(sharedConfig.load(o.id), () => subFetch(fn, draft)); | ||
| if (sharedConfig.has(o.id)) return readHydratedValue(sharedConfig.load(o.id), () => subFetch(fn, draft), options); | ||
| return fn(draft); | ||
@@ -535,22 +563,8 @@ } | ||
| if (aiResult !== null) return aiResult; | ||
| return coreFn(wrapStoreFn(fn), initialValue, options); | ||
| return coreFn(wrapStoreFn(fn, options), initialValue, options); | ||
| } | ||
| function hydratedCreateStore(first, second, third) { | ||
| if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createStore(first, second, third); | ||
| function hydrateStoreLike(coreFn, fn, initialValue, options) { | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = third?.ssrSource; | ||
| return hydrateStoreLikeFn(signals.createStore, first, second ?? {}, third, ssrSource); | ||
| return hydrateStoreLikeFn(coreFn, fn, initialValue, options, options?.ssrSource); | ||
| } | ||
| function hydratedCreateOptimisticStore(first, second, third) { | ||
| if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createOptimisticStore(first, second, third); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = third?.ssrSource; | ||
| return hydrateStoreLikeFn(signals.createOptimisticStore, first, second ?? {}, third, ssrSource); | ||
| } | ||
| function hydratedCreateProjection(fn, initialValue, options) { | ||
| if (!sharedConfig.hydrating) return signals.createProjection(fn, initialValue, options); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = options?.ssrSource; | ||
| return hydrateStoreLikeFn(signals.createProjection, fn, initialValue, options, ssrSource); | ||
| } | ||
| function hydratedEffect(coreFn, compute, effectFn, options) { | ||
@@ -598,6 +612,4 @@ if (!sharedConfig.hydrating || options?.transparent) return coreFn(compute, effectFn, options); | ||
| _createErrorBoundary = hydratedCreateErrorBoundary; | ||
| _createOptimistic = hydratedCreateOptimistic; | ||
| _createProjection = hydratedCreateProjection; | ||
| _createStore = hydratedCreateStore; | ||
| _createOptimisticStore = hydratedCreateOptimisticStore; | ||
| _hydrateSignalLike = hydrateSignalLike; | ||
| _hydrateStoreLike = hydrateStoreLike; | ||
| _createRenderEffect = hydratedCreateRenderEffect; | ||
@@ -608,2 +620,4 @@ _createEffect = hydratedCreateEffect; | ||
| sharedConfig.getNextContextId = hydrationGetNextContextId; | ||
| sharedConfig.isHydrationInProgress = isHydrationInProgress; | ||
| sharedConfig.onHydrationEnd = onHydrationEnd; | ||
| const hy = globalThis._$HY; | ||
@@ -662,4 +676,10 @@ if (hy && !hy.fr) { | ||
| } | ||
| const createMemo = (...args) => (_createMemo || signals.createMemo)(...args); | ||
| const createSignal = (...args) => (_createSignal || signals.createSignal)(...args); | ||
| const createMemo = (...args) => { | ||
| assertClientCommitZero(args[0], args[1]); | ||
| return (_createMemo || signals.createMemo)(...args); | ||
| }; | ||
| const createSignal = (...args) => { | ||
| assertClientCommitZero(args[0], args[1]); | ||
| return (_createSignal || signals.createSignal)(...args); | ||
| }; | ||
| const createErrorBoundary = (...args) => (_createErrorBoundary || signals.createErrorBoundary)(...args); | ||
@@ -669,6 +689,18 @@ function createRevealOrder(fn, options) { | ||
| } | ||
| const createOptimistic = (...args) => (_createOptimistic || signals.createOptimistic)(...args); | ||
| const createProjection = (...args) => (_createProjection || signals.createProjection)(...args); | ||
| const createStore = (...args) => (_createStore || signals.createStore)(...args); | ||
| const createOptimisticStore = (...args) => (_createOptimisticStore || signals.createOptimisticStore)(...args); | ||
| const createOptimistic = (...args) => { | ||
| assertClientCommitZero(args[0], args[1]); | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateSignalLike(signals.createOptimistic, args[0], args[1]) : signals.createOptimistic(...args); | ||
| }; | ||
| const createProjection = (...args) => { | ||
| assertClientCommitZero(args[0], args[2], true); | ||
| return sharedConfig.hydrating ? _hydrateStoreLike(signals.createProjection, args[0], args[1], args[2]) : signals.createProjection(...args); | ||
| }; | ||
| const createStore = (...args) => { | ||
| assertClientCommitZero(args[0], args[2], true); | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateStoreLike(signals.createStore, args[0], args[1] ?? {}, args[2]) : signals.createStore(...args); | ||
| }; | ||
| const createOptimisticStore = (...args) => { | ||
| assertClientCommitZero(args[0], args[2], true); | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateStoreLike(signals.createOptimisticStore, args[0], args[1] ?? {}, args[2]) : signals.createOptimisticStore(...args); | ||
| }; | ||
| const createRenderEffect = (...args) => (_createRenderEffect || signals.createRenderEffect)(...args); | ||
@@ -802,2 +834,3 @@ const createEffect = (...args) => (_createEffect || signals.createEffect)(...args); | ||
| } | ||
| setTimeout(() => rejectTruncatedRefs(hy)); | ||
| }, { | ||
@@ -807,2 +840,28 @@ once: true | ||
| } | ||
| function rejectTruncatedRefs(hy) { | ||
| const R = globalThis.$R; | ||
| if (!R || typeof R !== "object") return; | ||
| let registryKeys; | ||
| const sweep = entry => { | ||
| if (!entry || typeof entry !== "object" || typeof entry.f !== "function" || !entry.p || typeof entry.p.then !== "function" || entry.p.s) return; | ||
| if (!registryKeys) { | ||
| registryKeys = new Map(); | ||
| for (const key in hy.r) registryKeys.set(hy.r[key], key); | ||
| } | ||
| const key = registryKeys.get(entry.p); | ||
| if (key !== undefined) { | ||
| delete hy.r[key]; | ||
| return; | ||
| } | ||
| const err = new Error("Hydration value was truncated: the stream ended before it settled."); | ||
| entry.f(err); | ||
| entry.p.s = 2; | ||
| entry.p.v = err; | ||
| entry.p.then(undefined, () => {}); | ||
| }; | ||
| for (const key in R) { | ||
| const value = R[key]; | ||
| if (Array.isArray(value)) for (const entry of value) sweep(entry);else sweep(value); | ||
| } | ||
| } | ||
| function markTruncated(hy, id) { | ||
@@ -1113,2 +1172,11 @@ if (_truncated.has(id)) return; | ||
| } | ||
| function creationStamp() { | ||
| return 0; | ||
| } | ||
| function inServerComponentScope() { | ||
| return false; | ||
| } | ||
| function getProjectionTrace(value) { | ||
| return undefined; | ||
| } | ||
| const DEV = signals.DEV ; | ||
@@ -1291,4 +1359,8 @@ if (globalThis) { | ||
| exports.createUniqueId = createUniqueId; | ||
| exports.creationStamp = creationStamp; | ||
| exports.enableHydration = enableHydration; | ||
| exports.getProjectionTrace = getProjectionTrace; | ||
| exports.inServerComponentScope = inServerComponentScope; | ||
| exports.lazy = lazy; | ||
| exports.materializeContainerTrace = materializeContainerTrace; | ||
| exports.runInServerComponentScope = runInServerComponentScope; | ||
@@ -1295,0 +1367,0 @@ exports.sharedConfig = sharedConfig; |
+172
-104
@@ -59,5 +59,3 @@ import { getContext, createMemo as createMemo$1, flatten, createRoot, setContext, getOwner, untrack, createOwner, runWithOwner, createEffect as createEffect$1, createErrorBoundary as createErrorBoundary$1, createLoadingBoundary as createLoadingBoundary$1, createOptimistic as createOptimistic$1, createOptimisticStore as createOptimisticStore$1, createProjection as createProjection$1, createRenderEffect as createRenderEffect$1, createRevealOrder as createRevealOrder$1, createSignal as createSignal$1, createStore as createStore$1, setSnapshotCapture, releaseSnapshotScope, peekNextChildId, getNextChildId, clearSnapshots, flush, markSnapshotScope, onCleanup, isDisposed, mapArray, repeat, DEV as DEV$1 } from '@solidjs/signals'; | ||
| registry: undefined, | ||
| done: false, | ||
| isHydrationInProgress, | ||
| onHydrationEnd | ||
| done: false | ||
| }; | ||
@@ -117,9 +115,7 @@ function hydrationGetNextContextId() { | ||
| let _createErrorBoundary; | ||
| let _createOptimistic; | ||
| let _createProjection; | ||
| let _createStore; | ||
| let _createOptimisticStore; | ||
| let _createRenderEffect; | ||
| let _createEffect; | ||
| let _createLoadingBoundary; | ||
| let _hydrateSignalLike; | ||
| let _hydrateStoreLike; | ||
| let _lazyHydrationLookup; | ||
@@ -167,5 +163,8 @@ // it in EVERY client bundle even with zero references; the PURE-annotated | ||
| } | ||
| function readHydratedValue(initP, refresh) { | ||
| function readHydratedValue(initP, refresh, options) { | ||
| refresh(); | ||
| if (initP != null && typeof initP === "object") { | ||
| if (hasLoadingWindow(options) && typeof initP.then === "function") return { | ||
| then: initP.then.bind(initP) | ||
| }; | ||
| if (initP.s === 2) throw initP.v; | ||
@@ -176,7 +175,18 @@ if (initP.s === 1) return initP.v; | ||
| } | ||
| function readSerializedOrCompute(compute, prev) { | ||
| function readSerializedOrCompute(compute, prev, options) { | ||
| const o = getOwner(); | ||
| if (sharedConfig.done || !sharedConfig.has(o.id)) return compute(prev); | ||
| return readHydratedValue(sharedConfig.load(o.id), () => subFetch(compute, prev)); | ||
| return readHydratedValue(sharedConfig.load(o.id), () => subFetch(compute, prev), options); | ||
| } | ||
| function assertClientCommitZero(fn, options, seed) { | ||
| if (typeof fn !== "function" || options?.ssrSource !== "client") return; | ||
| if (seed ? options.seedLoadingValue === true : "loadingValue" in options) return; | ||
| throw new Error(`ssrSource: "client" requires ${seed ? "seedLoadingValue: true" : "a loadingValue"} — the server cannot run this source, so you must declare what it renders (commit #0).`); | ||
| } | ||
| const UNASKED = { | ||
| then() {} | ||
| }; | ||
| function hasLoadingWindow(options) { | ||
| return options != null && typeof options === "object" && ("loadingValue" in options || options.seedLoadingValue === true); | ||
| } | ||
| function forwardIteratorReturn(it, value) { | ||
@@ -189,3 +199,3 @@ const returned = it.return?.(value); | ||
| } | ||
| function normalizeIterator(it) { | ||
| function normalizeIterator(it, deferFirst) { | ||
| let first = true; | ||
@@ -198,3 +208,4 @@ let buffered = null; | ||
| const r = it.next(); | ||
| return r && typeof r.then === "function" ? r : syncThenable(r); | ||
| if (r && typeof r.then === "function") return r; | ||
| return deferFirst ? Promise.resolve(r) : syncThenable(r); | ||
| } | ||
@@ -208,2 +219,3 @@ if (buffered) { | ||
| if (latest && typeof latest.then === "function") return latest; | ||
| let result = latest; | ||
| while (!latest.done) { | ||
@@ -216,4 +228,5 @@ const peek = it.next(); | ||
| latest = peek; | ||
| if (!latest.done) result = latest;else if (result !== latest) buffered = Promise.resolve(latest); | ||
| } | ||
| return Promise.resolve(latest); | ||
| return Promise.resolve(result); | ||
| }, | ||
@@ -314,3 +327,3 @@ return(value) { | ||
| if (!isAsyncIterable(loaded)) return null; | ||
| const it = normalizeIterator(loaded[Symbol.asyncIterator]()); | ||
| const it = normalizeIterator(loaded[Symbol.asyncIterator](), hasLoadingWindow(options)); | ||
| const iterable = { | ||
@@ -333,2 +346,3 @@ [Symbol.asyncIterator]() { | ||
| const srcIt = loaded[Symbol.asyncIterator](); | ||
| const loading = hasLoadingWindow(options); | ||
| let isFirst = true; | ||
@@ -376,7 +390,13 @@ let buffered = null; | ||
| const r = srcIt.next(); | ||
| return r && typeof r.then === "function" ? { | ||
| if (r && typeof r.then === "function") return { | ||
| then(fn, rej) { | ||
| r.then(v => fn(process(v)), rej); | ||
| } | ||
| } : syncThenable(process(r)); | ||
| }; | ||
| if (loading) { | ||
| return new Promise(resolvePull => { | ||
| onHydrationEnd(() => resolvePull(process(r))); | ||
| }); | ||
| } | ||
| return syncThenable(process(r)); | ||
| } | ||
@@ -392,13 +412,17 @@ if (buffered) { | ||
| } | ||
| let result = process(r); | ||
| while (!r.done) { | ||
| const peek = srcIt.next(); | ||
| if (peek && typeof peek.then === "function") { | ||
| buffered = peek; | ||
| break; | ||
| } | ||
| r = peek; | ||
| if (!r.done) result = process(r); | ||
| } | ||
| return Promise.resolve(result); | ||
| return new Promise(resolvePull => { | ||
| onHydrationEnd(() => { | ||
| let result = process(r); | ||
| while (!r.done) { | ||
| const peek = srcIt.next(); | ||
| if (peek && typeof peek.then === "function") { | ||
| buffered = peek; | ||
| break; | ||
| } | ||
| r = peek; | ||
| if (!r.done) result = process(r); | ||
| } | ||
| resolvePull(result); | ||
| }); | ||
| }); | ||
| }, | ||
@@ -414,41 +438,63 @@ return(value) { | ||
| } | ||
| function hydratedCreateMemo(compute, options) { | ||
| if (!sharedConfig.hydrating || options?.transparent) { | ||
| return createMemo$1(compute, options); | ||
| } | ||
| function materializeContainerTrace(marker) { | ||
| const src = marker.$tr; | ||
| return createRoot(() => createProjection(draft => ({ | ||
| [Symbol.asyncIterator]() { | ||
| const srcIt = src[Symbol.asyncIterator](); | ||
| let first = true; | ||
| return { | ||
| next: () => Promise.resolve(srcIt.next()).then(res => { | ||
| if (res.done) return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| if (first) { | ||
| first = false; | ||
| if (Array.isArray(res.value)) { | ||
| for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i]; | ||
| draft.length = res.value.length; | ||
| } else { | ||
| Object.assign(draft, res.value); | ||
| } | ||
| } else { | ||
| applyPatches(draft, res.value); | ||
| } | ||
| return { | ||
| done: false, | ||
| value: undefined | ||
| }; | ||
| }), | ||
| return: value => forwardIteratorReturn(srcIt, value) | ||
| }; | ||
| } | ||
| }), marker.$ta ? [] : {})); | ||
| } | ||
| function hydrateSignalLike(coreFn, fn, options) { | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = options?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const windowed = hasLoadingWindow(options); | ||
| const [hydrated, setHydrated] = createSignal$1(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const memo = createMemo$1(prev => { | ||
| if (!hydrated()) return prev; | ||
| return compute(prev); | ||
| const sig = coreFn(prev => { | ||
| if (!hydrated()) return windowed ? UNASKED : prev; | ||
| return fn(prev); | ||
| }, options); | ||
| setHydrated(true); | ||
| return memo; | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(createMemo$1, compute, options); | ||
| const aiResult = hydrateSignalFromAsyncIterable(coreFn, fn, options); | ||
| if (aiResult !== null) return aiResult; | ||
| return createMemo$1(prev => readSerializedOrCompute(compute, prev), options); | ||
| return coreFn(prev => readSerializedOrCompute(fn, prev, options), options); | ||
| } | ||
| function hydratedCreateMemo(compute, options) { | ||
| if (!sharedConfig.hydrating || options?.transparent) { | ||
| return createMemo$1(compute, options); | ||
| } | ||
| return hydrateSignalLike(createMemo$1, compute, options); | ||
| } | ||
| function hydratedCreateSignal(fn, second) { | ||
| if (typeof fn !== "function" || !sharedConfig.hydrating) return createSignal$1(fn, second); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = second?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const [hydrated, setHydrated] = createSignal$1(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const sig = createSignal$1(prev => { | ||
| if (!hydrated()) return prev; | ||
| return fn(prev); | ||
| }, second); | ||
| setHydrated(true); | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(createSignal$1, fn, second); | ||
| if (aiResult !== null) return aiResult; | ||
| return createSignal$1(prev => readSerializedOrCompute(fn, prev), second); | ||
| return hydrateSignalLike(createSignal$1, fn, second); | ||
| } | ||
@@ -475,26 +521,8 @@ function hydratedCreateErrorBoundary(fn, fallback) { | ||
| } | ||
| function hydratedCreateOptimistic(fn, second) { | ||
| if (typeof fn !== "function" || !sharedConfig.hydrating) return createOptimistic$1(fn, second); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = second?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const [hydrated, setHydrated] = createSignal$1(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const sig = createOptimistic$1(prev => { | ||
| if (!hydrated()) return prev; | ||
| return fn(prev); | ||
| }, second); | ||
| setHydrated(true); | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(createOptimistic$1, fn, second); | ||
| if (aiResult !== null) return aiResult; | ||
| return createOptimistic$1(prev => readSerializedOrCompute(fn, prev), second); | ||
| function wrapStoreFn(fn, options) { | ||
| return draft => readSerializedOrCompute(() => fn(draft), draft, options); | ||
| } | ||
| function wrapStoreFn(fn) { | ||
| return draft => readSerializedOrCompute(() => fn(draft), draft); | ||
| } | ||
| function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) { | ||
| if (ssrSource === "client") { | ||
| const windowed = hasLoadingWindow(options); | ||
| const [hydrated, setHydrated] = createSignal$1(false, { | ||
@@ -504,3 +532,3 @@ ownedWrite: true | ||
| const result = coreFn(draft => { | ||
| if (!hydrated()) return; | ||
| if (!hydrated()) return windowed ? UNASKED : undefined; | ||
| return fn(draft); | ||
@@ -518,3 +546,3 @@ }, initialValue, options); | ||
| if (!hydrated()) { | ||
| if (sharedConfig.has(o.id)) return readHydratedValue(sharedConfig.load(o.id), () => subFetch(fn, draft)); | ||
| if (sharedConfig.has(o.id)) return readHydratedValue(sharedConfig.load(o.id), () => subFetch(fn, draft), options); | ||
| return fn(draft); | ||
@@ -534,22 +562,8 @@ } | ||
| if (aiResult !== null) return aiResult; | ||
| return coreFn(wrapStoreFn(fn), initialValue, options); | ||
| return coreFn(wrapStoreFn(fn, options), initialValue, options); | ||
| } | ||
| function hydratedCreateStore(first, second, third) { | ||
| if (typeof first !== "function" || !sharedConfig.hydrating) return createStore$1(first, second, third); | ||
| function hydrateStoreLike(coreFn, fn, initialValue, options) { | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = third?.ssrSource; | ||
| return hydrateStoreLikeFn(createStore$1, first, second ?? {}, third, ssrSource); | ||
| return hydrateStoreLikeFn(coreFn, fn, initialValue, options, options?.ssrSource); | ||
| } | ||
| function hydratedCreateOptimisticStore(first, second, third) { | ||
| if (typeof first !== "function" || !sharedConfig.hydrating) return createOptimisticStore$1(first, second, third); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = third?.ssrSource; | ||
| return hydrateStoreLikeFn(createOptimisticStore$1, first, second ?? {}, third, ssrSource); | ||
| } | ||
| function hydratedCreateProjection(fn, initialValue, options) { | ||
| if (!sharedConfig.hydrating) return createProjection$1(fn, initialValue, options); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = options?.ssrSource; | ||
| return hydrateStoreLikeFn(createProjection$1, fn, initialValue, options, ssrSource); | ||
| } | ||
| function hydratedEffect(coreFn, compute, effectFn, options) { | ||
@@ -597,6 +611,4 @@ if (!sharedConfig.hydrating || options?.transparent) return coreFn(compute, effectFn, options); | ||
| _createErrorBoundary = hydratedCreateErrorBoundary; | ||
| _createOptimistic = hydratedCreateOptimistic; | ||
| _createProjection = hydratedCreateProjection; | ||
| _createStore = hydratedCreateStore; | ||
| _createOptimisticStore = hydratedCreateOptimisticStore; | ||
| _hydrateSignalLike = hydrateSignalLike; | ||
| _hydrateStoreLike = hydrateStoreLike; | ||
| _createRenderEffect = hydratedCreateRenderEffect; | ||
@@ -607,2 +619,4 @@ _createEffect = hydratedCreateEffect; | ||
| sharedConfig.getNextContextId = hydrationGetNextContextId; | ||
| sharedConfig.isHydrationInProgress = isHydrationInProgress; | ||
| sharedConfig.onHydrationEnd = onHydrationEnd; | ||
| const hy = globalThis._$HY; | ||
@@ -661,4 +675,10 @@ if (hy && !hy.fr) { | ||
| } | ||
| const createMemo = (...args) => (_createMemo || createMemo$1)(...args); | ||
| const createSignal = (...args) => (_createSignal || createSignal$1)(...args); | ||
| const createMemo = (...args) => { | ||
| assertClientCommitZero(args[0], args[1]); | ||
| return (_createMemo || createMemo$1)(...args); | ||
| }; | ||
| const createSignal = (...args) => { | ||
| assertClientCommitZero(args[0], args[1]); | ||
| return (_createSignal || createSignal$1)(...args); | ||
| }; | ||
| const createErrorBoundary = (...args) => (_createErrorBoundary || createErrorBoundary$1)(...args); | ||
@@ -668,6 +688,18 @@ function createRevealOrder(fn, options) { | ||
| } | ||
| const createOptimistic = (...args) => (_createOptimistic || createOptimistic$1)(...args); | ||
| const createProjection = (...args) => (_createProjection || createProjection$1)(...args); | ||
| const createStore = (...args) => (_createStore || createStore$1)(...args); | ||
| const createOptimisticStore = (...args) => (_createOptimisticStore || createOptimisticStore$1)(...args); | ||
| const createOptimistic = (...args) => { | ||
| assertClientCommitZero(args[0], args[1]); | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateSignalLike(createOptimistic$1, args[0], args[1]) : createOptimistic$1(...args); | ||
| }; | ||
| const createProjection = (...args) => { | ||
| assertClientCommitZero(args[0], args[2], true); | ||
| return sharedConfig.hydrating ? _hydrateStoreLike(createProjection$1, args[0], args[1], args[2]) : createProjection$1(...args); | ||
| }; | ||
| const createStore = (...args) => { | ||
| assertClientCommitZero(args[0], args[2], true); | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateStoreLike(createStore$1, args[0], args[1] ?? {}, args[2]) : createStore$1(...args); | ||
| }; | ||
| const createOptimisticStore = (...args) => { | ||
| assertClientCommitZero(args[0], args[2], true); | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateStoreLike(createOptimisticStore$1, args[0], args[1] ?? {}, args[2]) : createOptimisticStore$1(...args); | ||
| }; | ||
| const createRenderEffect = (...args) => (_createRenderEffect || createRenderEffect$1)(...args); | ||
@@ -801,2 +833,3 @@ const createEffect = (...args) => (_createEffect || createEffect$1)(...args); | ||
| } | ||
| setTimeout(() => rejectTruncatedRefs(hy)); | ||
| }, { | ||
@@ -806,2 +839,28 @@ once: true | ||
| } | ||
| function rejectTruncatedRefs(hy) { | ||
| const R = globalThis.$R; | ||
| if (!R || typeof R !== "object") return; | ||
| let registryKeys; | ||
| const sweep = entry => { | ||
| if (!entry || typeof entry !== "object" || typeof entry.f !== "function" || !entry.p || typeof entry.p.then !== "function" || entry.p.s) return; | ||
| if (!registryKeys) { | ||
| registryKeys = new Map(); | ||
| for (const key in hy.r) registryKeys.set(hy.r[key], key); | ||
| } | ||
| const key = registryKeys.get(entry.p); | ||
| if (key !== undefined) { | ||
| delete hy.r[key]; | ||
| return; | ||
| } | ||
| const err = new Error("Hydration value was truncated: the stream ended before it settled."); | ||
| entry.f(err); | ||
| entry.p.s = 2; | ||
| entry.p.v = err; | ||
| entry.p.then(undefined, () => {}); | ||
| }; | ||
| for (const key in R) { | ||
| const value = R[key]; | ||
| if (Array.isArray(value)) for (const entry of value) sweep(entry);else sweep(value); | ||
| } | ||
| } | ||
| function markTruncated(hy, id) { | ||
@@ -1112,2 +1171,11 @@ if (_truncated.has(id)) return; | ||
| } | ||
| function creationStamp() { | ||
| return 0; | ||
| } | ||
| function inServerComponentScope() { | ||
| return false; | ||
| } | ||
| function getProjectionTrace(value) { | ||
| return undefined; | ||
| } | ||
| const DEV = DEV$1 ; | ||
@@ -1118,2 +1186,2 @@ if (globalThis) { | ||
| export { $DEVCOMP, DEV, Errored, For, Hydration, Loading, Match, NoHydrateContext, NoHydration, Repeat, Reveal, Show, Switch, children, createComponent, createContext, createEffect, createErrorBoundary, createLoadingBoundary, createMemo, createOptimistic, createOptimisticStore, createProjection, createRenderEffect, createRevealOrder, createSignal, createStore, createUniqueId, enableHydration, lazy, runInServerComponentScope, sharedConfig, ssrHandleError, ssrScope, useContext }; | ||
| export { $DEVCOMP, DEV, Errored, For, Hydration, Loading, Match, NoHydrateContext, NoHydration, Repeat, Reveal, Show, Switch, children, createComponent, createContext, createEffect, createErrorBoundary, createLoadingBoundary, createMemo, createOptimistic, createOptimisticStore, createProjection, createRenderEffect, createRevealOrder, createSignal, createStore, createUniqueId, creationStamp, enableHydration, getProjectionTrace, inServerComponentScope, lazy, materializeContainerTrace, runInServerComponentScope, sharedConfig, ssrHandleError, ssrScope, useContext }; |
+203
-80
@@ -41,3 +41,8 @@ 'use strict'; | ||
| } | ||
| let ownerCreations = 0; | ||
| function creationStamp() { | ||
| return ownerCreations; | ||
| } | ||
| function createOwner(options) { | ||
| ownerCreations++; | ||
| const parent = currentOwner; | ||
@@ -195,2 +200,7 @@ const transparent = options?.transparent ?? false; | ||
| } | ||
| function assertClientCommitZero(options, seed) { | ||
| if (options?.ssrSource !== "client") return; | ||
| if (seed ? options.seedLoadingValue === true : "loadingValue" in options) return; | ||
| throw new Error(`ssrSource: "client" requires ${seed ? "seedLoadingValue: true" : "a loadingValue"} — the server cannot run this source, so you must declare what it renders (commit #0).`); | ||
| } | ||
| let Observer = null; | ||
@@ -271,5 +281,9 @@ function runWithObserver(comp, fn) { | ||
| if (typeof first === "function") { | ||
| const opts = second?.deferStream || second?.ssrSource ? { | ||
| const hasLoadingValue = second != null && "loadingValue" in second; | ||
| const opts = second?.deferStream || second?.ssrSource || hasLoadingValue ? { | ||
| deferStream: second?.deferStream, | ||
| ssrSource: second?.ssrSource | ||
| ssrSource: second?.ssrSource, | ||
| ...(hasLoadingValue ? { | ||
| loadingValue: second.loadingValue | ||
| } : {}) | ||
| } : undefined; | ||
@@ -287,4 +301,9 @@ const memo = createMemo(prev => first(prev), opts); | ||
| } | ||
| assertClientCommitZero(options); | ||
| const ctx = sharedConfig.context; | ||
| const owner = createOwner(); | ||
| const loadingState = options != null && typeof options === "object" && "loadingValue" in options ? { | ||
| value: options.loadingValue, | ||
| served: false | ||
| } : undefined; | ||
| const comp = { | ||
@@ -313,6 +332,14 @@ owner, | ||
| comp.computed = true; | ||
| processResult(comp, result, owner, ctx, options?.deferStream, options?.ssrSource, run, options?.serialize); | ||
| processResult(comp, result, owner, ctx, options?.deferStream, options?.ssrSource, run, options?.serialize, loadingState); | ||
| } catch (err) { | ||
| if (err instanceof signals.NotReadyError) { | ||
| subscribePendingRetry(err, update); | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| comp.computed = true; | ||
| return; | ||
| } | ||
| } | ||
@@ -327,2 +354,6 @@ comp.error = err; | ||
| comp.computed = true; | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| } | ||
| } else if (!options?.lazy) { | ||
@@ -449,3 +480,3 @@ update(); | ||
| } | ||
| function processResult(comp, result, owner, ctx, deferStream, ssrSource, rerun, serialize) { | ||
| function processResult(comp, result, owner, ctx, deferStream, ssrSource, rerun, serialize, loadingState) { | ||
| if (comp.disposed) return; | ||
@@ -468,9 +499,12 @@ const id = owner.id; | ||
| const deferred = createDeferredPromise(); | ||
| if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, deferred.promise, deferStream); | ||
| const serializes = !!(ctx?.async && ctx.serialize && id && !noHydrate); | ||
| if (serializes) ctx.serialize(id, deferred.promise, deferStream); | ||
| settleServerAsync(result, () => rerun ? rerun() : result, deferred, value => { | ||
| result.s = 1; | ||
| result.v = value; | ||
| comp.value = value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| if (!(loadingState?.served && serializes)) { | ||
| comp.value = value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| } | ||
| ctx?.commit?.(); | ||
@@ -485,4 +519,9 @@ return value; | ||
| }, () => comp.disposed); | ||
| comp.error = new signals.NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| } else { | ||
| comp.error = new signals.NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| } | ||
| return; | ||
@@ -492,2 +531,3 @@ } | ||
| if (typeof iterator === "function") { | ||
| const serializes = !!(ctx?.async && ctx.serialize && id && !noHydrate); | ||
| if (ssrSource === "hybrid") { | ||
@@ -511,5 +551,7 @@ let currentResult = result; | ||
| settleServerAsync(runFirst(), runFirst, deferred, value => { | ||
| comp.value = value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| if (!(loadingState?.served && serializes)) { | ||
| comp.value = value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| } | ||
| ctx?.commit?.(); | ||
@@ -522,5 +564,10 @@ return value; | ||
| }, () => comp.disposed); | ||
| if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, deferred.promise, deferStream); | ||
| comp.error = new signals.NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| if (serializes) ctx.serialize(id, deferred.promise, deferStream); | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| } else { | ||
| comp.error = new signals.NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| } | ||
| } else { | ||
@@ -546,7 +593,9 @@ let currentResult = result; | ||
| const resolved = firstResult; | ||
| if (resolved && !resolved.done) { | ||
| if (resolved && !resolved.done && !(loadingState?.served && serializes)) { | ||
| comp.value = resolved.value; | ||
| } | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| if (!(loadingState?.served && serializes)) { | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| } | ||
| ctx?.commit?.(); | ||
@@ -559,3 +608,3 @@ return undefined; | ||
| }, () => comp.disposed); | ||
| if (ctx?.async && ctx.serialize && id && !noHydrate) { | ||
| if (serializes) { | ||
| let tappedFirst = true; | ||
@@ -580,6 +629,8 @@ const tapped = { | ||
| ctx.serialize(id, tapped, deferStream); | ||
| } else if (ctx?.commit) { | ||
| } else if (ctx?.commit && inServerComponentScope()) { | ||
| const release = ctx.hold?.(); | ||
| const pump = () => { | ||
| if (comp.disposed) { | ||
| closeAsyncIterator(iter); | ||
| release?.(); | ||
| return; | ||
@@ -590,17 +641,30 @@ } | ||
| closeAsyncIterator(iter); | ||
| release?.(); | ||
| return; | ||
| } | ||
| if (r.done) return; | ||
| if (r.done) { | ||
| release?.(); | ||
| return; | ||
| } | ||
| comp.value = r.value; | ||
| ctx.commit(); | ||
| pump(); | ||
| }, () => {}); | ||
| }, () => release?.()); | ||
| }; | ||
| deferred.promise.then(pump, () => {}); | ||
| deferred.promise.then(pump, () => release?.()); | ||
| } | ||
| comp.error = new signals.NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| } else { | ||
| comp.error = new signals.NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| } | ||
| } | ||
| return; | ||
| } | ||
| if (loadingState?.served) { | ||
| if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, Promise.resolve(result), deferStream); | ||
| return; | ||
| } | ||
| comp.value = result; | ||
@@ -722,2 +786,15 @@ comp.sync = true; | ||
| } | ||
| const projectionTraces = new WeakMap(); | ||
| function getProjectionTrace(value) { | ||
| return typeof value === "object" && value !== null ? projectionTraces.get(value) : undefined; | ||
| } | ||
| function registerSettledTrace(pending, ready, state) { | ||
| projectionTraces.set(pending, { | ||
| array: Array.isArray(state), | ||
| subscribe: async function* () { | ||
| await ready; | ||
| yield JSON.parse(JSON.stringify(state)); | ||
| } | ||
| }); | ||
| } | ||
| function replaceState(target, next) { | ||
@@ -730,2 +807,3 @@ for (const key of Object.keys(target)) { | ||
| function createProjection(fn, initialValue, options) { | ||
| assertClientCommitZero(options, true); | ||
| const ctx = sharedConfig.context; | ||
@@ -745,2 +823,7 @@ const owner = createOwner(); | ||
| const draft = useProxy ? createDeepProxy(state, patches) : state; | ||
| const seedLoading = !!options?.seedLoadingValue; | ||
| const frozenSeed = seedLoading ? JSON.parse(JSON.stringify(state)) : undefined; | ||
| const seedLock = markReady => { | ||
| if (seedLoading) markReady(frozenSeed); | ||
| }; | ||
| const runProjection = () => { | ||
@@ -757,2 +840,3 @@ resetOwnerForRerun(owner); | ||
| const [pending, markReady] = createPendingProxy(state, deferred.promise); | ||
| seedLock(markReady); | ||
| settleServerAsync(Promise.reject(error), () => runProjection(), deferred, value => { | ||
@@ -767,2 +851,3 @@ if (value !== undefined && value !== state && value !== draft) { | ||
| }, () => disposed); | ||
| registerSettledTrace(pending, deferred.promise, state); | ||
| if (ctx?.async && !getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, deferred.promise, options?.deferStream); | ||
@@ -778,2 +863,3 @@ return pending; | ||
| const [pending, markReady] = createPendingProxy(state, deferred.promise); | ||
| seedLock(markReady); | ||
| const runFirst = () => { | ||
@@ -801,2 +887,3 @@ const source = currentResult ?? runProjection(); | ||
| }, () => disposed); | ||
| registerSettledTrace(pending, deferred.promise, state); | ||
| if (ctx?.async && !getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, deferred.promise, options?.deferStream); | ||
@@ -810,2 +897,3 @@ return pending; | ||
| const [pending, markReady] = createPendingProxy(state, deferred.promise); | ||
| seedLock(markReady); | ||
| const runFirst = () => { | ||
@@ -830,3 +918,3 @@ const source = currentResult ?? runProjection(); | ||
| } | ||
| markReady(JSON.parse(JSON.stringify(state))); | ||
| markReady(seedLoading ? undefined : JSON.parse(JSON.stringify(state))); | ||
| return undefined; | ||
@@ -836,46 +924,51 @@ }, error => { | ||
| }, () => disposed); | ||
| const log = []; | ||
| let logDone = false; | ||
| let logError; | ||
| let pumping = null; | ||
| let consumers = 0; | ||
| const pump = () => pumping ??= iter.next().then(r => { | ||
| pumping = null; | ||
| if (disposed || r.done) { | ||
| logDone = true; | ||
| return; | ||
| } | ||
| if (r.value !== undefined && r.value !== draft) { | ||
| replaceState(draft, r.value); | ||
| } | ||
| log.push(patches.splice(0)); | ||
| }, error => { | ||
| pumping = null; | ||
| logDone = true; | ||
| logError = error; | ||
| }); | ||
| const subscribe = async function* () { | ||
| await deferred.promise; | ||
| if (firstResult?.done) return; | ||
| while (pumping) await pumping; | ||
| let cursor = log.length; | ||
| consumers++; | ||
| try { | ||
| yield JSON.parse(JSON.stringify(state)); | ||
| while (true) { | ||
| if (cursor < log.length) { | ||
| yield log[cursor++]; | ||
| continue; | ||
| } | ||
| if (logDone) { | ||
| if (logError) throw logError; | ||
| return; | ||
| } | ||
| await pump(); | ||
| } | ||
| } finally { | ||
| if (--consumers === 0 && !logDone) closeAsyncIterator(iter); | ||
| } | ||
| }; | ||
| projectionTraces.set(pending, { | ||
| subscribe, | ||
| array: Array.isArray(state) | ||
| }); | ||
| if (ctx?.async && !getContext(NoHydrateContext) && owner.id) { | ||
| let tappedFirst = true; | ||
| const tapped = { | ||
| [Symbol.asyncIterator]: () => ({ | ||
| next() { | ||
| if (tappedFirst) { | ||
| tappedFirst = false; | ||
| return deferred.promise.then(() => { | ||
| if (firstResult?.done) return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| return { | ||
| done: false, | ||
| value: JSON.parse(JSON.stringify(state)) | ||
| }; | ||
| }); | ||
| } | ||
| return iter.next().then(r => { | ||
| if (disposed) return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| if (!r.done) { | ||
| if (r.value !== undefined && r.value !== draft) { | ||
| replaceState(draft, r.value); | ||
| } | ||
| return { | ||
| done: false, | ||
| value: patches.splice(0) | ||
| }; | ||
| } | ||
| return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| }); | ||
| }, | ||
| return(value) { | ||
| return iter.return?.(value); | ||
| } | ||
| }) | ||
| }; | ||
| ctx.serialize(owner.id, tapped, options?.deferStream); | ||
| ctx.serialize(owner.id, subscribe(), options?.deferStream); | ||
| } | ||
@@ -888,2 +981,3 @@ return pending; | ||
| const [pending, markReady] = createPendingProxy(state, deferred.promise); | ||
| seedLock(markReady); | ||
| settleServerAsync(result, () => runProjection(), deferred, value => { | ||
@@ -898,2 +992,3 @@ if (value !== undefined && value !== state) { | ||
| }, () => disposed); | ||
| registerSettledTrace(pending, deferred.promise, state); | ||
| if (ctx?.async && !getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, deferred.promise, options?.deferStream); | ||
@@ -1084,3 +1179,3 @@ return pending; | ||
| }; | ||
| return () => { | ||
| return Object.assign(() => { | ||
| let result; | ||
@@ -1102,3 +1197,5 @@ let handled = false; | ||
| return result; | ||
| }; | ||
| }, { | ||
| $lhSkip: true | ||
| }); | ||
| } | ||
@@ -1138,2 +1235,6 @@ function createLoadingBoundary$1(fn, fallback, options) { | ||
| } | ||
| function inServerComponentScope() { | ||
| const o = currentOwner; | ||
| return !!o && o._context[ServerComponentContext.id] === true; | ||
| } | ||
| function serverComponentContextError(context) { | ||
@@ -1262,3 +1363,10 @@ const o = currentOwner; | ||
| const registerLazyAssets = id => { | ||
| const assets = ctx.resolveAssets(id); | ||
| const cache = ctx._lazyAssets ??= new Map(); | ||
| let assets; | ||
| if (cache.has(id)) { | ||
| assets = cache.get(id); | ||
| } else { | ||
| assets = ctx.resolveAssets(id); | ||
| cache.set(id, assets); | ||
| } | ||
| if (assets && typeof assets.then === "function") { | ||
@@ -1348,3 +1456,3 @@ const boundary = ctx._currentBoundaryId; | ||
| if (probe) return; | ||
| const handler = getContext(ErrorContext); | ||
| const handler = getOwner() ? getContext(ErrorContext) : null; | ||
| if (handler) { | ||
@@ -1409,7 +1517,12 @@ handler(err); | ||
| if (done?.(undefined, err)) return; | ||
| if (!parentHandler) throw err; | ||
| if (!parentHandler) { | ||
| ctx.failRender ? ctx.failRender(err) : console.error(err); | ||
| return; | ||
| } | ||
| try { | ||
| runWithOwner(parent, () => parentHandler(err)); | ||
| } catch (caught) { | ||
| if (caught !== err) throw caught; | ||
| if (caught !== err) { | ||
| ctx.failRender ? ctx.failRender(caught) : console.error(caught); | ||
| } | ||
| } | ||
@@ -1433,6 +1546,9 @@ } | ||
| } | ||
| const skipLive = f => Object.assign(f, { | ||
| $lhSkip: true | ||
| }); | ||
| let ret = runDiscovery(); | ||
| if (!retryPromise && !ret?.p?.length) { | ||
| commitBoundaryState(); | ||
| return () => ret; | ||
| return skipLive(() => ret); | ||
| } | ||
@@ -1444,3 +1560,3 @@ const regResult = revealGroup ? revealGroup.register(id) : null; | ||
| ctx.serialize(id, "$$f"); | ||
| return () => undefined; | ||
| return skipLive(() => undefined); | ||
| } | ||
@@ -1480,7 +1596,7 @@ const fallbackOwner = createOwner({ | ||
| })(); | ||
| return () => fallbackResult; | ||
| return skipLive(() => fallbackResult); | ||
| } | ||
| commitBoundaryState(); | ||
| ctx.serialize(id, "$$f"); | ||
| return () => fallbackResult; | ||
| return skipLive(() => fallbackResult); | ||
| } | ||
@@ -1764,2 +1880,5 @@ function NoHydration(props) { | ||
| function materializeContainerTrace(marker) { | ||
| return marker; | ||
| } | ||
| const DEV = undefined; | ||
@@ -1850,2 +1969,3 @@ | ||
| exports.createUniqueId = createUniqueId; | ||
| exports.creationStamp = creationStamp; | ||
| exports.deep = deep; | ||
@@ -1857,2 +1977,4 @@ exports.enableHydration = enableHydration; | ||
| exports.getOwner = getOwner; | ||
| exports.getProjectionTrace = getProjectionTrace; | ||
| exports.inServerComponentScope = inServerComponentScope; | ||
| exports.isDisposed = isDisposed; | ||
@@ -1863,2 +1985,3 @@ exports.isPending = isPending; | ||
| exports.mapArray = mapArray; | ||
| exports.materializeContainerTrace = materializeContainerTrace; | ||
| exports.merge = merge; | ||
@@ -1865,0 +1988,0 @@ exports.onCleanup = onCleanup; |
+200
-81
@@ -40,3 +40,8 @@ import { NotReadyError, $REFRESH, merge as merge$1, isWrappable, NoOwnerError, ContextNotFoundError, $PROXY, flatten } from '@solidjs/signals'; | ||
| } | ||
| let ownerCreations = 0; | ||
| function creationStamp() { | ||
| return ownerCreations; | ||
| } | ||
| function createOwner(options) { | ||
| ownerCreations++; | ||
| const parent = currentOwner; | ||
@@ -194,2 +199,7 @@ const transparent = options?.transparent ?? false; | ||
| } | ||
| function assertClientCommitZero(options, seed) { | ||
| if (options?.ssrSource !== "client") return; | ||
| if (seed ? options.seedLoadingValue === true : "loadingValue" in options) return; | ||
| throw new Error(`ssrSource: "client" requires ${seed ? "seedLoadingValue: true" : "a loadingValue"} — the server cannot run this source, so you must declare what it renders (commit #0).`); | ||
| } | ||
| let Observer = null; | ||
@@ -270,5 +280,9 @@ function runWithObserver(comp, fn) { | ||
| if (typeof first === "function") { | ||
| const opts = second?.deferStream || second?.ssrSource ? { | ||
| const hasLoadingValue = second != null && "loadingValue" in second; | ||
| const opts = second?.deferStream || second?.ssrSource || hasLoadingValue ? { | ||
| deferStream: second?.deferStream, | ||
| ssrSource: second?.ssrSource | ||
| ssrSource: second?.ssrSource, | ||
| ...(hasLoadingValue ? { | ||
| loadingValue: second.loadingValue | ||
| } : {}) | ||
| } : undefined; | ||
@@ -286,4 +300,9 @@ const memo = createMemo(prev => first(prev), opts); | ||
| } | ||
| assertClientCommitZero(options); | ||
| const ctx = sharedConfig.context; | ||
| const owner = createOwner(); | ||
| const loadingState = options != null && typeof options === "object" && "loadingValue" in options ? { | ||
| value: options.loadingValue, | ||
| served: false | ||
| } : undefined; | ||
| const comp = { | ||
@@ -312,6 +331,14 @@ owner, | ||
| comp.computed = true; | ||
| processResult(comp, result, owner, ctx, options?.deferStream, options?.ssrSource, run, options?.serialize); | ||
| processResult(comp, result, owner, ctx, options?.deferStream, options?.ssrSource, run, options?.serialize, loadingState); | ||
| } catch (err) { | ||
| if (err instanceof NotReadyError) { | ||
| subscribePendingRetry(err, update); | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| comp.computed = true; | ||
| return; | ||
| } | ||
| } | ||
@@ -326,2 +353,6 @@ comp.error = err; | ||
| comp.computed = true; | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| } | ||
| } else if (!options?.lazy) { | ||
@@ -448,3 +479,3 @@ update(); | ||
| } | ||
| function processResult(comp, result, owner, ctx, deferStream, ssrSource, rerun, serialize) { | ||
| function processResult(comp, result, owner, ctx, deferStream, ssrSource, rerun, serialize, loadingState) { | ||
| if (comp.disposed) return; | ||
@@ -467,9 +498,12 @@ const id = owner.id; | ||
| const deferred = createDeferredPromise(); | ||
| if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, deferred.promise, deferStream); | ||
| const serializes = !!(ctx?.async && ctx.serialize && id && !noHydrate); | ||
| if (serializes) ctx.serialize(id, deferred.promise, deferStream); | ||
| settleServerAsync(result, () => rerun ? rerun() : result, deferred, value => { | ||
| result.s = 1; | ||
| result.v = value; | ||
| comp.value = value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| if (!(loadingState?.served && serializes)) { | ||
| comp.value = value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| } | ||
| ctx?.commit?.(); | ||
@@ -484,4 +518,9 @@ return value; | ||
| }, () => comp.disposed); | ||
| comp.error = new NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| } else { | ||
| comp.error = new NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| } | ||
| return; | ||
@@ -491,2 +530,3 @@ } | ||
| if (typeof iterator === "function") { | ||
| const serializes = !!(ctx?.async && ctx.serialize && id && !noHydrate); | ||
| if (ssrSource === "hybrid") { | ||
@@ -510,5 +550,7 @@ let currentResult = result; | ||
| settleServerAsync(runFirst(), runFirst, deferred, value => { | ||
| comp.value = value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| if (!(loadingState?.served && serializes)) { | ||
| comp.value = value; | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| } | ||
| ctx?.commit?.(); | ||
@@ -521,5 +563,10 @@ return value; | ||
| }, () => comp.disposed); | ||
| if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, deferred.promise, deferStream); | ||
| comp.error = new NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| if (serializes) ctx.serialize(id, deferred.promise, deferStream); | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| } else { | ||
| comp.error = new NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| } | ||
| } else { | ||
@@ -545,7 +592,9 @@ let currentResult = result; | ||
| const resolved = firstResult; | ||
| if (resolved && !resolved.done) { | ||
| if (resolved && !resolved.done && !(loadingState?.served && serializes)) { | ||
| comp.value = resolved.value; | ||
| } | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| if (!(loadingState?.served && serializes)) { | ||
| comp.error = undefined; | ||
| comp.errored = false; | ||
| } | ||
| ctx?.commit?.(); | ||
@@ -558,3 +607,3 @@ return undefined; | ||
| }, () => comp.disposed); | ||
| if (ctx?.async && ctx.serialize && id && !noHydrate) { | ||
| if (serializes) { | ||
| let tappedFirst = true; | ||
@@ -579,6 +628,8 @@ const tapped = { | ||
| ctx.serialize(id, tapped, deferStream); | ||
| } else if (ctx?.commit) { | ||
| } else if (ctx?.commit && inServerComponentScope()) { | ||
| const release = ctx.hold?.(); | ||
| const pump = () => { | ||
| if (comp.disposed) { | ||
| closeAsyncIterator(iter); | ||
| release?.(); | ||
| return; | ||
@@ -589,17 +640,30 @@ } | ||
| closeAsyncIterator(iter); | ||
| release?.(); | ||
| return; | ||
| } | ||
| if (r.done) return; | ||
| if (r.done) { | ||
| release?.(); | ||
| return; | ||
| } | ||
| comp.value = r.value; | ||
| ctx.commit(); | ||
| pump(); | ||
| }, () => {}); | ||
| }, () => release?.()); | ||
| }; | ||
| deferred.promise.then(pump, () => {}); | ||
| deferred.promise.then(pump, () => release?.()); | ||
| } | ||
| comp.error = new NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| if (loadingState) { | ||
| loadingState.served = true; | ||
| comp.value = loadingState.value; | ||
| } else { | ||
| comp.error = new NotReadyError(deferred.promise); | ||
| comp.errored = true; | ||
| } | ||
| } | ||
| return; | ||
| } | ||
| if (loadingState?.served) { | ||
| if (ctx?.async && ctx.serialize && id && !noHydrate) ctx.serialize(id, Promise.resolve(result), deferStream); | ||
| return; | ||
| } | ||
| comp.value = result; | ||
@@ -721,2 +785,15 @@ comp.sync = true; | ||
| } | ||
| const projectionTraces = new WeakMap(); | ||
| function getProjectionTrace(value) { | ||
| return typeof value === "object" && value !== null ? projectionTraces.get(value) : undefined; | ||
| } | ||
| function registerSettledTrace(pending, ready, state) { | ||
| projectionTraces.set(pending, { | ||
| array: Array.isArray(state), | ||
| subscribe: async function* () { | ||
| await ready; | ||
| yield JSON.parse(JSON.stringify(state)); | ||
| } | ||
| }); | ||
| } | ||
| function replaceState(target, next) { | ||
@@ -729,2 +806,3 @@ for (const key of Object.keys(target)) { | ||
| function createProjection(fn, initialValue, options) { | ||
| assertClientCommitZero(options, true); | ||
| const ctx = sharedConfig.context; | ||
@@ -744,2 +822,7 @@ const owner = createOwner(); | ||
| const draft = useProxy ? createDeepProxy(state, patches) : state; | ||
| const seedLoading = !!options?.seedLoadingValue; | ||
| const frozenSeed = seedLoading ? JSON.parse(JSON.stringify(state)) : undefined; | ||
| const seedLock = markReady => { | ||
| if (seedLoading) markReady(frozenSeed); | ||
| }; | ||
| const runProjection = () => { | ||
@@ -756,2 +839,3 @@ resetOwnerForRerun(owner); | ||
| const [pending, markReady] = createPendingProxy(state, deferred.promise); | ||
| seedLock(markReady); | ||
| settleServerAsync(Promise.reject(error), () => runProjection(), deferred, value => { | ||
@@ -766,2 +850,3 @@ if (value !== undefined && value !== state && value !== draft) { | ||
| }, () => disposed); | ||
| registerSettledTrace(pending, deferred.promise, state); | ||
| if (ctx?.async && !getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, deferred.promise, options?.deferStream); | ||
@@ -777,2 +862,3 @@ return pending; | ||
| const [pending, markReady] = createPendingProxy(state, deferred.promise); | ||
| seedLock(markReady); | ||
| const runFirst = () => { | ||
@@ -800,2 +886,3 @@ const source = currentResult ?? runProjection(); | ||
| }, () => disposed); | ||
| registerSettledTrace(pending, deferred.promise, state); | ||
| if (ctx?.async && !getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, deferred.promise, options?.deferStream); | ||
@@ -809,2 +896,3 @@ return pending; | ||
| const [pending, markReady] = createPendingProxy(state, deferred.promise); | ||
| seedLock(markReady); | ||
| const runFirst = () => { | ||
@@ -829,3 +917,3 @@ const source = currentResult ?? runProjection(); | ||
| } | ||
| markReady(JSON.parse(JSON.stringify(state))); | ||
| markReady(seedLoading ? undefined : JSON.parse(JSON.stringify(state))); | ||
| return undefined; | ||
@@ -835,46 +923,51 @@ }, error => { | ||
| }, () => disposed); | ||
| const log = []; | ||
| let logDone = false; | ||
| let logError; | ||
| let pumping = null; | ||
| let consumers = 0; | ||
| const pump = () => pumping ??= iter.next().then(r => { | ||
| pumping = null; | ||
| if (disposed || r.done) { | ||
| logDone = true; | ||
| return; | ||
| } | ||
| if (r.value !== undefined && r.value !== draft) { | ||
| replaceState(draft, r.value); | ||
| } | ||
| log.push(patches.splice(0)); | ||
| }, error => { | ||
| pumping = null; | ||
| logDone = true; | ||
| logError = error; | ||
| }); | ||
| const subscribe = async function* () { | ||
| await deferred.promise; | ||
| if (firstResult?.done) return; | ||
| while (pumping) await pumping; | ||
| let cursor = log.length; | ||
| consumers++; | ||
| try { | ||
| yield JSON.parse(JSON.stringify(state)); | ||
| while (true) { | ||
| if (cursor < log.length) { | ||
| yield log[cursor++]; | ||
| continue; | ||
| } | ||
| if (logDone) { | ||
| if (logError) throw logError; | ||
| return; | ||
| } | ||
| await pump(); | ||
| } | ||
| } finally { | ||
| if (--consumers === 0 && !logDone) closeAsyncIterator(iter); | ||
| } | ||
| }; | ||
| projectionTraces.set(pending, { | ||
| subscribe, | ||
| array: Array.isArray(state) | ||
| }); | ||
| if (ctx?.async && !getContext(NoHydrateContext) && owner.id) { | ||
| let tappedFirst = true; | ||
| const tapped = { | ||
| [Symbol.asyncIterator]: () => ({ | ||
| next() { | ||
| if (tappedFirst) { | ||
| tappedFirst = false; | ||
| return deferred.promise.then(() => { | ||
| if (firstResult?.done) return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| return { | ||
| done: false, | ||
| value: JSON.parse(JSON.stringify(state)) | ||
| }; | ||
| }); | ||
| } | ||
| return iter.next().then(r => { | ||
| if (disposed) return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| if (!r.done) { | ||
| if (r.value !== undefined && r.value !== draft) { | ||
| replaceState(draft, r.value); | ||
| } | ||
| return { | ||
| done: false, | ||
| value: patches.splice(0) | ||
| }; | ||
| } | ||
| return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| }); | ||
| }, | ||
| return(value) { | ||
| return iter.return?.(value); | ||
| } | ||
| }) | ||
| }; | ||
| ctx.serialize(owner.id, tapped, options?.deferStream); | ||
| ctx.serialize(owner.id, subscribe(), options?.deferStream); | ||
| } | ||
@@ -887,2 +980,3 @@ return pending; | ||
| const [pending, markReady] = createPendingProxy(state, deferred.promise); | ||
| seedLock(markReady); | ||
| settleServerAsync(result, () => runProjection(), deferred, value => { | ||
@@ -897,2 +991,3 @@ if (value !== undefined && value !== state) { | ||
| }, () => disposed); | ||
| registerSettledTrace(pending, deferred.promise, state); | ||
| if (ctx?.async && !getContext(NoHydrateContext) && owner.id) ctx.serialize(owner.id, deferred.promise, options?.deferStream); | ||
@@ -1083,3 +1178,3 @@ return pending; | ||
| }; | ||
| return () => { | ||
| return Object.assign(() => { | ||
| let result; | ||
@@ -1101,3 +1196,5 @@ let handled = false; | ||
| return result; | ||
| }; | ||
| }, { | ||
| $lhSkip: true | ||
| }); | ||
| } | ||
@@ -1137,2 +1234,6 @@ function createLoadingBoundary$1(fn, fallback, options) { | ||
| } | ||
| function inServerComponentScope() { | ||
| const o = currentOwner; | ||
| return !!o && o._context[ServerComponentContext.id] === true; | ||
| } | ||
| function serverComponentContextError(context) { | ||
@@ -1261,3 +1362,10 @@ const o = currentOwner; | ||
| const registerLazyAssets = id => { | ||
| const assets = ctx.resolveAssets(id); | ||
| const cache = ctx._lazyAssets ??= new Map(); | ||
| let assets; | ||
| if (cache.has(id)) { | ||
| assets = cache.get(id); | ||
| } else { | ||
| assets = ctx.resolveAssets(id); | ||
| cache.set(id, assets); | ||
| } | ||
| if (assets && typeof assets.then === "function") { | ||
@@ -1347,3 +1455,3 @@ const boundary = ctx._currentBoundaryId; | ||
| if (probe) return; | ||
| const handler = getContext(ErrorContext); | ||
| const handler = getOwner() ? getContext(ErrorContext) : null; | ||
| if (handler) { | ||
@@ -1408,7 +1516,12 @@ handler(err); | ||
| if (done?.(undefined, err)) return; | ||
| if (!parentHandler) throw err; | ||
| if (!parentHandler) { | ||
| ctx.failRender ? ctx.failRender(err) : console.error(err); | ||
| return; | ||
| } | ||
| try { | ||
| runWithOwner(parent, () => parentHandler(err)); | ||
| } catch (caught) { | ||
| if (caught !== err) throw caught; | ||
| if (caught !== err) { | ||
| ctx.failRender ? ctx.failRender(caught) : console.error(caught); | ||
| } | ||
| } | ||
@@ -1432,6 +1545,9 @@ } | ||
| } | ||
| const skipLive = f => Object.assign(f, { | ||
| $lhSkip: true | ||
| }); | ||
| let ret = runDiscovery(); | ||
| if (!retryPromise && !ret?.p?.length) { | ||
| commitBoundaryState(); | ||
| return () => ret; | ||
| return skipLive(() => ret); | ||
| } | ||
@@ -1443,3 +1559,3 @@ const regResult = revealGroup ? revealGroup.register(id) : null; | ||
| ctx.serialize(id, "$$f"); | ||
| return () => undefined; | ||
| return skipLive(() => undefined); | ||
| } | ||
@@ -1479,7 +1595,7 @@ const fallbackOwner = createOwner({ | ||
| })(); | ||
| return () => fallbackResult; | ||
| return skipLive(() => fallbackResult); | ||
| } | ||
| commitBoundaryState(); | ||
| ctx.serialize(id, "$$f"); | ||
| return () => fallbackResult; | ||
| return skipLive(() => fallbackResult); | ||
| } | ||
@@ -1763,4 +1879,7 @@ function NoHydration(props) { | ||
| function materializeContainerTrace(marker) { | ||
| return marker; | ||
| } | ||
| const DEV = undefined; | ||
| export { $DEVCOMP, DEV, Errored, For, Hydration, Loading, Match, NoHydrateContext, NoHydration, Repeat, Reveal, Show, Switch, action, affects, children, createComponent, createContext, createDeepProxy, createEffect, createErrorBoundary, createLoadingBoundary, createMemo, createOptimistic, createOptimisticStore, createOwner, createProjection, createReaction, createRenderEffect, createRevealOrder, createRoot, createSignal, createStore, createTrackedEffect, createUniqueId, deep, enableHydration, flush, getNextChildId, getObserver, getOwner, isDisposed, isPending, latest, lazy, mapArray, merge, onCleanup, onSettled, reconcile, refresh, repeat, resolve, runInServerComponentScope, runWithOwner, sharedConfig, ssrHandleError, ssrScope, untrack, useContext }; | ||
| export { $DEVCOMP, DEV, Errored, For, Hydration, Loading, Match, NoHydrateContext, NoHydration, Repeat, Reveal, Show, Switch, action, affects, children, createComponent, createContext, createDeepProxy, createEffect, createErrorBoundary, createLoadingBoundary, createMemo, createOptimistic, createOptimisticStore, createOwner, createProjection, createReaction, createRenderEffect, createRevealOrder, createRoot, createSignal, createStore, createTrackedEffect, createUniqueId, creationStamp, deep, enableHydration, flush, getNextChildId, getObserver, getOwner, getProjectionTrace, inServerComponentScope, isDisposed, isPending, latest, lazy, mapArray, materializeContainerTrace, merge, onCleanup, onSettled, reconcile, refresh, repeat, resolve, runInServerComponentScope, runWithOwner, sharedConfig, ssrHandleError, ssrScope, untrack, useContext }; |
+164
-103
@@ -44,5 +44,3 @@ 'use strict'; | ||
| registry: undefined, | ||
| done: false, | ||
| isHydrationInProgress, | ||
| onHydrationEnd | ||
| done: false | ||
| }; | ||
@@ -101,9 +99,7 @@ function hydrationGetNextContextId() { | ||
| let _createErrorBoundary; | ||
| let _createOptimistic; | ||
| let _createProjection; | ||
| let _createStore; | ||
| let _createOptimisticStore; | ||
| let _createRenderEffect; | ||
| let _createEffect; | ||
| let _createLoadingBoundary; | ||
| let _hydrateSignalLike; | ||
| let _hydrateStoreLike; | ||
| let _lazyHydrationLookup; | ||
@@ -151,5 +147,8 @@ // it in EVERY client bundle even with zero references; the PURE-annotated | ||
| } | ||
| function readHydratedValue(initP, refresh) { | ||
| function readHydratedValue(initP, refresh, options) { | ||
| refresh(); | ||
| if (initP != null && typeof initP === "object") { | ||
| if (hasLoadingWindow(options) && typeof initP.then === "function") return { | ||
| then: initP.then.bind(initP) | ||
| }; | ||
| if (initP.s === 2) throw initP.v; | ||
@@ -160,7 +159,13 @@ if (initP.s === 1) return initP.v; | ||
| } | ||
| function readSerializedOrCompute(compute, prev) { | ||
| function readSerializedOrCompute(compute, prev, options) { | ||
| const o = signals.getOwner(); | ||
| if (sharedConfig.done || !sharedConfig.has(o.id)) return compute(prev); | ||
| return readHydratedValue(sharedConfig.load(o.id), () => subFetch(compute, prev)); | ||
| return readHydratedValue(sharedConfig.load(o.id), () => subFetch(compute, prev), options); | ||
| } | ||
| const UNASKED = { | ||
| then() {} | ||
| }; | ||
| function hasLoadingWindow(options) { | ||
| return options != null && typeof options === "object" && ("loadingValue" in options || options.seedLoadingValue === true); | ||
| } | ||
| function forwardIteratorReturn(it, value) { | ||
@@ -173,3 +178,3 @@ const returned = it.return?.(value); | ||
| } | ||
| function normalizeIterator(it) { | ||
| function normalizeIterator(it, deferFirst) { | ||
| let first = true; | ||
@@ -182,3 +187,4 @@ let buffered = null; | ||
| const r = it.next(); | ||
| return r && typeof r.then === "function" ? r : syncThenable(r); | ||
| if (r && typeof r.then === "function") return r; | ||
| return deferFirst ? Promise.resolve(r) : syncThenable(r); | ||
| } | ||
@@ -192,2 +198,3 @@ if (buffered) { | ||
| if (latest && typeof latest.then === "function") return latest; | ||
| let result = latest; | ||
| while (!latest.done) { | ||
@@ -200,4 +207,5 @@ const peek = it.next(); | ||
| latest = peek; | ||
| if (!latest.done) result = latest;else if (result !== latest) buffered = Promise.resolve(latest); | ||
| } | ||
| return Promise.resolve(latest); | ||
| return Promise.resolve(result); | ||
| }, | ||
@@ -298,3 +306,3 @@ return(value) { | ||
| if (!isAsyncIterable(loaded)) return null; | ||
| const it = normalizeIterator(loaded[Symbol.asyncIterator]()); | ||
| const it = normalizeIterator(loaded[Symbol.asyncIterator](), hasLoadingWindow(options)); | ||
| const iterable = { | ||
@@ -317,2 +325,3 @@ [Symbol.asyncIterator]() { | ||
| const srcIt = loaded[Symbol.asyncIterator](); | ||
| const loading = hasLoadingWindow(options); | ||
| let isFirst = true; | ||
@@ -360,7 +369,13 @@ let buffered = null; | ||
| const r = srcIt.next(); | ||
| return r && typeof r.then === "function" ? { | ||
| if (r && typeof r.then === "function") return { | ||
| then(fn, rej) { | ||
| r.then(v => fn(process(v)), rej); | ||
| } | ||
| } : syncThenable(process(r)); | ||
| }; | ||
| if (loading) { | ||
| return new Promise(resolvePull => { | ||
| onHydrationEnd(() => resolvePull(process(r))); | ||
| }); | ||
| } | ||
| return syncThenable(process(r)); | ||
| } | ||
@@ -376,13 +391,17 @@ if (buffered) { | ||
| } | ||
| let result = process(r); | ||
| while (!r.done) { | ||
| const peek = srcIt.next(); | ||
| if (peek && typeof peek.then === "function") { | ||
| buffered = peek; | ||
| break; | ||
| } | ||
| r = peek; | ||
| if (!r.done) result = process(r); | ||
| } | ||
| return Promise.resolve(result); | ||
| return new Promise(resolvePull => { | ||
| onHydrationEnd(() => { | ||
| let result = process(r); | ||
| while (!r.done) { | ||
| const peek = srcIt.next(); | ||
| if (peek && typeof peek.then === "function") { | ||
| buffered = peek; | ||
| break; | ||
| } | ||
| r = peek; | ||
| if (!r.done) result = process(r); | ||
| } | ||
| resolvePull(result); | ||
| }); | ||
| }); | ||
| }, | ||
@@ -398,41 +417,63 @@ return(value) { | ||
| } | ||
| function hydratedCreateMemo(compute, options) { | ||
| if (!sharedConfig.hydrating || options?.transparent) { | ||
| return signals.createMemo(compute, options); | ||
| } | ||
| function materializeContainerTrace(marker) { | ||
| const src = marker.$tr; | ||
| return signals.createRoot(() => createProjection(draft => ({ | ||
| [Symbol.asyncIterator]() { | ||
| const srcIt = src[Symbol.asyncIterator](); | ||
| let first = true; | ||
| return { | ||
| next: () => Promise.resolve(srcIt.next()).then(res => { | ||
| if (res.done) return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| if (first) { | ||
| first = false; | ||
| if (Array.isArray(res.value)) { | ||
| for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i]; | ||
| draft.length = res.value.length; | ||
| } else { | ||
| Object.assign(draft, res.value); | ||
| } | ||
| } else { | ||
| applyPatches(draft, res.value); | ||
| } | ||
| return { | ||
| done: false, | ||
| value: undefined | ||
| }; | ||
| }), | ||
| return: value => forwardIteratorReturn(srcIt, value) | ||
| }; | ||
| } | ||
| }), marker.$ta ? [] : {})); | ||
| } | ||
| function hydrateSignalLike(coreFn, fn, options) { | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = options?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const windowed = hasLoadingWindow(options); | ||
| const [hydrated, setHydrated] = signals.createSignal(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const memo = signals.createMemo(prev => { | ||
| if (!hydrated()) return prev; | ||
| return compute(prev); | ||
| const sig = coreFn(prev => { | ||
| if (!hydrated()) return windowed ? UNASKED : prev; | ||
| return fn(prev); | ||
| }, options); | ||
| setHydrated(true); | ||
| return memo; | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(signals.createMemo, compute, options); | ||
| const aiResult = hydrateSignalFromAsyncIterable(coreFn, fn, options); | ||
| if (aiResult !== null) return aiResult; | ||
| return signals.createMemo(prev => readSerializedOrCompute(compute, prev), options); | ||
| return coreFn(prev => readSerializedOrCompute(fn, prev, options), options); | ||
| } | ||
| function hydratedCreateMemo(compute, options) { | ||
| if (!sharedConfig.hydrating || options?.transparent) { | ||
| return signals.createMemo(compute, options); | ||
| } | ||
| return hydrateSignalLike(signals.createMemo, compute, options); | ||
| } | ||
| function hydratedCreateSignal(fn, second) { | ||
| if (typeof fn !== "function" || !sharedConfig.hydrating) return signals.createSignal(fn, second); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = second?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const [hydrated, setHydrated] = signals.createSignal(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const sig = signals.createSignal(prev => { | ||
| if (!hydrated()) return prev; | ||
| return fn(prev); | ||
| }, second); | ||
| setHydrated(true); | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(signals.createSignal, fn, second); | ||
| if (aiResult !== null) return aiResult; | ||
| return signals.createSignal(prev => readSerializedOrCompute(fn, prev), second); | ||
| return hydrateSignalLike(signals.createSignal, fn, second); | ||
| } | ||
@@ -459,26 +500,8 @@ function hydratedCreateErrorBoundary(fn, fallback) { | ||
| } | ||
| function hydratedCreateOptimistic(fn, second) { | ||
| if (typeof fn !== "function" || !sharedConfig.hydrating) return signals.createOptimistic(fn, second); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = second?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const [hydrated, setHydrated] = signals.createSignal(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const sig = signals.createOptimistic(prev => { | ||
| if (!hydrated()) return prev; | ||
| return fn(prev); | ||
| }, second); | ||
| setHydrated(true); | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(signals.createOptimistic, fn, second); | ||
| if (aiResult !== null) return aiResult; | ||
| return signals.createOptimistic(prev => readSerializedOrCompute(fn, prev), second); | ||
| function wrapStoreFn(fn, options) { | ||
| return draft => readSerializedOrCompute(() => fn(draft), draft, options); | ||
| } | ||
| function wrapStoreFn(fn) { | ||
| return draft => readSerializedOrCompute(() => fn(draft), draft); | ||
| } | ||
| function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) { | ||
| if (ssrSource === "client") { | ||
| const windowed = hasLoadingWindow(options); | ||
| const [hydrated, setHydrated] = signals.createSignal(false, { | ||
@@ -488,3 +511,3 @@ ownedWrite: true | ||
| const result = coreFn(draft => { | ||
| if (!hydrated()) return; | ||
| if (!hydrated()) return windowed ? UNASKED : undefined; | ||
| return fn(draft); | ||
@@ -502,3 +525,3 @@ }, initialValue, options); | ||
| if (!hydrated()) { | ||
| if (sharedConfig.has(o.id)) return readHydratedValue(sharedConfig.load(o.id), () => subFetch(fn, draft)); | ||
| if (sharedConfig.has(o.id)) return readHydratedValue(sharedConfig.load(o.id), () => subFetch(fn, draft), options); | ||
| return fn(draft); | ||
@@ -518,22 +541,8 @@ } | ||
| if (aiResult !== null) return aiResult; | ||
| return coreFn(wrapStoreFn(fn), initialValue, options); | ||
| return coreFn(wrapStoreFn(fn, options), initialValue, options); | ||
| } | ||
| function hydratedCreateStore(first, second, third) { | ||
| if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createStore(first, second, third); | ||
| function hydrateStoreLike(coreFn, fn, initialValue, options) { | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = third?.ssrSource; | ||
| return hydrateStoreLikeFn(signals.createStore, first, second ?? {}, third, ssrSource); | ||
| return hydrateStoreLikeFn(coreFn, fn, initialValue, options, options?.ssrSource); | ||
| } | ||
| function hydratedCreateOptimisticStore(first, second, third) { | ||
| if (typeof first !== "function" || !sharedConfig.hydrating) return signals.createOptimisticStore(first, second, third); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = third?.ssrSource; | ||
| return hydrateStoreLikeFn(signals.createOptimisticStore, first, second ?? {}, third, ssrSource); | ||
| } | ||
| function hydratedCreateProjection(fn, initialValue, options) { | ||
| if (!sharedConfig.hydrating) return signals.createProjection(fn, initialValue, options); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = options?.ssrSource; | ||
| return hydrateStoreLikeFn(signals.createProjection, fn, initialValue, options, ssrSource); | ||
| } | ||
| function hydratedEffect(coreFn, compute, effectFn, options) { | ||
@@ -581,6 +590,4 @@ if (!sharedConfig.hydrating || options?.transparent) return coreFn(compute, effectFn, options); | ||
| _createErrorBoundary = hydratedCreateErrorBoundary; | ||
| _createOptimistic = hydratedCreateOptimistic; | ||
| _createProjection = hydratedCreateProjection; | ||
| _createStore = hydratedCreateStore; | ||
| _createOptimisticStore = hydratedCreateOptimisticStore; | ||
| _hydrateSignalLike = hydrateSignalLike; | ||
| _hydrateStoreLike = hydrateStoreLike; | ||
| _createRenderEffect = hydratedCreateRenderEffect; | ||
@@ -591,2 +598,4 @@ _createEffect = hydratedCreateEffect; | ||
| sharedConfig.getNextContextId = hydrationGetNextContextId; | ||
| sharedConfig.isHydrationInProgress = isHydrationInProgress; | ||
| sharedConfig.onHydrationEnd = onHydrationEnd; | ||
| const hy = globalThis._$HY; | ||
@@ -645,4 +654,8 @@ if (hy && !hy.fr) { | ||
| } | ||
| const createMemo = (...args) => (_createMemo || signals.createMemo)(...args); | ||
| const createSignal = (...args) => (_createSignal || signals.createSignal)(...args); | ||
| const createMemo = (...args) => { | ||
| return (_createMemo || signals.createMemo)(...args); | ||
| }; | ||
| const createSignal = (...args) => { | ||
| return (_createSignal || signals.createSignal)(...args); | ||
| }; | ||
| const createErrorBoundary = (...args) => (_createErrorBoundary || signals.createErrorBoundary)(...args); | ||
@@ -652,6 +665,14 @@ function createRevealOrder(fn, options) { | ||
| } | ||
| const createOptimistic = (...args) => (_createOptimistic || signals.createOptimistic)(...args); | ||
| const createProjection = (...args) => (_createProjection || signals.createProjection)(...args); | ||
| const createStore = (...args) => (_createStore || signals.createStore)(...args); | ||
| const createOptimisticStore = (...args) => (_createOptimisticStore || signals.createOptimisticStore)(...args); | ||
| const createOptimistic = (...args) => { | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateSignalLike(signals.createOptimistic, args[0], args[1]) : signals.createOptimistic(...args); | ||
| }; | ||
| const createProjection = (...args) => { | ||
| return sharedConfig.hydrating ? _hydrateStoreLike(signals.createProjection, args[0], args[1], args[2]) : signals.createProjection(...args); | ||
| }; | ||
| const createStore = (...args) => { | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateStoreLike(signals.createStore, args[0], args[1] ?? {}, args[2]) : signals.createStore(...args); | ||
| }; | ||
| const createOptimisticStore = (...args) => { | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateStoreLike(signals.createOptimisticStore, args[0], args[1] ?? {}, args[2]) : signals.createOptimisticStore(...args); | ||
| }; | ||
| const createRenderEffect = (...args) => (_createRenderEffect || signals.createRenderEffect)(...args); | ||
@@ -785,2 +806,3 @@ const createEffect = (...args) => (_createEffect || signals.createEffect)(...args); | ||
| } | ||
| setTimeout(() => rejectTruncatedRefs(hy)); | ||
| }, { | ||
@@ -790,2 +812,28 @@ once: true | ||
| } | ||
| function rejectTruncatedRefs(hy) { | ||
| const R = globalThis.$R; | ||
| if (!R || typeof R !== "object") return; | ||
| let registryKeys; | ||
| const sweep = entry => { | ||
| if (!entry || typeof entry !== "object" || typeof entry.f !== "function" || !entry.p || typeof entry.p.then !== "function" || entry.p.s) return; | ||
| if (!registryKeys) { | ||
| registryKeys = new Map(); | ||
| for (const key in hy.r) registryKeys.set(hy.r[key], key); | ||
| } | ||
| const key = registryKeys.get(entry.p); | ||
| if (key !== undefined) { | ||
| delete hy.r[key]; | ||
| return; | ||
| } | ||
| const err = new Error("Hydration value was truncated: the stream ended before it settled."); | ||
| entry.f(err); | ||
| entry.p.s = 2; | ||
| entry.p.v = err; | ||
| entry.p.then(undefined, () => {}); | ||
| }; | ||
| for (const key in R) { | ||
| const value = R[key]; | ||
| if (Array.isArray(value)) for (const entry of value) sweep(entry);else sweep(value); | ||
| } | ||
| } | ||
| function markTruncated(hy, id) { | ||
@@ -1082,2 +1130,11 @@ if (_truncated.has(id)) return; | ||
| } | ||
| function creationStamp() { | ||
| return 0; | ||
| } | ||
| function inServerComponentScope() { | ||
| return false; | ||
| } | ||
| function getProjectionTrace(value) { | ||
| return undefined; | ||
| } | ||
| const DEV = undefined; | ||
@@ -1257,4 +1314,8 @@ | ||
| exports.createUniqueId = createUniqueId; | ||
| exports.creationStamp = creationStamp; | ||
| exports.enableHydration = enableHydration; | ||
| exports.getProjectionTrace = getProjectionTrace; | ||
| exports.inServerComponentScope = inServerComponentScope; | ||
| exports.lazy = lazy; | ||
| exports.materializeContainerTrace = materializeContainerTrace; | ||
| exports.runInServerComponentScope = runInServerComponentScope; | ||
@@ -1261,0 +1322,0 @@ exports.sharedConfig = sharedConfig; |
+161
-104
@@ -43,5 +43,3 @@ import { getContext, createMemo as createMemo$1, flatten, createRoot, setContext, createOwner, runWithOwner, createEffect as createEffect$1, createErrorBoundary as createErrorBoundary$1, createLoadingBoundary as createLoadingBoundary$1, createOptimistic as createOptimistic$1, createOptimisticStore as createOptimisticStore$1, createProjection as createProjection$1, createRenderEffect as createRenderEffect$1, createRevealOrder as createRevealOrder$1, createSignal as createSignal$1, createStore as createStore$1, setSnapshotCapture, releaseSnapshotScope, getOwner, peekNextChildId, getNextChildId, clearSnapshots, flush, markSnapshotScope, onCleanup, isDisposed, untrack, mapArray, repeat } from '@solidjs/signals'; | ||
| registry: undefined, | ||
| done: false, | ||
| isHydrationInProgress, | ||
| onHydrationEnd | ||
| done: false | ||
| }; | ||
@@ -100,9 +98,7 @@ function hydrationGetNextContextId() { | ||
| let _createErrorBoundary; | ||
| let _createOptimistic; | ||
| let _createProjection; | ||
| let _createStore; | ||
| let _createOptimisticStore; | ||
| let _createRenderEffect; | ||
| let _createEffect; | ||
| let _createLoadingBoundary; | ||
| let _hydrateSignalLike; | ||
| let _hydrateStoreLike; | ||
| let _lazyHydrationLookup; | ||
@@ -150,5 +146,8 @@ // it in EVERY client bundle even with zero references; the PURE-annotated | ||
| } | ||
| function readHydratedValue(initP, refresh) { | ||
| function readHydratedValue(initP, refresh, options) { | ||
| refresh(); | ||
| if (initP != null && typeof initP === "object") { | ||
| if (hasLoadingWindow(options) && typeof initP.then === "function") return { | ||
| then: initP.then.bind(initP) | ||
| }; | ||
| if (initP.s === 2) throw initP.v; | ||
@@ -159,7 +158,13 @@ if (initP.s === 1) return initP.v; | ||
| } | ||
| function readSerializedOrCompute(compute, prev) { | ||
| function readSerializedOrCompute(compute, prev, options) { | ||
| const o = getOwner(); | ||
| if (sharedConfig.done || !sharedConfig.has(o.id)) return compute(prev); | ||
| return readHydratedValue(sharedConfig.load(o.id), () => subFetch(compute, prev)); | ||
| return readHydratedValue(sharedConfig.load(o.id), () => subFetch(compute, prev), options); | ||
| } | ||
| const UNASKED = { | ||
| then() {} | ||
| }; | ||
| function hasLoadingWindow(options) { | ||
| return options != null && typeof options === "object" && ("loadingValue" in options || options.seedLoadingValue === true); | ||
| } | ||
| function forwardIteratorReturn(it, value) { | ||
@@ -172,3 +177,3 @@ const returned = it.return?.(value); | ||
| } | ||
| function normalizeIterator(it) { | ||
| function normalizeIterator(it, deferFirst) { | ||
| let first = true; | ||
@@ -181,3 +186,4 @@ let buffered = null; | ||
| const r = it.next(); | ||
| return r && typeof r.then === "function" ? r : syncThenable(r); | ||
| if (r && typeof r.then === "function") return r; | ||
| return deferFirst ? Promise.resolve(r) : syncThenable(r); | ||
| } | ||
@@ -191,2 +197,3 @@ if (buffered) { | ||
| if (latest && typeof latest.then === "function") return latest; | ||
| let result = latest; | ||
| while (!latest.done) { | ||
@@ -199,4 +206,5 @@ const peek = it.next(); | ||
| latest = peek; | ||
| if (!latest.done) result = latest;else if (result !== latest) buffered = Promise.resolve(latest); | ||
| } | ||
| return Promise.resolve(latest); | ||
| return Promise.resolve(result); | ||
| }, | ||
@@ -297,3 +305,3 @@ return(value) { | ||
| if (!isAsyncIterable(loaded)) return null; | ||
| const it = normalizeIterator(loaded[Symbol.asyncIterator]()); | ||
| const it = normalizeIterator(loaded[Symbol.asyncIterator](), hasLoadingWindow(options)); | ||
| const iterable = { | ||
@@ -316,2 +324,3 @@ [Symbol.asyncIterator]() { | ||
| const srcIt = loaded[Symbol.asyncIterator](); | ||
| const loading = hasLoadingWindow(options); | ||
| let isFirst = true; | ||
@@ -359,7 +368,13 @@ let buffered = null; | ||
| const r = srcIt.next(); | ||
| return r && typeof r.then === "function" ? { | ||
| if (r && typeof r.then === "function") return { | ||
| then(fn, rej) { | ||
| r.then(v => fn(process(v)), rej); | ||
| } | ||
| } : syncThenable(process(r)); | ||
| }; | ||
| if (loading) { | ||
| return new Promise(resolvePull => { | ||
| onHydrationEnd(() => resolvePull(process(r))); | ||
| }); | ||
| } | ||
| return syncThenable(process(r)); | ||
| } | ||
@@ -375,13 +390,17 @@ if (buffered) { | ||
| } | ||
| let result = process(r); | ||
| while (!r.done) { | ||
| const peek = srcIt.next(); | ||
| if (peek && typeof peek.then === "function") { | ||
| buffered = peek; | ||
| break; | ||
| } | ||
| r = peek; | ||
| if (!r.done) result = process(r); | ||
| } | ||
| return Promise.resolve(result); | ||
| return new Promise(resolvePull => { | ||
| onHydrationEnd(() => { | ||
| let result = process(r); | ||
| while (!r.done) { | ||
| const peek = srcIt.next(); | ||
| if (peek && typeof peek.then === "function") { | ||
| buffered = peek; | ||
| break; | ||
| } | ||
| r = peek; | ||
| if (!r.done) result = process(r); | ||
| } | ||
| resolvePull(result); | ||
| }); | ||
| }); | ||
| }, | ||
@@ -397,41 +416,63 @@ return(value) { | ||
| } | ||
| function hydratedCreateMemo(compute, options) { | ||
| if (!sharedConfig.hydrating || options?.transparent) { | ||
| return createMemo$1(compute, options); | ||
| } | ||
| function materializeContainerTrace(marker) { | ||
| const src = marker.$tr; | ||
| return createRoot(() => createProjection(draft => ({ | ||
| [Symbol.asyncIterator]() { | ||
| const srcIt = src[Symbol.asyncIterator](); | ||
| let first = true; | ||
| return { | ||
| next: () => Promise.resolve(srcIt.next()).then(res => { | ||
| if (res.done) return { | ||
| done: true, | ||
| value: undefined | ||
| }; | ||
| if (first) { | ||
| first = false; | ||
| if (Array.isArray(res.value)) { | ||
| for (let i = 0; i < res.value.length; i++) draft[i] = res.value[i]; | ||
| draft.length = res.value.length; | ||
| } else { | ||
| Object.assign(draft, res.value); | ||
| } | ||
| } else { | ||
| applyPatches(draft, res.value); | ||
| } | ||
| return { | ||
| done: false, | ||
| value: undefined | ||
| }; | ||
| }), | ||
| return: value => forwardIteratorReturn(srcIt, value) | ||
| }; | ||
| } | ||
| }), marker.$ta ? [] : {})); | ||
| } | ||
| function hydrateSignalLike(coreFn, fn, options) { | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = options?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const windowed = hasLoadingWindow(options); | ||
| const [hydrated, setHydrated] = createSignal$1(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const memo = createMemo$1(prev => { | ||
| if (!hydrated()) return prev; | ||
| return compute(prev); | ||
| const sig = coreFn(prev => { | ||
| if (!hydrated()) return windowed ? UNASKED : prev; | ||
| return fn(prev); | ||
| }, options); | ||
| setHydrated(true); | ||
| return memo; | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(createMemo$1, compute, options); | ||
| const aiResult = hydrateSignalFromAsyncIterable(coreFn, fn, options); | ||
| if (aiResult !== null) return aiResult; | ||
| return createMemo$1(prev => readSerializedOrCompute(compute, prev), options); | ||
| return coreFn(prev => readSerializedOrCompute(fn, prev, options), options); | ||
| } | ||
| function hydratedCreateMemo(compute, options) { | ||
| if (!sharedConfig.hydrating || options?.transparent) { | ||
| return createMemo$1(compute, options); | ||
| } | ||
| return hydrateSignalLike(createMemo$1, compute, options); | ||
| } | ||
| function hydratedCreateSignal(fn, second) { | ||
| if (typeof fn !== "function" || !sharedConfig.hydrating) return createSignal$1(fn, second); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = second?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const [hydrated, setHydrated] = createSignal$1(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const sig = createSignal$1(prev => { | ||
| if (!hydrated()) return prev; | ||
| return fn(prev); | ||
| }, second); | ||
| setHydrated(true); | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(createSignal$1, fn, second); | ||
| if (aiResult !== null) return aiResult; | ||
| return createSignal$1(prev => readSerializedOrCompute(fn, prev), second); | ||
| return hydrateSignalLike(createSignal$1, fn, second); | ||
| } | ||
@@ -458,26 +499,8 @@ function hydratedCreateErrorBoundary(fn, fallback) { | ||
| } | ||
| function hydratedCreateOptimistic(fn, second) { | ||
| if (typeof fn !== "function" || !sharedConfig.hydrating) return createOptimistic$1(fn, second); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = second?.ssrSource; | ||
| if (ssrSource === "client") { | ||
| const [hydrated, setHydrated] = createSignal$1(false, { | ||
| ownedWrite: true | ||
| }); | ||
| const sig = createOptimistic$1(prev => { | ||
| if (!hydrated()) return prev; | ||
| return fn(prev); | ||
| }, second); | ||
| setHydrated(true); | ||
| return sig; | ||
| } | ||
| const aiResult = hydrateSignalFromAsyncIterable(createOptimistic$1, fn, second); | ||
| if (aiResult !== null) return aiResult; | ||
| return createOptimistic$1(prev => readSerializedOrCompute(fn, prev), second); | ||
| function wrapStoreFn(fn, options) { | ||
| return draft => readSerializedOrCompute(() => fn(draft), draft, options); | ||
| } | ||
| function wrapStoreFn(fn) { | ||
| return draft => readSerializedOrCompute(() => fn(draft), draft); | ||
| } | ||
| function hydrateStoreLikeFn(coreFn, fn, initialValue, options, ssrSource) { | ||
| if (ssrSource === "client") { | ||
| const windowed = hasLoadingWindow(options); | ||
| const [hydrated, setHydrated] = createSignal$1(false, { | ||
@@ -487,3 +510,3 @@ ownedWrite: true | ||
| const result = coreFn(draft => { | ||
| if (!hydrated()) return; | ||
| if (!hydrated()) return windowed ? UNASKED : undefined; | ||
| return fn(draft); | ||
@@ -501,3 +524,3 @@ }, initialValue, options); | ||
| if (!hydrated()) { | ||
| if (sharedConfig.has(o.id)) return readHydratedValue(sharedConfig.load(o.id), () => subFetch(fn, draft)); | ||
| if (sharedConfig.has(o.id)) return readHydratedValue(sharedConfig.load(o.id), () => subFetch(fn, draft), options); | ||
| return fn(draft); | ||
@@ -517,22 +540,8 @@ } | ||
| if (aiResult !== null) return aiResult; | ||
| return coreFn(wrapStoreFn(fn), initialValue, options); | ||
| return coreFn(wrapStoreFn(fn, options), initialValue, options); | ||
| } | ||
| function hydratedCreateStore(first, second, third) { | ||
| if (typeof first !== "function" || !sharedConfig.hydrating) return createStore$1(first, second, third); | ||
| function hydrateStoreLike(coreFn, fn, initialValue, options) { | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = third?.ssrSource; | ||
| return hydrateStoreLikeFn(createStore$1, first, second ?? {}, third, ssrSource); | ||
| return hydrateStoreLikeFn(coreFn, fn, initialValue, options, options?.ssrSource); | ||
| } | ||
| function hydratedCreateOptimisticStore(first, second, third) { | ||
| if (typeof first !== "function" || !sharedConfig.hydrating) return createOptimisticStore$1(first, second, third); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = third?.ssrSource; | ||
| return hydrateStoreLikeFn(createOptimisticStore$1, first, second ?? {}, third, ssrSource); | ||
| } | ||
| function hydratedCreateProjection(fn, initialValue, options) { | ||
| if (!sharedConfig.hydrating) return createProjection$1(fn, initialValue, options); | ||
| markTopLevelSnapshotScope(); | ||
| const ssrSource = options?.ssrSource; | ||
| return hydrateStoreLikeFn(createProjection$1, fn, initialValue, options, ssrSource); | ||
| } | ||
| function hydratedEffect(coreFn, compute, effectFn, options) { | ||
@@ -580,6 +589,4 @@ if (!sharedConfig.hydrating || options?.transparent) return coreFn(compute, effectFn, options); | ||
| _createErrorBoundary = hydratedCreateErrorBoundary; | ||
| _createOptimistic = hydratedCreateOptimistic; | ||
| _createProjection = hydratedCreateProjection; | ||
| _createStore = hydratedCreateStore; | ||
| _createOptimisticStore = hydratedCreateOptimisticStore; | ||
| _hydrateSignalLike = hydrateSignalLike; | ||
| _hydrateStoreLike = hydrateStoreLike; | ||
| _createRenderEffect = hydratedCreateRenderEffect; | ||
@@ -590,2 +597,4 @@ _createEffect = hydratedCreateEffect; | ||
| sharedConfig.getNextContextId = hydrationGetNextContextId; | ||
| sharedConfig.isHydrationInProgress = isHydrationInProgress; | ||
| sharedConfig.onHydrationEnd = onHydrationEnd; | ||
| const hy = globalThis._$HY; | ||
@@ -644,4 +653,8 @@ if (hy && !hy.fr) { | ||
| } | ||
| const createMemo = (...args) => (_createMemo || createMemo$1)(...args); | ||
| const createSignal = (...args) => (_createSignal || createSignal$1)(...args); | ||
| const createMemo = (...args) => { | ||
| return (_createMemo || createMemo$1)(...args); | ||
| }; | ||
| const createSignal = (...args) => { | ||
| return (_createSignal || createSignal$1)(...args); | ||
| }; | ||
| const createErrorBoundary = (...args) => (_createErrorBoundary || createErrorBoundary$1)(...args); | ||
@@ -651,6 +664,14 @@ function createRevealOrder(fn, options) { | ||
| } | ||
| const createOptimistic = (...args) => (_createOptimistic || createOptimistic$1)(...args); | ||
| const createProjection = (...args) => (_createProjection || createProjection$1)(...args); | ||
| const createStore = (...args) => (_createStore || createStore$1)(...args); | ||
| const createOptimisticStore = (...args) => (_createOptimisticStore || createOptimisticStore$1)(...args); | ||
| const createOptimistic = (...args) => { | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateSignalLike(createOptimistic$1, args[0], args[1]) : createOptimistic$1(...args); | ||
| }; | ||
| const createProjection = (...args) => { | ||
| return sharedConfig.hydrating ? _hydrateStoreLike(createProjection$1, args[0], args[1], args[2]) : createProjection$1(...args); | ||
| }; | ||
| const createStore = (...args) => { | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateStoreLike(createStore$1, args[0], args[1] ?? {}, args[2]) : createStore$1(...args); | ||
| }; | ||
| const createOptimisticStore = (...args) => { | ||
| return typeof args[0] === "function" && sharedConfig.hydrating ? _hydrateStoreLike(createOptimisticStore$1, args[0], args[1] ?? {}, args[2]) : createOptimisticStore$1(...args); | ||
| }; | ||
| const createRenderEffect = (...args) => (_createRenderEffect || createRenderEffect$1)(...args); | ||
@@ -784,2 +805,3 @@ const createEffect = (...args) => (_createEffect || createEffect$1)(...args); | ||
| } | ||
| setTimeout(() => rejectTruncatedRefs(hy)); | ||
| }, { | ||
@@ -789,2 +811,28 @@ once: true | ||
| } | ||
| function rejectTruncatedRefs(hy) { | ||
| const R = globalThis.$R; | ||
| if (!R || typeof R !== "object") return; | ||
| let registryKeys; | ||
| const sweep = entry => { | ||
| if (!entry || typeof entry !== "object" || typeof entry.f !== "function" || !entry.p || typeof entry.p.then !== "function" || entry.p.s) return; | ||
| if (!registryKeys) { | ||
| registryKeys = new Map(); | ||
| for (const key in hy.r) registryKeys.set(hy.r[key], key); | ||
| } | ||
| const key = registryKeys.get(entry.p); | ||
| if (key !== undefined) { | ||
| delete hy.r[key]; | ||
| return; | ||
| } | ||
| const err = new Error("Hydration value was truncated: the stream ended before it settled."); | ||
| entry.f(err); | ||
| entry.p.s = 2; | ||
| entry.p.v = err; | ||
| entry.p.then(undefined, () => {}); | ||
| }; | ||
| for (const key in R) { | ||
| const value = R[key]; | ||
| if (Array.isArray(value)) for (const entry of value) sweep(entry);else sweep(value); | ||
| } | ||
| } | ||
| function markTruncated(hy, id) { | ||
@@ -1081,4 +1129,13 @@ if (_truncated.has(id)) return; | ||
| } | ||
| function creationStamp() { | ||
| return 0; | ||
| } | ||
| function inServerComponentScope() { | ||
| return false; | ||
| } | ||
| function getProjectionTrace(value) { | ||
| return undefined; | ||
| } | ||
| const DEV = undefined; | ||
| export { $DEVCOMP, DEV, Errored, For, Hydration, Loading, Match, NoHydrateContext, NoHydration, Repeat, Reveal, Show, Switch, children, createComponent, createContext, createEffect, createErrorBoundary, createLoadingBoundary, createMemo, createOptimistic, createOptimisticStore, createProjection, createRenderEffect, createRevealOrder, createSignal, createStore, createUniqueId, enableHydration, lazy, runInServerComponentScope, sharedConfig, ssrHandleError, ssrScope, useContext }; | ||
| export { $DEVCOMP, DEV, Errored, For, Hydration, Loading, Match, NoHydrateContext, NoHydration, Repeat, Reveal, Show, Switch, children, createComponent, createContext, createEffect, createErrorBoundary, createLoadingBoundary, createMemo, createOptimistic, createOptimisticStore, createProjection, createRenderEffect, createRevealOrder, createSignal, createStore, createUniqueId, creationStamp, enableHydration, getProjectionTrace, inServerComponentScope, lazy, materializeContainerTrace, runInServerComponentScope, sharedConfig, ssrHandleError, ssrScope, useContext }; |
+2
-2
| { | ||
| "name": "solid-js", | ||
| "description": "Reactive JavaScript library for building user interfaces. Compiles JSX to real DOM with fine-grained signal-based updates — no virtual DOM.", | ||
| "version": "2.0.0-beta.32", | ||
| "version": "2.0.0-beta.33", | ||
| "author": "Ryan Carniato", | ||
@@ -131,3 +131,3 @@ "license": "MIT", | ||
| "dependencies": { | ||
| "@solidjs/signals": "^2.0.0-beta.32", | ||
| "@solidjs/signals": "^2.0.0-beta.33", | ||
| "csstype": "^3.1.0", | ||
@@ -134,0 +134,0 @@ "seroval": "~1.5.4", |
@@ -26,3 +26,7 @@ import { createRenderEffect as coreRenderEffect, createEffect as coreEffect, type Accessor, type ComputeFunction, type MemoOptions, type NoInfer, type ProjectionOptions, type Refreshable, type Signal, type SignalOptions, type SourceAccessor, type Store, type StoreSetter, type RevealOrder, type Context } from "@solidjs/signals"; | ||
| * Choose this for client-only state where serialization is | ||
| * meaningless. | ||
| * meaningless. Requires a declared commit #0: `loadingValue` on | ||
| * signal-family sources (`loadingValue: undefined` is a valid | ||
| * declaration), `seedLoadingValue: true` on store-family sources — | ||
| * the server can't run the compute, so the author must say what | ||
| * the pre-compute window renders. | ||
| */ | ||
@@ -53,3 +57,4 @@ ssrSource?: "server" | "hybrid" | "client"; | ||
| * - `"client"`: skip serialization; compute runs only after hydration | ||
| * completes. | ||
| * completes. Requires `seedLoadingValue: true` — the seed is what the | ||
| * pre-compute window renders, and that promotion must be declared. | ||
| * | ||
@@ -70,2 +75,9 @@ * See {@link HydrationSsrFields} for the fuller explanation. | ||
| }; | ||
| type HydrationProjectionOptions = Omit<ProjectionOptions, "ssrSource"> & { | ||
| ssrSource?: "server" | "hybrid"; | ||
| }; | ||
| type HydrationClientProjectionOptions = Omit<ProjectionOptions, "ssrSource" | "seedLoadingValue"> & { | ||
| ssrSource: "client"; | ||
| seedLoadingValue: true; | ||
| }; | ||
| export type HydrationContext = {}; | ||
@@ -112,4 +124,6 @@ /** | ||
| * resumed or been cancelled. Consumed by dev tooling (the refresh runtime | ||
| * defers hot swaps that would race the claim, #2919). Absent on the server | ||
| * sharedConfig. Cross-package wiring; not part of the user-facing API. | ||
| * defers hot swaps that would race the claim, #2919). Assigned by | ||
| * enableHydration(); absent in CSR bundles and on the server sharedConfig — | ||
| * treat absence as "not hydrating". Cross-package wiring; not part of the | ||
| * user-facing API. | ||
| * | ||
@@ -122,4 +136,7 @@ * @internal | ||
| * boundaries hydrated or cancelled). If hydration is already complete (or | ||
| * not hydrating), fires via queueMicrotask. Absent on the server | ||
| * sharedConfig. Cross-package wiring; not part of the user-facing API. | ||
| * not hydrating), fires via queueMicrotask. Assigned by enableHydration(); | ||
| * absent in CSR bundles and on the server sharedConfig — when absent, | ||
| * hydration is definitionally complete, so fire the callback via | ||
| * queueMicrotask yourself. Cross-package wiring; not part of the | ||
| * user-facing API. | ||
| * | ||
@@ -139,2 +156,23 @@ * @internal | ||
| export declare let _lazyHydrationLookup: (<T>(comp: (() => T | undefined) | undefined, moduleUrl?: string) => (() => T) | undefined) | undefined; | ||
| /** | ||
| * Materialize a container TRACE — snapshot then patch batches, the | ||
| * continuation protocol a server projection serializes as when it crosses a | ||
| * boundary (hydration resume above; the slot border via the serializer's | ||
| * container plugin) — into a live local projection. The result reads like | ||
| * the server value did: not-ready until the snapshot lands, then a | ||
| * read-only store the batches keep updating, done when the trace ends. | ||
| * | ||
| * Created DETACHED (`runWithOwner(null)`): revival can run inside a render | ||
| * effect's owner, and the store is memoized per trace (see the plugin's | ||
| * WeakMap) — a store owned by its first reader would be disposed by that | ||
| * reader's re-render while other readers still hold it. Consumption is | ||
| * pull-driven and the trace is response-bounded, so the projection settles | ||
| * on its own; GC collects the pair with the trace. | ||
| * | ||
| * @internal — consumed by the serialization layer (@solidjs/web). | ||
| */ | ||
| export declare function materializeContainerTrace(marker: { | ||
| $tr: AsyncIterable<any>; | ||
| $ta?: number; | ||
| }): Store<any>; | ||
| export declare function enableHydration(): void; | ||
@@ -184,3 +222,8 @@ /** | ||
| export declare const createMemo: { | ||
| <T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientMemoOptions<T>): SourceAccessor<T | undefined>; | ||
| <T>(compute: ComputeFunction<NoInfer<T>, T>, options: HydrationClientMemoOptions<T> & { | ||
| loadingValue: T; | ||
| }): SourceAccessor<T>; | ||
| <T>(compute: ComputeFunction<NoInfer<T>, T>, options: HydrationMemoOptions<T> & { | ||
| loadingValue: T; | ||
| }): SourceAccessor<T>; | ||
| <T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationMemoOptions<T>): SourceAccessor<T>; | ||
@@ -225,3 +268,8 @@ }; | ||
| <T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>; | ||
| <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientSignalOptions<T>): Signal<T | undefined>; | ||
| <T>(fn: ComputeFunction<NoInfer<T>, T>, options: HydrationClientSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| <T>(fn: ComputeFunction<NoInfer<T>, T>, options: HydrationSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationSignalOptions<T>): Signal<T>; | ||
@@ -290,3 +338,8 @@ }; | ||
| <T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>; | ||
| <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientSignalOptions<T>): Signal<T | undefined>; | ||
| <T>(fn: ComputeFunction<NoInfer<T>, T>, options: HydrationClientSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| <T>(fn: ComputeFunction<NoInfer<T>, T>, options: HydrationSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationSignalOptions<T>): Signal<T>; | ||
@@ -331,3 +384,3 @@ }; | ||
| */ | ||
| export declare const createProjection: <T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions) => Refreshable<Store<T>>; | ||
| export declare const createProjection: <T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: Partial<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions | HydrationClientProjectionOptions) => Refreshable<Store<T>>; | ||
| type NoFn<T> = T extends Function ? never : T; | ||
@@ -399,3 +452,3 @@ /** | ||
| }): [get: Store<T>, set: StoreSetter<T>]; | ||
| <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>]; | ||
| <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions | HydrationClientProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>]; | ||
| }; | ||
@@ -450,3 +503,3 @@ /** | ||
| <T extends object = {}>(store: NoFn<T> | Store<NoFn<T>>): [get: Store<T>, set: StoreSetter<T>]; | ||
| <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>]; | ||
| <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions | HydrationClientProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>]; | ||
| }; | ||
@@ -468,2 +521,6 @@ /** | ||
| * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}. | ||
| * `transparent: true` makes the effect invisible to hydration entirely — | ||
| * it consumes no hydration id slot and its compute runs live rather than | ||
| * adopting the serialized server value — for client-only effects the | ||
| * server never created. | ||
| * | ||
@@ -535,2 +592,6 @@ * @example | ||
| * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}. | ||
| * `transparent: true` makes the effect invisible to hydration entirely — | ||
| * it consumes no hydration id slot and its compute runs live rather than | ||
| * adopting the serialized server value — for client-only effects the | ||
| * server never created. | ||
| * | ||
@@ -537,0 +598,0 @@ * @description https://docs.solidjs.com/reference/basic-reactivity/create-effect |
@@ -8,3 +8,3 @@ export { $PROXY, $REFRESH, $TRACK, action, affects, createOwner, createReaction, createRoot, createTrackedEffect, deep, flatten, flush, getNextChildId, getObserver, getOwner, isDisposed, isEqual, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, latest, reconcile, refresh, repeat, resolve, NotReadyError, runWithOwner, enableExternalSource, enforceLoadingBoundary, snapshot, storePath, untrack } from "@solidjs/signals"; | ||
| export type { ArrayElement, Element } from "./types.cjs"; | ||
| export { sharedConfig, enableHydration, createErrorBoundary, createLoadingBoundary, createRevealOrder, createMemo, createSignal, createStore, createProjection, createOptimistic, createOptimisticStore, createRenderEffect, createEffect, NoHydration, Hydration, NoHydrateContext } from "./client/hydration.cjs"; | ||
| export { sharedConfig, enableHydration, createErrorBoundary, createLoadingBoundary, createRevealOrder, createMemo, createSignal, createStore, createProjection, createOptimistic, createOptimisticStore, createRenderEffect, createEffect, NoHydration, Hydration, NoHydrateContext, materializeContainerTrace } from "./client/hydration.cjs"; | ||
| /** @internal */ | ||
@@ -16,2 +16,11 @@ export declare function ssrHandleError(): void; | ||
| export declare function runInServerComponentScope<T>(fn: () => T): T; | ||
| /** @internal */ | ||
| export declare function creationStamp(): number; | ||
| /** @internal */ | ||
| export declare function inServerComponentScope(): boolean; | ||
| /** @internal — server-only: on the client no value carries a trace. */ | ||
| export declare function getProjectionTrace(value: unknown): { | ||
| subscribe(): AsyncIterable<any>; | ||
| array: boolean; | ||
| } | undefined; | ||
| import { type Dev } from "@solidjs/signals"; | ||
@@ -18,0 +27,0 @@ export declare const DEV: Dev | undefined; |
@@ -1,2 +0,2 @@ | ||
| export { $PROXY, $REFRESH, $TRACK, action, affects, createEffect, createMemo, createOptimistic, createOptimisticStore, createErrorBoundary, createOwner, createProjection, createReaction, createRenderEffect, createRevealOrder, createRoot, createSignal, createStore, createTrackedEffect, deep, flatten, flush, getNextChildId, getObserver, getOwner, isDisposed, isEqual, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, latest, reconcile, refresh, repeat, resolve, NotReadyError, runInServerComponentScope, runWithOwner, snapshot, storePath, createDeepProxy, enableExternalSource, enforceLoadingBoundary, untrack } from "./signals.cjs"; | ||
| export { $PROXY, $REFRESH, $TRACK, action, affects, createEffect, createMemo, createOptimistic, createOptimisticStore, createErrorBoundary, createOwner, creationStamp, createProjection, createReaction, createRenderEffect, createRevealOrder, createRoot, createSignal, createStore, createTrackedEffect, deep, flatten, flush, getNextChildId, getObserver, getOwner, isDisposed, isEqual, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, latest, reconcile, refresh, repeat, resolve, NotReadyError, runInServerComponentScope, inServerComponentScope, getProjectionTrace, runWithOwner, snapshot, storePath, createDeepProxy, enableExternalSource, enforceLoadingBoundary, untrack } from "./signals.cjs"; | ||
| export type { Accessor, ComputeFunction, EffectFunction, EffectOptions, ExternalSource, ExternalSourceConfig, ExternalSourceFactory, Merge, NoInfer, NotWrappable, Omit, Owner, Refreshable, Signal, SignalOptions, Setter, Store, SolidStore, StoreNode, StoreSetter, StorePathRange, ArrayFilterFn, CustomPartial, Part, PathSetter, PatchOp } from "./signals.cjs"; | ||
@@ -10,2 +10,7 @@ export { $DEVCOMP, children, createContext, useContext } from "./core.cjs"; | ||
| export type { HydrationContext } from "./hydration.cjs"; | ||
| /** | ||
| * @internal — client-only (see client/hydration.ts). The server stub is | ||
| * inert: nothing delivers a trace TO a server, so a marker passes through. | ||
| */ | ||
| export declare function materializeContainerTrace(marker: unknown): unknown; | ||
| export declare const DEV: undefined; |
@@ -66,2 +66,18 @@ import type { Context } from "./signals.cjs"; | ||
| /** | ||
| * @internal Containment channel for errors surfacing in async resume loops | ||
| * (boundary retries, flush passes), where nothing is on the stack to catch | ||
| * a throw. Set by dom-expressions' renderToStream: reports through the | ||
| * render's onError and winds the render down — the request fails, the | ||
| * process survives. | ||
| */ | ||
| failRender?: (err: any) => void; | ||
| /** | ||
| * @internal Per-request memo of `resolveAssets(moduleUrl)` results, keyed | ||
| * by moduleUrl. lazy() consults it so a component re-created across | ||
| * suspended render passes asks the manifest exactly once per module — | ||
| * dev-server resolvers answer from the live module graph and can do real | ||
| * work per call (SSR stack-overflow diagnosis amplifier). | ||
| */ | ||
| _lazyAssets?: Map<string, ResolvedAssets | null | undefined | Promise<ResolvedAssets | null>>; | ||
| /** | ||
| * @internal True during a Loading discovery pass — the only render phase | ||
@@ -91,2 +107,10 @@ * with a retryable NotReady catch. Set/restored by | ||
| commitEpoch?: () => number; | ||
| /** | ||
| * Take a response-window hold; returns the release. Live work with a | ||
| * knowable end that isn't a fragment or a serialized promise — a | ||
| * server-consumed async iterable feeding live bindings (a bounded async | ||
| * trace) — keeps the response open until it completes. Set by | ||
| * dom-expressions' render core; holds gate only the end of the response. | ||
| */ | ||
| hold?: () => () => void; | ||
| }; | ||
@@ -93,0 +117,0 @@ export declare const NoHydrateContext: Context<boolean>; |
@@ -14,2 +14,4 @@ import { $REFRESH } from "@solidjs/signals"; | ||
| export declare function peekNextChildId(owner: Owner): string; | ||
| /** The reactive-scope creation stamp (see `ownerCreations`). */ | ||
| export declare function creationStamp(): number; | ||
| export declare function createOwner(options?: { | ||
@@ -90,2 +92,9 @@ id?: string; | ||
| ssrSource?: SsrSourceMode; | ||
| /** | ||
| * Commit #0 for derived stores: serve the seed instead of suspending. The | ||
| * markup flushes with the seed (locked for the whole response — the | ||
| * first-value lock at commit #0) and the landing streams as data for the | ||
| * client, whose store is born committed with the same seed. | ||
| */ | ||
| seedLoadingValue?: boolean; | ||
| }; | ||
@@ -112,8 +121,25 @@ type ServerClientMemoOptions<T> = Omit<MemoOptions<T>, "ssrSource"> & { | ||
| }; | ||
| type ServerStoreOptions = Omit<ServerSsrOptions, "ssrSource"> & { | ||
| ssrSource?: "server" | "hybrid"; | ||
| }; | ||
| type ServerClientStoreOptions = Omit<ServerSsrOptions, "ssrSource" | "seedLoadingValue"> & { | ||
| ssrSource: "client"; | ||
| seedLoadingValue: true; | ||
| }; | ||
| export declare function getObserver(): ServerComputation<any> | null; | ||
| export declare function createSignal<T>(): Signal<T | undefined>; | ||
| export declare function createSignal<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>; | ||
| export declare function createSignal<T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: ServerClientSignalOptions<T>): Signal<T | undefined>; | ||
| export declare function createSignal<T>(fn: ComputeFunction<NoInfer<T>, T>, options: ServerClientSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| export declare function createSignal<T>(fn: ComputeFunction<NoInfer<T>, T>, options: ServerSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| export declare function createSignal<T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: ServerSignalOptions<T>): Signal<T>; | ||
| export declare function createMemo<T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options: ServerClientMemoOptions<T>): SourceAccessor<T | undefined>; | ||
| export declare function createMemo<T>(compute: ComputeFunction<NoInfer<T>, T>, options: ServerClientMemoOptions<T> & { | ||
| loadingValue: T; | ||
| }): SourceAccessor<T>; | ||
| export declare function createMemo<T>(compute: ComputeFunction<NoInfer<T>, T>, options: ServerMemoOptions<T> & { | ||
| loadingValue: T; | ||
| }): SourceAccessor<T>; | ||
| export declare function createMemo<T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options?: ServerMemoOptions<T>): SourceAccessor<T>; | ||
@@ -130,3 +156,8 @@ export type PatchOp = [path: PropertyKey[]] | [path: PropertyKey[], value: any] | [path: PropertyKey[], value: any, insert: 1]; | ||
| export declare function createOptimistic<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>; | ||
| export declare function createOptimistic<T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: ServerClientSignalOptions<T>): Signal<T | undefined>; | ||
| export declare function createOptimistic<T>(fn: ComputeFunction<NoInfer<T>, T>, options: ServerClientSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| export declare function createOptimistic<T>(fn: ComputeFunction<NoInfer<T>, T>, options: ServerSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| export declare function createOptimistic<T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: ServerSignalOptions<T>): Signal<T>; | ||
@@ -137,3 +168,3 @@ export declare function createStore<T extends object>(store: T | Store<T>, options?: { | ||
| }): [get: Store<T>, set: StoreSetter<T>]; | ||
| export declare function createStore<T extends object>(fn: (store: T) => void | T | Promise<void | T>, store: Partial<T> | Store<T>, options?: ServerSsrOptions & { | ||
| export declare function createStore<T extends object>(fn: (store: T) => void | T | Promise<void | T>, store: Partial<T> | Store<T>, options?: (ServerStoreOptions | ServerClientStoreOptions) & { | ||
| name?: string; | ||
@@ -143,3 +174,17 @@ shallow?: boolean; | ||
| export declare const createOptimisticStore: typeof createStore; | ||
| export declare function createProjection<T extends object>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: Partial<T> | Store<T>, options?: ServerSsrOptions): Store<T>; | ||
| export interface ProjectionTrace { | ||
| /** An independent consumer: snapshot at subscribe, then every batch after. */ | ||
| subscribe(): AsyncIterable<any>; | ||
| /** Whether the projection's root is an array — the consumer's seed shape. */ | ||
| array: boolean; | ||
| } | ||
| /** | ||
| * The trace for a projection proxy, or `undefined` for anything that isn't | ||
| * an async projection (including plain stores and settled sync projections | ||
| * — both are constants within a response and serialize as plain data). | ||
| * | ||
| * @internal — consumed by the serialization layer (@solidjs/web). | ||
| */ | ||
| export declare function getProjectionTrace(value: unknown): ProjectionTrace | undefined; | ||
| export declare function createProjection<T extends object>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: Partial<T> | Store<T>, options?: ServerStoreOptions | ServerClientStoreOptions): Store<T>; | ||
| export declare function reconcile<T extends U, U extends object>(value: T): (state: U) => T; | ||
@@ -225,2 +270,13 @@ export declare function deep<T extends object>(store: Store<T>): Store<T>; | ||
| /** | ||
| * Whether the current owner is inside a server-component render scope. | ||
| * The live-hole engine's arming gate on the document face: a document | ||
| * render arms `ctx.liveHoles` once (any server component present), but | ||
| * only holes minted INSIDE a component's barrier may mark and bind — | ||
| * plain app content keeps its t=0 latch and its exact bytes. O(1): the | ||
| * barrier writes `ServerComponentContext` into the scope owner's context | ||
| * record and records inherit by spread at owner creation. | ||
| * @internal | ||
| */ | ||
| export declare function inServerComponentScope(): boolean; | ||
| /** | ||
| * Builds the explanatory error for a context read that missed INSIDE a | ||
@@ -227,0 +283,0 @@ * server-component scope, or returns `null` when the current owner isn't |
@@ -26,3 +26,7 @@ import { createRenderEffect as coreRenderEffect, createEffect as coreEffect, type Accessor, type ComputeFunction, type MemoOptions, type NoInfer, type ProjectionOptions, type Refreshable, type Signal, type SignalOptions, type SourceAccessor, type Store, type StoreSetter, type RevealOrder, type Context } from "@solidjs/signals"; | ||
| * Choose this for client-only state where serialization is | ||
| * meaningless. | ||
| * meaningless. Requires a declared commit #0: `loadingValue` on | ||
| * signal-family sources (`loadingValue: undefined` is a valid | ||
| * declaration), `seedLoadingValue: true` on store-family sources — | ||
| * the server can't run the compute, so the author must say what | ||
| * the pre-compute window renders. | ||
| */ | ||
@@ -53,3 +57,4 @@ ssrSource?: "server" | "hybrid" | "client"; | ||
| * - `"client"`: skip serialization; compute runs only after hydration | ||
| * completes. | ||
| * completes. Requires `seedLoadingValue: true` — the seed is what the | ||
| * pre-compute window renders, and that promotion must be declared. | ||
| * | ||
@@ -70,2 +75,9 @@ * See {@link HydrationSsrFields} for the fuller explanation. | ||
| }; | ||
| type HydrationProjectionOptions = Omit<ProjectionOptions, "ssrSource"> & { | ||
| ssrSource?: "server" | "hybrid"; | ||
| }; | ||
| type HydrationClientProjectionOptions = Omit<ProjectionOptions, "ssrSource" | "seedLoadingValue"> & { | ||
| ssrSource: "client"; | ||
| seedLoadingValue: true; | ||
| }; | ||
| export type HydrationContext = {}; | ||
@@ -112,4 +124,6 @@ /** | ||
| * resumed or been cancelled. Consumed by dev tooling (the refresh runtime | ||
| * defers hot swaps that would race the claim, #2919). Absent on the server | ||
| * sharedConfig. Cross-package wiring; not part of the user-facing API. | ||
| * defers hot swaps that would race the claim, #2919). Assigned by | ||
| * enableHydration(); absent in CSR bundles and on the server sharedConfig — | ||
| * treat absence as "not hydrating". Cross-package wiring; not part of the | ||
| * user-facing API. | ||
| * | ||
@@ -122,4 +136,7 @@ * @internal | ||
| * boundaries hydrated or cancelled). If hydration is already complete (or | ||
| * not hydrating), fires via queueMicrotask. Absent on the server | ||
| * sharedConfig. Cross-package wiring; not part of the user-facing API. | ||
| * not hydrating), fires via queueMicrotask. Assigned by enableHydration(); | ||
| * absent in CSR bundles and on the server sharedConfig — when absent, | ||
| * hydration is definitionally complete, so fire the callback via | ||
| * queueMicrotask yourself. Cross-package wiring; not part of the | ||
| * user-facing API. | ||
| * | ||
@@ -139,2 +156,23 @@ * @internal | ||
| export declare let _lazyHydrationLookup: (<T>(comp: (() => T | undefined) | undefined, moduleUrl?: string) => (() => T) | undefined) | undefined; | ||
| /** | ||
| * Materialize a container TRACE — snapshot then patch batches, the | ||
| * continuation protocol a server projection serializes as when it crosses a | ||
| * boundary (hydration resume above; the slot border via the serializer's | ||
| * container plugin) — into a live local projection. The result reads like | ||
| * the server value did: not-ready until the snapshot lands, then a | ||
| * read-only store the batches keep updating, done when the trace ends. | ||
| * | ||
| * Created DETACHED (`runWithOwner(null)`): revival can run inside a render | ||
| * effect's owner, and the store is memoized per trace (see the plugin's | ||
| * WeakMap) — a store owned by its first reader would be disposed by that | ||
| * reader's re-render while other readers still hold it. Consumption is | ||
| * pull-driven and the trace is response-bounded, so the projection settles | ||
| * on its own; GC collects the pair with the trace. | ||
| * | ||
| * @internal — consumed by the serialization layer (@solidjs/web). | ||
| */ | ||
| export declare function materializeContainerTrace(marker: { | ||
| $tr: AsyncIterable<any>; | ||
| $ta?: number; | ||
| }): Store<any>; | ||
| export declare function enableHydration(): void; | ||
@@ -184,3 +222,8 @@ /** | ||
| export declare const createMemo: { | ||
| <T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientMemoOptions<T>): SourceAccessor<T | undefined>; | ||
| <T>(compute: ComputeFunction<NoInfer<T>, T>, options: HydrationClientMemoOptions<T> & { | ||
| loadingValue: T; | ||
| }): SourceAccessor<T>; | ||
| <T>(compute: ComputeFunction<NoInfer<T>, T>, options: HydrationMemoOptions<T> & { | ||
| loadingValue: T; | ||
| }): SourceAccessor<T>; | ||
| <T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationMemoOptions<T>): SourceAccessor<T>; | ||
@@ -225,3 +268,8 @@ }; | ||
| <T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>; | ||
| <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientSignalOptions<T>): Signal<T | undefined>; | ||
| <T>(fn: ComputeFunction<NoInfer<T>, T>, options: HydrationClientSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| <T>(fn: ComputeFunction<NoInfer<T>, T>, options: HydrationSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationSignalOptions<T>): Signal<T>; | ||
@@ -290,3 +338,8 @@ }; | ||
| <T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>; | ||
| <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: HydrationClientSignalOptions<T>): Signal<T | undefined>; | ||
| <T>(fn: ComputeFunction<NoInfer<T>, T>, options: HydrationClientSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| <T>(fn: ComputeFunction<NoInfer<T>, T>, options: HydrationSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| <T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: HydrationSignalOptions<T>): Signal<T>; | ||
@@ -331,3 +384,3 @@ }; | ||
| */ | ||
| export declare const createProjection: <T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions) => Refreshable<Store<T>>; | ||
| export declare const createProjection: <T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: Partial<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions | HydrationClientProjectionOptions) => Refreshable<Store<T>>; | ||
| type NoFn<T> = T extends Function ? never : T; | ||
@@ -399,3 +452,3 @@ /** | ||
| }): [get: Store<T>, set: StoreSetter<T>]; | ||
| <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>]; | ||
| <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions | HydrationClientProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>]; | ||
| }; | ||
@@ -450,3 +503,3 @@ /** | ||
| <T extends object = {}>(store: NoFn<T> | Store<NoFn<T>>): [get: Store<T>, set: StoreSetter<T>]; | ||
| <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>]; | ||
| <T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: NoFn<T> | Store<NoFn<T>>, options?: HydrationProjectionOptions | HydrationClientProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>]; | ||
| }; | ||
@@ -468,2 +521,6 @@ /** | ||
| * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}. | ||
| * `transparent: true` makes the effect invisible to hydration entirely — | ||
| * it consumes no hydration id slot and its compute runs live rather than | ||
| * adopting the serialized server value — for client-only effects the | ||
| * server never created. | ||
| * | ||
@@ -535,2 +592,6 @@ * @example | ||
| * (`"server"` | `"hybrid"` | `"client"`). See {@link HydrationSsrFields}. | ||
| * `transparent: true` makes the effect invisible to hydration entirely — | ||
| * it consumes no hydration id slot and its compute runs live rather than | ||
| * adopting the serialized server value — for client-only effects the | ||
| * server never created. | ||
| * | ||
@@ -537,0 +598,0 @@ * @description https://docs.solidjs.com/reference/basic-reactivity/create-effect |
+10
-1
@@ -8,3 +8,3 @@ export { $PROXY, $REFRESH, $TRACK, action, affects, createOwner, createReaction, createRoot, createTrackedEffect, deep, flatten, flush, getNextChildId, getObserver, getOwner, isDisposed, isEqual, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, latest, reconcile, refresh, repeat, resolve, NotReadyError, runWithOwner, enableExternalSource, enforceLoadingBoundary, snapshot, storePath, untrack } from "@solidjs/signals"; | ||
| export type { ArrayElement, Element } from "./types.js"; | ||
| export { sharedConfig, enableHydration, createErrorBoundary, createLoadingBoundary, createRevealOrder, createMemo, createSignal, createStore, createProjection, createOptimistic, createOptimisticStore, createRenderEffect, createEffect, NoHydration, Hydration, NoHydrateContext } from "./client/hydration.js"; | ||
| export { sharedConfig, enableHydration, createErrorBoundary, createLoadingBoundary, createRevealOrder, createMemo, createSignal, createStore, createProjection, createOptimistic, createOptimisticStore, createRenderEffect, createEffect, NoHydration, Hydration, NoHydrateContext, materializeContainerTrace } from "./client/hydration.js"; | ||
| /** @internal */ | ||
@@ -16,2 +16,11 @@ export declare function ssrHandleError(): void; | ||
| export declare function runInServerComponentScope<T>(fn: () => T): T; | ||
| /** @internal */ | ||
| export declare function creationStamp(): number; | ||
| /** @internal */ | ||
| export declare function inServerComponentScope(): boolean; | ||
| /** @internal — server-only: on the client no value carries a trace. */ | ||
| export declare function getProjectionTrace(value: unknown): { | ||
| subscribe(): AsyncIterable<any>; | ||
| array: boolean; | ||
| } | undefined; | ||
| import { type Dev } from "@solidjs/signals"; | ||
@@ -18,0 +27,0 @@ export declare const DEV: Dev | undefined; |
@@ -1,2 +0,2 @@ | ||
| export { $PROXY, $REFRESH, $TRACK, action, affects, createEffect, createMemo, createOptimistic, createOptimisticStore, createErrorBoundary, createOwner, createProjection, createReaction, createRenderEffect, createRevealOrder, createRoot, createSignal, createStore, createTrackedEffect, deep, flatten, flush, getNextChildId, getObserver, getOwner, isDisposed, isEqual, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, latest, reconcile, refresh, repeat, resolve, NotReadyError, runInServerComponentScope, runWithOwner, snapshot, storePath, createDeepProxy, enableExternalSource, enforceLoadingBoundary, untrack } from "./signals.js"; | ||
| export { $PROXY, $REFRESH, $TRACK, action, affects, createEffect, createMemo, createOptimistic, createOptimisticStore, createErrorBoundary, createOwner, creationStamp, createProjection, createReaction, createRenderEffect, createRevealOrder, createRoot, createSignal, createStore, createTrackedEffect, deep, flatten, flush, getNextChildId, getObserver, getOwner, isDisposed, isEqual, isPending, isWrappable, mapArray, merge, omit, onCleanup, onSettled, latest, reconcile, refresh, repeat, resolve, NotReadyError, runInServerComponentScope, inServerComponentScope, getProjectionTrace, runWithOwner, snapshot, storePath, createDeepProxy, enableExternalSource, enforceLoadingBoundary, untrack } from "./signals.js"; | ||
| export type { Accessor, ComputeFunction, EffectFunction, EffectOptions, ExternalSource, ExternalSourceConfig, ExternalSourceFactory, Merge, NoInfer, NotWrappable, Omit, Owner, Refreshable, Signal, SignalOptions, Setter, Store, SolidStore, StoreNode, StoreSetter, StorePathRange, ArrayFilterFn, CustomPartial, Part, PathSetter, PatchOp } from "./signals.js"; | ||
@@ -10,2 +10,7 @@ export { $DEVCOMP, children, createContext, useContext } from "./core.js"; | ||
| export type { HydrationContext } from "./hydration.js"; | ||
| /** | ||
| * @internal — client-only (see client/hydration.ts). The server stub is | ||
| * inert: nothing delivers a trace TO a server, so a marker passes through. | ||
| */ | ||
| export declare function materializeContainerTrace(marker: unknown): unknown; | ||
| export declare const DEV: undefined; |
@@ -66,2 +66,18 @@ import type { Context } from "./signals.js"; | ||
| /** | ||
| * @internal Containment channel for errors surfacing in async resume loops | ||
| * (boundary retries, flush passes), where nothing is on the stack to catch | ||
| * a throw. Set by dom-expressions' renderToStream: reports through the | ||
| * render's onError and winds the render down — the request fails, the | ||
| * process survives. | ||
| */ | ||
| failRender?: (err: any) => void; | ||
| /** | ||
| * @internal Per-request memo of `resolveAssets(moduleUrl)` results, keyed | ||
| * by moduleUrl. lazy() consults it so a component re-created across | ||
| * suspended render passes asks the manifest exactly once per module — | ||
| * dev-server resolvers answer from the live module graph and can do real | ||
| * work per call (SSR stack-overflow diagnosis amplifier). | ||
| */ | ||
| _lazyAssets?: Map<string, ResolvedAssets | null | undefined | Promise<ResolvedAssets | null>>; | ||
| /** | ||
| * @internal True during a Loading discovery pass — the only render phase | ||
@@ -91,2 +107,10 @@ * with a retryable NotReady catch. Set/restored by | ||
| commitEpoch?: () => number; | ||
| /** | ||
| * Take a response-window hold; returns the release. Live work with a | ||
| * knowable end that isn't a fragment or a serialized promise — a | ||
| * server-consumed async iterable feeding live bindings (a bounded async | ||
| * trace) — keeps the response open until it completes. Set by | ||
| * dom-expressions' render core; holds gate only the end of the response. | ||
| */ | ||
| hold?: () => () => void; | ||
| }; | ||
@@ -93,0 +117,0 @@ export declare const NoHydrateContext: Context<boolean>; |
@@ -14,2 +14,4 @@ import { $REFRESH } from "@solidjs/signals"; | ||
| export declare function peekNextChildId(owner: Owner): string; | ||
| /** The reactive-scope creation stamp (see `ownerCreations`). */ | ||
| export declare function creationStamp(): number; | ||
| export declare function createOwner(options?: { | ||
@@ -90,2 +92,9 @@ id?: string; | ||
| ssrSource?: SsrSourceMode; | ||
| /** | ||
| * Commit #0 for derived stores: serve the seed instead of suspending. The | ||
| * markup flushes with the seed (locked for the whole response — the | ||
| * first-value lock at commit #0) and the landing streams as data for the | ||
| * client, whose store is born committed with the same seed. | ||
| */ | ||
| seedLoadingValue?: boolean; | ||
| }; | ||
@@ -112,8 +121,25 @@ type ServerClientMemoOptions<T> = Omit<MemoOptions<T>, "ssrSource"> & { | ||
| }; | ||
| type ServerStoreOptions = Omit<ServerSsrOptions, "ssrSource"> & { | ||
| ssrSource?: "server" | "hybrid"; | ||
| }; | ||
| type ServerClientStoreOptions = Omit<ServerSsrOptions, "ssrSource" | "seedLoadingValue"> & { | ||
| ssrSource: "client"; | ||
| seedLoadingValue: true; | ||
| }; | ||
| export declare function getObserver(): ServerComputation<any> | null; | ||
| export declare function createSignal<T>(): Signal<T | undefined>; | ||
| export declare function createSignal<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>; | ||
| export declare function createSignal<T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: ServerClientSignalOptions<T>): Signal<T | undefined>; | ||
| export declare function createSignal<T>(fn: ComputeFunction<NoInfer<T>, T>, options: ServerClientSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| export declare function createSignal<T>(fn: ComputeFunction<NoInfer<T>, T>, options: ServerSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| export declare function createSignal<T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: ServerSignalOptions<T>): Signal<T>; | ||
| export declare function createMemo<T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options: ServerClientMemoOptions<T>): SourceAccessor<T | undefined>; | ||
| export declare function createMemo<T>(compute: ComputeFunction<NoInfer<T>, T>, options: ServerClientMemoOptions<T> & { | ||
| loadingValue: T; | ||
| }): SourceAccessor<T>; | ||
| export declare function createMemo<T>(compute: ComputeFunction<NoInfer<T>, T>, options: ServerMemoOptions<T> & { | ||
| loadingValue: T; | ||
| }): SourceAccessor<T>; | ||
| export declare function createMemo<T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, options?: ServerMemoOptions<T>): SourceAccessor<T>; | ||
@@ -130,3 +156,8 @@ export type PatchOp = [path: PropertyKey[]] | [path: PropertyKey[], value: any] | [path: PropertyKey[], value: any, insert: 1]; | ||
| export declare function createOptimistic<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>; | ||
| export declare function createOptimistic<T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options: ServerClientSignalOptions<T>): Signal<T | undefined>; | ||
| export declare function createOptimistic<T>(fn: ComputeFunction<NoInfer<T>, T>, options: ServerClientSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| export declare function createOptimistic<T>(fn: ComputeFunction<NoInfer<T>, T>, options: ServerSignalOptions<T> & { | ||
| loadingValue: T; | ||
| }): Signal<T>; | ||
| export declare function createOptimistic<T>(fn: ComputeFunction<undefined | NoInfer<T>, T>, options?: ServerSignalOptions<T>): Signal<T>; | ||
@@ -137,3 +168,3 @@ export declare function createStore<T extends object>(store: T | Store<T>, options?: { | ||
| }): [get: Store<T>, set: StoreSetter<T>]; | ||
| export declare function createStore<T extends object>(fn: (store: T) => void | T | Promise<void | T>, store: Partial<T> | Store<T>, options?: ServerSsrOptions & { | ||
| export declare function createStore<T extends object>(fn: (store: T) => void | T | Promise<void | T>, store: Partial<T> | Store<T>, options?: (ServerStoreOptions | ServerClientStoreOptions) & { | ||
| name?: string; | ||
@@ -143,3 +174,17 @@ shallow?: boolean; | ||
| export declare const createOptimisticStore: typeof createStore; | ||
| export declare function createProjection<T extends object>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: Partial<T> | Store<T>, options?: ServerSsrOptions): Store<T>; | ||
| export interface ProjectionTrace { | ||
| /** An independent consumer: snapshot at subscribe, then every batch after. */ | ||
| subscribe(): AsyncIterable<any>; | ||
| /** Whether the projection's root is an array — the consumer's seed shape. */ | ||
| array: boolean; | ||
| } | ||
| /** | ||
| * The trace for a projection proxy, or `undefined` for anything that isn't | ||
| * an async projection (including plain stores and settled sync projections | ||
| * — both are constants within a response and serialize as plain data). | ||
| * | ||
| * @internal — consumed by the serialization layer (@solidjs/web). | ||
| */ | ||
| export declare function getProjectionTrace(value: unknown): ProjectionTrace | undefined; | ||
| export declare function createProjection<T extends object>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, initialValue: Partial<T> | Store<T>, options?: ServerStoreOptions | ServerClientStoreOptions): Store<T>; | ||
| export declare function reconcile<T extends U, U extends object>(value: T): (state: U) => T; | ||
@@ -225,2 +270,13 @@ export declare function deep<T extends object>(store: Store<T>): Store<T>; | ||
| /** | ||
| * Whether the current owner is inside a server-component render scope. | ||
| * The live-hole engine's arming gate on the document face: a document | ||
| * render arms `ctx.liveHoles` once (any server component present), but | ||
| * only holes minted INSIDE a component's barrier may mark and bind — | ||
| * plain app content keeps its t=0 latch and its exact bytes. O(1): the | ||
| * barrier writes `ServerComponentContext` into the scope owner's context | ||
| * record and records inherit by spread at owner creation. | ||
| * @internal | ||
| */ | ||
| export declare function inServerComponentScope(): boolean; | ||
| /** | ||
| * Builds the explanatory error for a context read that missed INSIDE a | ||
@@ -227,0 +283,0 @@ * server-component scope, or returns `null` when the current owner isn't |
513293
6.63%11465
6.09%