@tanstack/db
Version:
A reactive client store for building super fast apps on sync
909 lines (908 loc) • 32.3 kB
JavaScript
import { canExpressCursorOrder, buildCursorCurrent } from "../../utils/cursor.js";
import { normalizeError } from "../../utils/error.js";
import { runAllCallbacks, reportUncaught } from "../../utils/callbacks.js";
import { normalizeOrderByPaths } from "../compiler/expressions.js";
const workState = (work) => work.kind === `full-source` ? work.status : work.kind;
class OrderedLoaderInvariantError extends Error {
}
function reportReleaseError(error) {
if (error instanceof OrderedLoaderInvariantError) throw error;
reportUncaught(error);
}
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: 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: 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: 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: 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`);
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 {
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 (error) {
reportReleaseError(error);
}
})
);
} 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: 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: 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 (!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: 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 = normalizeOrderByPaths(this.info.orderBy, this.alias);
if (!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 = 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;
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 (error) {
reportReleaseError(error);
} 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 (error) {
if (canSettleSynchronously) {
synchronousCompletionFailure = { error };
throw error;
}
fail(error);
}
}
}
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 = (error, 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 error;
}
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 error;
};
if (canSettleSynchronously) {
try {
runAllCallbacks([
() => complete(void 0, true),
() => {
if (!synchronousCompletionFailure) {
this.f_(true, false, false);
}
},
() => {
if (!synchronousCompletionFailure && this.gJ(graphInputRevision)) {
this.es(graphInputRevision);
}
}
]);
} catch (error) {
if (synchronousCompletionFailure) {
throw synchronousCompletionFailure.error;
}
throw new OrderedPostSettlementError(error);
}
return this.pending;
}
const transport = settlesAsync ? result : Promise.resolve();
const tracked = transport.then(
() => complete(tracked),
(error) => fail(error, tracked)
);
this.pending = tracked;
void tracked.catch(() => {
});
this.f_(
tracked,
isAuthoritativeRequest && this.ap,
settlesAsync,
options
);
return tracked;
} catch (error) {
if (error instanceof OrderedPostSettlementError) throw error.cause;
if (error instanceof OrderedLoaderInvariantError) throw error;
this.fT = true;
try {
const failure = normalizeError(error);
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;
}
}
}
}
export {
OrderedLoaderInvariantError,
OrderedSourceLoader
};
//# sourceMappingURL=ordered-source-loader.js.map