UNPKG

@tanstack/db

Version:

A reactive client store for building super fast apps on sync

909 lines (908 loc) • 32.6 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const cursor = require("../../utils/cursor.cjs"); const error = require("../../utils/error.cjs"); const callbacks = require("../../utils/callbacks.cjs"); const expressions = require("../compiler/expressions.cjs"); const workState = (work) => work.kind === `full-source` ? work.status : work.kind; class OrderedLoaderInvariantError extends Error { } function reportReleaseError(error2) { if (error2 instanceof OrderedLoaderInvariantError) throw error2; callbacks.reportUncaught(error2); } class OrderedPostSettlementError { constructor(cause) { this.cause = cause; } } class OrderedSourceLoader { constructor(info, subscription, alias, onResult = () => { }, canRetryRepair = () => false, getGraphInputRevision, hasPendingJoinedWork = () => false) { this.info = info; this.subscription = subscription; this.alias = alias; this.f_ = onResult; this.f0 = canRetryRepair; this.getGraphInputRevision = getGraphInputRevision; this.hasPendingJoinedWork = hasPendingJoinedWork; this.aL = false; this.gO = `none`; this.fT = false; this.work = { kind: `idle` }; this.aF = /* @__PURE__ */ new Map(); this.a_ = /* @__PURE__ */ new Map(); this.active = true; this.orderedLoadGeneration = 0; this.orderingInvalidationGeneration = 0; this.authorityGeneration = 0; this.F = false; this.l = false; this.cr = 0; this.bG = false; this.info.isRequesting = () => this.fT; this.gp = info.sourceHoldsAllRows && info.index !== void 0 && info.orderBy.length === 1 && info.joinedFilterSourceId === void 0; } get ap() { return this.gO !== `none`; } // Every move of the work slot names the states it may leave. Any other // move, or a work and debt pair the rules forbid, is an invariant violation. ae(next, from, debt = this.gO) { if (!from.includes(workState(this.work))) { throw new OrderedLoaderInvariantError( `Ordered loader work cannot move from ${workState(this.work)} to ${workState(next)}` ); } this.work = next; this.gO = debt; this.gQ(); } gS(next) { this.gO = next; this.gQ(); } // Complete coverage owes nothing, a repair runs only to pay a debt, and a // failed full-source read owes its replacement. gQ() { const state = workState(this.work); if (state === `complete` && this.gO !== `none` || state === `repair` && this.gO === `none` || state === `failed` && this.gO !== `full`) { throw new OrderedLoaderInvariantError( `Ordered loader work ${state} cannot owe ${this.gO} debt` ); } } gL() { return this.work.kind === `full-source` && this.work.status === `complete`; } // A repair whose epoch moved, or whose debt rose to a full-source read, is // replaced before it issues another tie or refill. gK() { return this.work.kind === `repair` && (this.work.epoch !== this.orderingInvalidationGeneration || this.gO === `full`); } /** Derive invalidation from actual contributions, not a second cursor. */ onSourceChanges(changes, sentRows, hasOptimisticOverlay) { let hasNewRows = false; let hasOptimisticDeparture = false; for (const change of changes) { const previous = sentRows?.get(change.key); if (change.type === `delete` && this.l) { continue; } if (change.type !== `insert` && previous !== void 0 && (change.type === `delete` || this.info.comparator(previous, change.value) !== 0)) { if (hasOptimisticOverlay(change.key)) hasOptimisticDeparture = true; else { this.invalidateSourceOrdering(); return; } } if (change.type !== `delete` && previous === void 0) hasNewRows = true; } if (hasOptimisticDeparture && !this.info.sourceHoldsAllRows) { const locallyAvailable = this.subscription.readOrderedSnapshot({ orderBy: expressions.normalizeOrderByPaths(this.info.orderBy, this.alias), limit: this.info.offset + this.info.limit }).filter(({ key }) => !hasOptimisticOverlay(key)).length; if (locallyAvailable < this.info.offset + this.info.limit) { this.F = true; this.invalidateCursor(); } } if (hasNewRows) this.invalidateCursor(); } start() { const { index, limit, offset, requiresFullSource } = this.info; if (index) this.subscription.setOrderByIndex(index); if (limit === 0) return; if (requiresFullSource) { this.loadFullSource(); return; } if (!index) { this.e$(offset + limit); return; } this.fK(offset + limit); } loadMore(windowOperationGeneration, continuesOrderedPrefixRepair = false) { if (this.fT) { this.W = this.getGraphInputRevision?.(); } if (!this.active || this.info.limit === 0 || this.fT) return; windowOperationGeneration ??= this.bN?.windowOperationGeneration; continuesOrderedPrefixRepair ||= this.bN?.continuesOrderedPrefixRepair ?? false; if (this.info.joinedFilterSourceId && this.hasPendingJoinedWork()) { if (windowOperationGeneration !== void 0 || continuesOrderedPrefixRepair) { this.bN = { windowOperationGeneration, continuesOrderedPrefixRepair }; } return this.pending; } this.bN = void 0; if (this.S) { this.c3(windowOperationGeneration); if (!this.active || this.pending) return this.pending; } const mayRetryFailure = this.aj === void 0 || windowOperationGeneration !== void 0 && windowOperationGeneration !== this.aj.windowOperationGeneration; if (!mayRetryFailure) return this.pending; if (this.work.kind === `full-source` && this.work.status === `failed`) { this.ae({ kind: `idle` }, [`failed`]); } if ((this.aj || this.a_.size > 0) && windowOperationGeneration !== void 0 && // The explicit retry releases them, not a repair-chain step that runs // inside it: a throwing release would unwind the chain mid-step. !continuesOrderedPrefixRepair) { this.cG(); this.cr = 0; if (this.aj) { this.aj.windowOperationGeneration = windowOperationGeneration; } this.gP(this.a_, () => true); } if (this.work.kind !== `idle` && !(continuesOrderedPrefixRepair && this.work.kind === `repair`)) { if (windowOperationGeneration !== void 0) { this.bN = { windowOperationGeneration, continuesOrderedPrefixRepair }; } return this.pending; } if (this.ap && !(continuesOrderedPrefixRepair && this.work.kind === `repair`) || this.info.requiresFullSource) { if (this.gO === `bounded` && !this.info.requiresFullSource) { this.dw(windowOperationGeneration); } else { this.loadFullSource(windowOperationGeneration); } return this.pending; } if (!this.info.index) { const shouldLoad = windowOperationGeneration !== void 0 || this.F || (this.info.dataNeeded?.(this.ah) ?? 0) > 0 || this.bQ !== void 0 && this.bQ < this.info.offset + this.info.limit; if (shouldLoad) { this.F = false; this.e$( this.info.offset + this.info.limit, windowOperationGeneration, continuesOrderedPrefixRepair ); } else if (continuesOrderedPrefixRepair) { this.au(windowOperationGeneration); } return this.pending; } if (!this.info.dataNeeded || this.pending) { if (this.pending && windowOperationGeneration !== void 0) { this.bN = { windowOperationGeneration, continuesOrderedPrefixRepair }; } if (continuesOrderedPrefixRepair && !this.pending) { this.au(windowOperationGeneration); } return this.pending; } let count = Math.max( this.info.dataNeeded(this.ah), this.aL ? 0 : this.info.offset + this.info.limit, this.F ? 1 : 0 ); if (windowOperationGeneration !== void 0 && this.ah !== void 0) { const needed = this.info.offset + this.info.limit; count = Math.max(count, needed - this.em()); } if (count > 0) { this.F = false; this.fK( count, windowOperationGeneration, continuesOrderedPrefixRepair ); } else if (continuesOrderedPrefixRepair) { this.au(windowOperationGeneration); } return this.pending; } loadFullSource(windowOperationGeneration) { if (!this.active || this.work.kind !== `idle`) return; this.pending = void 0; this.ae({ kind: `full-source`, status: `held` }, [`idle`]); this.bY( (tracking) => this.subscription.requestSnapshot(tracking), `full-source`, windowOperationGeneration ); } dw(windowOperationGeneration) { if (!this.active || this.work.kind !== `idle`) return; this.pending = void 0; this.ae( { kind: `repair`, epoch: this.orderingInvalidationGeneration }, [`idle`] ); this.gI = this.info.offset + this.info.limit; this.bY( (tracking) => this.subscription.requestSnapshot({ ...tracking, orderBy: expressions.normalizeOrderByPaths(this.info.orderBy, this.alias), limit: this.info.offset + this.info.limit, boundedPrefix: this.gp }), `ordered-repair`, windowOperationGeneration, true, this.info.offset + this.info.limit ); } e$(count, windowOperationGeneration, continuesOrderedPrefixRepair = false) { if (!this.active || this.pending || this.S) return; const last = this.bQ ?? 0; if (last >= count) { if ((this.info.dataNeeded?.(this.ah) ?? 0) === 0) { if (continuesOrderedPrefixRepair) { this.au(windowOperationGeneration); } return; } const rows = this.subscription.readOrderedSnapshot({ orderBy: expressions.normalizeOrderByPaths(this.info.orderBy, this.alias), limit: last }).length; if (rows <= (this.gZ ?? -1)) { if (continuesOrderedPrefixRepair) { this.au(windowOperationGeneration); } return; } this.gZ = rows; count = last * 2; } this.bY( (tracking) => this.subscription.requestSnapshot({ ...tracking, orderBy: expressions.normalizeOrderByPaths(this.info.orderBy, this.alias), limit: count, boundedPrefix: this.gp }), `ordered`, windowOperationGeneration, continuesOrderedPrefixRepair, count ); this.bQ = count; this.gI = count; } resetCursor() { this.cG(); this.cr = 0; this.orderedLoadGeneration++; if (this.gL()) this.ae({ kind: `full-source`, status: `held` }, [`complete`]); this.pending = void 0; this.bN = void 0; this.dl = void 0; this.ah = void 0; this.S = void 0; this.invalidateCursor(); } settleFullSourceReplay() { if (this.work.kind === `repair`) { this.au(); return; } if (this.work.kind === `full-source` && this.work.status === `failed`) { for (const [release, { kind }] of this.a_) { if (kind === `full-source`) this.a_.delete(release); } } if (this.work.kind !== `idle`) { this.fN([`held`, `failed`, `complete`]); } } // Full coverage pays every debt, ends the backoff retry, and retires both // kinds of lease; a throwing release in one pass must not skip the other. fN(from) { this.cG(); this.cr = 0; this.ae({ kind: `full-source`, status: `complete` }, from, `none`); callbacks.runAllCallbacks([ () => this.aB(), () => this.gH() ]); } aB(prefix, keptChain) { if (!this.gL() && !prefix && keptChain === void 0 || this.subscription.hasPendingTruncateReplacement) return; this.gP( this.aF, (release, { count, chain }) => keptChain !== void 0 ? chain !== keptChain : this.gL() || prefix !== void 0 && release !== prefix.release && count !== void 0 && count <= prefix.count ); } // A full-source read covers every row, so it supersedes the partial writes // of each failed request that authoritative work had superseded. gH() { if (this.subscription.hasPendingTruncateReplacement) return; this.gP( this.a_, (_, { superseded }) => superseded ); } // Release each selected lease once. A release that resets the cursor, which // dispose also does, stops the pass; the replay that follows owns the // remaining leases. A release can run the graph synchronously, so // refinement stays blocked until the pass unwinds. gP(owner, selected) { const orderedLoadGeneration = this.orderedLoadGeneration; const requesting = this.fT; this.fT = true; try { callbacks.runAllCallbacks( Array.from(owner, ([release, entry]) => () => { if (orderedLoadGeneration !== this.orderedLoadGeneration || !selected(release, entry)) return; if (owner.get(release) !== entry) { throw new OrderedLoaderInvariantError( `Ordered loader lease was released by another pass` ); } owner.delete(release); try { release(); } catch (error2) { reportReleaseError(error2); } }) ); } finally { this.fT = requesting; } } invalidateCursor() { if ((this.S?.role ?? `finite`) === `finite`) { this.S = void 0; } this.eZ = void 0; this.bQ = void 0; this.gZ = void 0; } invalidateSourceOrdering() { this.orderingInvalidationGeneration++; this.invalidateCursor(); this.dl = void 0; if (this.gO === `none` && !this.gL()) { this.gS( this.aL && this.work.kind === `idle` ? `bounded` : `full` ); } this.ah = void 0; } /** * The source's sync adapter reports that served pages may have shifted. * Coverage that one full-source acquisition established has no page * boundary to repair, and the adapter's refetch has already re-read it. * A window inside this loader's own first page needs no repair either. */ revalidateLoadedCoverage() { if (!this.aL) return; const end = this.he(); if (end !== void 0 && ((this.gI ?? 0) > this.info.offset + this.info.limit || Object.is(this.info.valueExtractorForRawRow(end), this.dl))) return; this.invalidateSourceOrdering(); } // The refetched first page holds every row from the start of the order // through its end, and any row it left out sorts after that end. So a // window whose rows all sort at or before the end is right. A row after // the page that ties with its end could sort before a window row; then // the window is not proven. Returns the end when the window is inside // the page. he() { const size = this.info.offset + this.info.limit; if ((this.gI ?? 0) < size || !this.info.dataNeeded || this.subscription.hasHeldSyncTransaction) { return void 0; } const rows = this.subscription.readOrderedSnapshot({ orderBy: expressions.normalizeOrderByPaths(this.info.orderBy, this.alias), limit: size + 1 }); if (rows.length <= size) return void 0; const end = rows[size - 1].value; return this.info.comparator(rows[size].value, end) > 0 && this.info.dataNeeded(end) === 0 ? end : void 0; } au(windowOperationGeneration) { if (this.work.kind !== `repair`) return; const epoch = this.work.epoch; if (this.gK()) { this.ae({ kind: `idle` }, [`repair`]); if (this.gO === `full`) { this.loadFullSource(windowOperationGeneration); } else { this.dw(windowOperationGeneration); } return; } this.l = true; try { this.aB(void 0, epoch); } finally { this.l = false; const hasSupersededAcquisition = [ ...this.aF.values() ].some(({ chain }) => chain !== epoch); if (!this.active || !hasSupersededAcquisition) { this.cG(); this.cr = 0; this.ae({ kind: `idle` }, [`repair`], `none`); } } } bi() { if (this.work.kind !== `repair`) return; this.ae({ kind: `idle` }, [`repair`], `full`); } dispose() { this.active = false; this.resetCursor(); this.a_.clear(); this.aF.clear(); } em() { return this.subscription.readOrderedSnapshot({ orderBy: expressions.normalizeOrderByPaths(this.info.orderBy, this.alias), limit: this.info.offset + this.info.limit }).filter( ({ value }) => this.info.comparator(value, this.ah) <= 0 ).length; } fK(count, windowOperationGeneration, continuesOrderedPrefixRepair = false) { if (!this.active || this.pending || this.S) return; const startsFromSourcePrefix = this.ah === void 0; const biggest = this.ah; let minValues; if (biggest !== void 0) { const value = this.info.valueExtractorForRawRow(biggest); if (!cursor.canExpressCursorOrder(this.info.orderBy, [value])) { this.e$( this.info.offset + this.info.limit, windowOperationGeneration, continuesOrderedPrefixRepair ); return; } minValues = [value]; } const boundary = minValues?.[0]; if (this.eZ?.count === count && Object.is(this.eZ.boundary, boundary)) { if (continuesOrderedPrefixRepair) { this.au(windowOperationGeneration); } return; } this.eZ = { count, boundary }; this.gI = startsFromSourcePrefix ? count : void 0; this.bY( (tracking) => this.subscription.requestLimitedSnapshot({ ...tracking, orderBy: expressions.normalizeOrderByPaths(this.info.orderBy, this.alias), limit: count, minValues, // Local rows seen before the first provider request prove neither // a cursor nor a remote offset. Start the first acquisition at zero. offset: startsFromSourcePrefix ? 0 : this.em() }), `ordered`, windowOperationGeneration, continuesOrderedPrefixRepair, count ); } // A result is dead after a cursor reset. A non-authoritative result is stale // after an ordering invalidation: it proves no current coverage. gM(stamp) { if (stamp.orderedLoadGeneration !== this.orderedLoadGeneration) return `dead`; const stale = stamp.role === `repair` ? this.gR(stamp) : stamp.role === `finite` && stamp.orderingInvalidationGeneration !== this.orderingInvalidationGeneration; return stale ? `stale` : `current`; } // Authoritative work started after the request was issued. gR(stamp) { return stamp.authorityGeneration !== this.authorityGeneration; } eI(continuation, windowOperationGeneration = continuation.windowOperationGeneration) { if (!this.active || this.gM(continuation) !== `current`) return; if (continuation.kind === `boundary`) { this.fJ( windowOperationGeneration, continuation.continuesOrderedPrefixRepair ); } else { if (this.info.joinedFilterSourceId && this.hasPendingJoinedWork()) { this.S = continuation; return; } this.loadMore( windowOperationGeneration, continuation.continuesOrderedPrefixRepair ); } } c3(windowOperationGeneration) { const continuation = this.S; if (!continuation) return; this.S = void 0; this.eI(continuation, windowOperationGeneration); } // A staged continuation waits for the graph to process the writes that // staged it; the graph turn that does so resumes it. If no write arrived // since `graphInputRevision`, or a graph turn already processed every // write while the request ran and asked for more, no turn will resume it, // so the loader continues now. gJ(graphInputRevision) { const revision = this.getGraphInputRevision?.(); return revision === graphInputRevision || revision === this.W; } es(graphInputRevision) { if (this.bG) return; this.bG = true; try { while (this.S && !this.pending && this.gJ(graphInputRevision)) { this.c3(); } } finally { this.bG = false; } } fJ(windowOperationGeneration, continuesOrderedPrefixRepair = false) { const biggest = this.ah; if (biggest === void 0) { return continuesOrderedPrefixRepair ? this.loadMore(windowOperationGeneration, true) : void 0; } const value = this.info.valueExtractorForRawRow(biggest); const orderBy = expressions.normalizeOrderByPaths(this.info.orderBy, this.alias); if (!cursor.canExpressCursorOrder(orderBy.slice(0, 1), [value])) { if (continuesOrderedPrefixRepair) this.bi(); this.loadFullSource(windowOperationGeneration); return this.pending; } if (Object.is(this.dl, value)) { return this.loadMore( windowOperationGeneration, continuesOrderedPrefixRepair ); } const where = cursor.buildCursorCurrent(orderBy, [value]); if (!where) { if (continuesOrderedPrefixRepair) this.bi(); this.loadFullSource(windowOperationGeneration); return this.pending; } this.dl = value; return this.bY( (tracking) => this.subscription.requestSnapshot({ ...tracking, where }), `boundary`, windowOperationGeneration, continuesOrderedPrefixRepair ); } dy() { this.ah = void 0; if (!this.gL()) this.gS(`full`); } cG() { clearTimeout(this.dK); this.dK = void 0; } // Only the loader's own failure outside a window move schedules a retry. // That failure blocks the ordinary passes that could fail again, and the // timer clears itself before it retries, so no timer is pending here. An // explicit move cancels the timer before it takes the failure over. eh() { if (!this.active || !this.f0() || this.cr >= 2) return; const orderedLoadGeneration = this.orderedLoadGeneration; const failedRequest = this.aj; this.dK = setTimeout( () => { this.dK = void 0; const retry = Promise.resolve().then(() => { if (!this.active || !this.f0() || orderedLoadGeneration !== this.orderedLoadGeneration || this.aj !== failedRequest) return; this.ae({ kind: `idle` }, [`idle`, `failed`]); this.gP(this.a_, () => true); if ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- release callbacks can dispose the loader !this.active || orderedLoadGeneration !== this.orderedLoadGeneration || this.subscription.hasPendingTruncateReplacement ) return; this.aj = void 0; this.loadFullSource(); }); void retry.catch(() => { }); this.f_(retry, true, true); }, 250 * 2 ** this.cr++ ); } /** A failed request blocks ordinary refinement until a new operation. */ d5(windowOperationGeneration) { this.aj = { windowOperationGeneration }; this.S = void 0; this.bN = void 0; this.invalidateCursor(); this.dl = void 0; } /** Observe settlement only after all synchronous request work succeeds. */ bY(request, kind, windowOperationGeneration, continuesOrderedPrefixRepair = false, requestedCount) { const isFullSource = kind === `full-source`; const isOrderedRepair = kind === `ordered-repair`; const isAuthoritativeRequest = isFullSource || isOrderedRepair || continuesOrderedPrefixRepair; let observed; this.fT = true; this.W = void 0; let observing = false; const graphInputRevision = this.getGraphInputRevision?.(); const issuedOrderingGeneration = this.orderingInvalidationGeneration; try { try { request({ ...(isFullSource ? this.ap : isAuthoritativeRequest) ? { refetch: true } : {}, trackLoadSubsetPromise: false, onLoadSubsetResult: (result2, options2, release2) => { observed = { result: result2, options: options2, release: release2 }; } }); } finally { this.fT = false; } if (isFullSource || isOrderedRepair) { this.authorityGeneration++; } if (!observed) return; observing = true; const { result, options, release } = observed; const retryRepair = isAuthoritativeRequest && this.aL && this.ap && windowOperationGeneration === void 0; const chain = (isOrderedRepair || continuesOrderedPrefixRepair) && this.work.kind === `repair` ? this.work.epoch : void 0; const stamp = { orderedLoadGeneration: this.orderedLoadGeneration, authorityGeneration: this.authorityGeneration, orderingInvalidationGeneration: issuedOrderingGeneration, role: isFullSource ? `full-source` : isAuthoritativeRequest ? `repair` : `finite` }; const settlesAsync = result instanceof Promise; const canSettleSynchronously = !settlesAsync && windowOperationGeneration === void 0 && // A full-source request without ordering-repair debt can finish in the // current graph turn, including an initial fallback. A bounded prefix // repair reads only installed rows and can also finish in that turn. // Other repairs keep asynchronous settlement. (!isAuthoritativeRequest || (isFullSource ? !this.ap : this.gp)) && graphInputRevision !== void 0; let synchronousCompletionFailure; const continuation = (continuationKind) => ({ ...stamp, kind: continuationKind, windowOperationGeneration, continuesOrderedPrefixRepair }); const continueOrStage = (next, deferContinuation) => { if (deferContinuation) { this.S = next; } else { this.eI(next); } }; const complete = (trackedRequest, deferContinuation = false) => { if (trackedRequest && this.pending === trackedRequest) { this.pending = void 0; } if (!this.active) return; callbacks.runAllCallbacks([ () => { if (!isFullSource) { const prefixCount = options.orderBy && !options.cursor ? options.limit : void 0; this.aF.set(release, { count: prefixCount, chain }); this.aB(); if (!continuesOrderedPrefixRepair && this.gM(stamp) === `current` && prefixCount !== void 0) { this.aB({ release, count: prefixCount }); } if (this.gM(stamp) === `stale` && this.work.kind === `idle` && !this.ap && this.aF.delete(release)) { this.l = true; try { release(); } catch (error2) { reportReleaseError(error2); } finally { this.l = false; } } } }, () => { if (this.gM(stamp) !== `current`) return; if (!isAuthoritativeRequest && (this.aj || this.work.kind !== `idle`)) return; this.aj = void 0; if (kind !== `boundary`) { this.aL = true; if (options.orderBy && !options.cursor) { this.bQ = options.limit; } if (!isFullSource && options.orderBy) { try { this.ah = this.subscription.readOrderedSnapshot({ ...options, // Provider limits include optimistic headroom. Those // extra local ranks do not prove a source boundary. limit: requestedCount ?? options.limit }).at(-1)?.value ?? this.ah; } catch (error2) { if (canSettleSynchronously) { synchronousCompletionFailure = { error: error2 }; throw error2; } fail(error2); } } } if ((isOrderedRepair || continuesOrderedPrefixRepair) && (this.work.kind !== `repair` || this.gK())) { this.au(windowOperationGeneration); return; } if (isFullSource) this.fN([`held`, `complete`]); if (isOrderedRepair || kind === `ordered`) { continueOrStage(continuation(`boundary`), deferContinuation); return; } continueOrStage(continuation(`more`), deferContinuation); } ]); }; const fail = (error2, trackedRequest) => { this.aF.delete(release); if (trackedRequest && this.pending === trackedRequest) { this.pending = void 0; } if (isFullSource && this.gL()) return; this.dy(); if (this.gM(stamp) === `dead`) return; const ownsAuthority = isAuthoritativeRequest && this.gM(stamp) === `current` && (isFullSource || this.work.kind === `repair`); if (ownsAuthority || (this.S?.role ?? `finite`) === `finite`) { this.S = void 0; } if (isAuthoritativeRequest ? !ownsAuthority : this.gR(stamp)) { this.a_.set(release, { kind, superseded: true }); if (this.gL()) { this.gH(); } this.invalidateCursor(); this.dl = void 0; if (this.aj === void 0 && this.work.kind === `idle`) { try { this.loadFullSource(windowOperationGeneration); } catch (startError) { if (startError instanceof OrderedLoaderInvariantError) { throw startError; } } } throw error2; } if (isFullSource) { this.ae({ kind: `full-source`, status: `failed` }, [`held`]); } else if (isAuthoritativeRequest) { this.ae({ kind: `idle` }, [`repair`]); } this.d5(windowOperationGeneration); this.a_.set(release, { kind, superseded: false }); if (retryRepair) this.eh(); throw error2; }; if (canSettleSynchronously) { try { callbacks.runAllCallbacks([ () => complete(void 0, true), () => { if (!synchronousCompletionFailure) { this.f_(true, false, false); } }, () => { if (!synchronousCompletionFailure && this.gJ(graphInputRevision)) { this.es(graphInputRevision); } } ]); } catch (error2) { if (synchronousCompletionFailure) { throw synchronousCompletionFailure.error; } throw new OrderedPostSettlementError(error2); } return this.pending; } const transport = settlesAsync ? result : Promise.resolve(); const tracked = transport.then( () => complete(tracked), (error2) => fail(error2, tracked) ); this.pending = tracked; void tracked.catch(() => { }); this.f_( tracked, isAuthoritativeRequest && this.ap, settlesAsync, options ); return tracked; } catch (error$1) { if (error$1 instanceof OrderedPostSettlementError) throw error$1.cause; if (error$1 instanceof OrderedLoaderInvariantError) throw error$1; this.fT = true; try { const failure = error.normalizeError(error$1); if (observing) { this.orderedLoadGeneration++; this.pending = void 0; } this.dy(); this.d5(windowOperationGeneration); if (isAuthoritativeRequest) { this.ae({ kind: `idle` }, [`held`, `repair`]); } try { observed?.release({ error: failure }); } catch (releaseError) { reportReleaseError(releaseError); } if (isAuthoritativeRequest && this.aL) { if (windowOperationGeneration === void 0) { this.eh(); } if (!observing) { const rejected = Promise.reject(failure); void rejected.catch(() => { }); this.f_(rejected, true, true); } } throw failure; } finally { this.fT = false; } } } } exports.OrderedLoaderInvariantError = OrderedLoaderInvariantError; exports.OrderedSourceLoader = OrderedSourceLoader; //# sourceMappingURL=ordered-source-loader.cjs.map