@tearleads/client-sdk 0.1.35 → 0.1.37

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.
Files changed (31) hide show
  1. package/client/Tearleads.d.ts +4 -3
  2. package/client/Tearleads.js +4 -3
  3. package/client/Tearleads.js.map +1 -1
  4. package/internal/api-client/ApiClient.d.ts +3 -0
  5. package/internal/api-client/ApiClient.js +10 -7
  6. package/internal/api-client/ApiClient.js.map +1 -1
  7. package/internal/api-client/webSocketTickets.js +45 -0
  8. package/internal/api-client/webSocketTickets.js.map +1 -0
  9. package/internal/validators/operation/auth.d.ts +20 -0
  10. package/internal/validators/realtime/index.js +2 -2
  11. package/internal/validators/realtime/index.js.map +1 -1
  12. package/internal/validators/realtime/wsServerFrames.js +3 -8
  13. package/internal/validators/realtime/wsServerFrames.js.map +1 -1
  14. package/internal/validators/realtime/wsShared.js +6 -0
  15. package/internal/validators/realtime/wsShared.js.map +1 -1
  16. package/internal/validators/response/auth/verify.d.ts +8 -0
  17. package/internal/validators/response/auth/verify.js +3 -0
  18. package/internal/validators/response/auth/verify.js.map +1 -1
  19. package/package.json +1 -1
  20. package/stores/documents/documentStore/deferredInitialUpdate.js +9 -1
  21. package/stores/documents/documentStore/deferredInitialUpdate.js.map +1 -1
  22. package/stores/documents/documentStore/initialization.js +4 -0
  23. package/stores/documents/documentStore/initialization.js.map +1 -1
  24. package/stores/documents/documentStore.js +3 -3
  25. package/stores/documents/documentStore.js.map +1 -1
  26. package/sync/reconciliation/service.js +22 -12
  27. package/sync/reconciliation/service.js.map +1 -1
  28. package/sync/reconciliation/serviceTypes.d.ts +10 -1
  29. package/sync/reconciliation/serviceTypes.js.map +1 -1
  30. package/workflows/runtimeInput.d.ts +4 -3
  31. package/workflows/runtimeInput.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"documentStore.js","sourceRoot":"","sources":["documentStore.ts"],"names":[],"mappings":"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","sourcesContent":["import { DEFAULT_DOCUMENT_KIND } from \"../../data/documents/documentConstants\";\nimport type { StoredDocumentKind } from \"../../data/documents/documentKinds\";\nimport type { DomainScope } from \"../../data/domainScope\";\nimport {\n createDocumentProjectionUserKeyResolver,\n type DocumentsPersistence,\n defaultDocumentsPersistence,\n didDocumentProjectionKeyRuntimeChange,\n didRegainSyncPrerequisites,\n requestDocumentSyncLaneAndWait,\n} from \"../../workflows/documents\";\nimport { removeAttachmentFromDocumentStore } from \"./documentStore/attachmentRemoval\";\nimport {\n attachFilesToDocumentStore,\n replaceAttachmentInDocumentStore,\n} from \"./documentStore/attachments\";\nimport { discardDocumentStoreLocalState } from \"./documentStore/discard\";\nimport {\n ensureDocumentStoreInitialized,\n ensureDocumentStoreReady,\n relinkDocumentStore,\n} from \"./documentStore/initialization\";\nimport { registerInternalDocumentRelink } from \"./documentStore/internalRelink\";\nimport {\n setDocumentStructuredFields,\n setDocumentText,\n} from \"./documentStore/mutations\";\nimport { logRevalidationScheduled } from \"./documentStore/remoteRevalidationTelemetry\";\nimport { assertDocumentStoreCanRotateContentKey } from \"./documentStore/rotation\";\nimport {\n addRowToDocumentStore,\n removeRowFromDocumentStore,\n updateRowInDocumentStore,\n} from \"./documentStore/rows\";\nimport {\n createDocumentStoreState,\n type DocumentStoreState,\n refreshAttachabilitySnapshot,\n resetDocumentStore,\n subscribeToDocumentStore,\n} from \"./documentStore/state\";\nimport { registerDocumentStoreSyncLane } from \"./documentStore/sync\";\nimport {\n allowDocumentStoreRemoteSync,\n captureDocumentStoreRemoteSyncRequestGeneration,\n captureDocumentStoreSyncLaneGeneration,\n type DocumentStoreRemoteSyncRequestGeneration,\n type DocumentStoreSyncLaneGeneration,\n didDocumentStoreRemoteSyncRequestComplete,\n hasPendingIndependentDocumentStoreRemoteSync,\n invalidateDocumentStoreRemoteSync,\n invalidateDocumentStoreSyncLane,\n isDocumentStoreRemoteSyncBlocked,\n isDocumentStoreRemoteSyncRequestGenerationCurrent,\n markDocumentStoreRemoteSyncPending,\n registerDocumentStoreRemoteSyncWaiter,\n} from \"./documentStore/syncGeneration\";\nimport { handleDocumentRemoteEvents } from \"./documentStore/syncRemoteSignals\";\nimport {\n createDocumentStoreFacade,\n emitPersistedDocument,\n getOrCreateDocumentStoreRegistry,\n registerDocumentStore,\n registerDocumentStoreIdentity,\n requestDocumentStoreSync,\n resolveDocumentStoreKey,\n} from \"./registry\";\nimport type {\n DocumentAttachmentUpload,\n DocumentStore,\n DocumentStoreFacade,\n DocumentStoreOpenOptions,\n DocumentsRuntime,\n} from \"./types\";\n\nexport {\n discardRegisteredDocumentLocalState,\n requestDomainDocumentSync,\n subscribeToPersistedDocuments,\n} from \"./registry\";\n\nfunction refreshDocumentStoreSyncLane(\n state: DocumentStoreState,\n force = false,\n): void {\n if (!force && state.syncLane && !state.syncLane.isDisposed?.()) {\n return;\n }\n if (state.syncLane) {\n invalidateDocumentStoreSyncLane(state);\n }\n let syncLaneGeneration: DocumentStoreSyncLaneGeneration | null = null;\n state.syncLane = registerDocumentStoreSyncLane(\n state,\n () => syncLaneGeneration,\n );\n syncLaneGeneration = captureDocumentStoreSyncLaneGeneration(state);\n}\n\nfunction updateDocumentStoreRuntime(\n state: DocumentStoreState,\n nextRuntime: DocumentsRuntime,\n scheduleSync: () => void,\n) {\n const previousRuntime = state.runtime;\n const serverEventsReconnected =\n (nextRuntime.state.serverEventsConnectionGeneration ?? 0) >\n (previousRuntime.state.serverEventsConnectionGeneration ?? 0);\n const domainScopeChanged =\n previousRuntime.state.domainScope !== nextRuntime.state.domainScope;\n const projectionKeyRuntimeChanged = didDocumentProjectionKeyRuntimeChange(\n previousRuntime,\n nextRuntime,\n );\n if (projectionKeyRuntimeChanged) {\n state.resolveProjectionUserKey =\n createDocumentProjectionUserKeyResolver(nextRuntime);\n state.writerProjection = null;\n }\n state.runtime = nextRuntime;\n refreshDocumentStoreSyncLane(state, domainScopeChanged);\n if (domainScopeChanged) {\n state.locallyAcceptedUpdateIds = new Set();\n state.remoteUpdatePending = false;\n state.writerProjection = null;\n }\n\n if (nextRuntime.infra.dbStatus !== \"ready\") {\n if (state.snapshot.ready || state.initialized || state.initializePromise) {\n resetDocumentStore(state);\n }\n state.lastEventCount = nextRuntime.state.events.length;\n return;\n }\n\n refreshAttachabilitySnapshot(state);\n ensureDocumentStoreInitialized(state, scheduleSync);\n handleDocumentRemoteEvents(state, scheduleSync);\n\n if (state.snapshot.ready) {\n if (serverEventsReconnected) {\n // The invalidation stream is lossy while disconnected. Once the server\n // has restored this session's interest baseline, every already-open\n // remote document needs one HTTP probe to cover peer writes made during\n // the gap. This also closes iOS background/resume reconnects where the\n // native network source remained online throughout.\n requestRemoteDocumentStoreSync(state, scheduleSync);\n logRevalidationScheduled(state.runtime, \"reconnect\");\n } else if (didRegainSyncPrerequisites(previousRuntime, state.runtime)) {\n scheduleSync();\n }\n }\n}\n\nfunction requestRemoteDocumentStoreSync(\n state: DocumentStoreState,\n scheduleSync: () => void,\n owner: \"independent\" | \"waiter\" = \"independent\",\n): number {\n allowDocumentStoreRemoteSync(state);\n const signalSequence = markDocumentStoreRemoteSyncPending(state, owner);\n scheduleSync();\n return signalSequence;\n}\n\nfunction requestOrdinaryDocumentStoreSync(\n state: DocumentStoreState,\n scheduleSync: () => void,\n): void {\n // A normal UI reopen is a fresh owner for remote-only work. It may recover\n // a probe that an earlier, now-unmounted owner aborted.\n if (isDocumentStoreRemoteSyncBlocked(state)) {\n requestRemoteDocumentStoreSync(state, scheduleSync);\n return;\n }\n scheduleSync();\n}\n\nfunction requestRemoteDocumentStoreSyncAndWait(\n state: DocumentStoreState,\n scheduleSync: () => void,\n signal?: AbortSignal,\n): Promise<boolean> {\n let requestGeneration: DocumentStoreRemoteSyncRequestGeneration | null = null;\n let requestedSignalSequence = 0;\n let releaseWaiter: (() => boolean) | null = null;\n const releaseRemoteSyncWaiter = (invalidate: boolean) => {\n const releasedLastWaiter = releaseWaiter?.() ?? false;\n if (\n invalidate &&\n releasedLastWaiter &&\n requestGeneration !== null &&\n isDocumentStoreRemoteSyncRequestGenerationCurrent(\n state,\n requestGeneration,\n ) &&\n !hasPendingIndependentDocumentStoreRemoteSync(state)\n ) {\n invalidateDocumentStoreRemoteSync(state);\n }\n };\n // A coordinator can be disposed and recreated while this same-scope store\n // remains registered. Refresh its handle before requesting work.\n refreshDocumentStoreSyncLane(state);\n return requestDocumentSyncLaneAndWait({\n didCompleteRequest: () =>\n requestGeneration !== null &&\n didDocumentStoreRemoteSyncRequestComplete(\n state,\n requestGeneration,\n requestedSignalSequence,\n ),\n domainScope: state.runtime.state.domainScope,\n localId: state.localId,\n request: () => {\n requestGeneration =\n captureDocumentStoreRemoteSyncRequestGeneration(state);\n releaseWaiter = registerDocumentStoreRemoteSyncWaiter(\n state,\n requestGeneration,\n );\n requestedSignalSequence = requestRemoteDocumentStoreSync(\n state,\n scheduleSync,\n \"waiter\",\n );\n },\n onInvalidated: () => releaseRemoteSyncWaiter(true),\n signal,\n }).then(\n (completed) => {\n releaseRemoteSyncWaiter(!completed);\n return completed;\n },\n (error: unknown) => {\n releaseRemoteSyncWaiter(true);\n throw error;\n },\n );\n}\n\nasync function assertBackingDocumentStoreCanRotate(\n state: DocumentStoreState,\n scheduleSync: () => void,\n) {\n if (!(await ensureDocumentStoreReady(state, scheduleSync)) || !state.doc) {\n throw new Error(\n \"Document must finish loading before its content key can rotate\",\n );\n }\n return assertDocumentStoreCanRotateContentKey(state);\n}\n\nasync function discardBackingDocumentStoreLocalState(\n state: DocumentStoreState,\n scheduleSync: () => void,\n expectedDocumentId: string,\n) {\n try {\n return await discardDocumentStoreLocalState(state, expectedDocumentId);\n } finally {\n // Restart hydration whenever the attempt reset the store. This runs outside\n // its identity-chained task because initialization also chains writes.\n ensureDocumentStoreInitialized(state, scheduleSync);\n scheduleSync();\n }\n}\n\nfunction createLiveSyncLaneRequest(state: DocumentStoreState) {\n return <Result>(request: () => Result): Result => {\n refreshDocumentStoreSyncLane(state);\n return request();\n };\n}\n\nfunction registerBackingStoreInternalRelink(input: {\n scheduleSync: () => void;\n state: DocumentStoreState;\n store: DocumentStore;\n withLiveSyncLane: ReturnType<typeof createLiveSyncLaneRequest>;\n}): DocumentStore {\n registerInternalDocumentRelink(input.store, (relinkInput, commitSideEffect) =>\n input.withLiveSyncLane(() =>\n relinkDocumentStore(\n input.state,\n relinkInput,\n input.scheduleSync,\n commitSideEffect,\n ),\n ),\n );\n return input.store;\n}\n\nfunction createBackingStoreContext(\n localId: string,\n runtime: DocumentsRuntime,\n persistence: DocumentsPersistence,\n documentId: string | null,\n text: string,\n documentKind: StoredDocumentKind,\n options: DocumentStoreOpenOptions,\n) {\n const state = createDocumentStoreState(\n localId,\n runtime,\n persistence,\n {\n emitPersistedDocument,\n registerDocumentIdentity: registerDocumentStoreIdentity,\n },\n documentId,\n text,\n documentKind,\n (options.remoteSyncMode ?? \"startup\") === \"startup\",\n );\n if (options.deferInitialUpdate) state.deferInitialUpdate = true;\n refreshDocumentStoreSyncLane(state);\n const scheduleSync = () => requestDocumentStoreSync(state);\n return {\n scheduleSync,\n state,\n withLiveSyncLane: createLiveSyncLaneRequest(state),\n };\n}\n\nfunction createBackingDocumentStore(\n localId: string,\n initialRuntime: DocumentsRuntime,\n persistence: DocumentsPersistence = defaultDocumentsPersistence,\n initialDocumentId: string | null = null,\n initialText = \"\",\n initialDocumentKind: StoredDocumentKind = DEFAULT_DOCUMENT_KIND,\n openOptions: DocumentStoreOpenOptions = {},\n): DocumentStore {\n const { scheduleSync, state, withLiveSyncLane } = createBackingStoreContext(\n localId,\n initialRuntime,\n persistence,\n initialDocumentId,\n initialText,\n initialDocumentKind,\n openOptions,\n );\n\n const store: DocumentStore = {\n addRow: (fields) =>\n withLiveSyncLane(() =>\n addRowToDocumentStore(state, scheduleSync, fields),\n ),\n assertCanRotateContentKey: () =>\n withLiveSyncLane(() =>\n assertBackingDocumentStoreCanRotate(state, scheduleSync),\n ),\n attachFiles: (files: ReadonlyArray<DocumentAttachmentUpload>) =>\n withLiveSyncLane(() =>\n attachFilesToDocumentStore(state, scheduleSync, files),\n ),\n discardLocalState: (expectedDocumentId: string) =>\n withLiveSyncLane(() =>\n discardBackingDocumentStoreLocalState(\n state,\n scheduleSync,\n expectedDocumentId,\n ),\n ),\n ensureInitialized: () =>\n withLiveSyncLane(() => ensureDocumentStoreReady(state, scheduleSync)),\n getSnapshot: () => state.snapshot,\n removeAttachment: (slotId: string) =>\n withLiveSyncLane(() =>\n removeAttachmentFromDocumentStore(state, scheduleSync, slotId),\n ),\n removeRow: (id) =>\n withLiveSyncLane(() =>\n removeRowFromDocumentStore(state, scheduleSync, id),\n ),\n replaceAttachment: (slotId: string, file: DocumentAttachmentUpload) =>\n withLiveSyncLane(() =>\n replaceAttachmentInDocumentStore(state, scheduleSync, slotId, file),\n ),\n requestRemoteSync: () =>\n withLiveSyncLane(() =>\n requestRemoteDocumentStoreSync(state, scheduleSync),\n ),\n requestRemoteSyncAndWait: (signal) =>\n requestRemoteDocumentStoreSyncAndWait(state, scheduleSync, signal),\n requestSync: () =>\n withLiveSyncLane(() =>\n requestOrdinaryDocumentStoreSync(state, scheduleSync),\n ),\n relink: (input) =>\n withLiveSyncLane(() => relinkDocumentStore(state, input, scheduleSync)),\n setStructuredFields: (kind, patch, options) =>\n withLiveSyncLane(() =>\n setDocumentStructuredFields(state, scheduleSync, kind, patch, options),\n ),\n setText: (value: string) =>\n withLiveSyncLane(() => setDocumentText(state, scheduleSync, value)),\n subscribe: (listener) => subscribeToDocumentStore(state, listener),\n updateRowFields: (id, patch) =>\n withLiveSyncLane(() =>\n updateRowInDocumentStore(state, scheduleSync, id, patch),\n ),\n updateRuntime: (runtime: DocumentsRuntime) =>\n updateDocumentStoreRuntime(state, runtime, scheduleSync),\n };\n return registerBackingStoreInternalRelink({\n scheduleSync,\n state,\n store,\n withLiveSyncLane,\n });\n}\n\nexport function createDocumentStore(\n localId: string,\n initialRuntime: DocumentsRuntime,\n persistence: DocumentsPersistence = defaultDocumentsPersistence,\n initialDocumentId: string | null = null,\n initialText = \"\",\n initialDocumentKind: StoredDocumentKind = DEFAULT_DOCUMENT_KIND,\n options: DocumentStoreOpenOptions = {},\n): DocumentStoreFacade {\n return createDocumentStoreFacade(\n createBackingDocumentStore(\n localId,\n initialRuntime,\n persistence,\n initialDocumentId,\n initialText,\n initialDocumentKind,\n options,\n ),\n );\n}\n\nexport function getOrCreateDocumentStore(\n domainScope: DomainScope,\n localId: string,\n runtime: DocumentsRuntime,\n initialDocumentId: string | null = null,\n initialText = \"\",\n initialDocumentKind: StoredDocumentKind = DEFAULT_DOCUMENT_KIND,\n options: DocumentStoreOpenOptions = {},\n): DocumentStore {\n const registry = getOrCreateDocumentStoreRegistry(domainScope);\n const existingStore = registry.storesByKey.get(\n resolveDocumentStoreKey(registry, localId, initialDocumentId),\n );\n if (existingStore) {\n registerDocumentStore(\n domainScope,\n localId,\n existingStore,\n initialDocumentId,\n );\n return existingStore;\n }\n\n const nextStore = createDocumentStore(\n localId,\n runtime,\n defaultDocumentsPersistence,\n initialDocumentId,\n initialText,\n initialDocumentKind,\n options,\n );\n registerDocumentStore(domainScope, localId, nextStore, initialDocumentId);\n return nextStore;\n}\n\nexport function openDocumentStore(\n domainScope: DomainScope,\n localId: string,\n runtime: DocumentsRuntime,\n initialDocumentId: string | null = null,\n initialText = \"\",\n initialDocumentKind: StoredDocumentKind = DEFAULT_DOCUMENT_KIND,\n options: DocumentStoreOpenOptions = {},\n): DocumentStore {\n const store = getOrCreateDocumentStore(\n domainScope,\n localId,\n runtime,\n initialDocumentId,\n initialText,\n initialDocumentKind,\n options,\n );\n store.updateRuntime(runtime);\n return store;\n}\n"]}
