@tanstack/db-sqlite-persistence-core 0.4.5 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -2
- package/dist/cjs/broadcast-coordinator.cjs +169 -18
- package/dist/cjs/broadcast-coordinator.cjs.map +1 -1
- package/dist/cjs/broadcast-coordinator.d.cts +11 -2
- package/dist/cjs/committed-tx-anchor.cjs +9 -0
- package/dist/cjs/committed-tx-anchor.cjs.map +1 -0
- package/dist/cjs/committed-tx-anchor.d.cts +1 -0
- package/dist/cjs/persisted.cjs +199 -43
- package/dist/cjs/persisted.cjs.map +1 -1
- package/dist/cjs/persisted.d.cts +46 -0
- package/dist/cjs/sqlite-core-adapter.cjs +94 -3
- package/dist/cjs/sqlite-core-adapter.cjs.map +1 -1
- package/dist/cjs/sqlite-core-adapter.d.cts +10 -1
- package/dist/esm/broadcast-coordinator.d.ts +11 -2
- package/dist/esm/broadcast-coordinator.js +170 -19
- package/dist/esm/broadcast-coordinator.js.map +1 -1
- package/dist/esm/committed-tx-anchor.d.ts +1 -0
- package/dist/esm/committed-tx-anchor.js +9 -0
- package/dist/esm/committed-tx-anchor.js.map +1 -0
- package/dist/esm/persisted.d.ts +46 -0
- package/dist/esm/persisted.js +201 -45
- package/dist/esm/persisted.js.map +1 -1
- package/dist/esm/sqlite-core-adapter.d.ts +10 -1
- package/dist/esm/sqlite-core-adapter.js +94 -3
- package/dist/esm/sqlite-core-adapter.js.map +1 -1
- package/package.json +2 -2
- package/src/broadcast-coordinator.ts +267 -44
- package/src/committed-tx-anchor.ts +13 -0
- package/src/persisted.ts +315 -53
- package/src/sqlite-core-adapter.ts +143 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broadcast-coordinator.cjs","sources":["../../src/broadcast-coordinator.ts"],"sourcesContent":["import { safeRandomUUID } from '@tanstack/db'\nimport {\n DuplicateRemoteSubsetOwnerError,\n IndeterminateCommitError,\n PersistedCollectionDurabilityError,\n RetryableRemoteSubsetAcquisitionError,\n toPersistedCollectionDurabilityError,\n} from './errors'\nimport {\n toProcessLocalLoadSubsetOptions,\n toTransportedLoadSubsetOptions,\n} from './remote-subset-wire'\nimport { unloadRemoteSubsetOwner } from './remote-subset-owner'\nimport type { LoadSubsetOptions } from '@tanstack/db'\nimport type { IndeterminateCommitRequestType } from './errors'\nimport type { TransportedLoadSubsetOptions } from './remote-subset-wire'\nimport type { RemoteSubsetOwner } from './remote-subset-owner'\nimport type {\n ApplyCommittedTxResponse,\n ApplyLocalMutationsResponse,\n EnsureRemoteSubsetRequest,\n EnsureRemoteSubsetResponse,\n HydrationPersistenceAdapter,\n PersistedCollectionCoordinator,\n PersistedIndexSpec,\n PersistedMutationEnvelope,\n PersistedRowMetadataMutation,\n PersistedTx,\n PersistenceAdapter,\n ProtocolEnvelope,\n PullSinceResponse,\n ReleaseRemoteSubsetRequest,\n ReleaseRemoteSubsetResponse,\n TxCommitted,\n} from './persisted'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst HEARTBEAT_INTERVAL_MS = 3_000\nconst LEADERSHIP_RETRY_DELAY_MS = 200\nconst RPC_TIMEOUT_MS = 10_000\nconst RPC_RETRY_ATTEMPTS = 2\nconst RPC_RETRY_DELAY_MS = 200\nconst REMOTE_SUBSET_REPLAY_RETRY_ATTEMPTS = 2\nconst RPC_DEDUPE_RETENTION_MS = 60_000\nconst WRITER_LOCK_BUSY_RETRY_MS = 50\nconst WRITER_LOCK_MAX_RETRIES = 20\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ntype RPCRequest =\n | EnsureRemoteSubsetRequest\n | ReleaseRemoteSubsetRequest\n | {\n type: `rpc:ensurePersistedIndex:req`\n rpcId: string\n signature: string\n spec: PersistedIndexSpec\n }\n | {\n type: `rpc:applyLocalMutations:req`\n rpcId: string\n envelopeId: string\n mutations: Array<PersistedMutationEnvelope>\n }\n | {\n type: `rpc:applyCommittedTx:req`\n rpcId: string\n envelopeId: string\n tx: PersistedTx\n }\n | {\n type: `rpc:pullSince:req`\n rpcId: string\n fromRowVersion: number\n }\n\ntype RPCResponse =\n | EnsureRemoteSubsetResponse\n | ReleaseRemoteSubsetResponse\n | {\n type: `rpc:ensurePersistedIndex:res`\n rpcId: string\n ok: boolean\n error?: string\n }\n | ApplyLocalMutationsResponse\n | ApplyCommittedTxResponse\n | PullSinceResponse\n\ntype PendingRPC = {\n resolve: (response: RPCResponse) => void\n reject: (error: Error) => void\n timer: ReturnType<typeof setTimeout>\n}\n\ntype CollectionState = {\n participatesInLeadership: boolean\n isLeader: boolean\n leaderId: string | null\n lockAbortController: AbortController | null\n heartbeatTimer: ReturnType<typeof setInterval> | null\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n subscribers: Set<(message: ProtocolEnvelope<unknown>) => void>\n routeWaiters?: Set<() => void>\n}\n\n// Adapter capabilities used by coordinator-side operations. Resume snapshots\n// belong to the persisted sync wrapper, not the elected writer transport.\ntype CoordinatorAdapter = Pick<\n PersistenceAdapter,\n `loadSubset` | `applyCommittedTx` | `ensureIndex` | `runInRegularScope`\n> & {\n pullSince?: (\n collectionId: string,\n fromRowVersion: number,\n ) => Promise<\n | {\n latestRowVersion: number\n requiresFullReload: true\n }\n | {\n latestRowVersion: number\n requiresFullReload: false\n changedKeys: Array<string | number>\n deletedKeys: Array<string | number>\n }\n >\n getStreamPosition?: (collectionId: string) => Promise<{\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n }>\n}\n\ntype ActiveRemoteSubsetAcquisition = {\n collectionId: string\n requesterId: string\n acquisitionId: string\n owner: RemoteSubsetOwner\n options: TransportedLoadSubsetOptions\n load: Promise<void>\n transferred: boolean\n released: boolean\n terminalRelease: boolean\n release: Promise<void> | null\n}\n\ntype AwaitingRemoteSubsetOwnerAcquisition = {\n collectionId: string\n requesterId: string\n acquisitionId: string\n options: TransportedLoadSubsetOptions\n released: true\n awaitingOwner: true\n}\n\ntype RemoteSubsetAcquisition =\n | ActiveRemoteSubsetAcquisition\n | AwaitingRemoteSubsetOwnerAcquisition\n | {\n collectionId: string\n requesterId: string\n acquisitionId: string\n released: true\n }\n\ntype OutboundRemoteSubsetAcquisition = {\n collectionId: string\n acquisitionId: string\n options: TransportedLoadSubsetOptions\n localOptions: TransportedLoadSubsetOptions &\n Pick<LoadSubsetOptions, `signal` | `subscription`>\n acquiredLeaderId: string | null\n inFlight: Promise<void> | null\n release: Promise<void> | null\n releaseRequested?: boolean\n forceReplay: boolean\n retryTimer: ReturnType<typeof setTimeout> | null\n retryAttempts: number\n}\n\ntype AppliedEnvelope =\n | {\n appliedAt: number\n requestType: `rpc:applyLocalMutations:req`\n response: ApplyLocalMutationsResponse\n }\n | {\n appliedAt: number\n requestType: `rpc:applyCommittedTx:req`\n response: ApplyCommittedTxResponse\n }\n\ntype InFlightEnvelope =\n | {\n requestType: `rpc:applyLocalMutations:req`\n response: Promise<ApplyLocalMutationsResponse>\n }\n | {\n requestType: `rpc:applyCommittedTx:req`\n response: Promise<ApplyCommittedTxResponse>\n }\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/** @internal Shared by the Browser and Electron persistence hosts. */\nexport type BroadcastCollectionCoordinatorOptions = {\n dbName: string\n adapter?: CoordinatorAdapter\n coordinatorName: string\n}\n\n// ---------------------------------------------------------------------------\n// BroadcastCollectionCoordinator\n// ---------------------------------------------------------------------------\n\n/** @internal Shared coordination engine for BroadcastChannel/Web Locks hosts. */\nexport class BroadcastCollectionCoordinator implements PersistedCollectionCoordinator {\n private readonly nodeId = safeRandomUUID()\n private readonly dbName: string\n private readonly coordinatorName: string\n private defaultAdapter: CoordinatorAdapter | null\n private readonly collectionAdapters = new Map<string, CoordinatorAdapter>()\n private readonly remoteSubsetOwners = new Map<string, RemoteSubsetOwner>()\n private readonly remoteSubsetIds = new Map<\n string,\n WeakMap<LoadSubsetOptions, string>\n >()\n private readonly outboundRemoteSubsetAcquisitions = new Map<\n string,\n OutboundRemoteSubsetAcquisition\n >()\n private readonly inboundRemoteSubsetAcquisitions = new Map<\n string,\n RemoteSubsetAcquisition\n >()\n private readonly releasedRemoteSubsetAcquisitionTimes = new Map<\n string,\n number\n >()\n private readonly channel: BroadcastChannel\n private readonly collections = new Map<string, CollectionState>()\n private readonly pendingRPCs = new Map<string, PendingRPC>()\n private readonly appliedEnvelopes = new Map<string, AppliedEnvelope>()\n private readonly inFlightEnvelopes = new Map<string, InFlightEnvelope>()\n private appliedEnvelopePruneTimer: ReturnType<typeof setTimeout> | null = null\n private rejectDisposed: ((error: Error) => void) | null = null\n private readonly disposedPromise: Promise<never>\n private disposed = false\n\n /** Method indirection to prevent TypeScript from narrowing `disposed` across awaits */\n private isDisposed(): boolean {\n return this.disposed\n }\n\n /** Method indirection to re-read leadership participation across awaits. */\n private participatesInLeadership(state: CollectionState): boolean {\n return state.participatesInLeadership\n }\n\n private requireAdapter(collectionId: string): CoordinatorAdapter {\n let adapter = this.collectionAdapters.get(collectionId)\n if (!adapter && this.defaultAdapter) {\n adapter = this.defaultAdapter\n this.collectionAdapters.set(collectionId, adapter)\n }\n if (!adapter) {\n throw new Error(\n `${this.coordinatorName}: adapter not set for collection \"${collectionId}\". Call setAdapterForCollection() before using leader-side operations.`,\n )\n }\n return adapter\n }\n\n constructor(options: BroadcastCollectionCoordinatorOptions) {\n this.dbName = options.dbName\n this.coordinatorName = options.coordinatorName\n this.defaultAdapter = options.adapter ?? null\n this.channel = new BroadcastChannel(`tsdb:coord:${this.dbName}`)\n this.channel.onmessage = (event: MessageEvent) => {\n this.onChannelMessage(event.data)\n }\n this.disposedPromise = new Promise<never>((_resolve, reject) => {\n this.rejectDisposed = reject\n })\n void this.disposedPromise.catch(() => undefined)\n }\n\n /**\n * Set or replace the persistence adapter used for leader-side RPC handling.\n * Called by a host persistence factory to wire the internally-created adapter.\n */\n setAdapter(adapter: CoordinatorAdapter): void {\n this.defaultAdapter = adapter\n }\n\n /** Register the persistence adapter that owns one collection. */\n setAdapterForCollection(\n collectionId: string,\n adapter: CoordinatorAdapter,\n ): void {\n this.collectionAdapters.set(collectionId, adapter)\n }\n\n registerRemoteSubsetOwner(\n collectionId: string,\n owner: RemoteSubsetOwner,\n ): () => void {\n if (this.remoteSubsetOwners.has(collectionId)) {\n throw new DuplicateRemoteSubsetOwnerError(collectionId)\n }\n this.remoteSubsetOwners.set(collectionId, owner)\n for (const acquisition of this.outboundRemoteSubsetAcquisitions.values()) {\n if (acquisition.collectionId !== collectionId) continue\n acquisition.acquiredLeaderId = null\n acquisition.forceReplay = true\n }\n void this.replayRemoteSubsetAcquisitions(collectionId)\n this.rebindRemoteInboundSubsetAcquisitions(collectionId, owner)\n return () => {\n if (this.remoteSubsetOwners.get(collectionId) !== owner) return\n this.remoteSubsetOwners.delete(collectionId)\n this.releaseInboundRemoteSubsetAcquisitions(collectionId, owner)\n }\n }\n\n // -----------------------------------------------------------------------\n // PersistedCollectionCoordinator interface\n // -----------------------------------------------------------------------\n\n getNodeId(): string {\n return this.nodeId\n }\n\n subscribe(\n collectionId: string,\n onMessage: (message: ProtocolEnvelope<unknown>) => void,\n ): () => void {\n const state = this.ensureCollectionState(collectionId)\n state.subscribers.add(onMessage)\n return () => {\n state.subscribers.delete(onMessage)\n if (state.subscribers.size === 0) {\n state.participatesInLeadership = false\n this.releaseCollectionIfUnused(collectionId, state)\n }\n }\n }\n\n publish(_collectionId: string, message: ProtocolEnvelope<unknown>): void {\n this.channel.postMessage(message)\n }\n\n isLeader(collectionId: string): boolean {\n return this.collections.get(collectionId)?.isLeader ?? false\n }\n\n async ensureLeadership(collectionId: string): Promise<void> {\n const state = this.ensureCollectionState(collectionId)\n if (state.isLeader) return\n await this.acquireLeadership(collectionId, state)\n }\n\n async requestEnsureRemoteSubset(\n collectionId: string,\n options: LoadSubsetOptions,\n ): Promise<void> {\n const transportedOptions = toTransportedLoadSubsetOptions(options)\n const localOptions = toProcessLocalLoadSubsetOptions(\n options,\n transportedOptions,\n )\n let collectionIds = this.remoteSubsetIds.get(collectionId)\n if (!collectionIds) {\n collectionIds = new WeakMap()\n this.remoteSubsetIds.set(collectionId, collectionIds)\n }\n let acquisitionId = collectionIds.get(options)\n let acquisition = acquisitionId\n ? this.outboundRemoteSubsetAcquisitions.get(\n remoteSubsetAcquisitionKey(collectionId, acquisitionId),\n )\n : undefined\n if (!acquisition) {\n acquisitionId = safeRandomUUID()\n collectionIds.set(options, acquisitionId)\n acquisition = {\n collectionId,\n acquisitionId,\n options: transportedOptions,\n localOptions,\n acquiredLeaderId: null,\n inFlight: null,\n release: null,\n releaseRequested: false,\n forceReplay: false,\n retryTimer: null,\n retryAttempts: 0,\n }\n this.outboundRemoteSubsetAcquisitions.set(\n remoteSubsetAcquisitionKey(collectionId, acquisitionId),\n acquisition,\n )\n }\n\n try {\n await this.acquireRemoteSubset(acquisition)\n } catch (error) {\n if (options.signal?.aborted) {\n acquisition.releaseRequested = true\n this.cancelRemoteSubsetReplayRetry(acquisition)\n // The route-pending case owns no lease, while a concurrent response\n // loss may have reached an owner. A best-effort terminal release is\n // harmless for the former and prevents an orphan in the latter.\n this.postRemoteSubsetRelease(acquisition)\n const key = remoteSubsetAcquisitionKey(\n collectionId,\n acquisition.acquisitionId,\n )\n if (this.outboundRemoteSubsetAcquisitions.get(key) === acquisition) {\n this.outboundRemoteSubsetAcquisitions.delete(key)\n collectionIds.delete(options)\n }\n }\n throw error\n }\n }\n\n async requestReleaseRemoteSubset(\n collectionId: string,\n options: LoadSubsetOptions,\n ): Promise<void> {\n const collectionIds = this.remoteSubsetIds.get(collectionId)\n const acquisitionId = collectionIds?.get(options)\n if (!acquisitionId) return\n const key = remoteSubsetAcquisitionKey(collectionId, acquisitionId)\n const acquisition = this.outboundRemoteSubsetAcquisitions.get(key)\n if (!acquisition) return\n acquisition.releaseRequested = true\n this.cancelRemoteSubsetReplayRetry(acquisition)\n if (!acquisition.release) {\n acquisition.release = (async () => {\n const request: Extract<\n RPCRequest,\n { type: `rpc:releaseRemoteSubset:req` }\n > = {\n type: `rpc:releaseRemoteSubset:req`,\n rpcId: safeRandomUUID(),\n acquisitionId,\n }\n const localLeader = this.isLeader(collectionId)\n let releaseReachedLeader = localLeader\n try {\n const response = localLeader\n ? await this.handleReleaseRemoteSubset(\n collectionId,\n request,\n this.nodeId,\n )\n : await this.sendRPC<ReleaseRemoteSubsetResponse>(\n collectionId,\n request,\n )\n releaseReachedLeader = true\n if (!response.ok) {\n throw new Error(`releaseRemoteSubset failed: ${response.error}`)\n }\n } finally {\n // A response (including an owner unload failure) proves that the\n // release reached the leader. Logical demand then retires exactly\n // once. Only a transport failure with no response retains retry\n // debt because delivery remains unknown.\n if (\n releaseReachedLeader &&\n this.outboundRemoteSubsetAcquisitions.get(key) === acquisition\n ) {\n this.outboundRemoteSubsetAcquisitions.delete(key)\n collectionIds!.delete(options)\n }\n }\n })()\n }\n try {\n await acquisition.release\n } finally {\n acquisition.release = null\n }\n }\n\n private async acquireRemoteSubset(\n acquisition: OutboundRemoteSubsetAcquisition,\n ): Promise<void> {\n if (acquisition.inFlight) return acquisition.inFlight\n\n const route = { localOwner: false }\n let resolveWork!: () => void\n let rejectWork!: (error: unknown) => void\n const work = new Promise<void>((resolve, reject) => {\n resolveWork = resolve\n rejectWork = reject\n })\n acquisition.inFlight = work\n const run = async (): Promise<void> => {\n const request: Extract<\n RPCRequest,\n { type: `rpc:ensureRemoteSubset:req` }\n > = {\n type: `rpc:ensureRemoteSubset:req`,\n rpcId: safeRandomUUID(),\n acquisitionId: acquisition.acquisitionId,\n options: acquisition.options,\n }\n const state = this.collections.get(acquisition.collectionId)\n if (\n state?.participatesInLeadership &&\n !state.isLeader &&\n state.leaderId === null\n ) {\n await this.waitForLeadershipRoute(\n acquisition.collectionId,\n state,\n acquisition.localOptions.signal,\n )\n }\n route.localOwner = this.isLeader(acquisition.collectionId)\n let response: EnsureRemoteSubsetResponse\n try {\n response = route.localOwner\n ? await this.handleEnsureRemoteSubset(\n acquisition.collectionId,\n request,\n this.nodeId,\n acquisition.localOptions,\n )\n : await this.sendRPC<EnsureRemoteSubsetResponse>(\n acquisition.collectionId,\n request,\n )\n } catch (error) {\n if (\n route.localOwner ||\n error instanceof RetryableRemoteSubsetAcquisitionError\n ) {\n throw error\n }\n throw new RetryableRemoteSubsetAcquisitionError(\n `Remote subset transport failed`,\n error,\n )\n }\n\n if (!response.ok) {\n if (response.retryable) {\n throw new RetryableRemoteSubsetAcquisitionError(response.error)\n }\n throw new Error(`ensureRemoteSubset failed: ${response.error}`)\n }\n acquisition.acquiredLeaderId = response.leaderId\n }\n void run().then(resolveWork, rejectWork)\n let acquired = false\n try {\n await work\n acquired = true\n this.cancelRemoteSubsetReplayRetry(acquisition)\n } finally {\n if (acquisition.inFlight === work) acquisition.inFlight = null\n const current = this.collections.get(acquisition.collectionId)\n const currentLeaderId = current?.isLeader\n ? this.nodeId\n : (current?.leaderId ?? null)\n const key = remoteSubsetAcquisitionKey(\n acquisition.collectionId,\n acquisition.acquisitionId,\n )\n if (\n acquired &&\n !acquisition.releaseRequested &&\n this.outboundRemoteSubsetAcquisitions.get(key) === acquisition &&\n (acquisition.forceReplay ||\n (currentLeaderId !== null &&\n acquisition.acquiredLeaderId !== currentLeaderId))\n ) {\n acquisition.forceReplay = false\n void this.acquireRemoteSubset(acquisition).catch((error) => {\n this.scheduleRemoteSubsetReplayRetry(acquisition, error)\n })\n }\n }\n }\n\n async requestEnsurePersistedIndex(\n collectionId: string,\n signature: string,\n spec: PersistedIndexSpec,\n scopedAdapter?: HydrationPersistenceAdapter,\n localEnsureCompleted = false,\n ): Promise<void> {\n if (this.isLeader(collectionId)) {\n if (localEnsureCompleted) return\n await (scopedAdapter ?? this.requireAdapter(collectionId)).ensureIndex(\n collectionId,\n signature,\n spec,\n )\n return\n }\n\n const response = await this.sendRPC<{\n type: `rpc:ensurePersistedIndex:res`\n rpcId: string\n ok: boolean\n error?: string\n }>(collectionId, {\n type: `rpc:ensurePersistedIndex:req`,\n rpcId: safeRandomUUID(),\n signature,\n spec,\n })\n\n if (!response.ok) {\n throw new Error(\n `ensurePersistedIndex failed: ${response.error ?? `unknown error`}`,\n )\n }\n }\n\n async requestApplyLocalMutations(\n collectionId: string,\n mutations: Array<PersistedMutationEnvelope>,\n ): Promise<ApplyLocalMutationsResponse> {\n const initialRoute = this.waitForInitialRoute(collectionId)\n if (initialRoute) await initialRoute\n if (this.isLeader(collectionId)) {\n return this.handleApplyLocalMutations(collectionId, {\n type: `rpc:applyLocalMutations:req`,\n rpcId: safeRandomUUID(),\n envelopeId: safeRandomUUID(),\n mutations,\n })\n }\n\n return this.sendRPC<ApplyLocalMutationsResponse>(collectionId, {\n type: `rpc:applyLocalMutations:req`,\n rpcId: safeRandomUUID(),\n envelopeId: safeRandomUUID(),\n mutations,\n })\n }\n\n async requestApplyCommittedTx(\n collectionId: string,\n tx: PersistedTx,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<ApplyCommittedTxResponse> {\n const initialRoute = this.waitForInitialRoute(collectionId)\n if (initialRoute) await initialRoute\n const request: Extract<RPCRequest, { type: `rpc:applyCommittedTx:req` }> = {\n type: `rpc:applyCommittedTx:req`,\n rpcId: safeRandomUUID(),\n envelopeId: safeRandomUUID(),\n tx,\n }\n if (this.isLeader(collectionId)) {\n return this.handleApplyCommittedTx(collectionId, request, scopedAdapter)\n }\n\n return this.sendRPC<ApplyCommittedTxResponse>(collectionId, request)\n }\n\n async pullSince(\n collectionId: string,\n fromRowVersion: number,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<PullSinceResponse> {\n if (this.isLeader(collectionId)) {\n return this.handlePullSince(\n collectionId,\n {\n type: `rpc:pullSince:req`,\n rpcId: safeRandomUUID(),\n fromRowVersion,\n },\n scopedAdapter,\n )\n }\n\n return this.sendRPC<PullSinceResponse>(collectionId, {\n type: `rpc:pullSince:req`,\n rpcId: safeRandomUUID(),\n fromRowVersion,\n })\n }\n\n // -----------------------------------------------------------------------\n // Lifecycle\n // -----------------------------------------------------------------------\n\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n const disposedError = new Error(`coordinator disposed`)\n this.rejectDisposed?.(disposedError)\n this.rejectDisposed = null\n\n for (const acquisition of this.outboundRemoteSubsetAcquisitions.values()) {\n this.cancelRemoteSubsetReplayRetry(acquisition)\n this.postRemoteSubsetRelease(acquisition)\n }\n this.outboundRemoteSubsetAcquisitions.clear()\n this.remoteSubsetIds.clear()\n\n for (const [collectionId, state] of this.collections) {\n this.releaseLeadership(collectionId, state)\n }\n\n for (const [, pending] of this.pendingRPCs) {\n clearTimeout(pending.timer)\n pending.reject(disposedError)\n }\n this.pendingRPCs.clear()\n if (this.appliedEnvelopePruneTimer !== null) {\n clearTimeout(this.appliedEnvelopePruneTimer)\n this.appliedEnvelopePruneTimer = null\n }\n\n this.channel.close()\n this.collections.clear()\n this.collectionAdapters.clear()\n for (const collectionId of this.remoteSubsetOwners.keys()) {\n this.releaseInboundRemoteSubsetAcquisitions(collectionId)\n }\n this.remoteSubsetOwners.clear()\n this.inboundRemoteSubsetAcquisitions.clear()\n this.releasedRemoteSubsetAcquisitionTimes.clear()\n this.appliedEnvelopes.clear()\n this.inFlightEnvelopes.clear()\n }\n\n // -----------------------------------------------------------------------\n // Leadership via Web Locks\n // -----------------------------------------------------------------------\n\n private getOrCreateCollectionState(collectionId: string): CollectionState {\n let state = this.collections.get(collectionId)\n if (!state) {\n state = {\n participatesInLeadership: false,\n isLeader: false,\n leaderId: null,\n lockAbortController: null,\n heartbeatTimer: null,\n latestTerm: 0,\n latestSeq: 0,\n latestRowVersion: 0,\n subscribers: new Set(),\n routeWaiters: new Set(),\n }\n this.collections.set(collectionId, state)\n }\n return state\n }\n\n private ensureCollectionState(collectionId: string): CollectionState {\n const state = this.getOrCreateCollectionState(collectionId)\n if (!state.participatesInLeadership) {\n state.participatesInLeadership = true\n void this.acquireLeadership(collectionId, state)\n }\n return state\n }\n\n private async acquireLeadership(\n collectionId: string,\n state: CollectionState,\n ): Promise<void> {\n if (this.disposed || !state.participatesInLeadership || state.isLeader) {\n return\n }\n\n const lockName = `tsdb:leader:${this.dbName}:${collectionId}`\n const abortController = new AbortController()\n state.lockAbortController?.abort()\n state.lockAbortController = abortController\n\n try {\n await navigator.locks.request(\n lockName,\n { signal: abortController.signal },\n async () => {\n if (\n this.isDisposed() ||\n !this.participatesInLeadership(state) ||\n this.collections.get(collectionId) !== state\n ) {\n return\n }\n\n try {\n // Restore stream position from DB before claiming leadership\n const adapter = this.requireAdapter(collectionId)\n if (adapter.getStreamPosition) {\n const pos = await adapter.getStreamPosition(collectionId)\n state.latestTerm = pos.latestTerm\n state.latestSeq = pos.latestSeq\n state.latestRowVersion = pos.latestRowVersion\n }\n\n if (\n this.isDisposed() ||\n !this.participatesInLeadership(state) ||\n this.collections.get(collectionId) !== state ||\n abortController.signal.aborted ||\n state.lockAbortController !== abortController\n ) {\n return\n }\n\n state.latestTerm++\n state.isLeader = true\n state.leaderId = this.nodeId\n this.notifyRouteWaiters(state)\n\n this.emitHeartbeat(collectionId, state)\n void this.replayRemoteSubsetAcquisitions(collectionId)\n state.heartbeatTimer = setInterval(() => {\n this.emitHeartbeat(collectionId, state)\n }, HEARTBEAT_INTERVAL_MS)\n\n // Hold the lock until disposed or aborted\n await new Promise<void>((resolve) => {\n const onAbort = () => {\n abortController.signal.removeEventListener(`abort`, onAbort)\n resolve()\n }\n if (abortController.signal.aborted) {\n resolve()\n return\n }\n abortController.signal.addEventListener(`abort`, onAbort)\n })\n } finally {\n this.releaseInboundRemoteSubsetAcquisitions(collectionId)\n state.isLeader = false\n state.leaderId = null\n if (state.heartbeatTimer) {\n clearInterval(state.heartbeatTimer)\n state.heartbeatTimer = null\n }\n }\n },\n )\n } catch (error) {\n if (error instanceof DOMException && error.name === `AbortError`) {\n return\n }\n console.warn(`Failed to acquire leadership for ${collectionId}:`, error)\n if (\n !this.isDisposed() &&\n this.participatesInLeadership(state) &&\n this.collections.get(collectionId) === state\n ) {\n await sleep(LEADERSHIP_RETRY_DELAY_MS)\n }\n } finally {\n if (state.lockAbortController === abortController) {\n state.lockAbortController = null\n }\n }\n\n // Re-acquire if not disposed (leadership was released by another means)\n if (\n !this.isDisposed() &&\n this.participatesInLeadership(state) &&\n this.collections.get(collectionId) === state &&\n state.lockAbortController === null\n ) {\n void this.acquireLeadership(collectionId, state)\n }\n }\n\n private waitForInitialRoute(collectionId: string): Promise<void> | undefined {\n const state = this.collections.get(collectionId)\n if (\n state?.participatesInLeadership &&\n !state.isLeader &&\n state.leaderId === null\n ) {\n this.channel.postMessage({\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: { type: `leader:routeRequest` },\n } satisfies ProtocolEnvelope<{ type: `leader:routeRequest` }>)\n return this.waitForLeadershipRoute(\n collectionId,\n state,\n undefined,\n RPC_TIMEOUT_MS,\n )\n }\n return undefined\n }\n\n private waitForLeadershipRoute(\n collectionId: string,\n state: CollectionState,\n signal?: AbortSignal,\n timeoutMs?: number,\n ): Promise<void> {\n if (state.isLeader || state.leaderId !== null) return Promise.resolve()\n\n return new Promise<void>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined\n const finish = () => {\n state.routeWaiters?.delete(onRouteChange)\n signal?.removeEventListener(`abort`, onAbort)\n if (timer !== undefined) clearTimeout(timer)\n }\n const onAbort = () => {\n finish()\n reject(\n new DOMException(`Remote subset acquisition aborted`, `AbortError`),\n )\n }\n const onRouteChange = () => {\n if (this.isDisposed() || !state.participatesInLeadership) {\n finish()\n reject(\n new Error(\n `${this.coordinatorName}: leadership route closed for collection \"${collectionId}\"`,\n ),\n )\n return\n }\n if (state.isLeader || state.leaderId !== null) {\n finish()\n resolve()\n }\n }\n\n ;(state.routeWaiters ??= new Set()).add(onRouteChange)\n if (timeoutMs !== undefined) {\n timer = setTimeout(() => {\n finish()\n reject(\n new Error(\n `${this.coordinatorName}: leadership route for collection \"${collectionId}\" timed out after ${timeoutMs}ms`,\n ),\n )\n }, timeoutMs)\n }\n signal?.addEventListener(`abort`, onAbort, { once: true })\n if (signal?.aborted) {\n onAbort()\n } else {\n onRouteChange()\n }\n })\n }\n\n private notifyRouteWaiters(state: CollectionState): void {\n for (const notify of Array.from(state.routeWaiters ?? [])) notify()\n }\n\n private releaseLeadership(\n collectionId: string,\n state: CollectionState,\n ): void {\n this.releaseInboundRemoteSubsetAcquisitions(collectionId)\n if (state.lockAbortController) {\n state.lockAbortController.abort()\n state.lockAbortController = null\n }\n if (state.heartbeatTimer) {\n clearInterval(state.heartbeatTimer)\n state.heartbeatTimer = null\n }\n state.isLeader = false\n state.leaderId = null\n this.notifyRouteWaiters(state)\n }\n\n private releaseCollectionIfUnused(\n collectionId: string,\n state: CollectionState,\n ): void {\n if (\n state.subscribers.size > 0 ||\n this.collections.get(collectionId) !== state\n ) {\n return\n }\n this.releaseLeadership(collectionId, state)\n this.collections.delete(collectionId)\n this.collectionAdapters.delete(collectionId)\n const prefix = `${JSON.stringify([collectionId]).slice(0, -1)},`\n for (const key of this.appliedEnvelopes.keys()) {\n if (key.startsWith(prefix)) this.appliedEnvelopes.delete(key)\n }\n this.pruneAppliedEnvelopes()\n }\n\n private postRemoteSubsetRelease(\n acquisition: OutboundRemoteSubsetAcquisition,\n ): void {\n if (acquisition.release) return\n const request: Extract<\n RPCRequest,\n { type: `rpc:releaseRemoteSubset:req` }\n > = {\n type: `rpc:releaseRemoteSubset:req`,\n rpcId: safeRandomUUID(),\n acquisitionId: acquisition.acquisitionId,\n }\n if (this.isLeader(acquisition.collectionId)) {\n void this.handleReleaseRemoteSubset(\n acquisition.collectionId,\n request,\n this.nodeId,\n ).catch(() => {\n // The owner already received the exact unload failure through onError.\n })\n return\n }\n this.channel.postMessage({\n v: 1,\n dbName: this.dbName,\n collectionId: acquisition.collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: request,\n } satisfies ProtocolEnvelope<unknown>)\n }\n\n private cancelRemoteSubsetReplayRetry(\n acquisition: OutboundRemoteSubsetAcquisition,\n ): void {\n if (acquisition.retryTimer !== null) {\n clearTimeout(acquisition.retryTimer)\n acquisition.retryTimer = null\n }\n acquisition.retryAttempts = 0\n }\n\n private scheduleRemoteSubsetReplayRetry(\n acquisition: OutboundRemoteSubsetAcquisition,\n error: unknown,\n ): void {\n const key = remoteSubsetAcquisitionKey(\n acquisition.collectionId,\n acquisition.acquisitionId,\n )\n if (\n !(error instanceof RetryableRemoteSubsetAcquisitionError) ||\n this.isDisposed() ||\n this.outboundRemoteSubsetAcquisitions.get(key) !== acquisition ||\n acquisition.releaseRequested ||\n acquisition.retryTimer !== null ||\n acquisition.retryAttempts >= REMOTE_SUBSET_REPLAY_RETRY_ATTEMPTS\n ) {\n return\n }\n\n acquisition.retryAttempts++\n acquisition.retryTimer = setTimeout(() => {\n acquisition.retryTimer = null\n if (\n this.isDisposed() ||\n this.outboundRemoteSubsetAcquisitions.get(key) !== acquisition ||\n acquisition.releaseRequested\n ) {\n return\n }\n void this.acquireRemoteSubset(acquisition).catch((retryError) => {\n this.scheduleRemoteSubsetReplayRetry(acquisition, retryError)\n })\n }, RPC_RETRY_DELAY_MS)\n }\n\n private async replayRemoteSubsetAcquisitions(\n collectionId: string,\n ): Promise<void> {\n if (this.isDisposed()) return\n const state = this.collections.get(collectionId)\n const leaderId = state?.isLeader ? this.nodeId : state?.leaderId\n if (!leaderId) return\n\n const replays: Array<Promise<void>> = []\n for (const acquisition of this.outboundRemoteSubsetAcquisitions.values()) {\n if (\n acquisition.collectionId !== collectionId ||\n acquisition.releaseRequested ||\n (!acquisition.forceReplay && acquisition.acquiredLeaderId === leaderId)\n ) {\n continue\n }\n if (acquisition.inFlight) {\n acquisition.forceReplay = true\n continue\n }\n acquisition.forceReplay = false\n replays.push(\n this.acquireRemoteSubset(acquisition).catch((error) => {\n this.scheduleRemoteSubsetReplayRetry(acquisition, error)\n }),\n )\n }\n await Promise.all(replays)\n }\n\n private emitHeartbeat(collectionId: string, state: CollectionState): void {\n const envelope: ProtocolEnvelope<unknown> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: {\n type: `leader:heartbeat`,\n term: state.latestTerm,\n leaderId: this.nodeId,\n latestSeq: state.latestSeq,\n latestRowVersion: state.latestRowVersion,\n },\n }\n this.channel.postMessage(envelope)\n }\n\n // -----------------------------------------------------------------------\n // BroadcastChannel message handling\n // -----------------------------------------------------------------------\n\n private onChannelMessage(data: unknown): void {\n if (!isProtocolEnvelope(data)) return\n\n const envelope = data\n\n // Ignore own messages\n if (envelope.senderId === this.nodeId) return\n\n const payload = envelope.payload\n if (!payload || typeof payload !== `object`) return\n\n const type = (payload as Record<string, unknown>).type as string | undefined\n\n if (type === `leader:routeRequest`) {\n const state = this.collections.get(envelope.collectionId)\n if (state?.isLeader) this.emitHeartbeat(envelope.collectionId, state)\n return\n }\n\n if (type === `leader:heartbeat`) {\n const heartbeat = payload as {\n leaderId?: unknown\n term?: unknown\n latestSeq?: unknown\n latestRowVersion?: unknown\n }\n if (\n typeof heartbeat.leaderId === `string` &&\n typeof heartbeat.term === `number` &&\n typeof heartbeat.latestSeq === `number` &&\n typeof heartbeat.latestRowVersion === `number`\n ) {\n const state = this.getOrCreateCollectionState(envelope.collectionId)\n if (heartbeat.term < state.latestTerm) return\n const changedLeader = state.leaderId !== heartbeat.leaderId\n state.leaderId = heartbeat.leaderId\n state.latestTerm = Math.max(state.latestTerm, heartbeat.term)\n state.latestSeq = Math.max(state.latestSeq, heartbeat.latestSeq)\n state.latestRowVersion = Math.max(\n state.latestRowVersion,\n heartbeat.latestRowVersion,\n )\n this.notifyRouteWaiters(state)\n if (changedLeader) {\n void this.replayRemoteSubsetAcquisitions(envelope.collectionId)\n }\n }\n }\n\n // Handle RPC responses (for pending outbound RPCs)\n if (type && type.endsWith(`:res`)) {\n const rpcId = (payload as { rpcId?: string }).rpcId\n if (rpcId && this.pendingRPCs.has(rpcId)) {\n const pending = this.pendingRPCs.get(rpcId)!\n this.pendingRPCs.delete(rpcId)\n clearTimeout(pending.timer)\n pending.resolve(payload as RPCResponse)\n return\n }\n }\n\n // Handle RPC requests (leader only)\n if (type && type.endsWith(`:req`)) {\n if (!isRPCRequest(payload)) return\n const collectionId = envelope.collectionId\n if (this.isLeader(collectionId)) {\n void this.handleRPCRequest(collectionId, payload, envelope.senderId)\n }\n return\n }\n\n // Forward protocol messages to subscribers\n const state = this.collections.get(envelope.collectionId)\n if (state) {\n for (const subscriber of state.subscribers) {\n subscriber(envelope)\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // RPC - Outbound (follower side)\n // -----------------------------------------------------------------------\n\n private async sendRPC<T extends RPCResponse>(\n collectionId: string,\n request: RPCRequest,\n ): Promise<T> {\n if (this.isDisposed()) throw new Error(`coordinator disposed`)\n let lastError: Error | undefined\n let firstTransportCause: unknown\n const mutationRequestType = isMutatingRPCRequest(request)\n ? request.type\n : undefined\n const mutationRoute = mutationRequestType\n ? this.captureMutationRoute(collectionId)\n : undefined\n\n for (let attempt = 0; attempt <= RPC_RETRY_ATTEMPTS; attempt++) {\n if (attempt > 0) {\n await Promise.race([\n sleep(RPC_RETRY_DELAY_MS * attempt),\n this.disposedPromise,\n ])\n }\n if (this.isDisposed()) throw new Error(`coordinator disposed`)\n\n if (\n mutationRoute &&\n mutationRequestType &&\n firstTransportCause !== undefined\n ) {\n this.assertMutationRouteUnchanged(\n collectionId,\n mutationRequestType,\n mutationRoute,\n firstTransportCause,\n )\n }\n\n if (this.isLeader(collectionId)) {\n return (await this.dispatchRPCRequest(\n collectionId,\n request,\n this.nodeId,\n )) as T\n }\n\n try {\n return await this.sendRPCOnce<T>(collectionId, request)\n } catch (error) {\n if (this.isDisposed()) throw error\n firstTransportCause ??= error\n if (mutationRoute && mutationRequestType) {\n this.assertMutationRouteUnchanged(\n collectionId,\n mutationRequestType,\n mutationRoute,\n firstTransportCause,\n )\n }\n lastError = error instanceof Error ? error : new Error(String(error))\n }\n }\n\n throw lastError ?? new Error(`RPC failed after retries`)\n }\n\n private captureMutationRoute(collectionId: string): {\n leaderId: string | null\n term: number | null\n } {\n const state = this.collections.get(collectionId)\n return {\n leaderId: state?.isLeader ? this.nodeId : (state?.leaderId ?? null),\n term: state?.latestTerm ?? null,\n }\n }\n\n private assertMutationRouteUnchanged(\n collectionId: string,\n requestType: IndeterminateCommitRequestType,\n previous: { leaderId: string | null; term: number | null },\n cause: unknown,\n ): void {\n const current = this.captureMutationRoute(collectionId)\n if (\n previous.leaderId !== null &&\n previous.term !== null &&\n current.leaderId === previous.leaderId &&\n current.term === previous.term\n ) {\n return\n }\n throw new IndeterminateCommitError({\n collectionId,\n requestType,\n previousLeaderId: previous.leaderId,\n previousTerm: previous.term,\n currentLeaderId: current.leaderId,\n currentTerm: current.term,\n cause,\n })\n }\n\n private sendRPCOnce<T extends RPCResponse>(\n collectionId: string,\n request: RPCRequest,\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const rpcId = request.rpcId\n\n const timer = setTimeout(() => {\n this.pendingRPCs.delete(rpcId)\n reject(\n new Error(`RPC ${request.type} timed out after ${RPC_TIMEOUT_MS}ms`),\n )\n }, RPC_TIMEOUT_MS)\n\n this.pendingRPCs.set(rpcId, {\n resolve: resolve as (response: RPCResponse) => void,\n reject,\n timer,\n })\n\n const envelope: ProtocolEnvelope<unknown> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: request,\n }\n this.channel.postMessage(envelope)\n })\n }\n\n // -----------------------------------------------------------------------\n // RPC - Inbound (leader side)\n // -----------------------------------------------------------------------\n\n private async handleRPCRequest(\n collectionId: string,\n request: RPCRequest,\n requesterId: string,\n ): Promise<void> {\n let response: RPCResponse\n\n try {\n response = await this.dispatchRPCRequest(\n collectionId,\n request,\n requesterId,\n )\n } catch (error) {\n response = createRPCErrorResponse(request, error)\n }\n\n if (this.isDisposed()) {\n return\n }\n\n const envelope: ProtocolEnvelope<unknown> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: response,\n }\n this.channel.postMessage(envelope)\n }\n\n private dispatchRPCRequest(\n collectionId: string,\n request: RPCRequest,\n requesterId: string,\n ): Promise<RPCResponse> {\n switch (request.type) {\n case `rpc:ensureRemoteSubset:req`:\n return this.handleEnsureRemoteSubset(collectionId, request, requesterId)\n case `rpc:releaseRemoteSubset:req`:\n return this.handleReleaseRemoteSubset(\n collectionId,\n request,\n requesterId,\n )\n case `rpc:ensurePersistedIndex:req`:\n return this.handleEnsurePersistedIndex(collectionId, request)\n case `rpc:applyLocalMutations:req`:\n return this.handleApplyLocalMutations(collectionId, request)\n case `rpc:applyCommittedTx:req`:\n return this.handleApplyCommittedTx(collectionId, request)\n case `rpc:pullSince:req`:\n return this.handlePullSince(collectionId, request)\n }\n }\n\n private async handleEnsureRemoteSubset(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:ensureRemoteSubset:req` }>,\n requesterId: string,\n localOptions?: TransportedLoadSubsetOptions,\n ): Promise<EnsureRemoteSubsetResponse> {\n this.pruneReleasedRemoteSubsetAcquisitions()\n const key = inboundRemoteSubsetAcquisitionKey(\n collectionId,\n requesterId,\n request.acquisitionId,\n )\n const existing = this.inboundRemoteSubsetAcquisitions.get(key)\n const awaitingOwner =\n existing && `awaitingOwner` in existing ? existing : undefined\n if (existing) {\n if (`owner` in existing) {\n if (!existing.released) {\n await existing.load\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n leaderId: this.nodeId,\n }\n }\n await existing.release\n if (existing.terminalRelease) {\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n leaderId: this.nodeId,\n }\n }\n if (this.inboundRemoteSubsetAcquisitions.get(key) === existing) {\n this.inboundRemoteSubsetAcquisitions.delete(key)\n }\n } else if (!(`awaitingOwner` in existing)) {\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n leaderId: this.nodeId,\n }\n }\n }\n\n const owner = this.remoteSubsetOwners.get(collectionId)\n if (!owner) {\n throw new RetryableRemoteSubsetAcquisitionError(\n `${this.coordinatorName}: no remote subset owner registered for collection \"${collectionId}\"`,\n )\n }\n\n await this.startRemoteSubsetOwnerAcquisition({\n collectionId,\n requesterId,\n acquisitionId: request.acquisitionId,\n owner,\n options: awaitingOwner?.options ?? localOptions ?? request.options,\n restoreOnSynchronousFailure: awaitingOwner,\n })\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n leaderId: this.nodeId,\n }\n }\n\n private async handleReleaseRemoteSubset(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:releaseRemoteSubset:req` }>,\n requesterId: string,\n ): Promise<ReleaseRemoteSubsetResponse> {\n this.pruneReleasedRemoteSubsetAcquisitions()\n const key = inboundRemoteSubsetAcquisitionKey(\n collectionId,\n requesterId,\n request.acquisitionId,\n )\n const acquisition = this.inboundRemoteSubsetAcquisitions.get(key)\n if (!acquisition) {\n this.setReleasedRemoteSubsetAcquisition(key, {\n collectionId,\n requesterId,\n acquisitionId: request.acquisitionId,\n released: true,\n })\n } else if (`owner` in acquisition) {\n acquisition.terminalRelease = true\n try {\n await this.releaseRemoteSubsetAcquisition(acquisition)\n } finally {\n if (this.inboundRemoteSubsetAcquisitions.get(key) === acquisition) {\n this.setReleasedRemoteSubsetAcquisition(key, {\n collectionId,\n requesterId,\n acquisitionId: request.acquisitionId,\n released: true,\n })\n }\n }\n } else if (`awaitingOwner` in acquisition) {\n this.setReleasedRemoteSubsetAcquisition(key, {\n collectionId,\n requesterId,\n acquisitionId: request.acquisitionId,\n released: true,\n })\n }\n return {\n type: `rpc:releaseRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n }\n }\n\n private releaseRemoteSubsetAcquisition(\n acquisition: ActiveRemoteSubsetAcquisition,\n ): Promise<void> {\n if (acquisition.release) return acquisition.release\n acquisition.released = true\n acquisition.release = (async () => {\n try {\n await acquisition.load\n } catch {\n // A returned promise transfers the lease even when initial loading fails.\n }\n try {\n if (acquisition.transferred) {\n await unloadRemoteSubsetOwner(acquisition.owner, acquisition.options)\n }\n } finally {\n if (!acquisition.terminalRelease) {\n const key = inboundRemoteSubsetAcquisitionKey(\n acquisition.collectionId,\n acquisition.requesterId,\n acquisition.acquisitionId,\n )\n if (this.inboundRemoteSubsetAcquisitions.get(key) === acquisition) {\n this.inboundRemoteSubsetAcquisitions.set(key, {\n collectionId: acquisition.collectionId,\n requesterId: acquisition.requesterId,\n acquisitionId: acquisition.acquisitionId,\n options: acquisition.options,\n released: true,\n awaitingOwner: true,\n })\n }\n }\n }\n })()\n return acquisition.release\n }\n\n private releaseInboundRemoteSubsetAcquisitions(\n collectionId: string,\n owner?: RemoteSubsetOwner,\n ): void {\n for (const acquisition of this.inboundRemoteSubsetAcquisitions.values()) {\n if (\n !(`owner` in acquisition) ||\n acquisition.collectionId !== collectionId ||\n (owner && acquisition.owner !== owner)\n ) {\n continue\n }\n void this.releaseRemoteSubsetAcquisition(acquisition).catch(\n () => undefined,\n )\n }\n }\n\n private rebindRemoteInboundSubsetAcquisitions(\n collectionId: string,\n owner: RemoteSubsetOwner,\n ): void {\n for (const acquisition of this.inboundRemoteSubsetAcquisitions.values()) {\n if (`awaitingOwner` in acquisition) {\n if (\n acquisition.collectionId === collectionId &&\n acquisition.requesterId !== this.nodeId\n ) {\n void this.bindAwaitingRemoteSubsetAcquisition(\n acquisition,\n owner,\n ).catch(() => {\n // The owner receives the exact load failure through onError.\n })\n }\n continue\n }\n if (\n !(`owner` in acquisition) ||\n acquisition.collectionId !== collectionId ||\n acquisition.requesterId === this.nodeId ||\n !acquisition.released ||\n acquisition.terminalRelease\n ) {\n continue\n }\n\n void this.rebindRemoteInboundSubsetAcquisition(acquisition, owner).catch(\n () => undefined,\n )\n }\n }\n\n private async rebindRemoteInboundSubsetAcquisition(\n previous: ActiveRemoteSubsetAcquisition,\n owner: RemoteSubsetOwner,\n ): Promise<void> {\n await previous.release\n if (\n previous.terminalRelease ||\n this.remoteSubsetOwners.get(previous.collectionId) !== owner\n ) {\n return\n }\n\n const key = inboundRemoteSubsetAcquisitionKey(\n previous.collectionId,\n previous.requesterId,\n previous.acquisitionId,\n )\n const current = this.inboundRemoteSubsetAcquisitions.get(key)\n if (current && current !== previous) {\n if (`awaitingOwner` in current) {\n await this.bindAwaitingRemoteSubsetAcquisition(current, owner)\n }\n return\n }\n\n const awaitingOwner: AwaitingRemoteSubsetOwnerAcquisition = {\n collectionId: previous.collectionId,\n requesterId: previous.requesterId,\n acquisitionId: previous.acquisitionId,\n options: previous.options,\n released: true,\n awaitingOwner: true,\n }\n this.inboundRemoteSubsetAcquisitions.set(key, awaitingOwner)\n await this.bindAwaitingRemoteSubsetAcquisition(awaitingOwner, owner)\n }\n\n private async bindAwaitingRemoteSubsetAcquisition(\n awaitingOwner: AwaitingRemoteSubsetOwnerAcquisition,\n owner: RemoteSubsetOwner,\n ): Promise<void> {\n if (this.remoteSubsetOwners.get(awaitingOwner.collectionId) !== owner) {\n return\n }\n const key = inboundRemoteSubsetAcquisitionKey(\n awaitingOwner.collectionId,\n awaitingOwner.requesterId,\n awaitingOwner.acquisitionId,\n )\n if (this.inboundRemoteSubsetAcquisitions.get(key) !== awaitingOwner) return\n\n await this.startRemoteSubsetOwnerAcquisition({\n collectionId: awaitingOwner.collectionId,\n requesterId: awaitingOwner.requesterId,\n acquisitionId: awaitingOwner.acquisitionId,\n owner,\n options: awaitingOwner.options,\n restoreOnSynchronousFailure: awaitingOwner,\n })\n }\n\n private async startRemoteSubsetOwnerAcquisition(options: {\n collectionId: string\n requesterId: string\n acquisitionId: string\n owner: RemoteSubsetOwner\n options: TransportedLoadSubsetOptions\n restoreOnSynchronousFailure?: AwaitingRemoteSubsetOwnerAcquisition\n }): Promise<void> {\n const key = inboundRemoteSubsetAcquisitionKey(\n options.collectionId,\n options.requesterId,\n options.acquisitionId,\n )\n const acquisition: ActiveRemoteSubsetAcquisition = {\n collectionId: options.collectionId,\n requesterId: options.requesterId,\n acquisitionId: options.acquisitionId,\n owner: options.owner,\n options: options.options,\n load: Promise.resolve(),\n transferred: false,\n released: false,\n terminalRelease: false,\n release: null,\n }\n this.releasedRemoteSubsetAcquisitionTimes.delete(key)\n this.inboundRemoteSubsetAcquisitions.set(key, acquisition)\n let resolveLoad!: () => void\n let rejectLoad!: (error: unknown) => void\n acquisition.load = new Promise<void>((resolve, reject) => {\n resolveLoad = resolve\n rejectLoad = reject\n })\n try {\n const load = options.owner(acquisition.options)\n acquisition.transferred = true\n void Promise.resolve(load).then(resolveLoad, rejectLoad)\n } catch (error) {\n rejectLoad(error)\n }\n\n try {\n await acquisition.load\n } catch (error) {\n if (!acquisition.transferred) {\n if (this.inboundRemoteSubsetAcquisitions.get(key) === acquisition) {\n if (options.restoreOnSynchronousFailure) {\n this.inboundRemoteSubsetAcquisitions.set(\n key,\n options.restoreOnSynchronousFailure,\n )\n } else {\n this.inboundRemoteSubsetAcquisitions.delete(key)\n }\n }\n } else {\n // A returned promise transfers a physical lease even when it rejects.\n // Retire that failed lease before allowing the same logical demand to\n // retry against the current owner.\n await this.releaseRemoteSubsetAcquisition(acquisition).catch(\n () => undefined,\n )\n }\n throw error\n }\n }\n\n private async handleEnsurePersistedIndex(\n collectionId: string,\n request: {\n type: `rpc:ensurePersistedIndex:req`\n rpcId: string\n signature: string\n spec: PersistedIndexSpec\n },\n ): Promise<RPCResponse> {\n await this.withScheduledWriterLock(collectionId, (adapter) =>\n adapter.ensureIndex(collectionId, request.signature, request.spec),\n )\n return {\n type: `rpc:ensurePersistedIndex:res`,\n rpcId: request.rpcId,\n ok: true,\n }\n }\n\n private async handleApplyLocalMutations(\n collectionId: string,\n request: {\n type: `rpc:applyLocalMutations:req`\n rpcId: string\n envelopeId: string\n mutations: Array<PersistedMutationEnvelope>\n },\n ): Promise<ApplyLocalMutationsResponse> {\n const envelopeKey = appliedEnvelopeKey(collectionId, request.envelopeId)\n return this.runDeduplicatedEnvelope({\n envelopeKey,\n rpcId: request.rpcId,\n selectApplied: (envelope) =>\n envelope.requestType === `rpc:applyLocalMutations:req`\n ? envelope.response\n : undefined,\n selectInFlight: (envelope) =>\n envelope.requestType === `rpc:applyLocalMutations:req`\n ? envelope.response\n : undefined,\n conflict: (phase) => ({\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `CONFLICT`,\n error: `envelope ${request.envelopeId} ${phase}`,\n }),\n apply: () => this.applyLocalMutationsOnce(collectionId, request),\n createPending: (response) => ({\n requestType: request.type,\n response,\n }),\n })\n }\n\n private async applyLocalMutationsOnce(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:applyLocalMutations:req` }>,\n ): Promise<ApplyLocalMutationsResponse> {\n const state = this.collections.get(collectionId)\n if (!state || !state.isLeader) {\n return {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n }\n }\n\n // Build and apply the persisted transaction\n const rowMetadataMutations: Array<PersistedRowMetadataMutation> = []\n for (const mutation of request.mutations) {\n if (!(`metadataChanged` in mutation) || !mutation.metadataChanged) {\n continue\n }\n rowMetadataMutations.push(\n mutation.metadata === undefined\n ? { type: `delete`, key: mutation.key }\n : {\n type: `set`,\n key: mutation.key,\n value: mutation.metadata,\n },\n )\n }\n const pendingTx = {\n txId: safeRandomUUID(),\n mutations: request.mutations.map((m) => ({\n type: m.type,\n key: m.key,\n value: m.value,\n ...(`metadataChanged` in m\n ? { metadata: m.metadata, metadataChanged: m.metadataChanged }\n : {}),\n })),\n rowMetadataMutations,\n }\n\n const tx = await this.applyDurablyAtNextStreamPosition(\n collectionId,\n state,\n pendingTx,\n )\n if (tx === null) {\n return {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n }\n }\n\n const response: ApplyLocalMutationsResponse = {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: true,\n term: tx.term,\n seq: tx.seq,\n latestRowVersion: tx.rowVersion,\n acceptedMutationIds: request.mutations.map((m) => m.mutationId),\n }\n if (this.isDisposed() || this.collections.get(collectionId) !== state) {\n return response\n }\n this.appliedEnvelopes.set(\n appliedEnvelopeKey(collectionId, request.envelopeId),\n {\n appliedAt: Date.now(),\n requestType: request.type,\n response,\n },\n )\n this.pruneAppliedEnvelopes()\n\n // Broadcast tx:committed to all tabs\n const changedRows = request.mutations\n .filter((m) => m.type !== `delete`)\n .map((m) => ({ key: m.key, value: m.value }))\n const deletedKeys = request.mutations\n .filter((m) => m.type === `delete`)\n .map((m) => m.key)\n\n const txCommitted: ProtocolEnvelope<unknown> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: {\n type: `tx:committed`,\n term: tx.term,\n seq: tx.seq,\n txId: tx.txId,\n latestRowVersion: tx.rowVersion,\n requiresFullReload: false,\n changedRows,\n deletedKeys,\n rowMetadataMutations,\n },\n }\n this.channel.postMessage(txCommitted)\n\n // Deliver to local subscribers too\n for (const subscriber of state.subscribers) {\n subscriber(txCommitted)\n }\n\n return response\n }\n\n private async handleApplyCommittedTx(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:applyCommittedTx:req` }>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<ApplyCommittedTxResponse> {\n const envelopeKey = appliedEnvelopeKey(collectionId, request.envelopeId)\n return this.runDeduplicatedEnvelope({\n envelopeKey,\n rpcId: request.rpcId,\n selectApplied: (envelope) =>\n envelope.requestType === `rpc:applyCommittedTx:req`\n ? envelope.response\n : undefined,\n selectInFlight: (envelope) =>\n envelope.requestType === `rpc:applyCommittedTx:req`\n ? envelope.response\n : undefined,\n conflict: (phase) => ({\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `CONFLICT`,\n error: `envelope ${request.envelopeId} ${phase}`,\n }),\n apply: () =>\n this.applyCommittedTxOnce(collectionId, request, scopedAdapter),\n createPending: (response) => ({\n requestType: request.type,\n response,\n }),\n })\n }\n\n private async runDeduplicatedEnvelope<\n TResponse extends { rpcId: string },\n >(options: {\n envelopeKey: string\n rpcId: string\n selectApplied: (envelope: AppliedEnvelope) => TResponse | undefined\n selectInFlight: (\n envelope: InFlightEnvelope,\n ) => Promise<TResponse> | undefined\n conflict: (phase: `already applied` | `is already in flight`) => TResponse\n apply: () => Promise<TResponse>\n createPending: (response: Promise<TResponse>) => InFlightEnvelope\n }): Promise<TResponse> {\n const appliedEnvelope = this.appliedEnvelopes.get(options.envelopeKey)\n if (appliedEnvelope) {\n const response = options.selectApplied(appliedEnvelope)\n return response\n ? { ...response, rpcId: options.rpcId }\n : options.conflict(`already applied`)\n }\n\n const inFlightEnvelope = this.inFlightEnvelopes.get(options.envelopeKey)\n if (inFlightEnvelope) {\n const pending = options.selectInFlight(inFlightEnvelope)\n if (!pending) return options.conflict(`is already in flight`)\n const response = await pending\n return { ...response, rpcId: options.rpcId }\n }\n\n const response = options.apply()\n const pendingEnvelope = options.createPending(response)\n this.inFlightEnvelopes.set(options.envelopeKey, pendingEnvelope)\n try {\n return await response\n } finally {\n if (this.inFlightEnvelopes.get(options.envelopeKey) === pendingEnvelope) {\n this.inFlightEnvelopes.delete(options.envelopeKey)\n }\n }\n }\n\n private async applyCommittedTxOnce(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:applyCommittedTx:req` }>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<ApplyCommittedTxResponse> {\n const state = this.collections.get(collectionId)\n if (!state || !state.isLeader) {\n return {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n }\n }\n\n const tx = await this.applyDurablyAtNextStreamPosition(\n collectionId,\n state,\n request.tx,\n scopedAdapter,\n )\n if (tx === null) {\n return {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n }\n }\n const response: ApplyCommittedTxResponse = {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: true,\n term: tx.term,\n seq: tx.seq,\n latestRowVersion: tx.rowVersion,\n }\n if (this.isDisposed() || this.collections.get(collectionId) !== state) {\n return response\n }\n this.appliedEnvelopes.set(\n appliedEnvelopeKey(collectionId, request.envelopeId),\n {\n appliedAt: Date.now(),\n requestType: request.type,\n response,\n },\n )\n this.pruneAppliedEnvelopes()\n\n const committedBase = {\n type: `tx:committed` as const,\n term: tx.term,\n seq: tx.seq,\n txId: tx.txId,\n latestRowVersion: tx.rowVersion,\n }\n const committedPayload: TxCommitted = tx.truncate\n ? {\n ...committedBase,\n requiresFullReload: true,\n }\n : {\n ...committedBase,\n requiresFullReload: false,\n changedRows: tx.mutations\n .filter((mutation) => mutation.type !== `delete`)\n .map((mutation) => ({\n key: mutation.key,\n value: mutation.value,\n })),\n deletedKeys: tx.mutations\n .filter((mutation) => mutation.type === `delete`)\n .map((mutation) => mutation.key),\n rowMetadataMutations: tx.rowMetadataMutations,\n collectionMetadataMutations: tx.collectionMetadataMutations,\n }\n const committed: ProtocolEnvelope<TxCommitted> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: committedPayload,\n }\n this.channel.postMessage(committed)\n for (const subscriber of state.subscribers) {\n subscriber(committed)\n }\n\n return response\n }\n\n private async applyDurablyAtNextStreamPosition(\n collectionId: string,\n state: CollectionState,\n pendingTx: Omit<PersistedTx, `term` | `seq` | `rowVersion`>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<PersistedTx | null> {\n const expectedTerm = state.latestTerm\n return this.withScheduledWriterLock(\n collectionId,\n async (adapter) => {\n if (\n this.isDisposed() ||\n this.collections.get(collectionId) !== state ||\n !state.isLeader ||\n state.leaderId !== this.nodeId ||\n state.latestTerm !== expectedTerm\n ) {\n return null\n }\n const tx: PersistedTx = {\n ...pendingTx,\n term: state.latestTerm,\n seq: state.latestSeq + 1,\n rowVersion: state.latestRowVersion + 1,\n }\n try {\n await adapter.applyCommittedTx(collectionId, tx)\n } catch (error) {\n throw toPersistedCollectionDurabilityError(collectionId, error)\n }\n state.latestSeq = tx.seq\n state.latestRowVersion = tx.rowVersion\n return tx\n },\n scopedAdapter,\n )\n }\n\n private async handlePullSince(\n collectionId: string,\n request: {\n type: `rpc:pullSince:req`\n rpcId: string\n fromRowVersion: number\n },\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<PullSinceResponse> {\n const state = this.collections.get(collectionId)\n\n const adapter = scopedAdapter ?? this.requireAdapter(collectionId)\n if (!adapter.pullSince) {\n return {\n type: `rpc:pullSince:res`,\n rpcId: request.rpcId,\n ok: true,\n latestTerm: state?.latestTerm ?? 0,\n latestSeq: state?.latestSeq ?? 0,\n latestRowVersion: state?.latestRowVersion ?? 0,\n requiresFullReload: true,\n }\n }\n\n const result = await adapter.pullSince(collectionId, request.fromRowVersion)\n\n if (result.requiresFullReload) {\n return {\n type: `rpc:pullSince:res`,\n rpcId: request.rpcId,\n ok: true,\n latestTerm: state?.latestTerm ?? 0,\n latestSeq: state?.latestSeq ?? 0,\n latestRowVersion: result.latestRowVersion,\n requiresFullReload: true,\n }\n }\n\n return {\n type: `rpc:pullSince:res`,\n rpcId: request.rpcId,\n ok: true,\n latestTerm: state?.latestTerm ?? 0,\n latestSeq: state?.latestSeq ?? 0,\n latestRowVersion: result.latestRowVersion,\n requiresFullReload: false,\n changedKeys: result.changedKeys,\n deletedKeys: result.deletedKeys,\n }\n }\n\n // -----------------------------------------------------------------------\n // DB Writer Lock\n // -----------------------------------------------------------------------\n\n private withScheduledWriterLock<T>(\n collectionId: string,\n task: (adapter: CoordinatorAdapter) => Promise<T>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<T> {\n if (scopedAdapter) {\n return this.withWriterLock(() => task(scopedAdapter))\n }\n // Enter the shared scheduler before taking the database-wide Web Lock.\n // A hydrate waiting for its first commit may need that lock to finish.\n const adapter = this.requireAdapter(collectionId)\n return adapter.runInRegularScope\n ? adapter.runInRegularScope((unscheduledAdapter) =>\n this.withWriterLock(() => task(unscheduledAdapter)),\n )\n : this.withWriterLock(() => task(adapter))\n }\n\n private async withWriterLock<T>(fn: () => Promise<T>): Promise<T> {\n const lockName = `tsdb:writer:${this.dbName}`\n\n for (let attempt = 0; attempt <= WRITER_LOCK_MAX_RETRIES; attempt++) {\n const callbackState = { entered: false }\n try {\n return await navigator.locks.request(lockName, async () => {\n callbackState.entered = true\n return fn()\n })\n } catch (error) {\n if (callbackState.entered) {\n throw error\n }\n if (error instanceof DOMException && error.name === `AbortError`) {\n throw error\n }\n\n if (attempt < WRITER_LOCK_MAX_RETRIES) {\n await sleep(WRITER_LOCK_BUSY_RETRY_MS * Math.min(attempt + 1, 5))\n continue\n }\n\n throw error\n }\n }\n\n // Unreachable but satisfies TypeScript\n throw new Error(`writer lock acquisition failed`)\n }\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n private pruneAppliedEnvelopes(): void {\n if (this.appliedEnvelopePruneTimer !== null) {\n clearTimeout(this.appliedEnvelopePruneTimer)\n this.appliedEnvelopePruneTimer = null\n }\n const cutoff = Date.now() - RPC_DEDUPE_RETENTION_MS\n for (const [key, envelope] of this.appliedEnvelopes) {\n if (envelope.appliedAt <= cutoff) {\n this.appliedEnvelopes.delete(key)\n }\n }\n if (this.disposed || this.appliedEnvelopes.size === 0) return\n\n let earliestAppliedAt = Number.POSITIVE_INFINITY\n for (const envelope of this.appliedEnvelopes.values()) {\n earliestAppliedAt = Math.min(earliestAppliedAt, envelope.appliedAt)\n }\n const delay = Math.max(\n 0,\n earliestAppliedAt + RPC_DEDUPE_RETENTION_MS - Date.now(),\n )\n this.appliedEnvelopePruneTimer = setTimeout(() => {\n this.appliedEnvelopePruneTimer = null\n this.pruneAppliedEnvelopes()\n }, delay)\n }\n\n private setReleasedRemoteSubsetAcquisition(\n key: string,\n acquisition: RemoteSubsetAcquisition,\n ): void {\n this.inboundRemoteSubsetAcquisitions.set(key, acquisition)\n this.releasedRemoteSubsetAcquisitionTimes.set(key, Date.now())\n }\n\n private pruneReleasedRemoteSubsetAcquisitions(): void {\n const cutoff = Date.now() - RPC_DEDUPE_RETENTION_MS\n for (const [key, releasedAt] of this.releasedRemoteSubsetAcquisitionTimes) {\n if (releasedAt < cutoff) {\n this.releasedRemoteSubsetAcquisitionTimes.delete(key)\n this.inboundRemoteSubsetAcquisitions.delete(key)\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Utilities\n// ---------------------------------------------------------------------------\n\nfunction isProtocolEnvelope(data: unknown): data is ProtocolEnvelope<unknown> {\n if (!data || typeof data !== `object`) return false\n const record = data as Record<string, unknown>\n return (\n record.v === 1 &&\n typeof record.dbName === `string` &&\n typeof record.collectionId === `string` &&\n typeof record.senderId === `string` &&\n typeof record.ts === `number`\n )\n}\n\nfunction isRPCRequest(payload: unknown): payload is RPCRequest {\n if (!payload || typeof payload !== `object`) return false\n switch ((payload as { type?: unknown }).type) {\n case `rpc:ensureRemoteSubset:req`:\n case `rpc:releaseRemoteSubset:req`:\n case `rpc:ensurePersistedIndex:req`:\n case `rpc:applyLocalMutations:req`:\n case `rpc:applyCommittedTx:req`:\n case `rpc:pullSince:req`:\n return true\n default:\n return false\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction appliedEnvelopeKey(collectionId: string, envelopeId: string): string {\n return JSON.stringify([collectionId, envelopeId])\n}\n\nfunction remoteSubsetAcquisitionKey(\n collectionId: string,\n acquisitionId: string,\n): string {\n return JSON.stringify([collectionId, acquisitionId])\n}\n\nfunction inboundRemoteSubsetAcquisitionKey(\n collectionId: string,\n requesterId: string,\n acquisitionId: string,\n): string {\n return JSON.stringify([collectionId, requesterId, acquisitionId])\n}\n\nfunction createRPCErrorResponse(\n request: RPCRequest,\n cause: unknown,\n): RPCResponse {\n const error = cause instanceof Error ? cause.message : String(cause)\n switch (request.type) {\n case `rpc:ensureRemoteSubset:req`:\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: false,\n error,\n ...(cause instanceof RetryableRemoteSubsetAcquisitionError\n ? { retryable: true as const }\n : {}),\n }\n case `rpc:releaseRemoteSubset:req`:\n return {\n type: `rpc:releaseRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: false,\n error,\n }\n case `rpc:ensurePersistedIndex:req`:\n return {\n type: `rpc:ensurePersistedIndex:res`,\n rpcId: request.rpcId,\n ok: false,\n error,\n }\n case `rpc:applyLocalMutations:req`:\n if (cause instanceof PersistedCollectionDurabilityError) {\n return {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `PERSISTENCE_ERROR`,\n error,\n ...toSafeDurabilityDetails(cause),\n }\n }\n return {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `CONFLICT`,\n error,\n }\n case `rpc:applyCommittedTx:req`:\n if (cause instanceof PersistedCollectionDurabilityError) {\n return {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `PERSISTENCE_ERROR`,\n error,\n ...toSafeDurabilityDetails(cause),\n }\n }\n return {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `CONFLICT`,\n error,\n }\n case `rpc:pullSince:req`:\n return {\n type: `rpc:pullSince:res`,\n rpcId: request.rpcId,\n ok: false,\n error,\n }\n }\n}\n\nfunction isMutatingRPCRequest(request: RPCRequest): request is Extract<\n RPCRequest,\n {\n type: IndeterminateCommitRequestType\n }\n> {\n return (\n request.type === `rpc:applyLocalMutations:req` ||\n request.type === `rpc:applyCommittedTx:req`\n )\n}\n\nfunction toSafeDurabilityDetails(error: PersistedCollectionDurabilityError): {\n sourceCode?: string | number\n path?: string | ReadonlyArray<string | number>\n} {\n const sourceCode =\n typeof error.code === `string` || typeof error.code === `number`\n ? error.code\n : undefined\n const path =\n typeof error.path === `string` ||\n (Array.isArray(error.path) &&\n error.path.every(\n (part) => typeof part === `string` || typeof part === `number`,\n ))\n ? (error.path as string | ReadonlyArray<string | number>)\n : undefined\n return {\n ...(sourceCode === undefined ? {} : { sourceCode }),\n ...(path === undefined ? {} : { path }),\n }\n}\n"],"names":["safeRandomUUID","DuplicateRemoteSubsetOwnerError","toTransportedLoadSubsetOptions","toProcessLocalLoadSubsetOptions","RetryableRemoteSubsetAcquisitionError","state","IndeterminateCommitError","unloadRemoteSubsetOwner","response","toPersistedCollectionDurabilityError","PersistedCollectionDurabilityError"],"mappings":";;;;;;AAwCA,MAAM,wBAAwB;AAC9B,MAAM,4BAA4B;AAClC,MAAM,iBAAiB;AACvB,MAAM,qBAAqB;AAC3B,MAAM,qBAAqB;AAC3B,MAAM,sCAAsC;AAC5C,MAAM,0BAA0B;AAChC,MAAM,4BAA4B;AAClC,MAAM,0BAA0B;AAkLzB,MAAM,+BAAyE;AAAA,EAyDpF,YAAY,SAAgD;AAxD5D,SAAiB,SAASA,kBAAA;AAI1B,SAAiB,yCAAyB,IAAA;AAC1C,SAAiB,yCAAyB,IAAA;AAC1C,SAAiB,sCAAsB,IAAA;AAIvC,SAAiB,uDAAuC,IAAA;AAIxD,SAAiB,sDAAsC,IAAA;AAIvD,SAAiB,2DAA2C,IAAA;AAK5D,SAAiB,kCAAkB,IAAA;AACnC,SAAiB,kCAAkB,IAAA;AACnC,SAAiB,uCAAuB,IAAA;AACxC,SAAiB,wCAAwB,IAAA;AACzC,SAAQ,4BAAkE;AAC1E,SAAQ,iBAAkD;AAE1D,SAAQ,WAAW;AA2BjB,SAAK,SAAS,QAAQ;AACtB,SAAK,kBAAkB,QAAQ;AAC/B,SAAK,iBAAiB,QAAQ,WAAW;AACzC,SAAK,UAAU,IAAI,iBAAiB,cAAc,KAAK,MAAM,EAAE;AAC/D,SAAK,QAAQ,YAAY,CAAC,UAAwB;AAChD,WAAK,iBAAiB,MAAM,IAAI;AAAA,IAClC;AACA,SAAK,kBAAkB,IAAI,QAAe,CAAC,UAAU,WAAW;AAC9D,WAAK,iBAAiB;AAAA,IACxB,CAAC;AACD,SAAK,KAAK,gBAAgB,MAAM,MAAM,MAAS;AAAA,EACjD;AAAA;AAAA,EAnCQ,aAAsB;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGQ,yBAAyB,OAAiC;AAChE,WAAO,MAAM;AAAA,EACf;AAAA,EAEQ,eAAe,cAA0C;AAC/D,QAAI,UAAU,KAAK,mBAAmB,IAAI,YAAY;AACtD,QAAI,CAAC,WAAW,KAAK,gBAAgB;AACnC,gBAAU,KAAK;AACf,WAAK,mBAAmB,IAAI,cAAc,OAAO;AAAA,IACnD;AACA,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,eAAe,qCAAqC,YAAY;AAAA,MAAA;AAAA,IAE5E;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,WAAW,SAAmC;AAC5C,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA,EAGA,wBACE,cACA,SACM;AACN,SAAK,mBAAmB,IAAI,cAAc,OAAO;AAAA,EACnD;AAAA,EAEA,0BACE,cACA,OACY;AACZ,QAAI,KAAK,mBAAmB,IAAI,YAAY,GAAG;AAC7C,YAAM,IAAIC,OAAAA,gCAAgC,YAAY;AAAA,IACxD;AACA,SAAK,mBAAmB,IAAI,cAAc,KAAK;AAC/C,eAAW,eAAe,KAAK,iCAAiC,OAAA,GAAU;AACxE,UAAI,YAAY,iBAAiB,aAAc;AAC/C,kBAAY,mBAAmB;AAC/B,kBAAY,cAAc;AAAA,IAC5B;AACA,SAAK,KAAK,+BAA+B,YAAY;AACrD,SAAK,sCAAsC,cAAc,KAAK;AAC9D,WAAO,MAAM;AACX,UAAI,KAAK,mBAAmB,IAAI,YAAY,MAAM,MAAO;AACzD,WAAK,mBAAmB,OAAO,YAAY;AAC3C,WAAK,uCAAuC,cAAc,KAAK;AAAA,IACjE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,YAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UACE,cACA,WACY;AACZ,UAAM,QAAQ,KAAK,sBAAsB,YAAY;AACrD,UAAM,YAAY,IAAI,SAAS;AAC/B,WAAO,MAAM;AACX,YAAM,YAAY,OAAO,SAAS;AAClC,UAAI,MAAM,YAAY,SAAS,GAAG;AAChC,cAAM,2BAA2B;AACjC,aAAK,0BAA0B,cAAc,KAAK;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAQ,eAAuB,SAA0C;AACvE,SAAK,QAAQ,YAAY,OAAO;AAAA,EAClC;AAAA,EAEA,SAAS,cAA+B;AACtC,WAAO,KAAK,YAAY,IAAI,YAAY,GAAG,YAAY;AAAA,EACzD;AAAA,EAEA,MAAM,iBAAiB,cAAqC;AAC1D,UAAM,QAAQ,KAAK,sBAAsB,YAAY;AACrD,QAAI,MAAM,SAAU;AACpB,UAAM,KAAK,kBAAkB,cAAc,KAAK;AAAA,EAClD;AAAA,EAEA,MAAM,0BACJ,cACA,SACe;AACf,UAAM,qBAAqBC,iBAAAA,+BAA+B,OAAO;AACjE,UAAM,eAAeC,iBAAAA;AAAAA,MACnB;AAAA,MACA;AAAA,IAAA;AAEF,QAAI,gBAAgB,KAAK,gBAAgB,IAAI,YAAY;AACzD,QAAI,CAAC,eAAe;AAClB,0CAAoB,QAAA;AACpB,WAAK,gBAAgB,IAAI,cAAc,aAAa;AAAA,IACtD;AACA,QAAI,gBAAgB,cAAc,IAAI,OAAO;AAC7C,QAAI,cAAc,gBACd,KAAK,iCAAiC;AAAA,MACpC,2BAA2B,cAAc,aAAa;AAAA,IAAA,IAExD;AACJ,QAAI,CAAC,aAAa;AAChB,sBAAgBH,GAAAA,eAAA;AAChB,oBAAc,IAAI,SAAS,aAAa;AACxC,oBAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA,kBAAkB;AAAA,QAClB,UAAU;AAAA,QACV,SAAS;AAAA,QACT,kBAAkB;AAAA,QAClB,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,eAAe;AAAA,MAAA;AAEjB,WAAK,iCAAiC;AAAA,QACpC,2BAA2B,cAAc,aAAa;AAAA,QACtD;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI;AACF,YAAM,KAAK,oBAAoB,WAAW;AAAA,IAC5C,SAAS,OAAO;AACd,UAAI,QAAQ,QAAQ,SAAS;AAC3B,oBAAY,mBAAmB;AAC/B,aAAK,8BAA8B,WAAW;AAI9C,aAAK,wBAAwB,WAAW;AACxC,cAAM,MAAM;AAAA,UACV;AAAA,UACA,YAAY;AAAA,QAAA;AAEd,YAAI,KAAK,iCAAiC,IAAI,GAAG,MAAM,aAAa;AAClE,eAAK,iCAAiC,OAAO,GAAG;AAChD,wBAAc,OAAO,OAAO;AAAA,QAC9B;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,2BACJ,cACA,SACe;AACf,UAAM,gBAAgB,KAAK,gBAAgB,IAAI,YAAY;AAC3D,UAAM,gBAAgB,eAAe,IAAI,OAAO;AAChD,QAAI,CAAC,cAAe;AACpB,UAAM,MAAM,2BAA2B,cAAc,aAAa;AAClE,UAAM,cAAc,KAAK,iCAAiC,IAAI,GAAG;AACjE,QAAI,CAAC,YAAa;AAClB,gBAAY,mBAAmB;AAC/B,SAAK,8BAA8B,WAAW;AAC9C,QAAI,CAAC,YAAY,SAAS;AACxB,kBAAY,WAAW,YAAY;AACjC,cAAM,UAGF;AAAA,UACF,MAAM;AAAA,UACN,OAAOA,GAAAA,eAAA;AAAA,UACP;AAAA,QAAA;AAEF,cAAM,cAAc,KAAK,SAAS,YAAY;AAC9C,YAAI,uBAAuB;AAC3B,YAAI;AACF,gBAAM,WAAW,cACb,MAAM,KAAK;AAAA,YACT;AAAA,YACA;AAAA,YACA,KAAK;AAAA,UAAA,IAEP,MAAM,KAAK;AAAA,YACT;AAAA,YACA;AAAA,UAAA;AAEN,iCAAuB;AACvB,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,+BAA+B,SAAS,KAAK,EAAE;AAAA,UACjE;AAAA,QACF,UAAA;AAKE,cACE,wBACA,KAAK,iCAAiC,IAAI,GAAG,MAAM,aACnD;AACA,iBAAK,iCAAiC,OAAO,GAAG;AAChD,0BAAe,OAAO,OAAO;AAAA,UAC/B;AAAA,QACF;AAAA,MACF,GAAA;AAAA,IACF;AACA,QAAI;AACF,YAAM,YAAY;AAAA,IACpB,UAAA;AACE,kBAAY,UAAU;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,oBACZ,aACe;AACf,QAAI,YAAY,SAAU,QAAO,YAAY;AAE7C,UAAM,QAAQ,EAAE,YAAY,MAAA;AAC5B,QAAI;AACJ,QAAI;AACJ,UAAM,OAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAClD,oBAAc;AACd,mBAAa;AAAA,IACf,CAAC;AACD,gBAAY,WAAW;AACvB,UAAM,MAAM,YAA2B;AACrC,YAAM,UAGF;AAAA,QACF,MAAM;AAAA,QACN,OAAOA,GAAAA,eAAA;AAAA,QACP,eAAe,YAAY;AAAA,QAC3B,SAAS,YAAY;AAAA,MAAA;AAEvB,YAAM,QAAQ,KAAK,YAAY,IAAI,YAAY,YAAY;AAC3D,UACE,OAAO,4BACP,CAAC,MAAM,YACP,MAAM,aAAa,MACnB;AACA,cAAM,KAAK;AAAA,UACT,YAAY;AAAA,UACZ;AAAA,UACA,YAAY,aAAa;AAAA,QAAA;AAAA,MAE7B;AACA,YAAM,aAAa,KAAK,SAAS,YAAY,YAAY;AACzD,UAAI;AACJ,UAAI;AACF,mBAAW,MAAM,aACb,MAAM,KAAK;AAAA,UACT,YAAY;AAAA,UACZ;AAAA,UACA,KAAK;AAAA,UACL,YAAY;AAAA,QAAA,IAEd,MAAM,KAAK;AAAA,UACT,YAAY;AAAA,UACZ;AAAA,QAAA;AAAA,MAER,SAAS,OAAO;AACd,YACE,MAAM,cACN,iBAAiBI,8CACjB;AACA,gBAAM;AAAA,QACR;AACA,cAAM,IAAIA,OAAAA;AAAAA,UACR;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,YAAI,SAAS,WAAW;AACtB,gBAAM,IAAIA,OAAAA,sCAAsC,SAAS,KAAK;AAAA,QAChE;AACA,cAAM,IAAI,MAAM,8BAA8B,SAAS,KAAK,EAAE;AAAA,MAChE;AACA,kBAAY,mBAAmB,SAAS;AAAA,IAC1C;AACA,SAAK,IAAA,EAAM,KAAK,aAAa,UAAU;AACvC,QAAI,WAAW;AACf,QAAI;AACF,YAAM;AACN,iBAAW;AACX,WAAK,8BAA8B,WAAW;AAAA,IAChD,UAAA;AACE,UAAI,YAAY,aAAa,KAAM,aAAY,WAAW;AAC1D,YAAM,UAAU,KAAK,YAAY,IAAI,YAAY,YAAY;AAC7D,YAAM,kBAAkB,SAAS,WAC7B,KAAK,SACJ,SAAS,YAAY;AAC1B,YAAM,MAAM;AAAA,QACV,YAAY;AAAA,QACZ,YAAY;AAAA,MAAA;AAEd,UACE,YACA,CAAC,YAAY,oBACb,KAAK,iCAAiC,IAAI,GAAG,MAAM,gBAClD,YAAY,eACV,oBAAoB,QACnB,YAAY,qBAAqB,kBACrC;AACA,oBAAY,cAAc;AAC1B,aAAK,KAAK,oBAAoB,WAAW,EAAE,MAAM,CAAC,UAAU;AAC1D,eAAK,gCAAgC,aAAa,KAAK;AAAA,QACzD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,4BACJ,cACA,WACA,MACA,eACA,uBAAuB,OACR;AACf,QAAI,KAAK,SAAS,YAAY,GAAG;AAC/B,UAAI,qBAAsB;AAC1B,aAAO,iBAAiB,KAAK,eAAe,YAAY,GAAG;AAAA,QACzD;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAEF;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,KAAK,QAKzB,cAAc;AAAA,MACf,MAAM;AAAA,MACN,OAAOJ,GAAAA,eAAA;AAAA,MACP;AAAA,MACA;AAAA,IAAA,CACD;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI;AAAA,QACR,gCAAgC,SAAS,SAAS,eAAe;AAAA,MAAA;AAAA,IAErE;AAAA,EACF;AAAA,EAEA,MAAM,2BACJ,cACA,WACsC;AACtC,UAAM,eAAe,KAAK,oBAAoB,YAAY;AAC1D,QAAI,aAAc,OAAM;AACxB,QAAI,KAAK,SAAS,YAAY,GAAG;AAC/B,aAAO,KAAK,0BAA0B,cAAc;AAAA,QAClD,MAAM;AAAA,QACN,OAAOA,GAAAA,eAAA;AAAA,QACP,YAAYA,GAAAA,eAAA;AAAA,QACZ;AAAA,MAAA,CACD;AAAA,IACH;AAEA,WAAO,KAAK,QAAqC,cAAc;AAAA,MAC7D,MAAM;AAAA,MACN,OAAOA,GAAAA,eAAA;AAAA,MACP,YAAYA,GAAAA,eAAA;AAAA,MACZ;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEA,MAAM,wBACJ,cACA,IACA,eACmC;AACnC,UAAM,eAAe,KAAK,oBAAoB,YAAY;AAC1D,QAAI,aAAc,OAAM;AACxB,UAAM,UAAqE;AAAA,MACzE,MAAM;AAAA,MACN,OAAOA,GAAAA,eAAA;AAAA,MACP,YAAYA,GAAAA,eAAA;AAAA,MACZ;AAAA,IAAA;AAEF,QAAI,KAAK,SAAS,YAAY,GAAG;AAC/B,aAAO,KAAK,uBAAuB,cAAc,SAAS,aAAa;AAAA,IACzE;AAEA,WAAO,KAAK,QAAkC,cAAc,OAAO;AAAA,EACrE;AAAA,EAEA,MAAM,UACJ,cACA,gBACA,eAC4B;AAC5B,QAAI,KAAK,SAAS,YAAY,GAAG;AAC/B,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,OAAOA,GAAAA,eAAA;AAAA,UACP;AAAA,QAAA;AAAA,QAEF;AAAA,MAAA;AAAA,IAEJ;AAEA,WAAO,KAAK,QAA2B,cAAc;AAAA,MACnD,MAAM;AAAA,MACN,OAAOA,GAAAA,eAAA;AAAA,MACP;AAAA,IAAA,CACD;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAMA,UAAgB;AACd,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAChB,UAAM,gBAAgB,IAAI,MAAM,sBAAsB;AACtD,SAAK,iBAAiB,aAAa;AACnC,SAAK,iBAAiB;AAEtB,eAAW,eAAe,KAAK,iCAAiC,OAAA,GAAU;AACxE,WAAK,8BAA8B,WAAW;AAC9C,WAAK,wBAAwB,WAAW;AAAA,IAC1C;AACA,SAAK,iCAAiC,MAAA;AACtC,SAAK,gBAAgB,MAAA;AAErB,eAAW,CAAC,cAAc,KAAK,KAAK,KAAK,aAAa;AACpD,WAAK,kBAAkB,cAAc,KAAK;AAAA,IAC5C;AAEA,eAAW,CAAA,EAAG,OAAO,KAAK,KAAK,aAAa;AAC1C,mBAAa,QAAQ,KAAK;AAC1B,cAAQ,OAAO,aAAa;AAAA,IAC9B;AACA,SAAK,YAAY,MAAA;AACjB,QAAI,KAAK,8BAA8B,MAAM;AAC3C,mBAAa,KAAK,yBAAyB;AAC3C,WAAK,4BAA4B;AAAA,IACnC;AAEA,SAAK,QAAQ,MAAA;AACb,SAAK,YAAY,MAAA;AACjB,SAAK,mBAAmB,MAAA;AACxB,eAAW,gBAAgB,KAAK,mBAAmB,KAAA,GAAQ;AACzD,WAAK,uCAAuC,YAAY;AAAA,IAC1D;AACA,SAAK,mBAAmB,MAAA;AACxB,SAAK,gCAAgC,MAAA;AACrC,SAAK,qCAAqC,MAAA;AAC1C,SAAK,iBAAiB,MAAA;AACtB,SAAK,kBAAkB,MAAA;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAMQ,2BAA2B,cAAuC;AACxE,QAAI,QAAQ,KAAK,YAAY,IAAI,YAAY;AAC7C,QAAI,CAAC,OAAO;AACV,cAAQ;AAAA,QACN,0BAA0B;AAAA,QAC1B,UAAU;AAAA,QACV,UAAU;AAAA,QACV,qBAAqB;AAAA,QACrB,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,kBAAkB;AAAA,QAClB,iCAAiB,IAAA;AAAA,QACjB,kCAAkB,IAAA;AAAA,MAAI;AAExB,WAAK,YAAY,IAAI,cAAc,KAAK;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,sBAAsB,cAAuC;AACnE,UAAM,QAAQ,KAAK,2BAA2B,YAAY;AAC1D,QAAI,CAAC,MAAM,0BAA0B;AACnC,YAAM,2BAA2B;AACjC,WAAK,KAAK,kBAAkB,cAAc,KAAK;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,kBACZ,cACA,OACe;AACf,QAAI,KAAK,YAAY,CAAC,MAAM,4BAA4B,MAAM,UAAU;AACtE;AAAA,IACF;AAEA,UAAM,WAAW,eAAe,KAAK,MAAM,IAAI,YAAY;AAC3D,UAAM,kBAAkB,IAAI,gBAAA;AAC5B,UAAM,qBAAqB,MAAA;AAC3B,UAAM,sBAAsB;AAE5B,QAAI;AACF,YAAM,UAAU,MAAM;AAAA,QACpB;AAAA,QACA,EAAE,QAAQ,gBAAgB,OAAA;AAAA,QAC1B,YAAY;AACV,cACE,KAAK,WAAA,KACL,CAAC,KAAK,yBAAyB,KAAK,KACpC,KAAK,YAAY,IAAI,YAAY,MAAM,OACvC;AACA;AAAA,UACF;AAEA,cAAI;AAEF,kBAAM,UAAU,KAAK,eAAe,YAAY;AAChD,gBAAI,QAAQ,mBAAmB;AAC7B,oBAAM,MAAM,MAAM,QAAQ,kBAAkB,YAAY;AACxD,oBAAM,aAAa,IAAI;AACvB,oBAAM,YAAY,IAAI;AACtB,oBAAM,mBAAmB,IAAI;AAAA,YAC/B;AAEA,gBACE,KAAK,WAAA,KACL,CAAC,KAAK,yBAAyB,KAAK,KACpC,KAAK,YAAY,IAAI,YAAY,MAAM,SACvC,gBAAgB,OAAO,WACvB,MAAM,wBAAwB,iBAC9B;AACA;AAAA,YACF;AAEA,kBAAM;AACN,kBAAM,WAAW;AACjB,kBAAM,WAAW,KAAK;AACtB,iBAAK,mBAAmB,KAAK;AAE7B,iBAAK,cAAc,cAAc,KAAK;AACtC,iBAAK,KAAK,+BAA+B,YAAY;AACrD,kBAAM,iBAAiB,YAAY,MAAM;AACvC,mBAAK,cAAc,cAAc,KAAK;AAAA,YACxC,GAAG,qBAAqB;AAGxB,kBAAM,IAAI,QAAc,CAAC,YAAY;AACnC,oBAAM,UAAU,MAAM;AACpB,gCAAgB,OAAO,oBAAoB,SAAS,OAAO;AAC3D,wBAAA;AAAA,cACF;AACA,kBAAI,gBAAgB,OAAO,SAAS;AAClC,wBAAA;AACA;AAAA,cACF;AACA,8BAAgB,OAAO,iBAAiB,SAAS,OAAO;AAAA,YAC1D,CAAC;AAAA,UACH,UAAA;AACE,iBAAK,uCAAuC,YAAY;AACxD,kBAAM,WAAW;AACjB,kBAAM,WAAW;AACjB,gBAAI,MAAM,gBAAgB;AACxB,4BAAc,MAAM,cAAc;AAClC,oBAAM,iBAAiB;AAAA,YACzB;AAAA,UACF;AAAA,QACF;AAAA,MAAA;AAAA,IAEJ,SAAS,OAAO;AACd,UAAI,iBAAiB,gBAAgB,MAAM,SAAS,cAAc;AAChE;AAAA,MACF;AACA,cAAQ,KAAK,oCAAoC,YAAY,KAAK,KAAK;AACvE,UACE,CAAC,KAAK,gBACN,KAAK,yBAAyB,KAAK,KACnC,KAAK,YAAY,IAAI,YAAY,MAAM,OACvC;AACA,cAAM,MAAM,yBAAyB;AAAA,MACvC;AAAA,IACF,UAAA;AACE,UAAI,MAAM,wBAAwB,iBAAiB;AACjD,cAAM,sBAAsB;AAAA,MAC9B;AAAA,IACF;AAGA,QACE,CAAC,KAAK,WAAA,KACN,KAAK,yBAAyB,KAAK,KACnC,KAAK,YAAY,IAAI,YAAY,MAAM,SACvC,MAAM,wBAAwB,MAC9B;AACA,WAAK,KAAK,kBAAkB,cAAc,KAAK;AAAA,IACjD;AAAA,EACF;AAAA,EAEQ,oBAAoB,cAAiD;AAC3E,UAAM,QAAQ,KAAK,YAAY,IAAI,YAAY;AAC/C,QACE,OAAO,4BACP,CAAC,MAAM,YACP,MAAM,aAAa,MACnB;AACA,WAAK,QAAQ,YAAY;AAAA,QACvB,GAAG;AAAA,QACH,QAAQ,KAAK;AAAA,QACb;AAAA,QACA,UAAU,KAAK;AAAA,QACf,IAAI,KAAK,IAAA;AAAA,QACT,SAAS,EAAE,MAAM,sBAAA;AAAA,MAAsB,CACoB;AAC7D,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,uBACN,cACA,OACA,QACA,WACe;AACf,QAAI,MAAM,YAAY,MAAM,aAAa,KAAM,QAAO,QAAQ,QAAA;AAE9D,WAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AAC5C,UAAI;AACJ,YAAM,SAAS,MAAM;AACnB,cAAM,cAAc,OAAO,aAAa;AACxC,gBAAQ,oBAAoB,SAAS,OAAO;AAC5C,YAAI,UAAU,OAAW,cAAa,KAAK;AAAA,MAC7C;AACA,YAAM,UAAU,MAAM;AACpB,eAAA;AACA;AAAA,UACE,IAAI,aAAa,qCAAqC,YAAY;AAAA,QAAA;AAAA,MAEtE;AACA,YAAM,gBAAgB,MAAM;AAC1B,YAAI,KAAK,WAAA,KAAgB,CAAC,MAAM,0BAA0B;AACxD,iBAAA;AACA;AAAA,YACE,IAAI;AAAA,cACF,GAAG,KAAK,eAAe,6CAA6C,YAAY;AAAA,YAAA;AAAA,UAClF;AAEF;AAAA,QACF;AACA,YAAI,MAAM,YAAY,MAAM,aAAa,MAAM;AAC7C,iBAAA;AACA,kBAAA;AAAA,QACF;AAAA,MACF;AAEC,OAAC,MAAM,iBAAiB,oBAAI,IAAA,GAAO,IAAI,aAAa;AACrD,UAAI,cAAc,QAAW;AAC3B,gBAAQ,WAAW,MAAM;AACvB,iBAAA;AACA;AAAA,YACE,IAAI;AAAA,cACF,GAAG,KAAK,eAAe,sCAAsC,YAAY,qBAAqB,SAAS;AAAA,YAAA;AAAA,UACzG;AAAA,QAEJ,GAAG,SAAS;AAAA,MACd;AACA,cAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM;AACzD,UAAI,QAAQ,SAAS;AACnB,gBAAA;AAAA,MACF,OAAO;AACL,sBAAA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,mBAAmB,OAA8B;AACvD,eAAW,UAAU,MAAM,KAAK,MAAM,gBAAgB,CAAA,CAAE,EAAG,QAAA;AAAA,EAC7D;AAAA,EAEQ,kBACN,cACA,OACM;AACN,SAAK,uCAAuC,YAAY;AACxD,QAAI,MAAM,qBAAqB;AAC7B,YAAM,oBAAoB,MAAA;AAC1B,YAAM,sBAAsB;AAAA,IAC9B;AACA,QAAI,MAAM,gBAAgB;AACxB,oBAAc,MAAM,cAAc;AAClC,YAAM,iBAAiB;AAAA,IACzB;AACA,UAAM,WAAW;AACjB,UAAM,WAAW;AACjB,SAAK,mBAAmB,KAAK;AAAA,EAC/B;AAAA,EAEQ,0BACN,cACA,OACM;AACN,QACE,MAAM,YAAY,OAAO,KACzB,KAAK,YAAY,IAAI,YAAY,MAAM,OACvC;AACA;AAAA,IACF;AACA,SAAK,kBAAkB,cAAc,KAAK;AAC1C,SAAK,YAAY,OAAO,YAAY;AACpC,SAAK,mBAAmB,OAAO,YAAY;AAC3C,UAAM,SAAS,GAAG,KAAK,UAAU,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7D,eAAW,OAAO,KAAK,iBAAiB,KAAA,GAAQ;AAC9C,UAAI,IAAI,WAAW,MAAM,EAAG,MAAK,iBAAiB,OAAO,GAAG;AAAA,IAC9D;AACA,SAAK,sBAAA;AAAA,EACP;AAAA,EAEQ,wBACN,aACM;AACN,QAAI,YAAY,QAAS;AACzB,UAAM,UAGF;AAAA,MACF,MAAM;AAAA,MACN,OAAOA,GAAAA,eAAA;AAAA,MACP,eAAe,YAAY;AAAA,IAAA;AAE7B,QAAI,KAAK,SAAS,YAAY,YAAY,GAAG;AAC3C,WAAK,KAAK;AAAA,QACR,YAAY;AAAA,QACZ;AAAA,QACA,KAAK;AAAA,MAAA,EACL,MAAM,MAAM;AAAA,MAEd,CAAC;AACD;AAAA,IACF;AACA,SAAK,QAAQ,YAAY;AAAA,MACvB,GAAG;AAAA,MACH,QAAQ,KAAK;AAAA,MACb,cAAc,YAAY;AAAA,MAC1B,UAAU,KAAK;AAAA,MACf,IAAI,KAAK,IAAA;AAAA,MACT,SAAS;AAAA,IAAA,CAC0B;AAAA,EACvC;AAAA,EAEQ,8BACN,aACM;AACN,QAAI,YAAY,eAAe,MAAM;AACnC,mBAAa,YAAY,UAAU;AACnC,kBAAY,aAAa;AAAA,IAC3B;AACA,gBAAY,gBAAgB;AAAA,EAC9B;AAAA,EAEQ,gCACN,aACA,OACM;AACN,UAAM,MAAM;AAAA,MACV,YAAY;AAAA,MACZ,YAAY;AAAA,IAAA;AAEd,QACE,EAAE,iBAAiBI,OAAAA,0CACnB,KAAK,gBACL,KAAK,iCAAiC,IAAI,GAAG,MAAM,eACnD,YAAY,oBACZ,YAAY,eAAe,QAC3B,YAAY,iBAAiB,qCAC7B;AACA;AAAA,IACF;AAEA,gBAAY;AACZ,gBAAY,aAAa,WAAW,MAAM;AACxC,kBAAY,aAAa;AACzB,UACE,KAAK,gBACL,KAAK,iCAAiC,IAAI,GAAG,MAAM,eACnD,YAAY,kBACZ;AACA;AAAA,MACF;AACA,WAAK,KAAK,oBAAoB,WAAW,EAAE,MAAM,CAAC,eAAe;AAC/D,aAAK,gCAAgC,aAAa,UAAU;AAAA,MAC9D,CAAC;AAAA,IACH,GAAG,kBAAkB;AAAA,EACvB;AAAA,EAEA,MAAc,+BACZ,cACe;AACf,QAAI,KAAK,aAAc;AACvB,UAAM,QAAQ,KAAK,YAAY,IAAI,YAAY;AAC/C,UAAM,WAAW,OAAO,WAAW,KAAK,SAAS,OAAO;AACxD,QAAI,CAAC,SAAU;AAEf,UAAM,UAAgC,CAAA;AACtC,eAAW,eAAe,KAAK,iCAAiC,OAAA,GAAU;AACxE,UACE,YAAY,iBAAiB,gBAC7B,YAAY,oBACX,CAAC,YAAY,eAAe,YAAY,qBAAqB,UAC9D;AACA;AAAA,MACF;AACA,UAAI,YAAY,UAAU;AACxB,oBAAY,cAAc;AAC1B;AAAA,MACF;AACA,kBAAY,cAAc;AAC1B,cAAQ;AAAA,QACN,KAAK,oBAAoB,WAAW,EAAE,MAAM,CAAC,UAAU;AACrD,eAAK,gCAAgC,aAAa,KAAK;AAAA,QACzD,CAAC;AAAA,MAAA;AAAA,IAEL;AACA,UAAM,QAAQ,IAAI,OAAO;AAAA,EAC3B;AAAA,EAEQ,cAAc,cAAsB,OAA8B;AACxE,UAAM,WAAsC;AAAA,MAC1C,GAAG;AAAA,MACH,QAAQ,KAAK;AAAA,MACb;AAAA,MACA,UAAU,KAAK;AAAA,MACf,IAAI,KAAK,IAAA;AAAA,MACT,SAAS;AAAA,QACP,MAAM;AAAA,QACN,MAAM,MAAM;AAAA,QACZ,UAAU,KAAK;AAAA,QACf,WAAW,MAAM;AAAA,QACjB,kBAAkB,MAAM;AAAA,MAAA;AAAA,IAC1B;AAEF,SAAK,QAAQ,YAAY,QAAQ;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,MAAqB;AAC5C,QAAI,CAAC,mBAAmB,IAAI,EAAG;AAE/B,UAAM,WAAW;AAGjB,QAAI,SAAS,aAAa,KAAK,OAAQ;AAEvC,UAAM,UAAU,SAAS;AACzB,QAAI,CAAC,WAAW,OAAO,YAAY,SAAU;AAE7C,UAAM,OAAQ,QAAoC;AAElD,QAAI,SAAS,uBAAuB;AAClC,YAAMC,SAAQ,KAAK,YAAY,IAAI,SAAS,YAAY;AACxD,UAAIA,QAAO,SAAU,MAAK,cAAc,SAAS,cAAcA,MAAK;AACpE;AAAA,IACF;AAEA,QAAI,SAAS,oBAAoB;AAC/B,YAAM,YAAY;AAMlB,UACE,OAAO,UAAU,aAAa,YAC9B,OAAO,UAAU,SAAS,YAC1B,OAAO,UAAU,cAAc,YAC/B,OAAO,UAAU,qBAAqB,UACtC;AACA,cAAMA,SAAQ,KAAK,2BAA2B,SAAS,YAAY;AACnE,YAAI,UAAU,OAAOA,OAAM,WAAY;AACvC,cAAM,gBAAgBA,OAAM,aAAa,UAAU;AACnDA,eAAM,WAAW,UAAU;AAC3BA,eAAM,aAAa,KAAK,IAAIA,OAAM,YAAY,UAAU,IAAI;AAC5DA,eAAM,YAAY,KAAK,IAAIA,OAAM,WAAW,UAAU,SAAS;AAC/DA,eAAM,mBAAmB,KAAK;AAAA,UAC5BA,OAAM;AAAA,UACN,UAAU;AAAA,QAAA;AAEZ,aAAK,mBAAmBA,MAAK;AAC7B,YAAI,eAAe;AACjB,eAAK,KAAK,+BAA+B,SAAS,YAAY;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAGA,QAAI,QAAQ,KAAK,SAAS,MAAM,GAAG;AACjC,YAAM,QAAS,QAA+B;AAC9C,UAAI,SAAS,KAAK,YAAY,IAAI,KAAK,GAAG;AACxC,cAAM,UAAU,KAAK,YAAY,IAAI,KAAK;AAC1C,aAAK,YAAY,OAAO,KAAK;AAC7B,qBAAa,QAAQ,KAAK;AAC1B,gBAAQ,QAAQ,OAAsB;AACtC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,QAAQ,KAAK,SAAS,MAAM,GAAG;AACjC,UAAI,CAAC,aAAa,OAAO,EAAG;AAC5B,YAAM,eAAe,SAAS;AAC9B,UAAI,KAAK,SAAS,YAAY,GAAG;AAC/B,aAAK,KAAK,iBAAiB,cAAc,SAAS,SAAS,QAAQ;AAAA,MACrE;AACA;AAAA,IACF;AAGA,UAAM,QAAQ,KAAK,YAAY,IAAI,SAAS,YAAY;AACxD,QAAI,OAAO;AACT,iBAAW,cAAc,MAAM,aAAa;AAC1C,mBAAW,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,QACZ,cACA,SACY;AACZ,QAAI,KAAK,WAAA,EAAc,OAAM,IAAI,MAAM,sBAAsB;AAC7D,QAAI;AACJ,QAAI;AACJ,UAAM,sBAAsB,qBAAqB,OAAO,IACpD,QAAQ,OACR;AACJ,UAAM,gBAAgB,sBAClB,KAAK,qBAAqB,YAAY,IACtC;AAEJ,aAAS,UAAU,GAAG,WAAW,oBAAoB,WAAW;AAC9D,UAAI,UAAU,GAAG;AACf,cAAM,QAAQ,KAAK;AAAA,UACjB,MAAM,qBAAqB,OAAO;AAAA,UAClC,KAAK;AAAA,QAAA,CACN;AAAA,MACH;AACA,UAAI,KAAK,WAAA,EAAc,OAAM,IAAI,MAAM,sBAAsB;AAE7D,UACE,iBACA,uBACA,wBAAwB,QACxB;AACA,aAAK;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAEA,UAAI,KAAK,SAAS,YAAY,GAAG;AAC/B,eAAQ,MAAM,KAAK;AAAA,UACjB;AAAA,UACA;AAAA,UACA,KAAK;AAAA,QAAA;AAAA,MAET;AAEA,UAAI;AACF,eAAO,MAAM,KAAK,YAAe,cAAc,OAAO;AAAA,MACxD,SAAS,OAAO;AACd,YAAI,KAAK,WAAA,EAAc,OAAM;AAC7B,gCAAwB;AACxB,YAAI,iBAAiB,qBAAqB;AACxC,eAAK;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAAA,QAEJ;AACA,oBAAY,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,MACtE;AAAA,IACF;AAEA,UAAM,aAAa,IAAI,MAAM,0BAA0B;AAAA,EACzD;AAAA,EAEQ,qBAAqB,cAG3B;AACA,UAAM,QAAQ,KAAK,YAAY,IAAI,YAAY;AAC/C,WAAO;AAAA,MACL,UAAU,OAAO,WAAW,KAAK,SAAU,OAAO,YAAY;AAAA,MAC9D,MAAM,OAAO,cAAc;AAAA,IAAA;AAAA,EAE/B;AAAA,EAEQ,6BACN,cACA,aACA,UACA,OACM;AACN,UAAM,UAAU,KAAK,qBAAqB,YAAY;AACtD,QACE,SAAS,aAAa,QACtB,SAAS,SAAS,QAClB,QAAQ,aAAa,SAAS,YAC9B,QAAQ,SAAS,SAAS,MAC1B;AACA;AAAA,IACF;AACA,UAAM,IAAIC,OAAAA,yBAAyB;AAAA,MACjC;AAAA,MACA;AAAA,MACA,kBAAkB,SAAS;AAAA,MAC3B,cAAc,SAAS;AAAA,MACvB,iBAAiB,QAAQ;AAAA,MACzB,aAAa,QAAQ;AAAA,MACrB;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEQ,YACN,cACA,SACY;AACZ,WAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AACzC,YAAM,QAAQ,QAAQ;AAEtB,YAAM,QAAQ,WAAW,MAAM;AAC7B,aAAK,YAAY,OAAO,KAAK;AAC7B;AAAA,UACE,IAAI,MAAM,OAAO,QAAQ,IAAI,oBAAoB,cAAc,IAAI;AAAA,QAAA;AAAA,MAEvE,GAAG,cAAc;AAEjB,WAAK,YAAY,IAAI,OAAO;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAED,YAAM,WAAsC;AAAA,QAC1C,GAAG;AAAA,QACH,QAAQ,KAAK;AAAA,QACb;AAAA,QACA,UAAU,KAAK;AAAA,QACf,IAAI,KAAK,IAAA;AAAA,QACT,SAAS;AAAA,MAAA;AAEX,WAAK,QAAQ,YAAY,QAAQ;AAAA,IACnC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,iBACZ,cACA,SACA,aACe;AACf,QAAI;AAEJ,QAAI;AACF,iBAAW,MAAM,KAAK;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,SAAS,OAAO;AACd,iBAAW,uBAAuB,SAAS,KAAK;AAAA,IAClD;AAEA,QAAI,KAAK,cAAc;AACrB;AAAA,IACF;AAEA,UAAM,WAAsC;AAAA,MAC1C,GAAG;AAAA,MACH,QAAQ,KAAK;AAAA,MACb;AAAA,MACA,UAAU,KAAK;AAAA,MACf,IAAI,KAAK,IAAA;AAAA,MACT,SAAS;AAAA,IAAA;AAEX,SAAK,QAAQ,YAAY,QAAQ;AAAA,EACnC;AAAA,EAEQ,mBACN,cACA,SACA,aACsB;AACtB,YAAQ,QAAQ,MAAA;AAAA,MACd,KAAK;AACH,eAAO,KAAK,yBAAyB,cAAc,SAAS,WAAW;AAAA,MACzE,KAAK;AACH,eAAO,KAAK;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ,KAAK;AACH,eAAO,KAAK,2BAA2B,cAAc,OAAO;AAAA,MAC9D,KAAK;AACH,eAAO,KAAK,0BAA0B,cAAc,OAAO;AAAA,MAC7D,KAAK;AACH,eAAO,KAAK,uBAAuB,cAAc,OAAO;AAAA,MAC1D,KAAK;AACH,eAAO,KAAK,gBAAgB,cAAc,OAAO;AAAA,IAAA;AAAA,EAEvD;AAAA,EAEA,MAAc,yBACZ,cACA,SACA,aACA,cACqC;AACrC,SAAK,sCAAA;AACL,UAAM,MAAM;AAAA,MACV;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IAAA;AAEV,UAAM,WAAW,KAAK,gCAAgC,IAAI,GAAG;AAC7D,UAAM,gBACJ,YAAY,mBAAmB,WAAW,WAAW;AACvD,QAAI,UAAU;AACZ,UAAI,WAAW,UAAU;AACvB,YAAI,CAAC,SAAS,UAAU;AACtB,gBAAM,SAAS;AACf,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,OAAO,QAAQ;AAAA,YACf,IAAI;AAAA,YACJ,UAAU,KAAK;AAAA,UAAA;AAAA,QAEnB;AACA,cAAM,SAAS;AACf,YAAI,SAAS,iBAAiB;AAC5B,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,OAAO,QAAQ;AAAA,YACf,IAAI;AAAA,YACJ,UAAU,KAAK;AAAA,UAAA;AAAA,QAEnB;AACA,YAAI,KAAK,gCAAgC,IAAI,GAAG,MAAM,UAAU;AAC9D,eAAK,gCAAgC,OAAO,GAAG;AAAA,QACjD;AAAA,MACF,WAAW,EAAE,mBAAmB,WAAW;AACzC,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,QAAQ;AAAA,UACf,IAAI;AAAA,UACJ,UAAU,KAAK;AAAA,QAAA;AAAA,MAEnB;AAAA,IACF;AAEA,UAAM,QAAQ,KAAK,mBAAmB,IAAI,YAAY;AACtD,QAAI,CAAC,OAAO;AACV,YAAM,IAAIF,OAAAA;AAAAA,QACR,GAAG,KAAK,eAAe,uDAAuD,YAAY;AAAA,MAAA;AAAA,IAE9F;AAEA,UAAM,KAAK,kCAAkC;AAAA,MAC3C;AAAA,MACA;AAAA,MACA,eAAe,QAAQ;AAAA,MACvB;AAAA,MACA,SAAS,eAAe,WAAW,gBAAgB,QAAQ;AAAA,MAC3D,6BAA6B;AAAA,IAAA,CAC9B;AACD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,IAAI;AAAA,MACJ,UAAU,KAAK;AAAA,IAAA;AAAA,EAEnB;AAAA,EAEA,MAAc,0BACZ,cACA,SACA,aACsC;AACtC,SAAK,sCAAA;AACL,UAAM,MAAM;AAAA,MACV;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IAAA;AAEV,UAAM,cAAc,KAAK,gCAAgC,IAAI,GAAG;AAChE,QAAI,CAAC,aAAa;AAChB,WAAK,mCAAmC,KAAK;AAAA,QAC3C;AAAA,QACA;AAAA,QACA,eAAe,QAAQ;AAAA,QACvB,UAAU;AAAA,MAAA,CACX;AAAA,IACH,WAAW,WAAW,aAAa;AACjC,kBAAY,kBAAkB;AAC9B,UAAI;AACF,cAAM,KAAK,+BAA+B,WAAW;AAAA,MACvD,UAAA;AACE,YAAI,KAAK,gCAAgC,IAAI,GAAG,MAAM,aAAa;AACjE,eAAK,mCAAmC,KAAK;AAAA,YAC3C;AAAA,YACA;AAAA,YACA,eAAe,QAAQ;AAAA,YACvB,UAAU;AAAA,UAAA,CACX;AAAA,QACH;AAAA,MACF;AAAA,IACF,WAAW,mBAAmB,aAAa;AACzC,WAAK,mCAAmC,KAAK;AAAA,QAC3C;AAAA,QACA;AAAA,QACA,eAAe,QAAQ;AAAA,QACvB,UAAU;AAAA,MAAA,CACX;AAAA,IACH;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,IAAI;AAAA,IAAA;AAAA,EAER;AAAA,EAEQ,+BACN,aACe;AACf,QAAI,YAAY,QAAS,QAAO,YAAY;AAC5C,gBAAY,WAAW;AACvB,gBAAY,WAAW,YAAY;AACjC,UAAI;AACF,cAAM,YAAY;AAAA,MACpB,QAAQ;AAAA,MAER;AACA,UAAI;AACF,YAAI,YAAY,aAAa;AAC3B,gBAAMG,kBAAAA,wBAAwB,YAAY,OAAO,YAAY,OAAO;AAAA,QACtE;AAAA,MACF,UAAA;AACE,YAAI,CAAC,YAAY,iBAAiB;AAChC,gBAAM,MAAM;AAAA,YACV,YAAY;AAAA,YACZ,YAAY;AAAA,YACZ,YAAY;AAAA,UAAA;AAEd,cAAI,KAAK,gCAAgC,IAAI,GAAG,MAAM,aAAa;AACjE,iBAAK,gCAAgC,IAAI,KAAK;AAAA,cAC5C,cAAc,YAAY;AAAA,cAC1B,aAAa,YAAY;AAAA,cACzB,eAAe,YAAY;AAAA,cAC3B,SAAS,YAAY;AAAA,cACrB,UAAU;AAAA,cACV,eAAe;AAAA,YAAA,CAChB;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAA;AACA,WAAO,YAAY;AAAA,EACrB;AAAA,EAEQ,uCACN,cACA,OACM;AACN,eAAW,eAAe,KAAK,gCAAgC,OAAA,GAAU;AACvE,UACE,EAAE,WAAW,gBACb,YAAY,iBAAiB,gBAC5B,SAAS,YAAY,UAAU,OAChC;AACA;AAAA,MACF;AACA,WAAK,KAAK,+BAA+B,WAAW,EAAE;AAAA,QACpD,MAAM;AAAA,MAAA;AAAA,IAEV;AAAA,EACF;AAAA,EAEQ,sCACN,cACA,OACM;AACN,eAAW,eAAe,KAAK,gCAAgC,OAAA,GAAU;AACvE,UAAI,mBAAmB,aAAa;AAClC,YACE,YAAY,iBAAiB,gBAC7B,YAAY,gBAAgB,KAAK,QACjC;AACA,eAAK,KAAK;AAAA,YACR;AAAA,YACA;AAAA,UAAA,EACA,MAAM,MAAM;AAAA,UAEd,CAAC;AAAA,QACH;AACA;AAAA,MACF;AACA,UACE,EAAE,WAAW,gBACb,YAAY,iBAAiB,gBAC7B,YAAY,gBAAgB,KAAK,UACjC,CAAC,YAAY,YACb,YAAY,iBACZ;AACA;AAAA,MACF;AAEA,WAAK,KAAK,qCAAqC,aAAa,KAAK,EAAE;AAAA,QACjE,MAAM;AAAA,MAAA;AAAA,IAEV;AAAA,EACF;AAAA,EAEA,MAAc,qCACZ,UACA,OACe;AACf,UAAM,SAAS;AACf,QACE,SAAS,mBACT,KAAK,mBAAmB,IAAI,SAAS,YAAY,MAAM,OACvD;AACA;AAAA,IACF;AAEA,UAAM,MAAM;AAAA,MACV,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,IAAA;AAEX,UAAM,UAAU,KAAK,gCAAgC,IAAI,GAAG;AAC5D,QAAI,WAAW,YAAY,UAAU;AACnC,UAAI,mBAAmB,SAAS;AAC9B,cAAM,KAAK,oCAAoC,SAAS,KAAK;AAAA,MAC/D;AACA;AAAA,IACF;AAEA,UAAM,gBAAsD;AAAA,MAC1D,cAAc,SAAS;AAAA,MACvB,aAAa,SAAS;AAAA,MACtB,eAAe,SAAS;AAAA,MACxB,SAAS,SAAS;AAAA,MAClB,UAAU;AAAA,MACV,eAAe;AAAA,IAAA;AAEjB,SAAK,gCAAgC,IAAI,KAAK,aAAa;AAC3D,UAAM,KAAK,oCAAoC,eAAe,KAAK;AAAA,EACrE;AAAA,EAEA,MAAc,oCACZ,eACA,OACe;AACf,QAAI,KAAK,mBAAmB,IAAI,cAAc,YAAY,MAAM,OAAO;AACrE;AAAA,IACF;AACA,UAAM,MAAM;AAAA,MACV,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,IAAA;AAEhB,QAAI,KAAK,gCAAgC,IAAI,GAAG,MAAM,cAAe;AAErE,UAAM,KAAK,kCAAkC;AAAA,MAC3C,cAAc,cAAc;AAAA,MAC5B,aAAa,cAAc;AAAA,MAC3B,eAAe,cAAc;AAAA,MAC7B;AAAA,MACA,SAAS,cAAc;AAAA,MACvB,6BAA6B;AAAA,IAAA,CAC9B;AAAA,EACH;AAAA,EAEA,MAAc,kCAAkC,SAO9B;AAChB,UAAM,MAAM;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA;AAEV,UAAM,cAA6C;AAAA,MACjD,cAAc,QAAQ;AAAA,MACtB,aAAa,QAAQ;AAAA,MACrB,eAAe,QAAQ;AAAA,MACvB,OAAO,QAAQ;AAAA,MACf,SAAS,QAAQ;AAAA,MACjB,MAAM,QAAQ,QAAA;AAAA,MACd,aAAa;AAAA,MACb,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,SAAS;AAAA,IAAA;AAEX,SAAK,qCAAqC,OAAO,GAAG;AACpD,SAAK,gCAAgC,IAAI,KAAK,WAAW;AACzD,QAAI;AACJ,QAAI;AACJ,gBAAY,OAAO,IAAI,QAAc,CAAC,SAAS,WAAW;AACxD,oBAAc;AACd,mBAAa;AAAA,IACf,CAAC;AACD,QAAI;AACF,YAAM,OAAO,QAAQ,MAAM,YAAY,OAAO;AAC9C,kBAAY,cAAc;AAC1B,WAAK,QAAQ,QAAQ,IAAI,EAAE,KAAK,aAAa,UAAU;AAAA,IACzD,SAAS,OAAO;AACd,iBAAW,KAAK;AAAA,IAClB;AAEA,QAAI;AACF,YAAM,YAAY;AAAA,IACpB,SAAS,OAAO;AACd,UAAI,CAAC,YAAY,aAAa;AAC5B,YAAI,KAAK,gCAAgC,IAAI,GAAG,MAAM,aAAa;AACjE,cAAI,QAAQ,6BAA6B;AACvC,iBAAK,gCAAgC;AAAA,cACnC;AAAA,cACA,QAAQ;AAAA,YAAA;AAAA,UAEZ,OAAO;AACL,iBAAK,gCAAgC,OAAO,GAAG;AAAA,UACjD;AAAA,QACF;AAAA,MACF,OAAO;AAIL,cAAM,KAAK,+BAA+B,WAAW,EAAE;AAAA,UACrD,MAAM;AAAA,QAAA;AAAA,MAEV;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAc,2BACZ,cACA,SAMsB;AACtB,UAAM,KAAK;AAAA,MAAwB;AAAA,MAAc,CAAC,YAChD,QAAQ,YAAY,cAAc,QAAQ,WAAW,QAAQ,IAAI;AAAA,IAAA;AAEnE,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,IAAI;AAAA,IAAA;AAAA,EAER;AAAA,EAEA,MAAc,0BACZ,cACA,SAMsC;AACtC,UAAM,cAAc,mBAAmB,cAAc,QAAQ,UAAU;AACvE,WAAO,KAAK,wBAAwB;AAAA,MAClC;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,eAAe,CAAC,aACd,SAAS,gBAAgB,gCACrB,SAAS,WACT;AAAA,MACN,gBAAgB,CAAC,aACf,SAAS,gBAAgB,gCACrB,SAAS,WACT;AAAA,MACN,UAAU,CAAC,WAAW;AAAA,QACpB,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,YAAY,QAAQ,UAAU,IAAI,KAAK;AAAA,MAAA;AAAA,MAEhD,OAAO,MAAM,KAAK,wBAAwB,cAAc,OAAO;AAAA,MAC/D,eAAe,CAAC,cAAc;AAAA,QAC5B,aAAa,QAAQ;AAAA,QACrB;AAAA,MAAA;AAAA,IACF,CACD;AAAA,EACH;AAAA,EAEA,MAAc,wBACZ,cACA,SACsC;AACtC,UAAM,QAAQ,KAAK,YAAY,IAAI,YAAY;AAC/C,QAAI,CAAC,SAAS,CAAC,MAAM,UAAU;AAC7B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,sBAAsB,YAAY;AAAA,MAAA;AAAA,IAE7C;AAGA,UAAM,uBAA4D,CAAA;AAClE,eAAW,YAAY,QAAQ,WAAW;AACxC,UAAI,EAAE,qBAAqB,aAAa,CAAC,SAAS,iBAAiB;AACjE;AAAA,MACF;AACA,2BAAqB;AAAA,QACnB,SAAS,aAAa,SAClB,EAAE,MAAM,UAAU,KAAK,SAAS,QAChC;AAAA,UACE,MAAM;AAAA,UACN,KAAK,SAAS;AAAA,UACd,OAAO,SAAS;AAAA,QAAA;AAAA,MAClB;AAAA,IAER;AACA,UAAM,YAAY;AAAA,MAChB,MAAMP,GAAAA,eAAA;AAAA,MACN,WAAW,QAAQ,UAAU,IAAI,CAAC,OAAO;AAAA,QACvC,MAAM,EAAE;AAAA,QACR,KAAK,EAAE;AAAA,QACP,OAAO,EAAE;AAAA,QACT,GAAI,qBAAqB,IACrB,EAAE,UAAU,EAAE,UAAU,iBAAiB,EAAE,oBAC3C,CAAA;AAAA,MAAC,EACL;AAAA,MACF;AAAA,IAAA;AAGF,UAAM,KAAK,MAAM,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,QAAI,OAAO,MAAM;AACf,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,sBAAsB,YAAY;AAAA,MAAA;AAAA,IAE7C;AAEA,UAAM,WAAwC;AAAA,MAC5C,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,IAAI;AAAA,MACJ,MAAM,GAAG;AAAA,MACT,KAAK,GAAG;AAAA,MACR,kBAAkB,GAAG;AAAA,MACrB,qBAAqB,QAAQ,UAAU,IAAI,CAAC,MAAM,EAAE,UAAU;AAAA,IAAA;AAEhE,QAAI,KAAK,gBAAgB,KAAK,YAAY,IAAI,YAAY,MAAM,OAAO;AACrE,aAAO;AAAA,IACT;AACA,SAAK,iBAAiB;AAAA,MACpB,mBAAmB,cAAc,QAAQ,UAAU;AAAA,MACnD;AAAA,QACE,WAAW,KAAK,IAAA;AAAA,QAChB,aAAa,QAAQ;AAAA,QACrB;AAAA,MAAA;AAAA,IACF;AAEF,SAAK,sBAAA;AAGL,UAAM,cAAc,QAAQ,UACzB,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,EACjC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,OAAO,EAAE,QAAQ;AAC9C,UAAM,cAAc,QAAQ,UACzB,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,EACjC,IAAI,CAAC,MAAM,EAAE,GAAG;AAEnB,UAAM,cAAyC;AAAA,MAC7C,GAAG;AAAA,MACH,QAAQ,KAAK;AAAA,MACb;AAAA,MACA,UAAU,KAAK;AAAA,MACf,IAAI,KAAK,IAAA;AAAA,MACT,SAAS;AAAA,QACP,MAAM;AAAA,QACN,MAAM,GAAG;AAAA,QACT,KAAK,GAAG;AAAA,QACR,MAAM,GAAG;AAAA,QACT,kBAAkB,GAAG;AAAA,QACrB,oBAAoB;AAAA,QACpB;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAEF,SAAK,QAAQ,YAAY,WAAW;AAGpC,eAAW,cAAc,MAAM,aAAa;AAC1C,iBAAW,WAAW;AAAA,IACxB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,uBACZ,cACA,SACA,eACmC;AACnC,UAAM,cAAc,mBAAmB,cAAc,QAAQ,UAAU;AACvE,WAAO,KAAK,wBAAwB;AAAA,MAClC;AAAA,MACA,OAAO,QAAQ;AAAA,MACf,eAAe,CAAC,aACd,SAAS,gBAAgB,6BACrB,SAAS,WACT;AAAA,MACN,gBAAgB,CAAC,aACf,SAAS,gBAAgB,6BACrB,SAAS,WACT;AAAA,MACN,UAAU,CAAC,WAAW;AAAA,QACpB,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,YAAY,QAAQ,UAAU,IAAI,KAAK;AAAA,MAAA;AAAA,MAEhD,OAAO,MACL,KAAK,qBAAqB,cAAc,SAAS,aAAa;AAAA,MAChE,eAAe,CAAC,cAAc;AAAA,QAC5B,aAAa,QAAQ;AAAA,QACrB;AAAA,MAAA;AAAA,IACF,CACD;AAAA,EACH;AAAA,EAEA,MAAc,wBAEZ,SAUqB;AACrB,UAAM,kBAAkB,KAAK,iBAAiB,IAAI,QAAQ,WAAW;AACrE,QAAI,iBAAiB;AACnB,YAAMQ,YAAW,QAAQ,cAAc,eAAe;AACtD,aAAOA,YACH,EAAE,GAAGA,WAAU,OAAO,QAAQ,MAAA,IAC9B,QAAQ,SAAS,iBAAiB;AAAA,IACxC;AAEA,UAAM,mBAAmB,KAAK,kBAAkB,IAAI,QAAQ,WAAW;AACvE,QAAI,kBAAkB;AACpB,YAAM,UAAU,QAAQ,eAAe,gBAAgB;AACvD,UAAI,CAAC,QAAS,QAAO,QAAQ,SAAS,sBAAsB;AAC5D,YAAMA,YAAW,MAAM;AACvB,aAAO,EAAE,GAAGA,WAAU,OAAO,QAAQ,MAAA;AAAA,IACvC;AAEA,UAAM,WAAW,QAAQ,MAAA;AACzB,UAAM,kBAAkB,QAAQ,cAAc,QAAQ;AACtD,SAAK,kBAAkB,IAAI,QAAQ,aAAa,eAAe;AAC/D,QAAI;AACF,aAAO,MAAM;AAAA,IACf,UAAA;AACE,UAAI,KAAK,kBAAkB,IAAI,QAAQ,WAAW,MAAM,iBAAiB;AACvE,aAAK,kBAAkB,OAAO,QAAQ,WAAW;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,qBACZ,cACA,SACA,eACmC;AACnC,UAAM,QAAQ,KAAK,YAAY,IAAI,YAAY;AAC/C,QAAI,CAAC,SAAS,CAAC,MAAM,UAAU;AAC7B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,sBAAsB,YAAY;AAAA,MAAA;AAAA,IAE7C;AAEA,UAAM,KAAK,MAAM,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,IAAA;AAEF,QAAI,OAAO,MAAM;AACf,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO,sBAAsB,YAAY;AAAA,MAAA;AAAA,IAE7C;AACA,UAAM,WAAqC;AAAA,MACzC,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,IAAI;AAAA,MACJ,MAAM,GAAG;AAAA,MACT,KAAK,GAAG;AAAA,MACR,kBAAkB,GAAG;AAAA,IAAA;AAEvB,QAAI,KAAK,gBAAgB,KAAK,YAAY,IAAI,YAAY,MAAM,OAAO;AACrE,aAAO;AAAA,IACT;AACA,SAAK,iBAAiB;AAAA,MACpB,mBAAmB,cAAc,QAAQ,UAAU;AAAA,MACnD;AAAA,QACE,WAAW,KAAK,IAAA;AAAA,QAChB,aAAa,QAAQ;AAAA,QACrB;AAAA,MAAA;AAAA,IACF;AAEF,SAAK,sBAAA;AAEL,UAAM,gBAAgB;AAAA,MACpB,MAAM;AAAA,MACN,MAAM,GAAG;AAAA,MACT,KAAK,GAAG;AAAA,MACR,MAAM,GAAG;AAAA,MACT,kBAAkB,GAAG;AAAA,IAAA;AAEvB,UAAM,mBAAgC,GAAG,WACrC;AAAA,MACE,GAAG;AAAA,MACH,oBAAoB;AAAA,IAAA,IAEtB;AAAA,MACE,GAAG;AAAA,MACH,oBAAoB;AAAA,MACpB,aAAa,GAAG,UACb,OAAO,CAAC,aAAa,SAAS,SAAS,QAAQ,EAC/C,IAAI,CAAC,cAAc;AAAA,QAClB,KAAK,SAAS;AAAA,QACd,OAAO,SAAS;AAAA,MAAA,EAChB;AAAA,MACJ,aAAa,GAAG,UACb,OAAO,CAAC,aAAa,SAAS,SAAS,QAAQ,EAC/C,IAAI,CAAC,aAAa,SAAS,GAAG;AAAA,MACjC,sBAAsB,GAAG;AAAA,MACzB,6BAA6B,GAAG;AAAA,IAAA;AAEtC,UAAM,YAA2C;AAAA,MAC/C,GAAG;AAAA,MACH,QAAQ,KAAK;AAAA,MACb;AAAA,MACA,UAAU,KAAK;AAAA,MACf,IAAI,KAAK,IAAA;AAAA,MACT,SAAS;AAAA,IAAA;AAEX,SAAK,QAAQ,YAAY,SAAS;AAClC,eAAW,cAAc,MAAM,aAAa;AAC1C,iBAAW,SAAS;AAAA,IACtB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,iCACZ,cACA,OACA,WACA,eAC6B;AAC7B,UAAM,eAAe,MAAM;AAC3B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,OAAO,YAAY;AACjB,YACE,KAAK,gBACL,KAAK,YAAY,IAAI,YAAY,MAAM,SACvC,CAAC,MAAM,YACP,MAAM,aAAa,KAAK,UACxB,MAAM,eAAe,cACrB;AACA,iBAAO;AAAA,QACT;AACA,cAAM,KAAkB;AAAA,UACtB,GAAG;AAAA,UACH,MAAM,MAAM;AAAA,UACZ,KAAK,MAAM,YAAY;AAAA,UACvB,YAAY,MAAM,mBAAmB;AAAA,QAAA;AAEvC,YAAI;AACF,gBAAM,QAAQ,iBAAiB,cAAc,EAAE;AAAA,QACjD,SAAS,OAAO;AACd,gBAAMC,OAAAA,qCAAqC,cAAc,KAAK;AAAA,QAChE;AACA,cAAM,YAAY,GAAG;AACrB,cAAM,mBAAmB,GAAG;AAC5B,eAAO;AAAA,MACT;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,MAAc,gBACZ,cACA,SAKA,eAC4B;AAC5B,UAAM,QAAQ,KAAK,YAAY,IAAI,YAAY;AAE/C,UAAM,UAAU,iBAAiB,KAAK,eAAe,YAAY;AACjE,QAAI,CAAC,QAAQ,WAAW;AACtB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,YAAY,OAAO,cAAc;AAAA,QACjC,WAAW,OAAO,aAAa;AAAA,QAC/B,kBAAkB,OAAO,oBAAoB;AAAA,QAC7C,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,SAAS,MAAM,QAAQ,UAAU,cAAc,QAAQ,cAAc;AAE3E,QAAI,OAAO,oBAAoB;AAC7B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,YAAY,OAAO,cAAc;AAAA,QACjC,WAAW,OAAO,aAAa;AAAA,QAC/B,kBAAkB,OAAO;AAAA,QACzB,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,QAAQ;AAAA,MACf,IAAI;AAAA,MACJ,YAAY,OAAO,cAAc;AAAA,MACjC,WAAW,OAAO,aAAa;AAAA,MAC/B,kBAAkB,OAAO;AAAA,MACzB,oBAAoB;AAAA,MACpB,aAAa,OAAO;AAAA,MACpB,aAAa,OAAO;AAAA,IAAA;AAAA,EAExB;AAAA;AAAA;AAAA;AAAA,EAMQ,wBACN,cACA,MACA,eACY;AACZ,QAAI,eAAe;AACjB,aAAO,KAAK,eAAe,MAAM,KAAK,aAAa,CAAC;AAAA,IACtD;AAGA,UAAM,UAAU,KAAK,eAAe,YAAY;AAChD,WAAO,QAAQ,oBACX,QAAQ;AAAA,MAAkB,CAAC,uBACzB,KAAK,eAAe,MAAM,KAAK,kBAAkB,CAAC;AAAA,IAAA,IAEpD,KAAK,eAAe,MAAM,KAAK,OAAO,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAc,eAAkB,IAAkC;AAChE,UAAM,WAAW,eAAe,KAAK,MAAM;AAE3C,aAAS,UAAU,GAAG,WAAW,yBAAyB,WAAW;AACnE,YAAM,gBAAgB,EAAE,SAAS,MAAA;AACjC,UAAI;AACF,eAAO,MAAM,UAAU,MAAM,QAAQ,UAAU,YAAY;AACzD,wBAAc,UAAU;AACxB,iBAAO,GAAA;AAAA,QACT,CAAC;AAAA,MACH,SAAS,OAAO;AACd,YAAI,cAAc,SAAS;AACzB,gBAAM;AAAA,QACR;AACA,YAAI,iBAAiB,gBAAgB,MAAM,SAAS,cAAc;AAChE,gBAAM;AAAA,QACR;AAEA,YAAI,UAAU,yBAAyB;AACrC,gBAAM,MAAM,4BAA4B,KAAK,IAAI,UAAU,GAAG,CAAC,CAAC;AAChE;AAAA,QACF;AAEA,cAAM;AAAA,MACR;AAAA,IACF;AAGA,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAMQ,wBAA8B;AACpC,QAAI,KAAK,8BAA8B,MAAM;AAC3C,mBAAa,KAAK,yBAAyB;AAC3C,WAAK,4BAA4B;AAAA,IACnC;AACA,UAAM,SAAS,KAAK,IAAA,IAAQ;AAC5B,eAAW,CAAC,KAAK,QAAQ,KAAK,KAAK,kBAAkB;AACnD,UAAI,SAAS,aAAa,QAAQ;AAChC,aAAK,iBAAiB,OAAO,GAAG;AAAA,MAClC;AAAA,IACF;AACA,QAAI,KAAK,YAAY,KAAK,iBAAiB,SAAS,EAAG;AAEvD,QAAI,oBAAoB,OAAO;AAC/B,eAAW,YAAY,KAAK,iBAAiB,OAAA,GAAU;AACrD,0BAAoB,KAAK,IAAI,mBAAmB,SAAS,SAAS;AAAA,IACpE;AACA,UAAM,QAAQ,KAAK;AAAA,MACjB;AAAA,MACA,oBAAoB,0BAA0B,KAAK,IAAA;AAAA,IAAI;AAEzD,SAAK,4BAA4B,WAAW,MAAM;AAChD,WAAK,4BAA4B;AACjC,WAAK,sBAAA;AAAA,IACP,GAAG,KAAK;AAAA,EACV;AAAA,EAEQ,mCACN,KACA,aACM;AACN,SAAK,gCAAgC,IAAI,KAAK,WAAW;AACzD,SAAK,qCAAqC,IAAI,KAAK,KAAK,KAAK;AAAA,EAC/D;AAAA,EAEQ,wCAA8C;AACpD,UAAM,SAAS,KAAK,IAAA,IAAQ;AAC5B,eAAW,CAAC,KAAK,UAAU,KAAK,KAAK,sCAAsC;AACzE,UAAI,aAAa,QAAQ;AACvB,aAAK,qCAAqC,OAAO,GAAG;AACpD,aAAK,gCAAgC,OAAO,GAAG;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,mBAAmB,MAAkD;AAC5E,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAC9C,QAAM,SAAS;AACf,SACE,OAAO,MAAM,KACb,OAAO,OAAO,WAAW,YACzB,OAAO,OAAO,iBAAiB,YAC/B,OAAO,OAAO,aAAa,YAC3B,OAAO,OAAO,OAAO;AAEzB;AAEA,SAAS,aAAa,SAAyC;AAC7D,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,UAAS,QAA+B,MAAA;AAAA,IACtC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEA,SAAS,mBAAmB,cAAsB,YAA4B;AAC5E,SAAO,KAAK,UAAU,CAAC,cAAc,UAAU,CAAC;AAClD;AAEA,SAAS,2BACP,cACA,eACQ;AACR,SAAO,KAAK,UAAU,CAAC,cAAc,aAAa,CAAC;AACrD;AAEA,SAAS,kCACP,cACA,aACA,eACQ;AACR,SAAO,KAAK,UAAU,CAAC,cAAc,aAAa,aAAa,CAAC;AAClE;AAEA,SAAS,uBACP,SACA,OACa;AACb,QAAM,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACnE,UAAQ,QAAQ,MAAA;AAAA,IACd,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ;AAAA,QACA,GAAI,iBAAiBL,OAAAA,wCACjB,EAAE,WAAW,KAAA,IACb,CAAA;AAAA,MAAC;AAAA,IAET,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ,KAAK;AACH,UAAI,iBAAiBM,OAAAA,oCAAoC;AACvD,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,QAAQ;AAAA,UACf,IAAI;AAAA,UACJ,MAAM;AAAA,UACN;AAAA,UACA,GAAG,wBAAwB,KAAK;AAAA,QAAA;AAAA,MAEpC;AACA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,MAAA;AAAA,IAEJ,KAAK;AACH,UAAI,iBAAiBA,OAAAA,oCAAoC;AACvD,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO,QAAQ;AAAA,UACf,IAAI;AAAA,UACJ,MAAM;AAAA,UACN;AAAA,UACA,GAAG,wBAAwB,KAAK;AAAA,QAAA;AAAA,MAEpC;AACA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,MAAA;AAAA,IAEJ,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,QAAQ;AAAA,QACf,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,EACF;AAEN;AAEA,SAAS,qBAAqB,SAK5B;AACA,SACE,QAAQ,SAAS,iCACjB,QAAQ,SAAS;AAErB;AAEA,SAAS,wBAAwB,OAG/B;AACA,QAAM,aACJ,OAAO,MAAM,SAAS,YAAY,OAAO,MAAM,SAAS,WACpD,MAAM,OACN;AACN,QAAM,OACJ,OAAO,MAAM,SAAS,YACrB,MAAM,QAAQ,MAAM,IAAI,KACvB,MAAM,KAAK;AAAA,IACT,CAAC,SAAS,OAAO,SAAS,YAAY,OAAO,SAAS;AAAA,EAAA,IAErD,MAAM,OACP;AACN,SAAO;AAAA,IACL,GAAI,eAAe,SAAY,CAAA,IAAK,EAAE,WAAA;AAAA,IACtC,GAAI,SAAS,SAAY,CAAA,IAAK,EAAE,KAAA;AAAA,EAAK;AAEzC;;"}
|
|
1
|
+
{"version":3,"file":"broadcast-coordinator.cjs","sources":["../../src/broadcast-coordinator.ts"],"sourcesContent":["import { safeRandomUUID } from '@tanstack/db'\nimport { isValidCommittedTxAnchor } from './committed-tx-anchor'\nimport {\n DuplicateRemoteSubsetOwnerError,\n IndeterminateCommitError,\n InvalidPersistenceAdapterError,\n PersistedCollectionDurabilityError,\n RetryableRemoteSubsetAcquisitionError,\n toPersistedCollectionDurabilityError,\n} from './errors'\nimport {\n toProcessLocalLoadSubsetOptions,\n toTransportedLoadSubsetOptions,\n} from './remote-subset-wire'\nimport { unloadRemoteSubsetOwner } from './remote-subset-owner'\nimport type { LoadSubsetOptions } from '@tanstack/db'\nimport type { IndeterminateCommitRequestType } from './errors'\nimport type { TransportedLoadSubsetOptions } from './remote-subset-wire'\nimport type { RemoteSubsetOwner } from './remote-subset-owner'\nimport type {\n ApplyCommittedTxResponse,\n ApplyLocalMutationsResponse,\n CommittedTxAnchor,\n EnsureRemoteSubsetRequest,\n EnsureRemoteSubsetResponse,\n HydrationPersistenceAdapter,\n PersistedCollectionCoordinator,\n PersistedIndexSpec,\n PersistedMutationEnvelope,\n PersistedRowMetadataMutation,\n PersistedTx,\n PersistenceAdapter,\n ProtocolEnvelope,\n PullSinceResponse,\n ReconcileCommittedTxResponse,\n ReleaseRemoteSubsetRequest,\n ReleaseRemoteSubsetResponse,\n TxCommitted,\n} from './persisted'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst HEARTBEAT_INTERVAL_MS = 3_000\nconst LEADERSHIP_RETRY_DELAY_MS = 200\nconst RPC_TIMEOUT_MS = 10_000\nconst RPC_RETRY_ATTEMPTS = 2\nconst RPC_RETRY_DELAY_MS = 200\nconst REMOTE_SUBSET_REPLAY_RETRY_ATTEMPTS = 2\nconst RPC_DEDUPE_RETENTION_MS = 60_000\nconst WRITER_LOCK_BUSY_RETRY_MS = 50\nconst WRITER_LOCK_MAX_RETRIES = 20\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ntype RPCRequest =\n | EnsureRemoteSubsetRequest\n | ReleaseRemoteSubsetRequest\n | {\n type: `rpc:ensurePersistedIndex:req`\n rpcId: string\n signature: string\n spec: PersistedIndexSpec\n }\n | {\n type: `rpc:applyLocalMutations:req`\n rpcId: string\n envelopeId: string\n mutations: Array<PersistedMutationEnvelope>\n }\n | {\n type: `rpc:applyCommittedTx:req`\n rpcId: string\n envelopeId: string\n tx: PersistedTx\n }\n | {\n type: `rpc:reconcileCommittedTx:req`\n rpcId: string\n tx: PersistedTx\n anchor: CommittedTxAnchor\n }\n | {\n type: `rpc:pullSince:req`\n rpcId: string\n fromRowVersion: number\n }\n\ntype RPCResponse =\n | EnsureRemoteSubsetResponse\n | ReleaseRemoteSubsetResponse\n | {\n type: `rpc:ensurePersistedIndex:res`\n rpcId: string\n ok: boolean\n error?: string\n }\n | ApplyLocalMutationsResponse\n | ApplyCommittedTxResponse\n | ReconcileCommittedTxResponse\n | PullSinceResponse\n\ntype PendingRPC = {\n resolve: (response: RPCResponse) => void\n reject: (error: Error) => void\n timer: ReturnType<typeof setTimeout>\n}\n\ntype CollectionState = {\n participatesInLeadership: boolean\n isLeader: boolean\n leaderId: string | null\n lockAbortController: AbortController | null\n heartbeatTimer: ReturnType<typeof setInterval> | null\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n subscribers: Set<(message: ProtocolEnvelope<unknown>) => void>\n routeWaiters?: Set<() => void>\n}\n\n// Adapter capabilities used by coordinator-side operations. Resume snapshots\n// belong to the persisted sync wrapper, not the elected writer transport.\ntype CoordinatorAdapter = Pick<\n PersistenceAdapter,\n | `loadSubset`\n | `applyCommittedTx`\n | `reconcileCommittedTx`\n | `ensureIndex`\n | `runInRegularScope`\n> & {\n pullSince?: (\n collectionId: string,\n fromRowVersion: number,\n ) => Promise<\n | {\n latestRowVersion: number\n requiresFullReload: true\n }\n | {\n latestRowVersion: number\n requiresFullReload: false\n changedKeys: Array<string | number>\n deletedKeys: Array<string | number>\n }\n >\n getStreamPosition?: (collectionId: string) => Promise<{\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n }>\n reserveLeadershipTerm?: (\n collectionId: string,\n observedTerm: number,\n ) => Promise<{\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n }>\n}\n\nfunction requireDurableElection(adapter: CoordinatorAdapter): void {\n if (typeof adapter.reserveLeadershipTerm !== `function`) {\n throw new InvalidPersistenceAdapterError(`reserveLeadershipTerm`)\n }\n}\n\ntype ActiveRemoteSubsetAcquisition = {\n collectionId: string\n requesterId: string\n acquisitionId: string\n owner: RemoteSubsetOwner\n options: TransportedLoadSubsetOptions\n load: Promise<void>\n transferred: boolean\n released: boolean\n terminalRelease: boolean\n release: Promise<void> | null\n}\n\ntype AwaitingRemoteSubsetOwnerAcquisition = {\n collectionId: string\n requesterId: string\n acquisitionId: string\n options: TransportedLoadSubsetOptions\n released: true\n awaitingOwner: true\n}\n\ntype RemoteSubsetAcquisition =\n | ActiveRemoteSubsetAcquisition\n | AwaitingRemoteSubsetOwnerAcquisition\n | {\n collectionId: string\n requesterId: string\n acquisitionId: string\n released: true\n }\n\ntype OutboundRemoteSubsetAcquisition = {\n collectionId: string\n acquisitionId: string\n options: TransportedLoadSubsetOptions\n localOptions: TransportedLoadSubsetOptions &\n Pick<LoadSubsetOptions, `signal` | `subscription`>\n acquiredLeaderId: string | null\n inFlight: Promise<void> | null\n release: Promise<void> | null\n releaseRequested?: boolean\n forceReplay: boolean\n retryTimer: ReturnType<typeof setTimeout> | null\n retryAttempts: number\n}\n\ntype AppliedEnvelope =\n | {\n appliedAt: number\n requestType: `rpc:applyLocalMutations:req`\n response: ApplyLocalMutationsResponse\n }\n | {\n appliedAt: number\n requestType: `rpc:applyCommittedTx:req`\n response: ApplyCommittedTxResponse\n }\n\ntype InFlightEnvelope =\n | {\n requestType: `rpc:applyLocalMutations:req`\n response: Promise<ApplyLocalMutationsResponse>\n }\n | {\n requestType: `rpc:applyCommittedTx:req`\n response: Promise<ApplyCommittedTxResponse>\n }\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/** @internal Shared by the Browser and Electron persistence hosts. */\nexport type BroadcastCollectionCoordinatorOptions = {\n dbName: string\n adapter?: CoordinatorAdapter\n coordinatorName: string\n}\n\n// ---------------------------------------------------------------------------\n// BroadcastCollectionCoordinator\n// ---------------------------------------------------------------------------\n\n/** @internal Shared coordination engine for BroadcastChannel/Web Locks hosts. */\nexport class BroadcastCollectionCoordinator implements PersistedCollectionCoordinator {\n private readonly nodeId = safeRandomUUID()\n private readonly dbName: string\n private readonly coordinatorName: string\n private defaultAdapter: CoordinatorAdapter | null\n private readonly collectionAdapters = new Map<string, CoordinatorAdapter>()\n private readonly remoteSubsetOwners = new Map<string, RemoteSubsetOwner>()\n private readonly remoteSubsetIds = new Map<\n string,\n WeakMap<LoadSubsetOptions, string>\n >()\n private readonly outboundRemoteSubsetAcquisitions = new Map<\n string,\n OutboundRemoteSubsetAcquisition\n >()\n private readonly inboundRemoteSubsetAcquisitions = new Map<\n string,\n RemoteSubsetAcquisition\n >()\n private readonly releasedRemoteSubsetAcquisitionTimes = new Map<\n string,\n number\n >()\n private readonly channel: BroadcastChannel\n private readonly collections = new Map<string, CollectionState>()\n private readonly pendingRPCs = new Map<string, PendingRPC>()\n private readonly appliedEnvelopes = new Map<string, AppliedEnvelope>()\n private readonly inFlightEnvelopes = new Map<string, InFlightEnvelope>()\n private appliedEnvelopePruneTimer: ReturnType<typeof setTimeout> | null = null\n private rejectDisposed: ((error: Error) => void) | null = null\n private readonly disposedPromise: Promise<never>\n private disposed = false\n\n /** Method indirection to prevent TypeScript from narrowing `disposed` across awaits */\n private isDisposed(): boolean {\n return this.disposed\n }\n\n /** Method indirection to re-read leadership participation across awaits. */\n private participatesInLeadership(state: CollectionState): boolean {\n return state.participatesInLeadership\n }\n\n private requireAdapter(collectionId: string): CoordinatorAdapter {\n let adapter = this.collectionAdapters.get(collectionId)\n if (!adapter && this.defaultAdapter) {\n adapter = this.defaultAdapter\n this.collectionAdapters.set(collectionId, adapter)\n }\n if (!adapter) {\n throw new Error(\n `${this.coordinatorName}: adapter not set for collection \"${collectionId}\". Call setAdapterForCollection() before using leader-side operations.`,\n )\n }\n return adapter\n }\n\n constructor(options: BroadcastCollectionCoordinatorOptions) {\n if (options.adapter) requireDurableElection(options.adapter)\n this.dbName = options.dbName\n this.coordinatorName = options.coordinatorName\n this.defaultAdapter = options.adapter ?? null\n this.channel = new BroadcastChannel(`tsdb:coord:${this.dbName}`)\n this.channel.onmessage = (event: MessageEvent) => {\n this.onChannelMessage(event.data)\n }\n this.disposedPromise = new Promise<never>((_resolve, reject) => {\n this.rejectDisposed = reject\n })\n void this.disposedPromise.catch(() => undefined)\n }\n\n /**\n * Set or replace the persistence adapter used for leader-side RPC handling.\n * Called by a host persistence factory to wire the internally-created adapter.\n */\n setAdapter(adapter: CoordinatorAdapter): void {\n requireDurableElection(adapter)\n this.defaultAdapter = adapter\n }\n\n /** Register the persistence adapter that owns one collection. */\n setAdapterForCollection(\n collectionId: string,\n adapter: CoordinatorAdapter,\n ): void {\n requireDurableElection(adapter)\n this.collectionAdapters.set(collectionId, adapter)\n }\n\n registerRemoteSubsetOwner(\n collectionId: string,\n owner: RemoteSubsetOwner,\n ): () => void {\n if (this.remoteSubsetOwners.has(collectionId)) {\n throw new DuplicateRemoteSubsetOwnerError(collectionId)\n }\n this.remoteSubsetOwners.set(collectionId, owner)\n for (const acquisition of this.outboundRemoteSubsetAcquisitions.values()) {\n if (acquisition.collectionId !== collectionId) continue\n acquisition.acquiredLeaderId = null\n acquisition.forceReplay = true\n }\n void this.replayRemoteSubsetAcquisitions(collectionId)\n this.rebindRemoteInboundSubsetAcquisitions(collectionId, owner)\n return () => {\n if (this.remoteSubsetOwners.get(collectionId) !== owner) return\n this.remoteSubsetOwners.delete(collectionId)\n this.releaseInboundRemoteSubsetAcquisitions(collectionId, owner)\n }\n }\n\n // -----------------------------------------------------------------------\n // PersistedCollectionCoordinator interface\n // -----------------------------------------------------------------------\n\n getNodeId(): string {\n return this.nodeId\n }\n\n subscribe(\n collectionId: string,\n onMessage: (message: ProtocolEnvelope<unknown>) => void,\n ): () => void {\n const state = this.ensureCollectionState(collectionId)\n state.subscribers.add(onMessage)\n return () => {\n state.subscribers.delete(onMessage)\n if (state.subscribers.size === 0) {\n state.participatesInLeadership = false\n this.releaseCollectionIfUnused(collectionId, state)\n }\n }\n }\n\n publish(_collectionId: string, message: ProtocolEnvelope<unknown>): void {\n this.channel.postMessage(message)\n }\n\n isLeader(collectionId: string): boolean {\n return this.collections.get(collectionId)?.isLeader ?? false\n }\n\n async ensureLeadership(collectionId: string): Promise<void> {\n const state = this.ensureCollectionState(collectionId)\n if (state.isLeader) return\n await this.acquireLeadership(collectionId, state)\n }\n\n async requestEnsureRemoteSubset(\n collectionId: string,\n options: LoadSubsetOptions,\n ): Promise<void> {\n const transportedOptions = toTransportedLoadSubsetOptions(options)\n const localOptions = toProcessLocalLoadSubsetOptions(\n options,\n transportedOptions,\n )\n let collectionIds = this.remoteSubsetIds.get(collectionId)\n if (!collectionIds) {\n collectionIds = new WeakMap()\n this.remoteSubsetIds.set(collectionId, collectionIds)\n }\n let acquisitionId = collectionIds.get(options)\n let acquisition = acquisitionId\n ? this.outboundRemoteSubsetAcquisitions.get(\n remoteSubsetAcquisitionKey(collectionId, acquisitionId),\n )\n : undefined\n if (!acquisition) {\n acquisitionId = safeRandomUUID()\n collectionIds.set(options, acquisitionId)\n acquisition = {\n collectionId,\n acquisitionId,\n options: transportedOptions,\n localOptions,\n acquiredLeaderId: null,\n inFlight: null,\n release: null,\n releaseRequested: false,\n forceReplay: false,\n retryTimer: null,\n retryAttempts: 0,\n }\n this.outboundRemoteSubsetAcquisitions.set(\n remoteSubsetAcquisitionKey(collectionId, acquisitionId),\n acquisition,\n )\n }\n\n try {\n await this.acquireRemoteSubset(acquisition)\n } catch (error) {\n if (options.signal?.aborted) {\n acquisition.releaseRequested = true\n this.cancelRemoteSubsetReplayRetry(acquisition)\n // The route-pending case owns no lease, while a concurrent response\n // loss may have reached an owner. A best-effort terminal release is\n // harmless for the former and prevents an orphan in the latter.\n this.postRemoteSubsetRelease(acquisition)\n const key = remoteSubsetAcquisitionKey(\n collectionId,\n acquisition.acquisitionId,\n )\n if (this.outboundRemoteSubsetAcquisitions.get(key) === acquisition) {\n this.outboundRemoteSubsetAcquisitions.delete(key)\n collectionIds.delete(options)\n }\n }\n throw error\n }\n }\n\n async requestReleaseRemoteSubset(\n collectionId: string,\n options: LoadSubsetOptions,\n ): Promise<void> {\n const collectionIds = this.remoteSubsetIds.get(collectionId)\n const acquisitionId = collectionIds?.get(options)\n if (!acquisitionId) return\n const key = remoteSubsetAcquisitionKey(collectionId, acquisitionId)\n const acquisition = this.outboundRemoteSubsetAcquisitions.get(key)\n if (!acquisition) return\n acquisition.releaseRequested = true\n this.cancelRemoteSubsetReplayRetry(acquisition)\n if (!acquisition.release) {\n acquisition.release = (async () => {\n const request: Extract<\n RPCRequest,\n { type: `rpc:releaseRemoteSubset:req` }\n > = {\n type: `rpc:releaseRemoteSubset:req`,\n rpcId: safeRandomUUID(),\n acquisitionId,\n }\n const localLeader = this.isLeader(collectionId)\n let releaseReachedLeader = localLeader\n try {\n const response = localLeader\n ? await this.handleReleaseRemoteSubset(\n collectionId,\n request,\n this.nodeId,\n )\n : await this.sendRPC<ReleaseRemoteSubsetResponse>(\n collectionId,\n request,\n )\n releaseReachedLeader = true\n if (!response.ok) {\n throw new Error(`releaseRemoteSubset failed: ${response.error}`)\n }\n } finally {\n // A response (including an owner unload failure) proves that the\n // release reached the leader. Logical demand then retires exactly\n // once. Only a transport failure with no response retains retry\n // debt because delivery remains unknown.\n if (\n releaseReachedLeader &&\n this.outboundRemoteSubsetAcquisitions.get(key) === acquisition\n ) {\n this.outboundRemoteSubsetAcquisitions.delete(key)\n collectionIds!.delete(options)\n }\n }\n })()\n }\n try {\n await acquisition.release\n } finally {\n acquisition.release = null\n }\n }\n\n private async acquireRemoteSubset(\n acquisition: OutboundRemoteSubsetAcquisition,\n ): Promise<void> {\n if (acquisition.inFlight) return acquisition.inFlight\n\n const route = { localOwner: false }\n let resolveWork!: () => void\n let rejectWork!: (error: unknown) => void\n const work = new Promise<void>((resolve, reject) => {\n resolveWork = resolve\n rejectWork = reject\n })\n acquisition.inFlight = work\n const run = async (): Promise<void> => {\n const request: Extract<\n RPCRequest,\n { type: `rpc:ensureRemoteSubset:req` }\n > = {\n type: `rpc:ensureRemoteSubset:req`,\n rpcId: safeRandomUUID(),\n acquisitionId: acquisition.acquisitionId,\n options: acquisition.options,\n }\n const state = this.collections.get(acquisition.collectionId)\n if (\n state?.participatesInLeadership &&\n !state.isLeader &&\n state.leaderId === null\n ) {\n await this.waitForLeadershipRoute(\n acquisition.collectionId,\n state,\n acquisition.localOptions.signal,\n )\n }\n route.localOwner = this.isLeader(acquisition.collectionId)\n let response: EnsureRemoteSubsetResponse\n try {\n response = route.localOwner\n ? await this.handleEnsureRemoteSubset(\n acquisition.collectionId,\n request,\n this.nodeId,\n acquisition.localOptions,\n )\n : await this.sendRPC<EnsureRemoteSubsetResponse>(\n acquisition.collectionId,\n request,\n )\n } catch (error) {\n if (\n route.localOwner ||\n error instanceof RetryableRemoteSubsetAcquisitionError\n ) {\n throw error\n }\n throw new RetryableRemoteSubsetAcquisitionError(\n `Remote subset transport failed`,\n error,\n )\n }\n\n if (!response.ok) {\n if (response.retryable) {\n throw new RetryableRemoteSubsetAcquisitionError(response.error)\n }\n throw new Error(`ensureRemoteSubset failed: ${response.error}`)\n }\n acquisition.acquiredLeaderId = response.leaderId\n }\n void run().then(resolveWork, rejectWork)\n let acquired = false\n try {\n await work\n acquired = true\n this.cancelRemoteSubsetReplayRetry(acquisition)\n } finally {\n if (acquisition.inFlight === work) acquisition.inFlight = null\n const current = this.collections.get(acquisition.collectionId)\n const currentLeaderId = current?.isLeader\n ? this.nodeId\n : (current?.leaderId ?? null)\n const key = remoteSubsetAcquisitionKey(\n acquisition.collectionId,\n acquisition.acquisitionId,\n )\n if (\n acquired &&\n !acquisition.releaseRequested &&\n this.outboundRemoteSubsetAcquisitions.get(key) === acquisition &&\n (acquisition.forceReplay ||\n (currentLeaderId !== null &&\n acquisition.acquiredLeaderId !== currentLeaderId))\n ) {\n acquisition.forceReplay = false\n void this.acquireRemoteSubset(acquisition).catch((error) => {\n this.scheduleRemoteSubsetReplayRetry(acquisition, error)\n })\n }\n }\n }\n\n async requestEnsurePersistedIndex(\n collectionId: string,\n signature: string,\n spec: PersistedIndexSpec,\n scopedAdapter?: HydrationPersistenceAdapter,\n localEnsureCompleted = false,\n ): Promise<void> {\n if (this.isLeader(collectionId)) {\n if (localEnsureCompleted) return\n await (scopedAdapter ?? this.requireAdapter(collectionId)).ensureIndex(\n collectionId,\n signature,\n spec,\n )\n return\n }\n\n const response = await this.sendRPC<{\n type: `rpc:ensurePersistedIndex:res`\n rpcId: string\n ok: boolean\n error?: string\n }>(collectionId, {\n type: `rpc:ensurePersistedIndex:req`,\n rpcId: safeRandomUUID(),\n signature,\n spec,\n })\n\n if (!response.ok) {\n throw new Error(\n `ensurePersistedIndex failed: ${response.error ?? `unknown error`}`,\n )\n }\n }\n\n async requestApplyLocalMutations(\n collectionId: string,\n mutations: Array<PersistedMutationEnvelope>,\n ): Promise<ApplyLocalMutationsResponse> {\n const initialRoute = this.waitForInitialRoute(collectionId)\n if (initialRoute) await initialRoute\n if (this.isLeader(collectionId)) {\n return this.handleApplyLocalMutations(collectionId, {\n type: `rpc:applyLocalMutations:req`,\n rpcId: safeRandomUUID(),\n envelopeId: safeRandomUUID(),\n mutations,\n })\n }\n\n return this.sendRPC<ApplyLocalMutationsResponse>(collectionId, {\n type: `rpc:applyLocalMutations:req`,\n rpcId: safeRandomUUID(),\n envelopeId: safeRandomUUID(),\n mutations,\n })\n }\n\n async requestApplyCommittedTx(\n collectionId: string,\n tx: PersistedTx,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<ApplyCommittedTxResponse> {\n const initialRoute = this.waitForInitialRoute(collectionId)\n if (initialRoute) await initialRoute\n const request: Extract<RPCRequest, { type: `rpc:applyCommittedTx:req` }> = {\n type: `rpc:applyCommittedTx:req`,\n rpcId: safeRandomUUID(),\n envelopeId: safeRandomUUID(),\n tx,\n }\n if (this.isLeader(collectionId)) {\n return this.handleApplyCommittedTx(collectionId, request, scopedAdapter)\n }\n\n return this.sendRPC<ApplyCommittedTxResponse>(collectionId, request)\n }\n\n async reconcileCommittedTx(\n collectionId: string,\n tx: PersistedTx,\n anchor: CommittedTxAnchor,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<ReconcileCommittedTxResponse> {\n const initialRoute = this.waitForInitialRoute(collectionId)\n if (initialRoute) await initialRoute\n // Each attempt checks the exact txId under the elected writer lock, so a\n // stale NOT_LEADER reply can follow the replacement route safely.\n let response: ReconcileCommittedTxResponse | undefined\n for (let attempt = 0; attempt <= RPC_RETRY_ATTEMPTS; attempt++) {\n if (attempt > 0) await sleep(RPC_RETRY_DELAY_MS * attempt)\n const request: Extract<\n RPCRequest,\n { type: `rpc:reconcileCommittedTx:req` }\n > = {\n type: `rpc:reconcileCommittedTx:req`,\n rpcId: safeRandomUUID(),\n tx,\n anchor,\n }\n response = this.isLeader(collectionId)\n ? await this.handleReconcileCommittedTx(\n collectionId,\n request,\n scopedAdapter,\n )\n : await this.sendRPC<ReconcileCommittedTxResponse>(\n collectionId,\n request,\n )\n if (response.ok || response.code !== `NOT_LEADER`) return response\n }\n return response!\n }\n\n async pullSince(\n collectionId: string,\n fromRowVersion: number,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<PullSinceResponse> {\n if (this.isLeader(collectionId)) {\n return this.handlePullSince(\n collectionId,\n {\n type: `rpc:pullSince:req`,\n rpcId: safeRandomUUID(),\n fromRowVersion,\n },\n scopedAdapter,\n )\n }\n\n return this.sendRPC<PullSinceResponse>(collectionId, {\n type: `rpc:pullSince:req`,\n rpcId: safeRandomUUID(),\n fromRowVersion,\n })\n }\n\n // -----------------------------------------------------------------------\n // Lifecycle\n // -----------------------------------------------------------------------\n\n dispose(): void {\n if (this.disposed) return\n this.disposed = true\n const disposedError = new Error(`coordinator disposed`)\n this.rejectDisposed?.(disposedError)\n this.rejectDisposed = null\n\n for (const acquisition of this.outboundRemoteSubsetAcquisitions.values()) {\n this.cancelRemoteSubsetReplayRetry(acquisition)\n this.postRemoteSubsetRelease(acquisition)\n }\n this.outboundRemoteSubsetAcquisitions.clear()\n this.remoteSubsetIds.clear()\n\n for (const [collectionId, state] of this.collections) {\n this.releaseLeadership(collectionId, state)\n }\n\n for (const [, pending] of this.pendingRPCs) {\n clearTimeout(pending.timer)\n pending.reject(disposedError)\n }\n this.pendingRPCs.clear()\n if (this.appliedEnvelopePruneTimer !== null) {\n clearTimeout(this.appliedEnvelopePruneTimer)\n this.appliedEnvelopePruneTimer = null\n }\n\n this.channel.close()\n this.collections.clear()\n this.collectionAdapters.clear()\n for (const collectionId of this.remoteSubsetOwners.keys()) {\n this.releaseInboundRemoteSubsetAcquisitions(collectionId)\n }\n this.remoteSubsetOwners.clear()\n this.inboundRemoteSubsetAcquisitions.clear()\n this.releasedRemoteSubsetAcquisitionTimes.clear()\n this.appliedEnvelopes.clear()\n this.inFlightEnvelopes.clear()\n }\n\n // -----------------------------------------------------------------------\n // Leadership via Web Locks\n // -----------------------------------------------------------------------\n\n private getOrCreateCollectionState(collectionId: string): CollectionState {\n let state = this.collections.get(collectionId)\n if (!state) {\n state = {\n participatesInLeadership: false,\n isLeader: false,\n leaderId: null,\n lockAbortController: null,\n heartbeatTimer: null,\n latestTerm: 0,\n latestSeq: 0,\n latestRowVersion: 0,\n subscribers: new Set(),\n routeWaiters: new Set(),\n }\n this.collections.set(collectionId, state)\n }\n return state\n }\n\n private ensureCollectionState(collectionId: string): CollectionState {\n const state = this.getOrCreateCollectionState(collectionId)\n if (!state.participatesInLeadership) {\n state.participatesInLeadership = true\n void this.acquireLeadership(collectionId, state)\n }\n return state\n }\n\n private async acquireLeadership(\n collectionId: string,\n state: CollectionState,\n ): Promise<void> {\n if (this.disposed || !state.participatesInLeadership || state.isLeader) {\n return\n }\n\n const lockName = `tsdb:leader:${this.dbName}:${collectionId}`\n const abortController = new AbortController()\n state.lockAbortController?.abort()\n state.lockAbortController = abortController\n\n try {\n await navigator.locks.request(\n lockName,\n { signal: abortController.signal },\n async () => {\n if (\n this.isDisposed() ||\n !this.participatesInLeadership(state) ||\n this.collections.get(collectionId) !== state\n ) {\n return\n }\n\n try {\n // Reserve an election term durably before advertising this route.\n // Election bypasses the shared scheduler because a hydrate may be\n // waiting for its first writer route. The writer Web Lock orders\n // reservation after any old owner's in-flight durable write.\n const adapter = this.requireAdapter(collectionId)\n const reserveTerm = adapter.reserveLeadershipTerm\n if (!reserveTerm)\n throw new InvalidPersistenceAdapterError(`reserveLeadershipTerm`)\n const pos = await this.withWriterLock(() =>\n reserveTerm.call(adapter, collectionId, state.latestTerm),\n )\n state.latestTerm = pos.latestTerm\n state.latestSeq = pos.latestSeq\n state.latestRowVersion = pos.latestRowVersion\n\n if (\n this.isDisposed() ||\n !this.participatesInLeadership(state) ||\n this.collections.get(collectionId) !== state ||\n abortController.signal.aborted ||\n state.lockAbortController !== abortController\n ) {\n return\n }\n\n state.isLeader = true\n state.leaderId = this.nodeId\n this.notifyRouteWaiters(state)\n\n this.emitHeartbeat(collectionId, state)\n void this.replayRemoteSubsetAcquisitions(collectionId)\n state.heartbeatTimer = setInterval(() => {\n this.emitHeartbeat(collectionId, state)\n }, HEARTBEAT_INTERVAL_MS)\n\n // Hold the lock until disposed or aborted\n await new Promise<void>((resolve) => {\n const onAbort = () => {\n abortController.signal.removeEventListener(`abort`, onAbort)\n resolve()\n }\n if (abortController.signal.aborted) {\n resolve()\n return\n }\n abortController.signal.addEventListener(`abort`, onAbort)\n })\n } finally {\n this.releaseInboundRemoteSubsetAcquisitions(collectionId)\n state.isLeader = false\n state.leaderId = null\n if (state.heartbeatTimer) {\n clearInterval(state.heartbeatTimer)\n state.heartbeatTimer = null\n }\n }\n },\n )\n } catch (error) {\n if (error instanceof DOMException && error.name === `AbortError`) {\n return\n }\n console.warn(`Failed to acquire leadership for ${collectionId}:`, error)\n if (\n !this.isDisposed() &&\n this.participatesInLeadership(state) &&\n this.collections.get(collectionId) === state\n ) {\n await sleep(LEADERSHIP_RETRY_DELAY_MS)\n }\n } finally {\n if (state.lockAbortController === abortController) {\n state.lockAbortController = null\n }\n }\n\n // Re-acquire if not disposed (leadership was released by another means)\n if (\n !this.isDisposed() &&\n this.participatesInLeadership(state) &&\n this.collections.get(collectionId) === state &&\n state.lockAbortController === null\n ) {\n void this.acquireLeadership(collectionId, state)\n }\n }\n\n private waitForInitialRoute(collectionId: string): Promise<void> | undefined {\n const state = this.collections.get(collectionId)\n if (\n state?.participatesInLeadership &&\n !state.isLeader &&\n state.leaderId === null\n ) {\n this.channel.postMessage({\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: { type: `leader:routeRequest` },\n } satisfies ProtocolEnvelope<{ type: `leader:routeRequest` }>)\n return this.waitForLeadershipRoute(\n collectionId,\n state,\n undefined,\n RPC_TIMEOUT_MS,\n )\n }\n return undefined\n }\n\n private waitForLeadershipRoute(\n collectionId: string,\n state: CollectionState,\n signal?: AbortSignal,\n timeoutMs?: number,\n ): Promise<void> {\n if (state.isLeader || state.leaderId !== null) return Promise.resolve()\n\n return new Promise<void>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined\n const finish = () => {\n state.routeWaiters?.delete(onRouteChange)\n signal?.removeEventListener(`abort`, onAbort)\n if (timer !== undefined) clearTimeout(timer)\n }\n const onAbort = () => {\n finish()\n reject(\n new DOMException(`Remote subset acquisition aborted`, `AbortError`),\n )\n }\n const onRouteChange = () => {\n if (this.isDisposed() || !state.participatesInLeadership) {\n finish()\n reject(\n new Error(\n `${this.coordinatorName}: leadership route closed for collection \"${collectionId}\"`,\n ),\n )\n return\n }\n if (state.isLeader || state.leaderId !== null) {\n finish()\n resolve()\n }\n }\n\n ;(state.routeWaiters ??= new Set()).add(onRouteChange)\n if (timeoutMs !== undefined) {\n timer = setTimeout(() => {\n finish()\n reject(\n new Error(\n `${this.coordinatorName}: leadership route for collection \"${collectionId}\" timed out after ${timeoutMs}ms`,\n ),\n )\n }, timeoutMs)\n }\n signal?.addEventListener(`abort`, onAbort, { once: true })\n if (signal?.aborted) {\n onAbort()\n } else {\n onRouteChange()\n }\n })\n }\n\n private notifyRouteWaiters(state: CollectionState): void {\n for (const notify of Array.from(state.routeWaiters ?? [])) notify()\n }\n\n private releaseLeadership(\n collectionId: string,\n state: CollectionState,\n ): void {\n this.releaseInboundRemoteSubsetAcquisitions(collectionId)\n if (state.lockAbortController) {\n state.lockAbortController.abort()\n state.lockAbortController = null\n }\n if (state.heartbeatTimer) {\n clearInterval(state.heartbeatTimer)\n state.heartbeatTimer = null\n }\n state.isLeader = false\n state.leaderId = null\n this.notifyRouteWaiters(state)\n }\n\n private releaseCollectionIfUnused(\n collectionId: string,\n state: CollectionState,\n ): void {\n if (\n state.subscribers.size > 0 ||\n this.collections.get(collectionId) !== state\n ) {\n return\n }\n this.releaseLeadership(collectionId, state)\n this.collections.delete(collectionId)\n this.collectionAdapters.delete(collectionId)\n const prefix = `${JSON.stringify([collectionId]).slice(0, -1)},`\n for (const key of this.appliedEnvelopes.keys()) {\n if (key.startsWith(prefix)) this.appliedEnvelopes.delete(key)\n }\n this.pruneAppliedEnvelopes()\n }\n\n private postRemoteSubsetRelease(\n acquisition: OutboundRemoteSubsetAcquisition,\n ): void {\n if (acquisition.release) return\n const request: Extract<\n RPCRequest,\n { type: `rpc:releaseRemoteSubset:req` }\n > = {\n type: `rpc:releaseRemoteSubset:req`,\n rpcId: safeRandomUUID(),\n acquisitionId: acquisition.acquisitionId,\n }\n if (this.isLeader(acquisition.collectionId)) {\n void this.handleReleaseRemoteSubset(\n acquisition.collectionId,\n request,\n this.nodeId,\n ).catch(() => {\n // The owner already received the exact unload failure through onError.\n })\n return\n }\n this.channel.postMessage({\n v: 1,\n dbName: this.dbName,\n collectionId: acquisition.collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: request,\n } satisfies ProtocolEnvelope<unknown>)\n }\n\n private cancelRemoteSubsetReplayRetry(\n acquisition: OutboundRemoteSubsetAcquisition,\n ): void {\n if (acquisition.retryTimer !== null) {\n clearTimeout(acquisition.retryTimer)\n acquisition.retryTimer = null\n }\n acquisition.retryAttempts = 0\n }\n\n private scheduleRemoteSubsetReplayRetry(\n acquisition: OutboundRemoteSubsetAcquisition,\n error: unknown,\n ): void {\n const key = remoteSubsetAcquisitionKey(\n acquisition.collectionId,\n acquisition.acquisitionId,\n )\n if (\n !(error instanceof RetryableRemoteSubsetAcquisitionError) ||\n this.isDisposed() ||\n this.outboundRemoteSubsetAcquisitions.get(key) !== acquisition ||\n acquisition.releaseRequested ||\n acquisition.retryTimer !== null ||\n acquisition.retryAttempts >= REMOTE_SUBSET_REPLAY_RETRY_ATTEMPTS\n ) {\n return\n }\n\n acquisition.retryAttempts++\n acquisition.retryTimer = setTimeout(() => {\n acquisition.retryTimer = null\n if (\n this.isDisposed() ||\n this.outboundRemoteSubsetAcquisitions.get(key) !== acquisition ||\n acquisition.releaseRequested\n ) {\n return\n }\n void this.acquireRemoteSubset(acquisition).catch((retryError) => {\n this.scheduleRemoteSubsetReplayRetry(acquisition, retryError)\n })\n }, RPC_RETRY_DELAY_MS)\n }\n\n private async replayRemoteSubsetAcquisitions(\n collectionId: string,\n ): Promise<void> {\n if (this.isDisposed()) return\n const state = this.collections.get(collectionId)\n const leaderId = state?.isLeader ? this.nodeId : state?.leaderId\n if (!leaderId) return\n\n const replays: Array<Promise<void>> = []\n for (const acquisition of this.outboundRemoteSubsetAcquisitions.values()) {\n if (\n acquisition.collectionId !== collectionId ||\n acquisition.releaseRequested ||\n (!acquisition.forceReplay && acquisition.acquiredLeaderId === leaderId)\n ) {\n continue\n }\n if (acquisition.inFlight) {\n acquisition.forceReplay = true\n continue\n }\n acquisition.forceReplay = false\n replays.push(\n this.acquireRemoteSubset(acquisition).catch((error) => {\n this.scheduleRemoteSubsetReplayRetry(acquisition, error)\n }),\n )\n }\n await Promise.all(replays)\n }\n\n private emitHeartbeat(collectionId: string, state: CollectionState): void {\n const envelope: ProtocolEnvelope<unknown> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: {\n type: `leader:heartbeat`,\n term: state.latestTerm,\n leaderId: this.nodeId,\n latestSeq: state.latestSeq,\n latestRowVersion: state.latestRowVersion,\n },\n }\n this.channel.postMessage(envelope)\n }\n\n // -----------------------------------------------------------------------\n // BroadcastChannel message handling\n // -----------------------------------------------------------------------\n\n private onChannelMessage(data: unknown): void {\n if (!isProtocolEnvelope(data)) return\n\n const envelope = data\n\n // Ignore own messages\n if (envelope.senderId === this.nodeId) return\n\n const payload = envelope.payload\n if (!payload || typeof payload !== `object`) return\n\n const type = (payload as Record<string, unknown>).type as string | undefined\n\n if (type === `leader:routeRequest`) {\n const state = this.collections.get(envelope.collectionId)\n if (state?.isLeader) this.emitHeartbeat(envelope.collectionId, state)\n return\n }\n\n if (type === `leader:heartbeat`) {\n const heartbeat = payload as {\n leaderId?: unknown\n term?: unknown\n latestSeq?: unknown\n latestRowVersion?: unknown\n }\n if (\n typeof heartbeat.leaderId === `string` &&\n typeof heartbeat.term === `number` &&\n typeof heartbeat.latestSeq === `number` &&\n typeof heartbeat.latestRowVersion === `number`\n ) {\n const state = this.getOrCreateCollectionState(envelope.collectionId)\n // The local Web Lock owns this route even if an older heartbeat arrives\n // while leadership changes.\n if (state.isLeader) return\n if (heartbeat.term < state.latestTerm) return\n const changedLeader = state.leaderId !== heartbeat.leaderId\n state.leaderId = heartbeat.leaderId\n state.latestTerm = Math.max(state.latestTerm, heartbeat.term)\n state.latestSeq = Math.max(state.latestSeq, heartbeat.latestSeq)\n state.latestRowVersion = Math.max(\n state.latestRowVersion,\n heartbeat.latestRowVersion,\n )\n this.notifyRouteWaiters(state)\n if (changedLeader) {\n void this.replayRemoteSubsetAcquisitions(envelope.collectionId)\n }\n }\n }\n\n // Handle RPC responses (for pending outbound RPCs)\n if (type && type.endsWith(`:res`)) {\n const rpcId = (payload as { rpcId?: string }).rpcId\n if (rpcId && this.pendingRPCs.has(rpcId)) {\n const pending = this.pendingRPCs.get(rpcId)!\n this.pendingRPCs.delete(rpcId)\n clearTimeout(pending.timer)\n pending.resolve(payload as RPCResponse)\n return\n }\n }\n\n // Handle RPC requests (leader only)\n if (type && type.endsWith(`:req`)) {\n if (!isRPCRequest(payload)) return\n const collectionId = envelope.collectionId\n if (this.isLeader(collectionId)) {\n void this.handleRPCRequest(collectionId, payload, envelope.senderId)\n }\n return\n }\n\n // Forward protocol messages to subscribers\n const state = this.collections.get(envelope.collectionId)\n if (state) {\n for (const subscriber of state.subscribers) {\n subscriber(envelope)\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // RPC - Outbound (follower side)\n // -----------------------------------------------------------------------\n\n private async sendRPC<T extends RPCResponse>(\n collectionId: string,\n request: RPCRequest,\n ): Promise<T> {\n if (this.isDisposed()) throw new Error(`coordinator disposed`)\n let lastError: Error | undefined\n let firstTransportCause: unknown\n const mutationRequestType = isMutatingRPCRequest(request)\n ? request.type\n : undefined\n const mutationRoute = mutationRequestType\n ? this.captureMutationRoute(collectionId)\n : undefined\n\n for (let attempt = 0; attempt <= RPC_RETRY_ATTEMPTS; attempt++) {\n if (attempt > 0) {\n await Promise.race([\n sleep(RPC_RETRY_DELAY_MS * attempt),\n this.disposedPromise,\n ])\n }\n if (this.isDisposed()) throw new Error(`coordinator disposed`)\n\n if (\n mutationRoute &&\n mutationRequestType &&\n firstTransportCause !== undefined\n ) {\n this.assertMutationRouteUnchanged(\n collectionId,\n mutationRequestType,\n mutationRoute,\n firstTransportCause,\n )\n }\n\n if (this.isLeader(collectionId)) {\n return (await this.dispatchRPCRequest(\n collectionId,\n request,\n this.nodeId,\n )) as T\n }\n\n try {\n return await this.sendRPCOnce<T>(collectionId, request)\n } catch (error) {\n if (this.isDisposed()) throw error\n firstTransportCause ??= error\n if (mutationRoute && mutationRequestType) {\n this.assertMutationRouteUnchanged(\n collectionId,\n mutationRequestType,\n mutationRoute,\n firstTransportCause,\n )\n }\n lastError = error instanceof Error ? error : new Error(String(error))\n }\n }\n\n throw lastError ?? new Error(`RPC failed after retries`)\n }\n\n private captureMutationRoute(collectionId: string): {\n leaderId: string | null\n term: number | null\n } {\n const state = this.collections.get(collectionId)\n return {\n leaderId: state?.isLeader ? this.nodeId : (state?.leaderId ?? null),\n term: state?.latestTerm ?? null,\n }\n }\n\n private assertMutationRouteUnchanged(\n collectionId: string,\n requestType: IndeterminateCommitRequestType,\n previous: { leaderId: string | null; term: number | null },\n cause: unknown,\n ): void {\n const current = this.captureMutationRoute(collectionId)\n if (\n previous.leaderId !== null &&\n previous.term !== null &&\n current.leaderId === previous.leaderId &&\n current.term === previous.term\n ) {\n return\n }\n throw new IndeterminateCommitError({\n collectionId,\n requestType,\n previousLeaderId: previous.leaderId,\n previousTerm: previous.term,\n currentLeaderId: current.leaderId,\n currentTerm: current.term,\n cause,\n })\n }\n\n private sendRPCOnce<T extends RPCResponse>(\n collectionId: string,\n request: RPCRequest,\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const rpcId = request.rpcId\n\n const timer = setTimeout(() => {\n this.pendingRPCs.delete(rpcId)\n reject(\n new Error(`RPC ${request.type} timed out after ${RPC_TIMEOUT_MS}ms`),\n )\n }, RPC_TIMEOUT_MS)\n\n this.pendingRPCs.set(rpcId, {\n resolve: resolve as (response: RPCResponse) => void,\n reject,\n timer,\n })\n\n const envelope: ProtocolEnvelope<unknown> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: request,\n }\n this.channel.postMessage(envelope)\n })\n }\n\n // -----------------------------------------------------------------------\n // RPC - Inbound (leader side)\n // -----------------------------------------------------------------------\n\n private async handleRPCRequest(\n collectionId: string,\n request: RPCRequest,\n requesterId: string,\n ): Promise<void> {\n let response: RPCResponse\n\n try {\n response = await this.dispatchRPCRequest(\n collectionId,\n request,\n requesterId,\n )\n } catch (error) {\n response = createRPCErrorResponse(request, error)\n }\n\n if (this.isDisposed()) {\n return\n }\n\n const envelope: ProtocolEnvelope<unknown> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: response,\n }\n this.channel.postMessage(envelope)\n }\n\n private dispatchRPCRequest(\n collectionId: string,\n request: RPCRequest,\n requesterId: string,\n ): Promise<RPCResponse> {\n switch (request.type) {\n case `rpc:ensureRemoteSubset:req`:\n return this.handleEnsureRemoteSubset(collectionId, request, requesterId)\n case `rpc:releaseRemoteSubset:req`:\n return this.handleReleaseRemoteSubset(\n collectionId,\n request,\n requesterId,\n )\n case `rpc:ensurePersistedIndex:req`:\n return this.handleEnsurePersistedIndex(collectionId, request)\n case `rpc:applyLocalMutations:req`:\n return this.handleApplyLocalMutations(collectionId, request)\n case `rpc:applyCommittedTx:req`:\n return this.handleApplyCommittedTx(collectionId, request)\n case `rpc:reconcileCommittedTx:req`:\n return this.handleReconcileCommittedTx(collectionId, request)\n case `rpc:pullSince:req`:\n return this.handlePullSince(collectionId, request)\n }\n }\n\n private async handleEnsureRemoteSubset(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:ensureRemoteSubset:req` }>,\n requesterId: string,\n localOptions?: TransportedLoadSubsetOptions,\n ): Promise<EnsureRemoteSubsetResponse> {\n this.pruneReleasedRemoteSubsetAcquisitions()\n const key = inboundRemoteSubsetAcquisitionKey(\n collectionId,\n requesterId,\n request.acquisitionId,\n )\n const existing = this.inboundRemoteSubsetAcquisitions.get(key)\n const awaitingOwner =\n existing && `awaitingOwner` in existing ? existing : undefined\n if (existing) {\n if (`owner` in existing) {\n if (!existing.released) {\n await existing.load\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n leaderId: this.nodeId,\n }\n }\n await existing.release\n if (existing.terminalRelease) {\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n leaderId: this.nodeId,\n }\n }\n if (this.inboundRemoteSubsetAcquisitions.get(key) === existing) {\n this.inboundRemoteSubsetAcquisitions.delete(key)\n }\n } else if (!(`awaitingOwner` in existing)) {\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n leaderId: this.nodeId,\n }\n }\n }\n\n const owner = this.remoteSubsetOwners.get(collectionId)\n if (!owner) {\n throw new RetryableRemoteSubsetAcquisitionError(\n `${this.coordinatorName}: no remote subset owner registered for collection \"${collectionId}\"`,\n )\n }\n\n await this.startRemoteSubsetOwnerAcquisition({\n collectionId,\n requesterId,\n acquisitionId: request.acquisitionId,\n owner,\n options: awaitingOwner?.options ?? localOptions ?? request.options,\n restoreOnSynchronousFailure: awaitingOwner,\n })\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n leaderId: this.nodeId,\n }\n }\n\n private async handleReleaseRemoteSubset(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:releaseRemoteSubset:req` }>,\n requesterId: string,\n ): Promise<ReleaseRemoteSubsetResponse> {\n this.pruneReleasedRemoteSubsetAcquisitions()\n const key = inboundRemoteSubsetAcquisitionKey(\n collectionId,\n requesterId,\n request.acquisitionId,\n )\n const acquisition = this.inboundRemoteSubsetAcquisitions.get(key)\n if (!acquisition) {\n this.setReleasedRemoteSubsetAcquisition(key, {\n collectionId,\n requesterId,\n acquisitionId: request.acquisitionId,\n released: true,\n })\n } else if (`owner` in acquisition) {\n acquisition.terminalRelease = true\n try {\n await this.releaseRemoteSubsetAcquisition(acquisition)\n } finally {\n if (this.inboundRemoteSubsetAcquisitions.get(key) === acquisition) {\n this.setReleasedRemoteSubsetAcquisition(key, {\n collectionId,\n requesterId,\n acquisitionId: request.acquisitionId,\n released: true,\n })\n }\n }\n } else if (`awaitingOwner` in acquisition) {\n this.setReleasedRemoteSubsetAcquisition(key, {\n collectionId,\n requesterId,\n acquisitionId: request.acquisitionId,\n released: true,\n })\n }\n return {\n type: `rpc:releaseRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: true,\n }\n }\n\n private releaseRemoteSubsetAcquisition(\n acquisition: ActiveRemoteSubsetAcquisition,\n ): Promise<void> {\n if (acquisition.release) return acquisition.release\n acquisition.released = true\n acquisition.release = (async () => {\n try {\n await acquisition.load\n } catch {\n // A returned promise transfers the lease even when initial loading fails.\n }\n try {\n if (acquisition.transferred) {\n await unloadRemoteSubsetOwner(acquisition.owner, acquisition.options)\n }\n } finally {\n if (!acquisition.terminalRelease) {\n const key = inboundRemoteSubsetAcquisitionKey(\n acquisition.collectionId,\n acquisition.requesterId,\n acquisition.acquisitionId,\n )\n if (this.inboundRemoteSubsetAcquisitions.get(key) === acquisition) {\n this.inboundRemoteSubsetAcquisitions.set(key, {\n collectionId: acquisition.collectionId,\n requesterId: acquisition.requesterId,\n acquisitionId: acquisition.acquisitionId,\n options: acquisition.options,\n released: true,\n awaitingOwner: true,\n })\n }\n }\n }\n })()\n return acquisition.release\n }\n\n private releaseInboundRemoteSubsetAcquisitions(\n collectionId: string,\n owner?: RemoteSubsetOwner,\n ): void {\n for (const acquisition of this.inboundRemoteSubsetAcquisitions.values()) {\n if (\n !(`owner` in acquisition) ||\n acquisition.collectionId !== collectionId ||\n (owner && acquisition.owner !== owner)\n ) {\n continue\n }\n void this.releaseRemoteSubsetAcquisition(acquisition).catch(\n () => undefined,\n )\n }\n }\n\n private rebindRemoteInboundSubsetAcquisitions(\n collectionId: string,\n owner: RemoteSubsetOwner,\n ): void {\n for (const acquisition of this.inboundRemoteSubsetAcquisitions.values()) {\n if (`awaitingOwner` in acquisition) {\n if (\n acquisition.collectionId === collectionId &&\n acquisition.requesterId !== this.nodeId\n ) {\n void this.bindAwaitingRemoteSubsetAcquisition(\n acquisition,\n owner,\n ).catch(() => {\n // The owner receives the exact load failure through onError.\n })\n }\n continue\n }\n if (\n !(`owner` in acquisition) ||\n acquisition.collectionId !== collectionId ||\n acquisition.requesterId === this.nodeId ||\n !acquisition.released ||\n acquisition.terminalRelease\n ) {\n continue\n }\n\n void this.rebindRemoteInboundSubsetAcquisition(acquisition, owner).catch(\n () => undefined,\n )\n }\n }\n\n private async rebindRemoteInboundSubsetAcquisition(\n previous: ActiveRemoteSubsetAcquisition,\n owner: RemoteSubsetOwner,\n ): Promise<void> {\n await previous.release\n if (\n previous.terminalRelease ||\n this.remoteSubsetOwners.get(previous.collectionId) !== owner\n ) {\n return\n }\n\n const key = inboundRemoteSubsetAcquisitionKey(\n previous.collectionId,\n previous.requesterId,\n previous.acquisitionId,\n )\n const current = this.inboundRemoteSubsetAcquisitions.get(key)\n if (current && current !== previous) {\n if (`awaitingOwner` in current) {\n await this.bindAwaitingRemoteSubsetAcquisition(current, owner)\n }\n return\n }\n\n const awaitingOwner: AwaitingRemoteSubsetOwnerAcquisition = {\n collectionId: previous.collectionId,\n requesterId: previous.requesterId,\n acquisitionId: previous.acquisitionId,\n options: previous.options,\n released: true,\n awaitingOwner: true,\n }\n this.inboundRemoteSubsetAcquisitions.set(key, awaitingOwner)\n await this.bindAwaitingRemoteSubsetAcquisition(awaitingOwner, owner)\n }\n\n private async bindAwaitingRemoteSubsetAcquisition(\n awaitingOwner: AwaitingRemoteSubsetOwnerAcquisition,\n owner: RemoteSubsetOwner,\n ): Promise<void> {\n if (this.remoteSubsetOwners.get(awaitingOwner.collectionId) !== owner) {\n return\n }\n const key = inboundRemoteSubsetAcquisitionKey(\n awaitingOwner.collectionId,\n awaitingOwner.requesterId,\n awaitingOwner.acquisitionId,\n )\n if (this.inboundRemoteSubsetAcquisitions.get(key) !== awaitingOwner) return\n\n await this.startRemoteSubsetOwnerAcquisition({\n collectionId: awaitingOwner.collectionId,\n requesterId: awaitingOwner.requesterId,\n acquisitionId: awaitingOwner.acquisitionId,\n owner,\n options: awaitingOwner.options,\n restoreOnSynchronousFailure: awaitingOwner,\n })\n }\n\n private async startRemoteSubsetOwnerAcquisition(options: {\n collectionId: string\n requesterId: string\n acquisitionId: string\n owner: RemoteSubsetOwner\n options: TransportedLoadSubsetOptions\n restoreOnSynchronousFailure?: AwaitingRemoteSubsetOwnerAcquisition\n }): Promise<void> {\n const key = inboundRemoteSubsetAcquisitionKey(\n options.collectionId,\n options.requesterId,\n options.acquisitionId,\n )\n const acquisition: ActiveRemoteSubsetAcquisition = {\n collectionId: options.collectionId,\n requesterId: options.requesterId,\n acquisitionId: options.acquisitionId,\n owner: options.owner,\n options: options.options,\n load: Promise.resolve(),\n transferred: false,\n released: false,\n terminalRelease: false,\n release: null,\n }\n this.releasedRemoteSubsetAcquisitionTimes.delete(key)\n this.inboundRemoteSubsetAcquisitions.set(key, acquisition)\n let resolveLoad!: () => void\n let rejectLoad!: (error: unknown) => void\n acquisition.load = new Promise<void>((resolve, reject) => {\n resolveLoad = resolve\n rejectLoad = reject\n })\n try {\n const load = options.owner(acquisition.options)\n acquisition.transferred = true\n void Promise.resolve(load).then(resolveLoad, rejectLoad)\n } catch (error) {\n rejectLoad(error)\n }\n\n try {\n await acquisition.load\n } catch (error) {\n if (!acquisition.transferred) {\n if (this.inboundRemoteSubsetAcquisitions.get(key) === acquisition) {\n if (options.restoreOnSynchronousFailure) {\n this.inboundRemoteSubsetAcquisitions.set(\n key,\n options.restoreOnSynchronousFailure,\n )\n } else {\n this.inboundRemoteSubsetAcquisitions.delete(key)\n }\n }\n } else {\n // A returned promise transfers a physical lease even when it rejects.\n // Retire that failed lease before allowing the same logical demand to\n // retry against the current owner.\n await this.releaseRemoteSubsetAcquisition(acquisition).catch(\n () => undefined,\n )\n }\n throw error\n }\n }\n\n private async handleEnsurePersistedIndex(\n collectionId: string,\n request: {\n type: `rpc:ensurePersistedIndex:req`\n rpcId: string\n signature: string\n spec: PersistedIndexSpec\n },\n ): Promise<RPCResponse> {\n await this.withScheduledWriterLock(collectionId, (adapter) =>\n adapter.ensureIndex(collectionId, request.signature, request.spec),\n )\n return {\n type: `rpc:ensurePersistedIndex:res`,\n rpcId: request.rpcId,\n ok: true,\n }\n }\n\n private async handleApplyLocalMutations(\n collectionId: string,\n request: {\n type: `rpc:applyLocalMutations:req`\n rpcId: string\n envelopeId: string\n mutations: Array<PersistedMutationEnvelope>\n },\n ): Promise<ApplyLocalMutationsResponse> {\n const envelopeKey = appliedEnvelopeKey(collectionId, request.envelopeId)\n return this.runDeduplicatedEnvelope({\n envelopeKey,\n rpcId: request.rpcId,\n selectApplied: (envelope) =>\n envelope.requestType === `rpc:applyLocalMutations:req`\n ? envelope.response\n : undefined,\n selectInFlight: (envelope) =>\n envelope.requestType === `rpc:applyLocalMutations:req`\n ? envelope.response\n : undefined,\n conflict: (phase) => ({\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `CONFLICT`,\n error: `envelope ${request.envelopeId} ${phase}`,\n }),\n apply: () => this.applyLocalMutationsOnce(collectionId, request),\n createPending: (response) => ({\n requestType: request.type,\n response,\n }),\n })\n }\n\n private async applyLocalMutationsOnce(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:applyLocalMutations:req` }>,\n ): Promise<ApplyLocalMutationsResponse> {\n const state = this.collections.get(collectionId)\n if (!state || !state.isLeader) {\n return {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n }\n }\n\n // Build and apply the persisted transaction\n const rowMetadataMutations: Array<PersistedRowMetadataMutation> = []\n for (const mutation of request.mutations) {\n if (!(`metadataChanged` in mutation) || !mutation.metadataChanged) {\n continue\n }\n rowMetadataMutations.push(\n mutation.metadata === undefined\n ? { type: `delete`, key: mutation.key }\n : {\n type: `set`,\n key: mutation.key,\n value: mutation.metadata,\n },\n )\n }\n const pendingTx = {\n txId: safeRandomUUID(),\n mutations: request.mutations.map((m) => ({\n type: m.type,\n key: m.key,\n value: m.value,\n ...(`metadataChanged` in m\n ? { metadata: m.metadata, metadataChanged: m.metadataChanged }\n : {}),\n })),\n rowMetadataMutations,\n }\n\n const tx = await this.applyDurablyAtNextStreamPosition(\n collectionId,\n state,\n pendingTx,\n )\n if (tx === null) {\n return {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n }\n }\n\n const response: ApplyLocalMutationsResponse = {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: true,\n term: tx.term,\n seq: tx.seq,\n latestRowVersion: tx.rowVersion,\n acceptedMutationIds: request.mutations.map((m) => m.mutationId),\n }\n if (this.isDisposed() || this.collections.get(collectionId) !== state) {\n return response\n }\n this.appliedEnvelopes.set(\n appliedEnvelopeKey(collectionId, request.envelopeId),\n {\n appliedAt: Date.now(),\n requestType: request.type,\n response,\n },\n )\n this.pruneAppliedEnvelopes()\n\n // Broadcast tx:committed to all tabs\n const changedRows = request.mutations\n .filter((m) => m.type !== `delete`)\n .map((m) => ({ key: m.key, value: m.value }))\n const deletedKeys = request.mutations\n .filter((m) => m.type === `delete`)\n .map((m) => m.key)\n\n const txCommitted: ProtocolEnvelope<unknown> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: {\n type: `tx:committed`,\n term: tx.term,\n seq: tx.seq,\n txId: tx.txId,\n latestRowVersion: tx.rowVersion,\n requiresFullReload: false,\n changedRows,\n deletedKeys,\n rowMetadataMutations,\n },\n }\n this.channel.postMessage(txCommitted)\n\n // Deliver to local subscribers too\n for (const subscriber of state.subscribers) {\n subscriber(txCommitted)\n }\n\n return response\n }\n\n private async handleApplyCommittedTx(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:applyCommittedTx:req` }>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<ApplyCommittedTxResponse> {\n const envelopeKey = appliedEnvelopeKey(collectionId, request.envelopeId)\n return this.runDeduplicatedEnvelope({\n envelopeKey,\n rpcId: request.rpcId,\n selectApplied: (envelope) =>\n envelope.requestType === `rpc:applyCommittedTx:req`\n ? envelope.response\n : undefined,\n selectInFlight: (envelope) =>\n envelope.requestType === `rpc:applyCommittedTx:req`\n ? envelope.response\n : undefined,\n conflict: (phase) => ({\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `CONFLICT`,\n error: `envelope ${request.envelopeId} ${phase}`,\n }),\n apply: () =>\n this.applyCommittedTxOnce(collectionId, request, scopedAdapter),\n createPending: (response) => ({\n requestType: request.type,\n response,\n }),\n })\n }\n\n private async runDeduplicatedEnvelope<\n TResponse extends { rpcId: string },\n >(options: {\n envelopeKey: string\n rpcId: string\n selectApplied: (envelope: AppliedEnvelope) => TResponse | undefined\n selectInFlight: (\n envelope: InFlightEnvelope,\n ) => Promise<TResponse> | undefined\n conflict: (phase: `already applied` | `is already in flight`) => TResponse\n apply: () => Promise<TResponse>\n createPending: (response: Promise<TResponse>) => InFlightEnvelope\n }): Promise<TResponse> {\n const appliedEnvelope = this.appliedEnvelopes.get(options.envelopeKey)\n if (appliedEnvelope) {\n const response = options.selectApplied(appliedEnvelope)\n return response\n ? { ...response, rpcId: options.rpcId }\n : options.conflict(`already applied`)\n }\n\n const inFlightEnvelope = this.inFlightEnvelopes.get(options.envelopeKey)\n if (inFlightEnvelope) {\n const pending = options.selectInFlight(inFlightEnvelope)\n if (!pending) return options.conflict(`is already in flight`)\n const response = await pending\n return { ...response, rpcId: options.rpcId }\n }\n\n const response = options.apply()\n const pendingEnvelope = options.createPending(response)\n this.inFlightEnvelopes.set(options.envelopeKey, pendingEnvelope)\n try {\n return await response\n } finally {\n if (this.inFlightEnvelopes.get(options.envelopeKey) === pendingEnvelope) {\n this.inFlightEnvelopes.delete(options.envelopeKey)\n }\n }\n }\n\n private async applyCommittedTxOnce(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:applyCommittedTx:req` }>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<ApplyCommittedTxResponse> {\n const state = this.collections.get(collectionId)\n if (!state || !state.isLeader) {\n return {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n }\n }\n\n const tx = await this.applyDurablyAtNextStreamPosition(\n collectionId,\n state,\n request.tx,\n scopedAdapter,\n )\n if (tx === null) {\n return {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n }\n }\n const response: ApplyCommittedTxResponse = {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: true,\n term: tx.term,\n seq: tx.seq,\n latestRowVersion: tx.rowVersion,\n }\n if (this.isDisposed() || this.collections.get(collectionId) !== state) {\n return response\n }\n this.appliedEnvelopes.set(\n appliedEnvelopeKey(collectionId, request.envelopeId),\n {\n appliedAt: Date.now(),\n requestType: request.type,\n response,\n },\n )\n this.pruneAppliedEnvelopes()\n\n this.publishCommittedTx(collectionId, state, tx)\n\n return response\n }\n\n private publishCommittedTx(\n collectionId: string,\n state: CollectionState,\n tx: PersistedTx,\n forceReload = false,\n ): void {\n const committedBase = {\n type: `tx:committed` as const,\n term: tx.term,\n seq: tx.seq,\n txId: tx.txId,\n latestRowVersion: tx.rowVersion,\n }\n const committedPayload: TxCommitted =\n tx.truncate || forceReload\n ? {\n ...committedBase,\n requiresFullReload: true,\n ...(forceReload ? { reconciliationReload: true as const } : {}),\n }\n : {\n ...committedBase,\n requiresFullReload: false,\n changedRows: tx.mutations\n .filter((mutation) => mutation.type !== `delete`)\n .map((mutation) => ({\n key: mutation.key,\n value: mutation.value,\n })),\n deletedKeys: tx.mutations\n .filter((mutation) => mutation.type === `delete`)\n .map((mutation) => mutation.key),\n rowMetadataMutations: tx.rowMetadataMutations,\n collectionMetadataMutations: tx.collectionMetadataMutations,\n }\n const committed: ProtocolEnvelope<TxCommitted> = {\n v: 1,\n dbName: this.dbName,\n collectionId,\n senderId: this.nodeId,\n ts: Date.now(),\n payload: committedPayload,\n }\n this.channel.postMessage(committed)\n for (const subscriber of state.subscribers) {\n subscriber(committed)\n }\n }\n\n private async handleReconcileCommittedTx(\n collectionId: string,\n request: Extract<RPCRequest, { type: `rpc:reconcileCommittedTx:req` }>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<ReconcileCommittedTxResponse> {\n const state = this.collections.get(collectionId)\n const notLeader = (): ReconcileCommittedTxResponse => ({\n type: `rpc:reconcileCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `NOT_LEADER`,\n error: `not the leader for ${collectionId}`,\n })\n if (!state?.isLeader) return notLeader()\n if (\n !isValidCommittedTxAnchor(request.anchor) ||\n !hasReconciliationTxPayload(request.tx)\n ) {\n return {\n type: `rpc:reconcileCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `UNDETERMINED`,\n error: `the source transaction has no valid durable proof`,\n }\n }\n\n const expectedTerm = state.latestTerm\n const result = await this.withScheduledWriterLock(\n collectionId,\n async (adapter) => {\n const candidate = this.nextPersistedTxIfLeader(\n collectionId,\n state,\n expectedTerm,\n request.tx,\n )\n if (candidate === null) return null\n if (!adapter.reconcileCommittedTx) return { kind: `unknown` as const }\n try {\n const reconciled = await adapter.reconcileCommittedTx(\n collectionId,\n candidate,\n request.anchor,\n )\n if (reconciled.kind !== `unknown`) {\n state.latestRowVersion = Math.max(\n state.latestRowVersion,\n reconciled.latestRowVersion,\n )\n if (reconciled.kind === `applied-now`) {\n state.latestSeq = reconciled.committed.seq\n }\n }\n return reconciled\n } catch (error) {\n throw toPersistedCollectionDurabilityError(collectionId, error)\n }\n },\n scopedAdapter,\n )\n if (result === null) return notLeader()\n if (result.kind === `unknown`) {\n return {\n type: `rpc:reconcileCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `UNDETERMINED`,\n error: `the durable outcome cannot be certified`,\n }\n }\n\n const current = {\n term: state.latestTerm,\n seq: state.latestSeq,\n rowVersion: state.latestRowVersion,\n }\n const response: ReconcileCommittedTxResponse = {\n type: `rpc:reconcileCommittedTx:res`,\n rpcId: request.rpcId,\n ok: true,\n alreadyApplied: result.kind === `already-applied`,\n committed: result.committed,\n }\n if (!this.isDisposed() && this.collections.get(collectionId) === state) {\n this.publishCommittedTx(\n collectionId,\n state,\n result.kind === `already-applied`\n ? { ...request.tx, ...current }\n : { ...request.tx, ...result.committed },\n result.kind === `already-applied`,\n )\n }\n return response\n }\n\n private nextPersistedTxIfLeader(\n collectionId: string,\n state: CollectionState,\n expectedTerm: number,\n pendingTx: Omit<PersistedTx, `term` | `seq` | `rowVersion`>,\n ): PersistedTx | null {\n if (\n this.isDisposed() ||\n this.collections.get(collectionId) !== state ||\n !state.isLeader ||\n state.leaderId !== this.nodeId ||\n state.latestTerm !== expectedTerm\n ) {\n return null\n }\n return {\n ...pendingTx,\n term: state.latestTerm,\n seq: state.latestSeq + 1,\n rowVersion: state.latestRowVersion + 1,\n }\n }\n\n private async applyDurablyAtNextStreamPosition(\n collectionId: string,\n state: CollectionState,\n pendingTx: Omit<PersistedTx, `term` | `seq` | `rowVersion`>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<PersistedTx | null> {\n const expectedTerm = state.latestTerm\n return this.withScheduledWriterLock(\n collectionId,\n async (adapter) => {\n const tx = this.nextPersistedTxIfLeader(\n collectionId,\n state,\n expectedTerm,\n pendingTx,\n )\n if (tx === null) return null\n try {\n await adapter.applyCommittedTx(collectionId, tx)\n } catch (error) {\n throw toPersistedCollectionDurabilityError(collectionId, error)\n }\n state.latestSeq = tx.seq\n state.latestRowVersion = tx.rowVersion\n return tx\n },\n scopedAdapter,\n )\n }\n\n private async handlePullSince(\n collectionId: string,\n request: {\n type: `rpc:pullSince:req`\n rpcId: string\n fromRowVersion: number\n },\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<PullSinceResponse> {\n const state = this.collections.get(collectionId)\n\n const adapter = scopedAdapter ?? this.requireAdapter(collectionId)\n if (!adapter.pullSince) {\n return {\n type: `rpc:pullSince:res`,\n rpcId: request.rpcId,\n ok: true,\n latestTerm: state?.latestTerm ?? 0,\n latestSeq: state?.latestSeq ?? 0,\n latestRowVersion: state?.latestRowVersion ?? 0,\n requiresFullReload: true,\n }\n }\n\n const result = await adapter.pullSince(collectionId, request.fromRowVersion)\n\n if (result.requiresFullReload) {\n return {\n type: `rpc:pullSince:res`,\n rpcId: request.rpcId,\n ok: true,\n latestTerm: state?.latestTerm ?? 0,\n latestSeq: state?.latestSeq ?? 0,\n latestRowVersion: result.latestRowVersion,\n requiresFullReload: true,\n }\n }\n\n return {\n type: `rpc:pullSince:res`,\n rpcId: request.rpcId,\n ok: true,\n latestTerm: state?.latestTerm ?? 0,\n latestSeq: state?.latestSeq ?? 0,\n latestRowVersion: result.latestRowVersion,\n requiresFullReload: false,\n changedKeys: result.changedKeys,\n deletedKeys: result.deletedKeys,\n }\n }\n\n // -----------------------------------------------------------------------\n // DB Writer Lock\n // -----------------------------------------------------------------------\n\n private withScheduledWriterLock<T>(\n collectionId: string,\n task: (adapter: CoordinatorAdapter) => Promise<T>,\n scopedAdapter?: HydrationPersistenceAdapter,\n ): Promise<T> {\n if (scopedAdapter) {\n return this.withWriterLock(() => task(scopedAdapter))\n }\n // Enter the shared scheduler before taking the database-wide Web Lock.\n // A hydrate waiting for its first commit may need that lock to finish.\n const adapter = this.requireAdapter(collectionId)\n return adapter.runInRegularScope\n ? adapter.runInRegularScope((unscheduledAdapter) =>\n this.withWriterLock(() => task(unscheduledAdapter)),\n )\n : this.withWriterLock(() => task(adapter))\n }\n\n private async withWriterLock<T>(fn: () => Promise<T>): Promise<T> {\n const lockName = `tsdb:writer:${this.dbName}`\n\n for (let attempt = 0; attempt <= WRITER_LOCK_MAX_RETRIES; attempt++) {\n const callbackState = { entered: false }\n try {\n return await navigator.locks.request(lockName, async () => {\n callbackState.entered = true\n return fn()\n })\n } catch (error) {\n if (callbackState.entered) {\n throw error\n }\n if (error instanceof DOMException && error.name === `AbortError`) {\n throw error\n }\n\n if (attempt < WRITER_LOCK_MAX_RETRIES) {\n await sleep(WRITER_LOCK_BUSY_RETRY_MS * Math.min(attempt + 1, 5))\n continue\n }\n\n throw error\n }\n }\n\n // Unreachable but satisfies TypeScript\n throw new Error(`writer lock acquisition failed`)\n }\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n private pruneAppliedEnvelopes(): void {\n if (this.appliedEnvelopePruneTimer !== null) {\n clearTimeout(this.appliedEnvelopePruneTimer)\n this.appliedEnvelopePruneTimer = null\n }\n const cutoff = Date.now() - RPC_DEDUPE_RETENTION_MS\n for (const [key, envelope] of this.appliedEnvelopes) {\n if (envelope.appliedAt <= cutoff) {\n this.appliedEnvelopes.delete(key)\n }\n }\n if (this.disposed || this.appliedEnvelopes.size === 0) return\n\n let earliestAppliedAt = Number.POSITIVE_INFINITY\n for (const envelope of this.appliedEnvelopes.values()) {\n earliestAppliedAt = Math.min(earliestAppliedAt, envelope.appliedAt)\n }\n const delay = Math.max(\n 0,\n earliestAppliedAt + RPC_DEDUPE_RETENTION_MS - Date.now(),\n )\n this.appliedEnvelopePruneTimer = setTimeout(() => {\n this.appliedEnvelopePruneTimer = null\n this.pruneAppliedEnvelopes()\n }, delay)\n }\n\n private setReleasedRemoteSubsetAcquisition(\n key: string,\n acquisition: RemoteSubsetAcquisition,\n ): void {\n this.inboundRemoteSubsetAcquisitions.set(key, acquisition)\n this.releasedRemoteSubsetAcquisitionTimes.set(key, Date.now())\n }\n\n private pruneReleasedRemoteSubsetAcquisitions(): void {\n const cutoff = Date.now() - RPC_DEDUPE_RETENTION_MS\n for (const [key, releasedAt] of this.releasedRemoteSubsetAcquisitionTimes) {\n if (releasedAt < cutoff) {\n this.releasedRemoteSubsetAcquisitionTimes.delete(key)\n this.inboundRemoteSubsetAcquisitions.delete(key)\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Utilities\n// ---------------------------------------------------------------------------\n\nfunction isProtocolEnvelope(data: unknown): data is ProtocolEnvelope<unknown> {\n if (!data || typeof data !== `object`) return false\n const record = data as Record<string, unknown>\n return (\n record.v === 1 &&\n typeof record.dbName === `string` &&\n typeof record.collectionId === `string` &&\n typeof record.senderId === `string` &&\n typeof record.ts === `number`\n )\n}\n\nfunction isRPCRequest(payload: unknown): payload is RPCRequest {\n if (!payload || typeof payload !== `object`) return false\n switch ((payload as { type?: unknown }).type) {\n case `rpc:ensureRemoteSubset:req`:\n case `rpc:releaseRemoteSubset:req`:\n case `rpc:ensurePersistedIndex:req`:\n case `rpc:applyLocalMutations:req`:\n case `rpc:applyCommittedTx:req`:\n case `rpc:reconcileCommittedTx:req`:\n case `rpc:pullSince:req`:\n return true\n default:\n return false\n }\n}\n\nfunction hasReconciliationTxPayload(value: unknown): boolean {\n if (!value || typeof value !== `object`) return false\n const tx = value as Record<string, unknown>\n return typeof tx.txId === `string` && Array.isArray(tx.mutations)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction appliedEnvelopeKey(collectionId: string, envelopeId: string): string {\n return JSON.stringify([collectionId, envelopeId])\n}\n\nfunction remoteSubsetAcquisitionKey(\n collectionId: string,\n acquisitionId: string,\n): string {\n return JSON.stringify([collectionId, acquisitionId])\n}\n\nfunction inboundRemoteSubsetAcquisitionKey(\n collectionId: string,\n requesterId: string,\n acquisitionId: string,\n): string {\n return JSON.stringify([collectionId, requesterId, acquisitionId])\n}\n\nfunction createRPCErrorResponse(\n request: RPCRequest,\n cause: unknown,\n): RPCResponse {\n const error = cause instanceof Error ? cause.message : String(cause)\n switch (request.type) {\n case `rpc:ensureRemoteSubset:req`:\n return {\n type: `rpc:ensureRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: false,\n error,\n ...(cause instanceof RetryableRemoteSubsetAcquisitionError\n ? { retryable: true as const }\n : {}),\n }\n case `rpc:releaseRemoteSubset:req`:\n return {\n type: `rpc:releaseRemoteSubset:res`,\n rpcId: request.rpcId,\n ok: false,\n error,\n }\n case `rpc:ensurePersistedIndex:req`:\n return {\n type: `rpc:ensurePersistedIndex:res`,\n rpcId: request.rpcId,\n ok: false,\n error,\n }\n case `rpc:applyLocalMutations:req`:\n if (cause instanceof PersistedCollectionDurabilityError) {\n return {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `PERSISTENCE_ERROR`,\n error,\n ...toSafeDurabilityDetails(cause),\n }\n }\n return {\n type: `rpc:applyLocalMutations:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `CONFLICT`,\n error,\n }\n case `rpc:applyCommittedTx:req`:\n if (cause instanceof PersistedCollectionDurabilityError) {\n return {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `PERSISTENCE_ERROR`,\n error,\n ...toSafeDurabilityDetails(cause),\n }\n }\n return {\n type: `rpc:applyCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code: `CONFLICT`,\n error,\n }\n case `rpc:reconcileCommittedTx:req`:\n return {\n type: `rpc:reconcileCommittedTx:res`,\n rpcId: request.rpcId,\n ok: false,\n code:\n cause instanceof PersistedCollectionDurabilityError\n ? `PERSISTENCE_ERROR`\n : `UNDETERMINED`,\n error,\n ...(cause instanceof PersistedCollectionDurabilityError\n ? toSafeDurabilityDetails(cause)\n : {}),\n }\n case `rpc:pullSince:req`:\n return {\n type: `rpc:pullSince:res`,\n rpcId: request.rpcId,\n ok: false,\n error,\n }\n }\n}\n\nfunction isMutatingRPCRequest(request: RPCRequest): request is Extract<\n RPCRequest,\n {\n type: IndeterminateCommitRequestType\n }\n> {\n return (\n request.type === `rpc:applyLocalMutations:req` ||\n request.type === `rpc:applyCommittedTx:req`\n )\n}\n\nfunction toSafeDurabilityDetails(error: PersistedCollectionDurabilityError): {\n sourceCode?: string | number\n path?: string | ReadonlyArray<string | number>\n} {\n const sourceCode =\n typeof error.code === `string` || typeof error.code === `number`\n ? error.code\n : undefined\n const path =\n typeof error.path === `string` ||\n (Array.isArray(error.path) &&\n error.path.every(\n (part) => typeof part === `string` || typeof part === `number`,\n ))\n ? (error.path as string | ReadonlyArray<string | number>)\n : undefined\n return {\n ...(sourceCode === undefined ? {} : { sourceCode }),\n ...(path === undefined ? {} : { path }),\n }\n}\n"],"names":["InvalidPersistenceAdapterError","safeRandomUUID","DuplicateRemoteSubsetOwnerError","toTransportedLoadSubsetOptions","toProcessLocalLoadSubsetOptions","RetryableRemoteSubsetAcquisitionError","state","IndeterminateCommitError","unloadRemoteSubsetOwner","response","isValidCommittedTxAnchor","toPersistedCollectionDurabilityError","PersistedCollectionDurabilityError"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LoadSubsetOptions } from '@tanstack/db';
|
|
2
2
|
import { RemoteSubsetOwner } from './remote-subset-owner.cjs';
|
|
3
|
-
import { ApplyCommittedTxResponse, ApplyLocalMutationsResponse, HydrationPersistenceAdapter, PersistedCollectionCoordinator, PersistedIndexSpec, PersistedMutationEnvelope, PersistedTx, PersistenceAdapter, ProtocolEnvelope, PullSinceResponse } from './persisted.cjs';
|
|
4
|
-
type CoordinatorAdapter = Pick<PersistenceAdapter, `loadSubset` | `applyCommittedTx` | `ensureIndex` | `runInRegularScope`> & {
|
|
3
|
+
import { ApplyCommittedTxResponse, ApplyLocalMutationsResponse, CommittedTxAnchor, HydrationPersistenceAdapter, PersistedCollectionCoordinator, PersistedIndexSpec, PersistedMutationEnvelope, PersistedTx, PersistenceAdapter, ProtocolEnvelope, PullSinceResponse, ReconcileCommittedTxResponse } from './persisted.cjs';
|
|
4
|
+
type CoordinatorAdapter = Pick<PersistenceAdapter, `loadSubset` | `applyCommittedTx` | `reconcileCommittedTx` | `ensureIndex` | `runInRegularScope`> & {
|
|
5
5
|
pullSince?: (collectionId: string, fromRowVersion: number) => Promise<{
|
|
6
6
|
latestRowVersion: number;
|
|
7
7
|
requiresFullReload: true;
|
|
@@ -16,6 +16,11 @@ type CoordinatorAdapter = Pick<PersistenceAdapter, `loadSubset` | `applyCommitte
|
|
|
16
16
|
latestSeq: number;
|
|
17
17
|
latestRowVersion: number;
|
|
18
18
|
}>;
|
|
19
|
+
reserveLeadershipTerm?: (collectionId: string, observedTerm: number) => Promise<{
|
|
20
|
+
latestTerm: number;
|
|
21
|
+
latestSeq: number;
|
|
22
|
+
latestRowVersion: number;
|
|
23
|
+
}>;
|
|
19
24
|
};
|
|
20
25
|
/** @internal Shared by the Browser and Electron persistence hosts. */
|
|
21
26
|
export type BroadcastCollectionCoordinatorOptions = {
|
|
@@ -69,6 +74,7 @@ export declare class BroadcastCollectionCoordinator implements PersistedCollecti
|
|
|
69
74
|
requestEnsurePersistedIndex(collectionId: string, signature: string, spec: PersistedIndexSpec, scopedAdapter?: HydrationPersistenceAdapter, localEnsureCompleted?: boolean): Promise<void>;
|
|
70
75
|
requestApplyLocalMutations(collectionId: string, mutations: Array<PersistedMutationEnvelope>): Promise<ApplyLocalMutationsResponse>;
|
|
71
76
|
requestApplyCommittedTx(collectionId: string, tx: PersistedTx, scopedAdapter?: HydrationPersistenceAdapter): Promise<ApplyCommittedTxResponse>;
|
|
77
|
+
reconcileCommittedTx(collectionId: string, tx: PersistedTx, anchor: CommittedTxAnchor, scopedAdapter?: HydrationPersistenceAdapter): Promise<ReconcileCommittedTxResponse>;
|
|
72
78
|
pullSince(collectionId: string, fromRowVersion: number, scopedAdapter?: HydrationPersistenceAdapter): Promise<PullSinceResponse>;
|
|
73
79
|
dispose(): void;
|
|
74
80
|
private getOrCreateCollectionState;
|
|
@@ -105,6 +111,9 @@ export declare class BroadcastCollectionCoordinator implements PersistedCollecti
|
|
|
105
111
|
private handleApplyCommittedTx;
|
|
106
112
|
private runDeduplicatedEnvelope;
|
|
107
113
|
private applyCommittedTxOnce;
|
|
114
|
+
private publishCommittedTx;
|
|
115
|
+
private handleReconcileCommittedTx;
|
|
116
|
+
private nextPersistedTxIfLeader;
|
|
108
117
|
private applyDurablyAtNextStreamPosition;
|
|
109
118
|
private handlePullSince;
|
|
110
119
|
private withScheduledWriterLock;
|