1
+ {"version":3,"file":"documentStore.js","sourceRoot":"","sources":["documentStore.ts"],"names":[],"mappings":"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","sourcesContent":["import { DEFAULT_DOCUMENT_KIND } from \"../../data/documents/documentConstants\";\nimport type { StoredDocumentKind } from \"../../data/documents/documentKinds\";\nimport type { DomainScope } from \"../../data/domainScope\";\nimport {\n createDocumentProjectionUserKeyResolver,\n type DocumentsPersistence,\n defaultDocumentsPersistence,\n didDocumentProjectionKeyRuntimeChange,\n didRegainSyncPrerequisites,\n requestDocumentSyncLaneAndWait,\n} from \"../../workflows/documents\";\nimport { removeAttachmentFromDocumentStore } from \"./documentStore/attachmentRemoval\";\nimport {\n attachFilesToDocumentStore,\n replaceAttachmentInDocumentStore,\n} from \"./documentStore/attachments\";\nimport { discardDocumentStoreLocalState } from \"./documentStore/discard\";\nimport {\n ensureDocumentStoreInitialized,\n ensureDocumentStoreReady,\n relinkDocumentStore,\n} from \"./documentStore/initialization\";\nimport { registerInternalDocumentRelink } from \"./documentStore/internalRelink\";\nimport {\n setDocumentStructuredFields,\n setDocumentText,\n} from \"./documentStore/mutations\";\nimport { logRevalidationScheduled } from \"./documentStore/remoteRevalidationTelemetry\";\nimport { assertDocumentStoreCanRotateContentKey } from \"./documentStore/rotation\";\nimport {\n addRowToDocumentStore,\n removeRowFromDocumentStore,\n updateRowInDocumentStore,\n} from \"./documentStore/rows\";\nimport {\n createDocumentStoreState,\n type DocumentStoreState,\n refreshAttachabilitySnapshot,\n resetDocumentStore,\n subscribeToDocumentStore,\n} from \"./documentStore/state\";\nimport { registerDocumentStoreSyncLane } from \"./documentStore/sync\";\nimport {\n allowDocumentStoreRemoteSync,\n captureDocumentStoreRemoteSyncRequestGeneration,\n captureDocumentStoreSyncLaneGeneration,\n type DocumentStoreRemoteSyncRequestGeneration,\n type DocumentStoreSyncLaneGeneration,\n didDocumentStoreRemoteSyncRequestComplete,\n hasPendingIndependentDocumentStoreRemoteSync,\n invalidateDocumentStoreRemoteSync,\n invalidateDocumentStoreSyncLane,\n isDocumentStoreRemoteSyncBlocked,\n isDocumentStoreRemoteSyncRequestGenerationCurrent,\n markDocumentStoreRemoteSyncPending,\n registerDocumentStoreRemoteSyncWaiter,\n} from \"./documentStore/syncGeneration\";\nimport { handleDocumentRemoteEvents } from \"./documentStore/syncRemoteSignals\";\nimport {\n createDocumentStoreFacade,\n emitPersistedDocument,\n getOrCreateDocumentStoreRegistry,\n registerDocumentStore,\n registerDocumentStoreIdentity,\n requestDocumentStoreSync,\n resolveDocumentStoreKey,\n} from \"./registry\";\nimport type {\n DocumentAttachmentUpload,\n DocumentStore,\n DocumentStoreFacade,\n DocumentStoreOpenOptions,\n DocumentsRuntime,\n} from \"./types\";\n\nexport {\n discardRegisteredDocumentLocalState,\n requestDomainDocumentSync,\n subscribeToPersistedDocuments,\n} from \"./registry\";\n\nfunction refreshDocumentStoreSyncLane(\n state: DocumentStoreState,\n force = false,\n): void {\n if (!force && state.syncLane && !state.syncLane.isDisposed?.()) {\n return;\n }\n if (state.syncLane) {\n invalidateDocumentStoreSyncLane(state);\n }\n let syncLaneGeneration: DocumentStoreSyncLaneGeneration | null = null;\n state.syncLane = registerDocumentStoreSyncLane(\n state,\n () => syncLaneGeneration,\n );\n syncLaneGeneration = captureDocumentStoreSyncLaneGeneration(state);\n}\n\nfunction updateDocumentStoreRuntime(\n state: DocumentStoreState,\n nextRuntime: DocumentsRuntime,\n scheduleSync: () => void,\n) {\n const previousRuntime = state.runtime;\n const serverEventsReconnected =\n (nextRuntime.state.serverEventsConnectionGeneration ?? 0) >\n (previousRuntime.state.serverEventsConnectionGeneration ?? 0);\n const domainScopeChanged =\n previousRuntime.state.domainScope !== nextRuntime.state.domainScope;\n const projectionKeyRuntimeChanged = didDocumentProjectionKeyRuntimeChange(\n previousRuntime,\n nextRuntime,\n );\n if (projectionKeyRuntimeChanged) {\n state.resolveProjectionUserKey =\n createDocumentProjectionUserKeyResolver(nextRuntime);\n state.writerProjection = null;\n }\n state.runtime = nextRuntime;\n refreshDocumentStoreSyncLane(state, domainScopeChanged);\n if (domainScopeChanged) {\n state.locallyAcceptedUpdateIds = new Set();\n state.remoteUpdatePending = false;\n state.writerProjection = null;\n }\n\n if (nextRuntime.infra.dbStatus !== \"ready\") {\n if (state.snapshot.ready || state.initialized || state.initializePromise) {\n resetDocumentStore(state);\n }\n state.lastEventCount = nextRuntime.state.events.length;\n return;\n }\n\n refreshAttachabilitySnapshot(state);\n ensureDocumentStoreInitialized(state, scheduleSync);\n handleDocumentRemoteEvents(state, scheduleSync);\n\n if (state.snapshot.ready) {\n if (serverEventsReconnected) {\n // The invalidation stream is lossy while disconnected. Once the server\n // has acknowledged this socket's authoritative interest declaration,\n // every already-open remote document needs one HTTP probe to cover peer\n // writes made during the gap. This also closes iOS background/resume reconnects where the\n // native network source remained online throughout.\n requestRemoteDocumentStoreSync(state, scheduleSync);\n logRevalidationScheduled(state.runtime, \"reconnect\");\n } else if (didRegainSyncPrerequisites(previousRuntime, state.runtime)) {\n scheduleSync();\n }\n }\n}\n\nfunction requestRemoteDocumentStoreSync(\n state: DocumentStoreState,\n scheduleSync: () => void,\n owner: \"independent\" | \"waiter\" = \"independent\",\n): number {\n allowDocumentStoreRemoteSync(state);\n const signalSequence = markDocumentStoreRemoteSyncPending(state, owner);\n scheduleSync();\n return signalSequence;\n}\n\nfunction requestOrdinaryDocumentStoreSync(\n state: DocumentStoreState,\n scheduleSync: () => void,\n): void {\n // A normal UI reopen is a fresh owner for remote-only work. It may recover\n // a probe that an earlier, now-unmounted owner aborted.\n if (isDocumentStoreRemoteSyncBlocked(state)) {\n requestRemoteDocumentStoreSync(state, scheduleSync);\n return;\n }\n scheduleSync();\n}\n\nfunction requestRemoteDocumentStoreSyncAndWait(\n state: DocumentStoreState,\n scheduleSync: () => void,\n signal?: AbortSignal,\n): Promise<boolean> {\n let requestGeneration: DocumentStoreRemoteSyncRequestGeneration | null = null;\n let requestedSignalSequence = 0;\n let releaseWaiter: (() => boolean) | null = null;\n const releaseRemoteSyncWaiter = (invalidate: boolean) => {\n const releasedLastWaiter = releaseWaiter?.() ?? false;\n if (\n invalidate &&\n releasedLastWaiter &&\n requestGeneration !== null &&\n isDocumentStoreRemoteSyncRequestGenerationCurrent(\n state,\n requestGeneration,\n ) &&\n !hasPendingIndependentDocumentStoreRemoteSync(state)\n ) {\n invalidateDocumentStoreRemoteSync(state);\n }\n };\n // A coordinator can be disposed and recreated while this same-scope store\n // remains registered. Refresh its handle before requesting work.\n refreshDocumentStoreSyncLane(state);\n return requestDocumentSyncLaneAndWait({\n didCompleteRequest: () =>\n requestGeneration !== null &&\n didDocumentStoreRemoteSyncRequestComplete(\n state,\n requestGeneration,\n requestedSignalSequence,\n ),\n domainScope: state.runtime.state.domainScope,\n localId: state.localId,\n request: () => {\n requestGeneration =\n captureDocumentStoreRemoteSyncRequestGeneration(state);\n releaseWaiter = registerDocumentStoreRemoteSyncWaiter(\n state,\n requestGeneration,\n );\n requestedSignalSequence = requestRemoteDocumentStoreSync(\n state,\n scheduleSync,\n \"waiter\",\n );\n },\n onInvalidated: () => releaseRemoteSyncWaiter(true),\n signal,\n }).then(\n (completed) => {\n releaseRemoteSyncWaiter(!completed);\n return completed;\n },\n (error: unknown) => {\n releaseRemoteSyncWaiter(true);\n throw error;\n },\n );\n}\n\nasync function assertBackingDocumentStoreCanRotate(\n state: DocumentStoreState,\n scheduleSync: () => void,\n) {\n if (!(await ensureDocumentStoreReady(state, scheduleSync)) || !state.doc) {\n throw new Error(\n \"Document must finish loading before its content key can rotate\",\n );\n }\n return assertDocumentStoreCanRotateContentKey(state);\n}\n\nasync function discardBackingDocumentStoreLocalState(\n state: DocumentStoreState,\n scheduleSync: () => void,\n expectedDocumentId: string,\n) {\n try {\n return await discardDocumentStoreLocalState(state, expectedDocumentId);\n } finally {\n // Restart hydration whenever the attempt reset the store. This runs outside\n // its identity-chained task because initialization also chains writes.\n ensureDocumentStoreInitialized(state, scheduleSync);\n scheduleSync();\n }\n}\n\nfunction createLiveSyncLaneRequest(state: DocumentStoreState) {\n return <Result>(request: () => Result): Result => {\n refreshDocumentStoreSyncLane(state);\n return request();\n };\n}\n\nfunction registerBackingStoreInternalRelink(input: {\n scheduleSync: () => void;\n state: DocumentStoreState;\n store: DocumentStore;\n withLiveSyncLane: ReturnType<typeof createLiveSyncLaneRequest>;\n}): DocumentStore {\n registerInternalDocumentRelink(input.store, (relinkInput, commitSideEffect) =>\n input.withLiveSyncLane(() =>\n relinkDocumentStore(\n input.state,\n relinkInput,\n input.scheduleSync,\n commitSideEffect,\n ),\n ),\n );\n return input.store;\n}\n\nfunction createBackingStoreContext(\n localId: string,\n runtime: DocumentsRuntime,\n persistence: DocumentsPersistence,\n documentId: string | null,\n text: string,\n documentKind: StoredDocumentKind,\n options: DocumentStoreOpenOptions,\n) {\n const state = createDocumentStoreState(\n localId,\n runtime,\n persistence,\n {\n emitPersistedDocument,\n registerDocumentIdentity: registerDocumentStoreIdentity,\n },\n documentId,\n text,\n documentKind,\n (options.remoteSyncMode ?? \"startup\") === \"startup\",\n );\n if (options.deferInitialUpdate) state.deferInitialUpdate = true;\n refreshDocumentStoreSyncLane(state);\n const scheduleSync = () => requestDocumentStoreSync(state);\n return {\n scheduleSync,\n state,\n withLiveSyncLane: createLiveSyncLaneRequest(state),\n };\n}\n\nfunction createBackingDocumentStore(\n localId: string,\n initialRuntime: DocumentsRuntime,\n persistence: DocumentsPersistence = defaultDocumentsPersistence,\n initialDocumentId: string | null = null,\n initialText = \"\",\n initialDocumentKind: StoredDocumentKind = DEFAULT_DOCUMENT_KIND,\n openOptions: DocumentStoreOpenOptions = {},\n): DocumentStore {\n const { scheduleSync, state, withLiveSyncLane } = createBackingStoreContext(\n localId,\n initialRuntime,\n persistence,\n initialDocumentId,\n initialText,\n initialDocumentKind,\n openOptions,\n );\n\n const store: DocumentStore = {\n addRow: (fields) =>\n withLiveSyncLane(() =>\n addRowToDocumentStore(state, scheduleSync, fields),\n ),\n assertCanRotateContentKey: () =>\n withLiveSyncLane(() =>\n assertBackingDocumentStoreCanRotate(state, scheduleSync),\n ),\n attachFiles: (files: ReadonlyArray<DocumentAttachmentUpload>) =>\n withLiveSyncLane(() =>\n attachFilesToDocumentStore(state, scheduleSync, files),\n ),\n discardLocalState: (expectedDocumentId: string) =>\n withLiveSyncLane(() =>\n discardBackingDocumentStoreLocalState(\n state,\n scheduleSync,\n expectedDocumentId,\n ),\n ),\n ensureInitialized: () =>\n withLiveSyncLane(() => ensureDocumentStoreReady(state, scheduleSync)),\n getSnapshot: () => state.snapshot,\n removeAttachment: (slotId: string) =>\n withLiveSyncLane(() =>\n removeAttachmentFromDocumentStore(state, scheduleSync, slotId),\n ),\n removeRow: (id) =>\n withLiveSyncLane(() =>\n removeRowFromDocumentStore(state, scheduleSync, id),\n ),\n replaceAttachment: (slotId: string, file: DocumentAttachmentUpload) =>\n withLiveSyncLane(() =>\n replaceAttachmentInDocumentStore(state, scheduleSync, slotId, file),\n ),\n requestRemoteSync: () =>\n withLiveSyncLane(() =>\n requestRemoteDocumentStoreSync(state, scheduleSync),\n ),\n requestRemoteSyncAndWait: (signal) =>\n requestRemoteDocumentStoreSyncAndWait(state, scheduleSync, signal),\n requestSync: () =>\n withLiveSyncLane(() =>\n requestOrdinaryDocumentStoreSync(state, scheduleSync),\n ),\n relink: (input) =>\n withLiveSyncLane(() => relinkDocumentStore(state, input, scheduleSync)),\n setStructuredFields: (kind, patch, options) =>\n withLiveSyncLane(() =>\n setDocumentStructuredFields(state, scheduleSync, kind, patch, options),\n ),\n setText: (value: string) =>\n withLiveSyncLane(() => setDocumentText(state, scheduleSync, value)),\n subscribe: (listener) => subscribeToDocumentStore(state, listener),\n updateRowFields: (id, patch) =>\n withLiveSyncLane(() =>\n updateRowInDocumentStore(state, scheduleSync, id, patch),\n ),\n updateRuntime: (runtime: DocumentsRuntime) =>\n updateDocumentStoreRuntime(state, runtime, scheduleSync),\n };\n return registerBackingStoreInternalRelink({\n scheduleSync,\n state,\n store,\n withLiveSyncLane,\n });\n}\n\nexport function createDocumentStore(\n localId: string,\n initialRuntime: DocumentsRuntime,\n persistence: DocumentsPersistence = defaultDocumentsPersistence,\n initialDocumentId: string | null = null,\n initialText = \"\",\n initialDocumentKind: StoredDocumentKind = DEFAULT_DOCUMENT_KIND,\n options: DocumentStoreOpenOptions = {},\n): DocumentStoreFacade {\n return createDocumentStoreFacade(\n createBackingDocumentStore(\n localId,\n initialRuntime,\n persistence,\n initialDocumentId,\n initialText,\n initialDocumentKind,\n options,\n ),\n );\n}\n\nexport function getOrCreateDocumentStore(\n domainScope: DomainScope,\n localId: string,\n runtime: DocumentsRuntime,\n initialDocumentId: string | null = null,\n initialText = \"\",\n initialDocumentKind: StoredDocumentKind = DEFAULT_DOCUMENT_KIND,\n options: DocumentStoreOpenOptions = {},\n): DocumentStore {\n const registry = getOrCreateDocumentStoreRegistry(domainScope);\n const existingStore = registry.storesByKey.get(\n resolveDocumentStoreKey(registry, localId, initialDocumentId),\n );\n if (existingStore) {\n registerDocumentStore(\n domainScope,\n localId,\n existingStore,\n initialDocumentId,\n );\n return existingStore;\n }\n\n const nextStore = createDocumentStore(\n localId,\n runtime,\n defaultDocumentsPersistence,\n initialDocumentId,\n initialText,\n initialDocumentKind,\n options,\n );\n registerDocumentStore(domainScope, localId, nextStore, initialDocumentId);\n return nextStore;\n}\n\nexport function openDocumentStore(\n domainScope: DomainScope,\n localId: string,\n runtime: DocumentsRuntime,\n initialDocumentId: string | null = null,\n initialText = \"\",\n initialDocumentKind: StoredDocumentKind = DEFAULT_DOCUMENT_KIND,\n options: DocumentStoreOpenOptions = {},\n): DocumentStore {\n const store = getOrCreateDocumentStore(\n domainScope,\n localId,\n runtime,\n initialDocumentId,\n initialText,\n initialDocumentKind,\n options,\n );\n store.updateRuntime(runtime);\n return store;\n}\n"]}
@@ -118,29 +118,37 @@ async function refreshAndReconcileContainers(input) {
118
118
  }
119
119
  // Sweeps share the queue and discovered set, so they must run serially.
120
120
  // Root requests join either kind of sweep; a full request after a root sweep
121
- // must wait for it and then refresh the whole tree.
121
+ // must wait for it and then refresh the whole tree. A fresh-listing request
122
+ // joins only a sweep that has not started: one already running may have listed
123
+ // before the event behind the request, so it queues a trailing sweep instead.
122
124
  function requestContainerRefresh(input) {
123
125
  const { state, scope } = input;
124
126
  const pending = state.pendingRefresh;
125
- if (pending && (scope === "root" || pending.scope === "full")) {
127
+ if (pending &&
128
+ (scope === "root" || pending.scope === "full") &&
129
+ !(input.freshListing && pending.started.value)) {
126
130
  return pending.promise;
127
131
  }
132
+ const started = { value: false };
128
133
  const promise = (pending?.promise ?? Promise.resolve())
129
- // A failed root sweep must not prevent the queued full refresh.
134
+ // A failed earlier sweep must not prevent the queued refresh.
130
135
  .catch(() => undefined)
131
- .then(() => refreshAndReconcileContainers({
132
- forceAllDocumentContentPulls: scope === "full",
133
- host: input.host,
134
- listContainerIds: input.listContainerIds,
135
- refreshTree: input.refreshTree,
136
- state,
137
- }))
136
+ .then(() => {
137
+ started.value = true;
138
+ return refreshAndReconcileContainers({
139
+ forceAllDocumentContentPulls: scope === "full",
140
+ host: input.host,
141
+ listContainerIds: input.listContainerIds,
142
+ refreshTree: input.refreshTree,
143
+ state,
144
+ });
145
+ })
138
146
  .finally(() => {
139
147
  if (state.pendingRefresh?.promise === promise) {
140
148
  state.pendingRefresh = null;
141
149
  }
142
150
  });
143
- state.pendingRefresh = { promise, scope };
151
+ state.pendingRefresh = { promise, scope, started };
144
152
  return promise;
145
153
  }
146
154
  function listFullRefreshContainerIds(host, state) {
@@ -267,7 +275,8 @@ export function createReconciliationService(host) {
267
275
  state.discoveredContainerIds.clear();
268
276
  state.initialDocumentProbe.resetSkippedListings();
269
277
  },
270
- reconcileRootContainersNow: () => requestContainerRefresh({
278
+ reconcileRootContainersNow: (options) => requestContainerRefresh({
279
+ freshListing: options?.freshListing === true,
271
280
  host,
272
281
  state,
273
282
  refreshTree: host.refreshRootTree,
@@ -275,6 +284,7 @@ export function createReconciliationService(host) {
275
284
  scope: "root",
276
285
  }),
277
286
  reconcileNow: () => requestContainerRefresh({
287
+ freshListing: false,
278
288
  host,
279
289
  state,
280
290
  refreshTree: host.refreshTree,
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getOrCreateDomainSyncCoordinator,\n type SyncLane,\n} from \"../../data/sync/syncCoordinator\";\nimport {\n acknowledgeContainerForce,\n activateContainer,\n enqueueKnownContainersForIdleBackfill,\n type IdleBackfillState,\n markContainerForced,\n} from \"./idleBackfill\";\nimport { createInitialDocumentProbe } from \"./initialDocumentProbe\";\nimport {\n clearPendingDiscoveryRetries,\n isCurrentReconciliationLifecycle,\n reconcileMarkedContainer,\n sweepKnownContainers,\n} from \"./knownContainerSweep\";\nimport { rearmFailedContainer } from \"./laneFailure\";\nimport { clearOriginatedDocuments } from \"./originatedDocuments\";\nimport { createReconcileQueue, type ReconcilePriority } from \"./queue\";\nimport type {\n ReconciliationHost,\n ReconciliationRuntimeStatus,\n ReconciliationService,\n} from \"./serviceTypes\";\n\nfunction canReconcile(status: ReconciliationRuntimeStatus): boolean {\n return status.dbStatus === \"ready\" && status.isAuthenticated && status.online;\n}\n\ntype RefreshScope = \"root\" | \"full\";\n\ninterface ReconciliationState extends IdleBackfillState {\n active: boolean;\n lane: SyncLane | null;\n lifecycleGeneration: number;\n probeContinuationCancel: (() => void) | null;\n pendingRefresh: {\n readonly promise: Promise<void>;\n readonly scope: RefreshScope;\n } | null;\n}\n\nasync function runReconcileLane(\n host: ReconciliationHost,\n state: ReconciliationState,\n): Promise<void> {\n if (!state.active || !canReconcile(host.getRuntimeStatus())) {\n return;\n }\n const lifecycleGeneration = state.lifecycleGeneration;\n\n const containerId = state.queue.dequeue();\n if (!containerId) {\n await state.initialDocumentProbe.run();\n scheduleProbeContinuation(host, state);\n return;\n }\n // Double-check at run time: a container may have been discovered (by an\n // explicit refresh or an earlier lane pass) after it was queued. Mark it\n // discovered up front to collapse concurrent re-enqueues into one fetch, but\n // roll the mark back on failure so a transient error can be retried later.\n const forceGeneration = state.forcedContainerGenerations.get(containerId);\n const shouldForce = forceGeneration !== undefined;\n if (shouldForce || !state.discoveredContainerIds.has(containerId)) {\n state.discoveredContainerIds.add(containerId);\n try {\n const reconciled = await reconcileMarkedContainer(\n host,\n state,\n containerId,\n shouldForce,\n );\n if (reconciled) {\n acknowledgeContainerForce(state, containerId, forceGeneration);\n }\n } catch (error) {\n rearmFailedContainer(\n state,\n containerId,\n forceGeneration,\n lifecycleGeneration,\n );\n throw error;\n }\n }\n\n // Keep draining: schedule another pass while the queue holds work.\n if (state.queue.size > 0) {\n state.lane?.requestSync();\n } else {\n scheduleProbeContinuation(host, state);\n }\n}\n\nfunction scheduleProbeContinuation(\n host: ReconciliationHost,\n state: ReconciliationState,\n): void {\n state.probeContinuationCancel?.();\n const canContinue = () =>\n state.active &&\n state.queue.size === 0 &&\n canReconcile(host.getRuntimeStatus()) &&\n state.initialDocumentProbe.hasPendingWork();\n if (!canContinue()) {\n state.probeContinuationCancel = null;\n return;\n }\n const timeout = setTimeout(() => {\n if (canContinue()) {\n state.probeContinuationCancel = null;\n state.lane?.requestSync();\n }\n }, state.initialDocumentProbe.continuationDelayMs());\n state.probeContinuationCancel = () => clearTimeout(timeout);\n}\n\nfunction forgetIneligibleDiscoveredContainers(\n host: ReconciliationHost,\n state: ReconciliationState,\n): void {\n for (const containerId of state.discoveredContainerIds) {\n if (!host.canDiscoverContainerDocuments(containerId)) {\n state.discoveredContainerIds.delete(containerId);\n }\n }\n}\n\nasync function refreshAndReconcileContainers(input: {\n forceAllDocumentContentPulls: boolean;\n host: ReconciliationHost;\n listContainerIds: () => ReadonlyArray<string>;\n refreshTree: () => Promise<void>;\n state: ReconciliationState;\n}): Promise<void> {\n const { host, listContainerIds, refreshTree, state } = input;\n if (!canReconcile(host.getRuntimeStatus())) {\n return;\n }\n const lifecycleGeneration = state.lifecycleGeneration;\n\n if (input.forceAllDocumentContentPulls) {\n state.queue.clear();\n }\n try {\n // A resync_required structural refresh runs independently of this service.\n // If it already removed a container after the forced document lane won its\n // race against the old tree, forget the stale discovered bit before this\n // refresh can re-add the same id.\n forgetIneligibleDiscoveredContainers(host, state);\n await refreshTree();\n if (!isCurrentReconciliationLifecycle(state, lifecycleGeneration)) {\n return;\n }\n // Structural hydration can revoke and remove a container after a targeted\n // force already reconciled it against the old tree. Forget every id that\n // is no longer remotely listable so a later share of the same container id\n // is treated as newly surfaced instead of being suppressed for the rest of\n // the session.\n forgetIneligibleDiscoveredContainers(host, state);\n await sweepKnownContainers({\n forceAllDocumentContentPulls: input.forceAllDocumentContentPulls,\n host,\n knownIds: listContainerIds(),\n lifecycleGeneration,\n state,\n });\n if (!isCurrentReconciliationLifecycle(state, lifecycleGeneration)) {\n return;\n }\n } catch (error) {\n if (!isCurrentReconciliationLifecycle(state, lifecycleGeneration)) {\n return;\n }\n if (!host.isIgnorableError(error)) {\n throw error;\n }\n }\n}\n\n// Sweeps share the queue and discovered set, so they must run serially.\n// Root requests join either kind of sweep; a full request after a root sweep\n// must wait for it and then refresh the whole tree.\nfunction requestContainerRefresh(input: {\n host: ReconciliationHost;\n state: ReconciliationState;\n refreshTree: () => Promise<void>;\n listContainerIds: () => ReadonlyArray<string>;\n scope: RefreshScope;\n}): Promise<void> {\n const { state, scope } = input;\n const pending = state.pendingRefresh;\n if (pending && (scope === \"root\" || pending.scope === \"full\")) {\n return pending.promise;\n }\n\n const promise = (pending?.promise ?? Promise.resolve())\n // A failed root sweep must not prevent the queued full refresh.\n .catch(() => undefined)\n .then(() =>\n refreshAndReconcileContainers({\n forceAllDocumentContentPulls: scope === \"full\",\n host: input.host,\n listContainerIds: input.listContainerIds,\n refreshTree: input.refreshTree,\n state,\n }),\n )\n .finally(() => {\n if (state.pendingRefresh?.promise === promise) {\n state.pendingRefresh = null;\n }\n });\n state.pendingRefresh = { promise, scope };\n return promise;\n}\n\nfunction listFullRefreshContainerIds(\n host: ReconciliationHost,\n state: ReconciliationState,\n): ReadonlyArray<string> {\n const knownIds = host.listKnownContainerIds();\n const activeContainerId = state.activeContainerId;\n if (\n !activeContainerId ||\n knownIds.includes(activeContainerId) ||\n !host.canDiscoverContainerDocuments(activeContainerId)\n ) {\n return knownIds;\n }\n // Explicit refresh also retries an open foreign system container that the\n // background discovery list excludes.\n return [...knownIds, activeContainerId];\n}\n\nfunction startReconciliationLane(\n host: ReconciliationHost,\n state: ReconciliationState,\n): void {\n if (state.active) {\n return;\n }\n state.lifecycleGeneration += 1;\n state.active = true;\n state.lane = getOrCreateDomainSyncCoordinator(host.domainScope).registerLane(\n \"reconciliation:documents\",\n {\n label: \"Device-first document reconciliation\",\n // Document discovery runs in the document phase, after structural\n // container hydration/metadata sync settles for the scope.\n phase: \"document\",\n priority: () => (state.activeContainerId ? -1 : 0),\n onUnexpectedError: (error) => {\n console.error(\"Device-first reconciliation failed:\", error);\n },\n // Fixed literal: no container or document id may reach a report. The\n // mapped stack identifies which lane body threw. Returning the host's\n // result hands a rejection to the lane reporter's wrapper; discarding it\n // would surface as an unhandled rejection instead.\n reportUnexpectedError: (error) =>\n host.logError?.(\"Reconciliation: sync lane failed\", error),\n run: () => runReconcileLane(host, state),\n shouldIgnoreError: host.isIgnorableError,\n },\n );\n}\n\nfunction createReconciliationState(\n host: ReconciliationHost,\n): ReconciliationState {\n return {\n active: false,\n activeContainerId: null,\n automaticRetryGenerations: new Map(),\n discoveredContainerIds: new Set(),\n forcedContainerGenerations: new Map(),\n forcedDocumentIds: new Map(),\n initialDocumentProbe: createInitialDocumentProbe(host),\n lane: null,\n lifecycleGeneration: 0,\n nextForceGeneration: 0,\n probeContinuationCancel: null,\n queue: createReconcileQueue(),\n pendingRefresh: null,\n };\n}\n\nfunction stopReconciliationService(\n host: ReconciliationHost,\n state: ReconciliationState,\n): void {\n clearPendingDiscoveryRetries(state);\n state.active = false;\n state.probeContinuationCancel?.();\n state.probeContinuationCancel = null;\n state.queue.clear();\n state.automaticRetryGenerations.clear();\n state.forcedContainerGenerations.clear();\n state.forcedDocumentIds.clear();\n state.pendingRefresh = null;\n state.initialDocumentProbe.resetPending();\n // Drop the per-session discovered suppression cache too: a stopped\n // reconciler is being torn down (scope/identity change) or paused across\n // a prerequisite loss, after which every container must be re-validated.\n state.discoveredContainerIds.clear();\n // Drop pending self-echo originations too — they are session-scoped and a\n // teardown invalidates them.\n clearOriginatedDocuments(host.domainScope);\n}\n\nexport function createReconciliationService(\n host: ReconciliationHost,\n): ReconciliationService {\n const state = createReconciliationState(host);\n\n const scheduleDrain = () => {\n if (\n !state.active ||\n (state.queue.size === 0 && !state.initialDocumentProbe.canRun())\n ) {\n return;\n }\n if (!canReconcile(host.getRuntimeStatus())) {\n return;\n }\n state.probeContinuationCancel?.();\n state.probeContinuationCancel = null;\n state.lane?.requestSync();\n };\n\n const enqueueContainer = (\n containerId: string,\n priority: ReconcilePriority,\n force = false,\n documentId?: string,\n ) => {\n if (!containerId) {\n return;\n }\n // Skip containers already reconciled this session unless forced. Events\n // force re-discovery; passive active/backfill scheduling does not, so\n // opening Explorer does not re-fetch every container on each navigation.\n if (\n !force &&\n !state.forcedContainerGenerations.has(containerId) &&\n state.discoveredContainerIds.has(containerId)\n ) {\n return;\n }\n if (force) {\n markContainerForced(state, containerId, documentId);\n }\n state.queue.enqueue(containerId, priority);\n scheduleDrain();\n };\n\n const enqueueIdleBackfill = () => {\n enqueueKnownContainersForIdleBackfill({\n host,\n scheduleDrain,\n state,\n });\n };\n\n return {\n start: () => {\n startReconciliationLane(host, state);\n scheduleDrain();\n },\n // Reconcile the active container first; siblings remain lazy until visited.\n setActiveContainer: (containerId) =>\n activateContainer(state, containerId, (activeId) =>\n enqueueContainer(activeId, \"active\"),\n ),\n enqueueContainer,\n enqueueIdleBackfill,\n resetDiscovered: () => {\n state.discoveredContainerIds.clear();\n state.initialDocumentProbe.resetSkippedListings();\n },\n reconcileRootContainersNow: () =>\n requestContainerRefresh({\n host,\n state,\n refreshTree: host.refreshRootTree,\n listContainerIds: host.listAutomaticRootCatchupContainerIds,\n scope: \"root\",\n }),\n reconcileNow: () =>\n requestContainerRefresh({\n host,\n state,\n refreshTree: host.refreshTree,\n listContainerIds: () => listFullRefreshContainerIds(host, state),\n scope: \"full\",\n }),\n stop: () => stopReconciliationService(host, state),\n };\n}\n"]}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getOrCreateDomainSyncCoordinator,\n type SyncLane,\n} from \"../../data/sync/syncCoordinator\";\nimport {\n acknowledgeContainerForce,\n activateContainer,\n enqueueKnownContainersForIdleBackfill,\n type IdleBackfillState,\n markContainerForced,\n} from \"./idleBackfill\";\nimport { createInitialDocumentProbe } from \"./initialDocumentProbe\";\nimport {\n clearPendingDiscoveryRetries,\n isCurrentReconciliationLifecycle,\n reconcileMarkedContainer,\n sweepKnownContainers,\n} from \"./knownContainerSweep\";\nimport { rearmFailedContainer } from \"./laneFailure\";\nimport { clearOriginatedDocuments } from \"./originatedDocuments\";\nimport { createReconcileQueue, type ReconcilePriority } from \"./queue\";\nimport type {\n ReconciliationHost,\n ReconciliationRuntimeStatus,\n ReconciliationService,\n} from \"./serviceTypes\";\n\nfunction canReconcile(status: ReconciliationRuntimeStatus): boolean {\n return status.dbStatus === \"ready\" && status.isAuthenticated && status.online;\n}\n\ntype RefreshScope = \"root\" | \"full\";\n\ninterface ReconciliationState extends IdleBackfillState {\n active: boolean;\n lane: SyncLane | null;\n lifecycleGeneration: number;\n probeContinuationCancel: (() => void) | null;\n pendingRefresh: {\n readonly promise: Promise<void>;\n readonly scope: RefreshScope;\n readonly started: { value: boolean };\n } | null;\n}\n\nasync function runReconcileLane(\n host: ReconciliationHost,\n state: ReconciliationState,\n): Promise<void> {\n if (!state.active || !canReconcile(host.getRuntimeStatus())) {\n return;\n }\n const lifecycleGeneration = state.lifecycleGeneration;\n\n const containerId = state.queue.dequeue();\n if (!containerId) {\n await state.initialDocumentProbe.run();\n scheduleProbeContinuation(host, state);\n return;\n }\n // Double-check at run time: a container may have been discovered (by an\n // explicit refresh or an earlier lane pass) after it was queued. Mark it\n // discovered up front to collapse concurrent re-enqueues into one fetch, but\n // roll the mark back on failure so a transient error can be retried later.\n const forceGeneration = state.forcedContainerGenerations.get(containerId);\n const shouldForce = forceGeneration !== undefined;\n if (shouldForce || !state.discoveredContainerIds.has(containerId)) {\n state.discoveredContainerIds.add(containerId);\n try {\n const reconciled = await reconcileMarkedContainer(\n host,\n state,\n containerId,\n shouldForce,\n );\n if (reconciled) {\n acknowledgeContainerForce(state, containerId, forceGeneration);\n }\n } catch (error) {\n rearmFailedContainer(\n state,\n containerId,\n forceGeneration,\n lifecycleGeneration,\n );\n throw error;\n }\n }\n\n // Keep draining: schedule another pass while the queue holds work.\n if (state.queue.size > 0) {\n state.lane?.requestSync();\n } else {\n scheduleProbeContinuation(host, state);\n }\n}\n\nfunction scheduleProbeContinuation(\n host: ReconciliationHost,\n state: ReconciliationState,\n): void {\n state.probeContinuationCancel?.();\n const canContinue = () =>\n state.active &&\n state.queue.size === 0 &&\n canReconcile(host.getRuntimeStatus()) &&\n state.initialDocumentProbe.hasPendingWork();\n if (!canContinue()) {\n state.probeContinuationCancel = null;\n return;\n }\n const timeout = setTimeout(() => {\n if (canContinue()) {\n state.probeContinuationCancel = null;\n state.lane?.requestSync();\n }\n }, state.initialDocumentProbe.continuationDelayMs());\n state.probeContinuationCancel = () => clearTimeout(timeout);\n}\n\nfunction forgetIneligibleDiscoveredContainers(\n host: ReconciliationHost,\n state: ReconciliationState,\n): void {\n for (const containerId of state.discoveredContainerIds) {\n if (!host.canDiscoverContainerDocuments(containerId)) {\n state.discoveredContainerIds.delete(containerId);\n }\n }\n}\n\nasync function refreshAndReconcileContainers(input: {\n forceAllDocumentContentPulls: boolean;\n host: ReconciliationHost;\n listContainerIds: () => ReadonlyArray<string>;\n refreshTree: () => Promise<void>;\n state: ReconciliationState;\n}): Promise<void> {\n const { host, listContainerIds, refreshTree, state } = input;\n if (!canReconcile(host.getRuntimeStatus())) {\n return;\n }\n const lifecycleGeneration = state.lifecycleGeneration;\n\n if (input.forceAllDocumentContentPulls) {\n state.queue.clear();\n }\n try {\n // A resync_required structural refresh runs independently of this service.\n // If it already removed a container after the forced document lane won its\n // race against the old tree, forget the stale discovered bit before this\n // refresh can re-add the same id.\n forgetIneligibleDiscoveredContainers(host, state);\n await refreshTree();\n if (!isCurrentReconciliationLifecycle(state, lifecycleGeneration)) {\n return;\n }\n // Structural hydration can revoke and remove a container after a targeted\n // force already reconciled it against the old tree. Forget every id that\n // is no longer remotely listable so a later share of the same container id\n // is treated as newly surfaced instead of being suppressed for the rest of\n // the session.\n forgetIneligibleDiscoveredContainers(host, state);\n await sweepKnownContainers({\n forceAllDocumentContentPulls: input.forceAllDocumentContentPulls,\n host,\n knownIds: listContainerIds(),\n lifecycleGeneration,\n state,\n });\n if (!isCurrentReconciliationLifecycle(state, lifecycleGeneration)) {\n return;\n }\n } catch (error) {\n if (!isCurrentReconciliationLifecycle(state, lifecycleGeneration)) {\n return;\n }\n if (!host.isIgnorableError(error)) {\n throw error;\n }\n }\n}\n\n// Sweeps share the queue and discovered set, so they must run serially.\n// Root requests join either kind of sweep; a full request after a root sweep\n// must wait for it and then refresh the whole tree. A fresh-listing request\n// joins only a sweep that has not started: one already running may have listed\n// before the event behind the request, so it queues a trailing sweep instead.\nfunction requestContainerRefresh(input: {\n freshListing: boolean;\n host: ReconciliationHost;\n state: ReconciliationState;\n refreshTree: () => Promise<void>;\n listContainerIds: () => ReadonlyArray<string>;\n scope: RefreshScope;\n}): Promise<void> {\n const { state, scope } = input;\n const pending = state.pendingRefresh;\n if (\n pending &&\n (scope === \"root\" || pending.scope === \"full\") &&\n !(input.freshListing && pending.started.value)\n ) {\n return pending.promise;\n }\n\n const started = { value: false };\n const promise = (pending?.promise ?? Promise.resolve())\n // A failed earlier sweep must not prevent the queued refresh.\n .catch(() => undefined)\n .then(() => {\n started.value = true;\n return refreshAndReconcileContainers({\n forceAllDocumentContentPulls: scope === \"full\",\n host: input.host,\n listContainerIds: input.listContainerIds,\n refreshTree: input.refreshTree,\n state,\n });\n })\n .finally(() => {\n if (state.pendingRefresh?.promise === promise) {\n state.pendingRefresh = null;\n }\n });\n state.pendingRefresh = { promise, scope, started };\n return promise;\n}\n\nfunction listFullRefreshContainerIds(\n host: ReconciliationHost,\n state: ReconciliationState,\n): ReadonlyArray<string> {\n const knownIds = host.listKnownContainerIds();\n const activeContainerId = state.activeContainerId;\n if (\n !activeContainerId ||\n knownIds.includes(activeContainerId) ||\n !host.canDiscoverContainerDocuments(activeContainerId)\n ) {\n return knownIds;\n }\n // Explicit refresh also retries an open foreign system container that the\n // background discovery list excludes.\n return [...knownIds, activeContainerId];\n}\n\nfunction startReconciliationLane(\n host: ReconciliationHost,\n state: ReconciliationState,\n): void {\n if (state.active) {\n return;\n }\n state.lifecycleGeneration += 1;\n state.active = true;\n state.lane = getOrCreateDomainSyncCoordinator(host.domainScope).registerLane(\n \"reconciliation:documents\",\n {\n label: \"Device-first document reconciliation\",\n // Document discovery runs in the document phase, after structural\n // container hydration/metadata sync settles for the scope.\n phase: \"document\",\n priority: () => (state.activeContainerId ? -1 : 0),\n onUnexpectedError: (error) => {\n console.error(\"Device-first reconciliation failed:\", error);\n },\n // Fixed literal: no container or document id may reach a report. The\n // mapped stack identifies which lane body threw. Returning the host's\n // result hands a rejection to the lane reporter's wrapper; discarding it\n // would surface as an unhandled rejection instead.\n reportUnexpectedError: (error) =>\n host.logError?.(\"Reconciliation: sync lane failed\", error),\n run: () => runReconcileLane(host, state),\n shouldIgnoreError: host.isIgnorableError,\n },\n );\n}\n\nfunction createReconciliationState(\n host: ReconciliationHost,\n): ReconciliationState {\n return {\n active: false,\n activeContainerId: null,\n automaticRetryGenerations: new Map(),\n discoveredContainerIds: new Set(),\n forcedContainerGenerations: new Map(),\n forcedDocumentIds: new Map(),\n initialDocumentProbe: createInitialDocumentProbe(host),\n lane: null,\n lifecycleGeneration: 0,\n nextForceGeneration: 0,\n probeContinuationCancel: null,\n queue: createReconcileQueue(),\n pendingRefresh: null,\n };\n}\n\nfunction stopReconciliationService(\n host: ReconciliationHost,\n state: ReconciliationState,\n): void {\n clearPendingDiscoveryRetries(state);\n state.active = false;\n state.probeContinuationCancel?.();\n state.probeContinuationCancel = null;\n state.queue.clear();\n state.automaticRetryGenerations.clear();\n state.forcedContainerGenerations.clear();\n state.forcedDocumentIds.clear();\n state.pendingRefresh = null;\n state.initialDocumentProbe.resetPending();\n // Drop the per-session discovered suppression cache too: a stopped\n // reconciler is being torn down (scope/identity change) or paused across\n // a prerequisite loss, after which every container must be re-validated.\n state.discoveredContainerIds.clear();\n // Drop pending self-echo originations too — they are session-scoped and a\n // teardown invalidates them.\n clearOriginatedDocuments(host.domainScope);\n}\n\nexport function createReconciliationService(\n host: ReconciliationHost,\n): ReconciliationService {\n const state = createReconciliationState(host);\n\n const scheduleDrain = () => {\n if (\n !state.active ||\n (state.queue.size === 0 && !state.initialDocumentProbe.canRun())\n ) {\n return;\n }\n if (!canReconcile(host.getRuntimeStatus())) {\n return;\n }\n state.probeContinuationCancel?.();\n state.probeContinuationCancel = null;\n state.lane?.requestSync();\n };\n\n const enqueueContainer = (\n containerId: string,\n priority: ReconcilePriority,\n force = false,\n documentId?: string,\n ) => {\n if (!containerId) {\n return;\n }\n // Skip containers already reconciled this session unless forced. Events\n // force re-discovery; passive active/backfill scheduling does not, so\n // opening Explorer does not re-fetch every container on each navigation.\n if (\n !force &&\n !state.forcedContainerGenerations.has(containerId) &&\n state.discoveredContainerIds.has(containerId)\n ) {\n return;\n }\n if (force) {\n markContainerForced(state, containerId, documentId);\n }\n state.queue.enqueue(containerId, priority);\n scheduleDrain();\n };\n\n const enqueueIdleBackfill = () => {\n enqueueKnownContainersForIdleBackfill({\n host,\n scheduleDrain,\n state,\n });\n };\n\n return {\n start: () => {\n startReconciliationLane(host, state);\n scheduleDrain();\n },\n // Reconcile the active container first; siblings remain lazy until visited.\n setActiveContainer: (containerId) =>\n activateContainer(state, containerId, (activeId) =>\n enqueueContainer(activeId, \"active\"),\n ),\n enqueueContainer,\n enqueueIdleBackfill,\n resetDiscovered: () => {\n state.discoveredContainerIds.clear();\n state.initialDocumentProbe.resetSkippedListings();\n },\n reconcileRootContainersNow: (options) =>\n requestContainerRefresh({\n freshListing: options?.freshListing === true,\n host,\n state,\n refreshTree: host.refreshRootTree,\n listContainerIds: host.listAutomaticRootCatchupContainerIds,\n scope: \"root\",\n }),\n reconcileNow: () =>\n requestContainerRefresh({\n freshListing: false,\n host,\n state,\n refreshTree: host.refreshTree,\n listContainerIds: () => listFullRefreshContainerIds(host, state),\n scope: \"full\",\n }),\n stop: () => stopReconciliationService(host, state),\n };\n}\n"]}
@@ -62,7 +62,16 @@ export interface ReconciliationService {
62
62
  * retries need a fresh opportunity once the server is reachable again.
63
63
  */
64
64
  resetDiscovered: () => void;
65
- reconcileRootContainersNow: () => Promise<void>;
65
+ /**
66
+ * Re-list root containers and reconcile the root catch-up set. By default a
67
+ * request joins a sweep already in flight. With `freshListing`, the returned
68
+ * sweep starts after this call: a discovery event (a root shared with or
69
+ * created for this user) must not be satisfied by a sweep that may have
70
+ * listed roots before the event committed.
71
+ */
72
+ reconcileRootContainersNow: (options?: {
73
+ readonly freshListing?: boolean;
74
+ }) => Promise<void>;
66
75
  reconcileNow: () => Promise<void>;
67
76
  stop: () => void;
68
77
  }
@@ -1 +1 @@
1
- {"version":3,"file":"serviceTypes.js","sourceRoot":"","sources":["serviceTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport type { DomainScope } from \"../../data/domainScope\";\nimport type { LocalProjectionReconciledDelta } from \"../../stores/local-projection\";\nimport type { InitialDocumentProbeHost } from \"./initialDocumentProbe\";\nimport type { ReconcilePriority } from \"./queue\";\n\nexport interface ReconciliationRuntimeStatus {\n dbStatus: string;\n isAuthenticated: boolean;\n online: boolean;\n}\n\n/**\n * Host contract injected by the device-first facade. Keeps the reconciler\n * React-free and decoupled from runtime/persistence construction — it only\n * orchestrates *when* these run and routes their results into Layer A.\n */\nexport interface ReconciliationHost extends InitialDocumentProbeHost {\n domainScope: DomainScope;\n getRuntimeStatus: () => ReconciliationRuntimeStatus;\n /** True when this container has enough remote state to list documents. */\n canDiscoverContainerDocuments: (containerId: string) => boolean;\n /** Known container ids eligible for idle document reconciliation. */\n listKnownContainerIds: () => ReadonlyArray<string>;\n /** Known ids eligible after an automatic root-lane discovery hint. */\n listAutomaticRootCatchupContainerIds: () => ReadonlyArray<string>;\n /** Discover + persist documents; `null` means the lane was not fully listed. */\n discoverContainerDocuments: (\n containerId: string,\n onFullListing?: ((documentIds: ReadonlyArray<string>) => void) | undefined,\n onPendingDiscovery?: ((delayMs: number) => void) | undefined,\n ) => Promise<ReadonlyArray<DocumentSummary> | null>;\n /** Read a container's freshly-persisted summaries+links from SQLite. */\n loadContainerDelta: (\n containerId: string,\n ) => Promise<LocalProjectionReconciledDelta>;\n /** Push a reconciled delta into the local projection store. */\n applyReconciled: (delta: LocalProjectionReconciledDelta) => void;\n /**\n * Sync document bodies for a reconciled container. `force` (an explicit\n * refresh) revalidates registered ordinary documents and retries system\n * documents; otherwise only unopened system documents are synced, so a\n * background pass can materialize projection-owned content without eagerly\n * opening every ordinary document. A documentIds set limits forced pulls to\n * hint-named documents while still discovering new system content.\n */\n requestDocumentContentPull: (\n containerId: string,\n documents: ReadonlyArray<DocumentSummary>,\n force: boolean,\n documentIds?: ReadonlySet<string>,\n ) => void;\n /** Refresh the container tree from the server (explicit refresh). */\n refreshTree: () => Promise<void>;\n /** Refresh only the top-level root lane from the server. */\n refreshRootTree: () => Promise<void>;\n /** True if the destroyed-db error should be swallowed rather than surfaced. */\n isIgnorableError: (error: unknown) => boolean;\n /** Host diagnostics sink; bare runtimes do not structure errors. */\n logError?: ((message: string, error: unknown) => void) | undefined;\n}\n\nexport interface ReconciliationService {\n start: () => void;\n setActiveContainer: (containerId: string | null) => void;\n /** Force a listing; documentId limits content revalidation to that hint. */\n enqueueContainer: (\n containerId: string,\n priority: ReconcilePriority,\n force?: boolean,\n documentId?: string,\n ) => void;\n /** Queue known containers at idle priority. */\n enqueueIdleBackfill: () => void;\n /**\n * Forget which containers were reconciled this session so the next enqueue of\n * each re-validates against the server exactly once. Call on the\n * cannot-reconcile → can-reconcile edge (relogin/reconnect): the discovered\n * set is a per-session suppression cache, a previously-visited container may\n * have changed remotely, and initial-probe listings that exhausted their\n * retries need a fresh opportunity once the server is reachable again.\n */\n resetDiscovered: () => void;\n reconcileRootContainersNow: () => Promise<void>;\n reconcileNow: () => Promise<void>;\n stop: () => void;\n}\n"]}
1
+ {"version":3,"file":"serviceTypes.js","sourceRoot":"","sources":["serviceTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { DocumentSummary } from \"../../data/documents/documentSummary\";\nimport type { DomainScope } from \"../../data/domainScope\";\nimport type { LocalProjectionReconciledDelta } from \"../../stores/local-projection\";\nimport type { InitialDocumentProbeHost } from \"./initialDocumentProbe\";\nimport type { ReconcilePriority } from \"./queue\";\n\nexport interface ReconciliationRuntimeStatus {\n dbStatus: string;\n isAuthenticated: boolean;\n online: boolean;\n}\n\n/**\n * Host contract injected by the device-first facade. Keeps the reconciler\n * React-free and decoupled from runtime/persistence construction — it only\n * orchestrates *when* these run and routes their results into Layer A.\n */\nexport interface ReconciliationHost extends InitialDocumentProbeHost {\n domainScope: DomainScope;\n getRuntimeStatus: () => ReconciliationRuntimeStatus;\n /** True when this container has enough remote state to list documents. */\n canDiscoverContainerDocuments: (containerId: string) => boolean;\n /** Known container ids eligible for idle document reconciliation. */\n listKnownContainerIds: () => ReadonlyArray<string>;\n /** Known ids eligible after an automatic root-lane discovery hint. */\n listAutomaticRootCatchupContainerIds: () => ReadonlyArray<string>;\n /** Discover + persist documents; `null` means the lane was not fully listed. */\n discoverContainerDocuments: (\n containerId: string,\n onFullListing?: ((documentIds: ReadonlyArray<string>) => void) | undefined,\n onPendingDiscovery?: ((delayMs: number) => void) | undefined,\n ) => Promise<ReadonlyArray<DocumentSummary> | null>;\n /** Read a container's freshly-persisted summaries+links from SQLite. */\n loadContainerDelta: (\n containerId: string,\n ) => Promise<LocalProjectionReconciledDelta>;\n /** Push a reconciled delta into the local projection store. */\n applyReconciled: (delta: LocalProjectionReconciledDelta) => void;\n /**\n * Sync document bodies for a reconciled container. `force` (an explicit\n * refresh) revalidates registered ordinary documents and retries system\n * documents; otherwise only unopened system documents are synced, so a\n * background pass can materialize projection-owned content without eagerly\n * opening every ordinary document. A documentIds set limits forced pulls to\n * hint-named documents while still discovering new system content.\n */\n requestDocumentContentPull: (\n containerId: string,\n documents: ReadonlyArray<DocumentSummary>,\n force: boolean,\n documentIds?: ReadonlySet<string>,\n ) => void;\n /** Refresh the container tree from the server (explicit refresh). */\n refreshTree: () => Promise<void>;\n /** Refresh only the top-level root lane from the server. */\n refreshRootTree: () => Promise<void>;\n /** True if the destroyed-db error should be swallowed rather than surfaced. */\n isIgnorableError: (error: unknown) => boolean;\n /** Host diagnostics sink; bare runtimes do not structure errors. */\n logError?: ((message: string, error: unknown) => void) | undefined;\n}\n\nexport interface ReconciliationService {\n start: () => void;\n setActiveContainer: (containerId: string | null) => void;\n /** Force a listing; documentId limits content revalidation to that hint. */\n enqueueContainer: (\n containerId: string,\n priority: ReconcilePriority,\n force?: boolean,\n documentId?: string,\n ) => void;\n /** Queue known containers at idle priority. */\n enqueueIdleBackfill: () => void;\n /**\n * Forget which containers were reconciled this session so the next enqueue of\n * each re-validates against the server exactly once. Call on the\n * cannot-reconcile → can-reconcile edge (relogin/reconnect): the discovered\n * set is a per-session suppression cache, a previously-visited container may\n * have changed remotely, and initial-probe listings that exhausted their\n * retries need a fresh opportunity once the server is reachable again.\n */\n resetDiscovered: () => void;\n /**\n * Re-list root containers and reconcile the root catch-up set. By default a\n * request joins a sweep already in flight. With `freshListing`, the returned\n * sweep starts after this call: a discovery event (a root shared with or\n * created for this user) must not be satisfied by a sweep that may have\n * listed roots before the event committed.\n */\n reconcileRootContainersNow: (options?: {\n readonly freshListing?: boolean;\n }) => Promise<void>;\n reconcileNow: () => Promise<void>;\n stop: () => void;\n}\n"]}
@@ -27,9 +27,10 @@ export interface WorkflowRuntimeStateInput {
27
27
  readonly events: ReadonlyArray<unknown>;
28
28
  readonly online: boolean;
29
29
  /**
30
- * Increments after each restored server-events interest baseline. Unlike a
31
- * boolean connection edge, this survives coalesced runtime notifications and
32
- * document stores retained while their host provider is unmounted.
30
+ * Increments after each acknowledged server-events interest declaration.
31
+ * Unlike a boolean connection edge, this survives coalesced runtime
32
+ * notifications and document stores retained while their host provider is
33
+ * unmounted.
33
34
  */
34
35
  readonly serverEventsConnectionGeneration?: number | undefined;
35
36
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeInput.js","sourceRoot":"","sources":["runtimeInput.ts"],"names":[],"mappings":"","sourcesContent":["import type { EncapsulationKeyPair, SigningKeyPair } from \"@tearleads/crypto\";\nimport type { BlobStore } from \"../data/blobContracts\";\nimport type { DocumentProjectorRegistry } from \"../data/documents/documentKinds\";\nimport type { DomainScope } from \"../data/domainScope\";\nimport type { SecurityIncidentReporter } from \"../data/securityIncidents\";\nimport type { ExecSql } from \"../data/sqlite/sqlSchema\";\n\nexport type WorkflowRuntimeDatabaseStatus =\n | \"idle\"\n | \"ready\"\n | \"error\"\n | \"terminated\";\n\nexport interface WorkflowRuntimeAuthInput {\n /** Server-backed personal organization; independent of organizationId. */\n readonly defaultOrganizationId?: string | null;\n /** Session root identity, independent of a document/pane target. */\n readonly rootContainerId?: string | null | undefined;\n readonly isAuthenticated: boolean;\n /** Platform-operator flag from the server; the API enforces root access. */\n readonly isRoot?: boolean | undefined;\n readonly organizationId: string | null;\n readonly userId: string | null;\n}\n\nexport interface WorkflowRuntimeCryptoInput {\n readonly encapsulationKeyPair: EncapsulationKeyPair | null;\n readonly signingFingerprint: string | null;\n readonly signingKeyPair: SigningKeyPair | null;\n}\n\nexport interface WorkflowRuntimeStateInput {\n readonly containerId: string | null;\n readonly domainScope: DomainScope;\n readonly events: ReadonlyArray<unknown>;\n readonly online: boolean;\n /**\n * Increments after each restored server-events interest baseline. Unlike a\n * boolean connection edge, this survives coalesced runtime notifications and\n * document stores retained while their host provider is unmounted.\n */\n readonly serverEventsConnectionGeneration?: number | undefined;\n /**\n * Per-pane CRDT peer-seed discriminator (e.g. the pane's local identity\n * namespace). Documents in distinct panes must derive distinct Loro peer ids;\n * absent/`null` means single-pane (bare scope). The document runtime factory\n * always populates it; other runtimes and test fixtures may omit it.\n */\n readonly peerScope?: string | null;\n}\n\nexport interface WorkflowRuntimeInfraInput {\n readonly blobStore: BlobStore;\n readonly dbStatus: WorkflowRuntimeDatabaseStatus;\n readonly documentProjectors: DocumentProjectorRegistry;\n readonly execSql: ExecSql;\n}\n\nexport interface WorkflowRuntimeUtilInput {\n readonly isRemoteSyncBlocked?:\n | ((organizationId: string) => boolean)\n | undefined;\n readonly log: (message: string) => void;\n readonly logError: (message: string | Error, cause?: unknown) => void;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n}\n\nexport interface WorkflowRuntimeGroups {\n readonly auth: WorkflowRuntimeAuthInput;\n readonly crypto: WorkflowRuntimeCryptoInput;\n readonly infra: WorkflowRuntimeInfraInput;\n readonly state: WorkflowRuntimeStateInput;\n readonly util: WorkflowRuntimeUtilInput;\n}\n"]}
1
+ {"version":3,"file":"runtimeInput.js","sourceRoot":"","sources":["runtimeInput.ts"],"names":[],"mappings":"","sourcesContent":["import type { EncapsulationKeyPair, SigningKeyPair } from \"@tearleads/crypto\";\nimport type { BlobStore } from \"../data/blobContracts\";\nimport type { DocumentProjectorRegistry } from \"../data/documents/documentKinds\";\nimport type { DomainScope } from \"../data/domainScope\";\nimport type { SecurityIncidentReporter } from \"../data/securityIncidents\";\nimport type { ExecSql } from \"../data/sqlite/sqlSchema\";\n\nexport type WorkflowRuntimeDatabaseStatus =\n | \"idle\"\n | \"ready\"\n | \"error\"\n | \"terminated\";\n\nexport interface WorkflowRuntimeAuthInput {\n /** Server-backed personal organization; independent of organizationId. */\n readonly defaultOrganizationId?: string | null;\n /** Session root identity, independent of a document/pane target. */\n readonly rootContainerId?: string | null | undefined;\n readonly isAuthenticated: boolean;\n /** Platform-operator flag from the server; the API enforces root access. */\n readonly isRoot?: boolean | undefined;\n readonly organizationId: string | null;\n readonly userId: string | null;\n}\n\nexport interface WorkflowRuntimeCryptoInput {\n readonly encapsulationKeyPair: EncapsulationKeyPair | null;\n readonly signingFingerprint: string | null;\n readonly signingKeyPair: SigningKeyPair | null;\n}\n\nexport interface WorkflowRuntimeStateInput {\n readonly containerId: string | null;\n readonly domainScope: DomainScope;\n readonly events: ReadonlyArray<unknown>;\n readonly online: boolean;\n /**\n * Increments after each acknowledged server-events interest declaration.\n * Unlike a boolean connection edge, this survives coalesced runtime\n * notifications and document stores retained while their host provider is\n * unmounted.\n */\n readonly serverEventsConnectionGeneration?: number | undefined;\n /**\n * Per-pane CRDT peer-seed discriminator (e.g. the pane's local identity\n * namespace). Documents in distinct panes must derive distinct Loro peer ids;\n * absent/`null` means single-pane (bare scope). The document runtime factory\n * always populates it; other runtimes and test fixtures may omit it.\n */\n readonly peerScope?: string | null;\n}\n\nexport interface WorkflowRuntimeInfraInput {\n readonly blobStore: BlobStore;\n readonly dbStatus: WorkflowRuntimeDatabaseStatus;\n readonly documentProjectors: DocumentProjectorRegistry;\n readonly execSql: ExecSql;\n}\n\nexport interface WorkflowRuntimeUtilInput {\n readonly isRemoteSyncBlocked?:\n | ((organizationId: string) => boolean)\n | undefined;\n readonly log: (message: string) => void;\n readonly logError: (message: string | Error, cause?: unknown) => void;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n}\n\nexport interface WorkflowRuntimeGroups {\n readonly auth: WorkflowRuntimeAuthInput;\n readonly crypto: WorkflowRuntimeCryptoInput;\n readonly infra: WorkflowRuntimeInfraInput;\n readonly state: WorkflowRuntimeStateInput;\n readonly util: WorkflowRuntimeUtilInput;\n}\n"]}