@tanstack/electron-db-sqlite-persistence 0.2.9 → 0.2.11
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 +9 -1
- package/dist/cjs/main.cjs +118 -17
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/protocol.cjs +1 -1
- package/dist/cjs/protocol.cjs.map +1 -1
- package/dist/cjs/protocol.d.cts +53 -5
- package/dist/cjs/renderer.cjs +176 -48
- package/dist/cjs/renderer.cjs.map +1 -1
- package/dist/cjs/renderer.d.cts +2 -0
- package/dist/esm/main.js +119 -18
- package/dist/esm/main.js.map +1 -1
- package/dist/esm/protocol.d.ts +53 -5
- package/dist/esm/protocol.js +1 -1
- package/dist/esm/protocol.js.map +1 -1
- package/dist/esm/renderer.d.ts +2 -0
- package/dist/esm/renderer.js +177 -49
- package/dist/esm/renderer.js.map +1 -1
- package/package.json +2 -2
- package/src/main.ts +141 -17
- package/src/protocol.ts +40 -5
- package/src/renderer.ts +229 -49
- package/dist/cjs/errors.d.cts +0 -33
- package/dist/esm/errors.d.ts +0 -33
- package/src/errors.ts +0 -110
package/dist/esm/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sources":["../../src/main.ts"],"sourcesContent":["import { InvalidPersistedCollectionConfigError } from '@tanstack/db-sqlite-persistence-core'\nimport {\n DEFAULT_ELECTRON_PERSISTENCE_CHANNEL,\n ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n} from './protocol'\nimport type {\n PersistedCollectionPersistence,\n PersistenceAdapter,\n SQLitePullSinceResult,\n} from '@tanstack/db-sqlite-persistence-core'\nimport type {\n ElectronPersistedKey,\n ElectronPersistedRow,\n ElectronPersistenceRequestEnvelope,\n ElectronPersistenceResponseEnvelope,\n ElectronSerializedError,\n} from './protocol'\n\ntype ElectronMainPersistenceAdapter = PersistenceAdapter & {\n loadCollectionMetadata?: (\n collectionId: string,\n ) => Promise<Array<{ key: string; value: unknown }>>\n scanRows?: (\n collectionId: string,\n options?: { metadataOnly?: boolean },\n ) => Promise<\n Array<{\n key: ElectronPersistedKey\n value: ElectronPersistedRow\n metadata?: unknown\n }>\n >\n pullSince?: (\n collectionId: string,\n fromRowVersion: number,\n ) => Promise<SQLitePullSinceResult<ElectronPersistedKey>>\n getStreamPosition?: (collectionId: string) => Promise<{\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n }>\n}\n\nfunction serializeError(error: unknown): ElectronSerializedError {\n const fallbackMessage = `Unknown electron persistence error`\n\n if (!(error instanceof Error)) {\n return {\n name: `Error`,\n message: fallbackMessage,\n code: undefined,\n }\n }\n\n const detailedError = error as Error & { code?: unknown; path?: unknown }\n const path = detailedError.path\n return {\n name: error.name || `Error`,\n message: error.message || fallbackMessage,\n stack: error.stack,\n code:\n typeof detailedError.code === `string` ||\n typeof detailedError.code === `number`\n ? detailedError.code\n : undefined,\n path:\n typeof path === `string` ||\n (Array.isArray(path) &&\n path.every(\n (segment: unknown) =>\n typeof segment === `string` || typeof segment === `number`,\n ))\n ? (path as string | ReadonlyArray<string | number>)\n : undefined,\n }\n}\n\nfunction createErrorResponse(\n request: ElectronPersistenceRequestEnvelope,\n error: unknown,\n): ElectronPersistenceResponseEnvelope {\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: false,\n error: serializeError(error),\n }\n}\n\nfunction assertValidRequest(request: ElectronPersistenceRequestEnvelope): void {\n if (request.v !== ELECTRON_PERSISTENCE_PROTOCOL_VERSION) {\n throw new InvalidPersistedCollectionConfigError(\n `Unsupported electron persistence protocol version \"${request.v}\"`,\n )\n }\n\n if (\n typeof request.requestId !== `string` ||\n request.requestId.trim().length === 0\n ) {\n throw new InvalidPersistedCollectionConfigError(\n `Electron persistence requestId cannot be empty`,\n )\n }\n\n if (\n typeof request.collectionId !== `string` ||\n request.collectionId.trim().length === 0\n ) {\n throw new InvalidPersistedCollectionConfigError(\n `Electron persistence collectionId cannot be empty`,\n )\n }\n}\n\nasync function executeRequestAgainstAdapter(\n request: ElectronPersistenceRequestEnvelope,\n adapter: ElectronMainPersistenceAdapter,\n): Promise<ElectronPersistenceResponseEnvelope> {\n switch (request.method) {\n case `loadSubset`: {\n const result = await adapter.loadSubset(\n request.collectionId,\n request.payload.options,\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `loadResumeSnapshot`: {\n const result = await adapter.loadResumeSnapshot(\n request.collectionId,\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `loadCollectionMetadata`: {\n if (!adapter.loadCollectionMetadata) {\n throw new InvalidPersistedCollectionConfigError(\n `loadCollectionMetadata is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.loadCollectionMetadata(request.collectionId)\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `scanRows`: {\n if (!adapter.scanRows) {\n throw new InvalidPersistedCollectionConfigError(\n `scanRows is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.scanRows(\n request.collectionId,\n request.payload.options,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `applyCommittedTx`: {\n await adapter.applyCommittedTx(request.collectionId, request.payload.tx)\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: null,\n }\n }\n\n case `reconcileCommittedTx`: {\n const result = adapter.reconcileCommittedTx\n ? await adapter.reconcileCommittedTx(\n request.collectionId,\n request.payload.tx,\n request.payload.anchor,\n )\n : { kind: `unknown` as const }\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `ensureIndex`: {\n await adapter.ensureIndex(\n request.collectionId,\n request.payload.signature,\n request.payload.spec,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: null,\n }\n }\n\n case `markIndexRemoved`: {\n if (!adapter.markIndexRemoved) {\n throw new InvalidPersistedCollectionConfigError(\n `markIndexRemoved is not supported by the configured electron persistence adapter`,\n )\n }\n await adapter.markIndexRemoved(\n request.collectionId,\n request.payload.signature,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: null,\n }\n }\n\n case `pullSince`: {\n if (!adapter.pullSince) {\n throw new InvalidPersistedCollectionConfigError(\n `pullSince is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.pullSince(\n request.collectionId,\n request.payload.fromRowVersion,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `reserveLeadershipTerm`: {\n if (!adapter.reserveLeadershipTerm) {\n throw new InvalidPersistedCollectionConfigError(\n `reserveLeadershipTerm is not supported by the configured electron persistence adapter`,\n )\n }\n const position = await adapter.reserveLeadershipTerm(\n request.collectionId,\n request.payload.observedTerm,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: position,\n }\n }\n\n case `getStreamPosition`: {\n if (!adapter.getStreamPosition) {\n throw new InvalidPersistedCollectionConfigError(\n `getStreamPosition is not supported by the configured electron persistence adapter`,\n )\n }\n const position = await adapter.getStreamPosition(request.collectionId)\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: position,\n }\n }\n }\n}\n\nfunction resolveModeAwarePersistence(\n persistence: PersistedCollectionPersistence,\n request: ElectronPersistenceRequestEnvelope,\n): PersistedCollectionPersistence {\n const mode = request.resolution?.mode ?? `sync-absent`\n const schemaVersion = request.resolution?.schemaVersion\n const collectionAwarePersistence =\n persistence.resolvePersistenceForCollection?.({\n collectionId: request.collectionId,\n mode,\n schemaVersion,\n })\n if (collectionAwarePersistence) {\n return collectionAwarePersistence\n }\n\n const modeAwarePersistence = persistence.resolvePersistenceForMode?.(mode)\n return modeAwarePersistence ?? persistence\n}\n\nexport type ElectronIpcMainLike = {\n handle: (\n channel: string,\n listener: (\n event: unknown,\n request: ElectronPersistenceRequestEnvelope,\n ) => Promise<ElectronPersistenceResponseEnvelope>,\n ) => void\n removeHandler?: (channel: string) => void\n}\n\nexport type ElectronSQLiteMainProcessOptions = {\n persistence: PersistedCollectionPersistence\n ipcMain: ElectronIpcMainLike\n channel?: string\n}\n\nexport function exposeElectronSQLitePersistence(\n options: ElectronSQLiteMainProcessOptions,\n): () => void {\n const channel = options.channel ?? DEFAULT_ELECTRON_PERSISTENCE_CHANNEL\n options.ipcMain.handle(\n channel,\n async (\n _event,\n request: ElectronPersistenceRequestEnvelope,\n ): Promise<ElectronPersistenceResponseEnvelope> => {\n try {\n assertValidRequest(request)\n const modeAwarePersistence = resolveModeAwarePersistence(\n options.persistence,\n request,\n )\n return await executeRequestAgainstAdapter(\n request,\n modeAwarePersistence.adapter,\n )\n } catch (error) {\n return createErrorResponse(request, error)\n }\n },\n )\n\n return () => {\n options.ipcMain.removeHandler?.(channel)\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.js","sources":["../../src/main.ts"],"sourcesContent":["import {\n InvalidPersistedCollectionConfigError,\n resolvePersistedStorageTarget,\n} from '@tanstack/db-sqlite-persistence-core'\nimport {\n DEFAULT_ELECTRON_PERSISTENCE_CHANNEL,\n ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n} from './protocol'\nimport type {\n PersistedCollectionPersistence,\n PersistedStorageTarget,\n PersistenceAdapter,\n SQLitePullSinceResult,\n} from '@tanstack/db-sqlite-persistence-core'\nimport type {\n ElectronPersistedKey,\n ElectronPersistedRow,\n ElectronPersistenceRequestEnvelope,\n ElectronPersistenceResponseEnvelope,\n ElectronSerializedError,\n} from './protocol'\n\ntype ElectronMainPersistenceAdapter = PersistenceAdapter & {\n loadCollectionMetadata?: (\n target: PersistedStorageTarget,\n ctx?: { cacheGenerationClaimId?: string },\n ) => Promise<Array<{ key: string; value: unknown }>>\n scanRows?: (\n target: PersistedStorageTarget,\n options?: { metadataOnly?: boolean },\n ctx?: { cacheGenerationClaimId?: string },\n ) => Promise<\n Array<{\n key: ElectronPersistedKey\n value: ElectronPersistedRow\n metadata?: unknown\n }>\n >\n pullSince?: (\n target: PersistedStorageTarget,\n fromRowVersion: number,\n ctx?: { cacheGenerationClaimId?: string },\n ) => Promise<SQLitePullSinceResult<ElectronPersistedKey>>\n getStreamPosition?: (\n target: PersistedStorageTarget,\n ctx?: { cacheGenerationClaimId?: string },\n ) => Promise<{\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n }>\n}\n\nfunction serializeError(error: unknown): ElectronSerializedError {\n const fallbackMessage = `Unknown electron persistence error`\n\n if (!(error instanceof Error)) {\n return {\n name: `Error`,\n message: fallbackMessage,\n code: undefined,\n }\n }\n\n const detailedError = error as Error & { code?: unknown; path?: unknown }\n const path = detailedError.path\n return {\n name: error.name || `Error`,\n message: error.message || fallbackMessage,\n stack: error.stack,\n code:\n typeof detailedError.code === `string` ||\n typeof detailedError.code === `number`\n ? detailedError.code\n : undefined,\n path:\n typeof path === `string` ||\n (Array.isArray(path) &&\n path.every(\n (segment: unknown) =>\n typeof segment === `string` || typeof segment === `number`,\n ))\n ? (path as string | ReadonlyArray<string | number>)\n : undefined,\n }\n}\n\nfunction createErrorResponse(\n request: ElectronPersistenceRequestEnvelope,\n error: unknown,\n): ElectronPersistenceResponseEnvelope {\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: false,\n error: serializeError(error),\n }\n}\n\nfunction assertValidRequest(request: ElectronPersistenceRequestEnvelope): void {\n if (request.v !== ELECTRON_PERSISTENCE_PROTOCOL_VERSION) {\n throw new InvalidPersistedCollectionConfigError(\n `Unsupported electron persistence protocol version \"${request.v}\"`,\n )\n }\n\n if (\n typeof request.requestId !== `string` ||\n request.requestId.trim().length === 0\n ) {\n throw new InvalidPersistedCollectionConfigError(\n `Electron persistence requestId cannot be empty`,\n )\n }\n\n if (\n typeof request.collectionId !== `string` ||\n request.collectionId.trim().length === 0\n ) {\n throw new InvalidPersistedCollectionConfigError(\n `Electron persistence collectionId cannot be empty`,\n )\n }\n}\n\nfunction requireStorageTarget(\n request: ElectronPersistenceRequestEnvelope,\n): PersistedStorageTarget {\n const target = request.storageTarget\n if (!target) {\n throw new InvalidPersistedCollectionConfigError(\n `Electron persistence data request requires an explicit storage target`,\n )\n }\n if (\n resolvePersistedStorageTarget(target).collectionId !== request.collectionId\n ) {\n throw new InvalidPersistedCollectionConfigError(\n `Electron persistence storage target does not match its collectionId`,\n )\n }\n return target\n}\n\nasync function executeRequestAgainstAdapter(\n request: ElectronPersistenceRequestEnvelope,\n adapter: ElectronMainPersistenceAdapter,\n): Promise<ElectronPersistenceResponseEnvelope> {\n switch (request.method) {\n case `loadSubset`: {\n const result = await adapter.loadSubset(\n requireStorageTarget(request),\n request.payload.options,\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `loadResumeSnapshot`: {\n const result = await adapter.loadResumeSnapshot(\n requireStorageTarget(request),\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `loadCollectionMetadata`: {\n if (!adapter.loadCollectionMetadata) {\n throw new InvalidPersistedCollectionConfigError(\n `loadCollectionMetadata is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.loadCollectionMetadata(\n requireStorageTarget(request),\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `scanRows`: {\n if (!adapter.scanRows) {\n throw new InvalidPersistedCollectionConfigError(\n `scanRows is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.scanRows(\n requireStorageTarget(request),\n request.payload.options,\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `applyCommittedTx`: {\n await adapter.applyCommittedTx(\n requireStorageTarget(request),\n request.payload.tx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: null,\n }\n }\n\n case `reconcileCommittedTx`: {\n const result = adapter.reconcileCommittedTx\n ? await adapter.reconcileCommittedTx(\n requireStorageTarget(request),\n request.payload.tx,\n request.payload.anchor,\n )\n : { kind: `unknown` as const }\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `ensureIndex`: {\n await adapter.ensureIndex(\n requireStorageTarget(request),\n request.payload.signature,\n request.payload.spec,\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: null,\n }\n }\n\n case `markIndexRemoved`: {\n if (!adapter.markIndexRemoved) {\n throw new InvalidPersistedCollectionConfigError(\n `markIndexRemoved is not supported by the configured electron persistence adapter`,\n )\n }\n await adapter.markIndexRemoved(\n requireStorageTarget(request),\n request.payload.signature,\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: null,\n }\n }\n\n case `pullSince`: {\n if (!adapter.pullSince) {\n throw new InvalidPersistedCollectionConfigError(\n `pullSince is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.pullSince(\n requireStorageTarget(request),\n request.payload.fromRowVersion,\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `reserveLeadershipTerm`: {\n if (!adapter.reserveLeadershipTerm) {\n throw new InvalidPersistedCollectionConfigError(\n `reserveLeadershipTerm is not supported by the configured electron persistence adapter`,\n )\n }\n const position = await adapter.reserveLeadershipTerm(\n requireStorageTarget(request),\n request.payload.observedTerm,\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: position,\n }\n }\n\n case `getStreamPosition`: {\n if (!adapter.getStreamPosition) {\n throw new InvalidPersistedCollectionConfigError(\n `getStreamPosition is not supported by the configured electron persistence adapter`,\n )\n }\n const position = await adapter.getStreamPosition(\n requireStorageTarget(request),\n request.payload.ctx,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: position,\n }\n }\n\n case `claimCacheGeneration`: {\n if (!adapter.claimCacheGeneration) {\n throw new InvalidPersistedCollectionConfigError(\n `claimCacheGeneration is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.claimCacheGeneration(request.collectionId)\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `rotateCacheGeneration`: {\n if (!adapter.rotateCacheGeneration) {\n throw new InvalidPersistedCollectionConfigError(\n `rotateCacheGeneration is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.rotateCacheGeneration(\n request.collectionId,\n request.payload.claimId,\n request.payload.resetMetadata,\n request.payload.expectedStorageCollectionId,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `renewCacheGenerationClaim`: {\n if (!adapter.renewCacheGenerationClaim) {\n throw new InvalidPersistedCollectionConfigError(\n `renewCacheGenerationClaim is not supported by the configured electron persistence adapter`,\n )\n }\n const result = await adapter.renewCacheGenerationClaim(\n request.payload.storageCollectionId,\n request.payload.claimId,\n )\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result,\n }\n }\n\n case `releaseCacheGenerationClaim`: {\n if (!adapter.releaseCacheGenerationClaim) {\n throw new InvalidPersistedCollectionConfigError(\n `releaseCacheGenerationClaim is not supported by the configured electron persistence adapter`,\n )\n }\n await adapter.releaseCacheGenerationClaim(request.payload.claimId)\n return {\n v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,\n requestId: request.requestId,\n method: request.method,\n ok: true,\n result: null,\n }\n }\n }\n}\n\nfunction resolveModeAwarePersistence(\n persistence: PersistedCollectionPersistence,\n request: ElectronPersistenceRequestEnvelope,\n): PersistedCollectionPersistence {\n if (\n request.storageTarget?.kind === `managed` &&\n !request.resolution?.logicalCollectionId\n ) {\n throw new InvalidPersistedCollectionConfigError(\n `Electron managed cache request requires a logical Collection ID`,\n )\n }\n const mode = request.resolution?.mode ?? `sync-absent`\n const schemaVersion = request.resolution?.schemaVersion\n const collectionAwarePersistence =\n persistence.resolvePersistenceForCollection?.({\n collectionId:\n request.resolution?.logicalCollectionId ?? request.collectionId,\n mode,\n schemaVersion,\n })\n if (collectionAwarePersistence) {\n return collectionAwarePersistence\n }\n\n const modeAwarePersistence = persistence.resolvePersistenceForMode?.(mode)\n return modeAwarePersistence ?? persistence\n}\n\nexport type ElectronIpcMainLike = {\n handle: (\n channel: string,\n listener: (\n event: unknown,\n request: ElectronPersistenceRequestEnvelope,\n ) => Promise<ElectronPersistenceResponseEnvelope>,\n ) => void\n removeHandler?: (channel: string) => void\n}\n\nexport type ElectronSQLiteMainProcessOptions = {\n persistence: PersistedCollectionPersistence\n ipcMain: ElectronIpcMainLike\n channel?: string\n}\n\nexport function exposeElectronSQLitePersistence(\n options: ElectronSQLiteMainProcessOptions,\n): () => void {\n const channel = options.channel ?? DEFAULT_ELECTRON_PERSISTENCE_CHANNEL\n options.ipcMain.handle(\n channel,\n async (\n _event,\n request: ElectronPersistenceRequestEnvelope,\n ): Promise<ElectronPersistenceResponseEnvelope> => {\n try {\n assertValidRequest(request)\n const modeAwarePersistence = resolveModeAwarePersistence(\n options.persistence,\n request,\n )\n return await executeRequestAgainstAdapter(\n request,\n modeAwarePersistence.adapter,\n )\n } catch (error) {\n return createErrorResponse(request, error)\n }\n },\n )\n\n return () => {\n options.ipcMain.removeHandler?.(channel)\n }\n}\n"],"names":[],"mappings":";;AAqDA,SAAS,eAAe,OAAyC;AAC/D,QAAM,kBAAkB;AAExB,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EAEV;AAEA,QAAM,gBAAgB;AACtB,QAAM,OAAO,cAAc;AAC3B,SAAO;AAAA,IACL,MAAM,MAAM,QAAQ;AAAA,IACpB,SAAS,MAAM,WAAW;AAAA,IAC1B,OAAO,MAAM;AAAA,IACb,MACE,OAAO,cAAc,SAAS,YAC9B,OAAO,cAAc,SAAS,WAC1B,cAAc,OACd;AAAA,IACN,MACE,OAAO,SAAS,YACf,MAAM,QAAQ,IAAI,KACjB,KAAK;AAAA,MACH,CAAC,YACC,OAAO,YAAY,YAAY,OAAO,YAAY;AAAA,IAAA,IAEnD,OACD;AAAA,EAAA;AAEV;AAEA,SAAS,oBACP,SACA,OACqC;AACrC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW,QAAQ;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,IAAI;AAAA,IACJ,OAAO,eAAe,KAAK;AAAA,EAAA;AAE/B;AAEA,SAAS,mBAAmB,SAAmD;AAC7E,MAAI,QAAQ,MAAM,uCAAuC;AACvD,UAAM,IAAI;AAAA,MACR,sDAAsD,QAAQ,CAAC;AAAA,IAAA;AAAA,EAEnE;AAEA,MACE,OAAO,QAAQ,cAAc,YAC7B,QAAQ,UAAU,KAAA,EAAO,WAAW,GACpC;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,MACE,OAAO,QAAQ,iBAAiB,YAChC,QAAQ,aAAa,KAAA,EAAO,WAAW,GACvC;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACF;AAEA,SAAS,qBACP,SACwB;AACxB,QAAM,SAAS,QAAQ;AACvB,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACA,MACE,8BAA8B,MAAM,EAAE,iBAAiB,QAAQ,cAC/D;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACA,SAAO;AACT;AAEA,eAAe,6BACb,SACA,SAC8C;AAC9C,UAAQ,QAAQ,QAAA;AAAA,IACd,KAAK,cAAc;AACjB,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,sBAAsB;AACzB,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,0BAA0B;AAC7B,UAAI,CAAC,QAAQ,wBAAwB;AACnC,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,YAAY;AACf,UAAI,CAAC,QAAQ,UAAU;AACrB,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,oBAAoB;AACvB,YAAM,QAAQ;AAAA,QACZ,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ,QAAQ;AAAA,MAAA;AAAA,IAEZ;AAAA,IAEA,KAAK,wBAAwB;AAC3B,YAAM,SAAS,QAAQ,uBACnB,MAAM,QAAQ;AAAA,QACZ,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA,IAElB,EAAE,MAAM,UAAA;AACZ,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,eAAe;AAClB,YAAM,QAAQ;AAAA,QACZ,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ,QAAQ;AAAA,MAAA;AAAA,IAEZ;AAAA,IAEA,KAAK,oBAAoB;AACvB,UAAI,CAAC,QAAQ,kBAAkB;AAC7B,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,QAAQ;AAAA,QACZ,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ,QAAQ;AAAA,MAAA;AAAA,IAEZ;AAAA,IAEA,KAAK,aAAa;AAChB,UAAI,CAAC,QAAQ,WAAW;AACtB,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,yBAAyB;AAC5B,UAAI,CAAC,QAAQ,uBAAuB;AAClC,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,WAAW,MAAM,QAAQ;AAAA,QAC7B,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ,QAAQ;AAAA,MAAA;AAAA,IAEZ;AAAA,IAEA,KAAK,qBAAqB;AACxB,UAAI,CAAC,QAAQ,mBAAmB;AAC9B,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,WAAW,MAAM,QAAQ;AAAA,QAC7B,qBAAqB,OAAO;AAAA,QAC5B,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ,QAAQ;AAAA,MAAA;AAAA,IAEZ;AAAA,IAEA,KAAK,wBAAwB;AAC3B,UAAI,CAAC,QAAQ,sBAAsB;AACjC,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,SAAS,MAAM,QAAQ,qBAAqB,QAAQ,YAAY;AACtE,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,yBAAyB;AAC5B,UAAI,CAAC,QAAQ,uBAAuB;AAClC,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,QAAQ;AAAA,QACR,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,6BAA6B;AAChC,UAAI,CAAC,QAAQ,2BAA2B;AACtC,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,MAAA;AAElB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAAA,IAEA,KAAK,+BAA+B;AAClC,UAAI,CAAC,QAAQ,6BAA6B;AACxC,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AACA,YAAM,QAAQ,4BAA4B,QAAQ,QAAQ,OAAO;AACjE,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ;AAAA,QAChB,IAAI;AAAA,QACJ,QAAQ;AAAA,MAAA;AAAA,IAEZ;AAAA,EAAA;AAEJ;AAEA,SAAS,4BACP,aACA,SACgC;AAChC,MACE,QAAQ,eAAe,SAAS,aAChC,CAAC,QAAQ,YAAY,qBACrB;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACA,QAAM,OAAO,QAAQ,YAAY,QAAQ;AACzC,QAAM,gBAAgB,QAAQ,YAAY;AAC1C,QAAM,6BACJ,YAAY,kCAAkC;AAAA,IAC5C,cACE,QAAQ,YAAY,uBAAuB,QAAQ;AAAA,IACrD;AAAA,IACA;AAAA,EAAA,CACD;AACH,MAAI,4BAA4B;AAC9B,WAAO;AAAA,EACT;AAEA,QAAM,uBAAuB,YAAY,4BAA4B,IAAI;AACzE,SAAO,wBAAwB;AACjC;AAmBO,SAAS,gCACd,SACY;AACZ,QAAM,UAAU,QAAQ,WAAW;AACnC,UAAQ,QAAQ;AAAA,IACd;AAAA,IACA,OACE,QACA,YACiD;AACjD,UAAI;AACF,2BAAmB,OAAO;AAC1B,cAAM,uBAAuB;AAAA,UAC3B,QAAQ;AAAA,UACR;AAAA,QAAA;AAEF,eAAO,MAAM;AAAA,UACX;AAAA,UACA,qBAAqB;AAAA,QAAA;AAAA,MAEzB,SAAS,OAAO;AACd,eAAO,oBAAoB,SAAS,KAAK;AAAA,MAC3C;AAAA,IACF;AAAA,EAAA;AAGF,SAAO,MAAM;AACX,YAAQ,QAAQ,gBAAgB,OAAO;AAAA,EACzC;AACF;"}
|
package/dist/esm/protocol.d.ts
CHANGED
|
@@ -1,32 +1,42 @@
|
|
|
1
1
|
import { LoadSubsetOptions } from '@tanstack/db';
|
|
2
|
-
import { CommittedTxAnchor, PersistedCollectionMode, PersistedIndexSpec, PersistedKeySetEvidence, PersistedTx, ReconciledCommittedTx, SQLitePullSinceResult } from '@tanstack/db-sqlite-persistence-core';
|
|
3
|
-
export declare const ELECTRON_PERSISTENCE_PROTOCOL_VERSION:
|
|
2
|
+
import { CommittedTxAnchor, PersistedCacheGenerationClaim, PersistedCollectionMode, PersistedIndexSpec, PersistedKeySetEvidence, PersistedStorageTarget, PersistedTx, ReconciledCommittedTx, SQLitePullSinceResult } from '@tanstack/db-sqlite-persistence-core';
|
|
3
|
+
export declare const ELECTRON_PERSISTENCE_PROTOCOL_VERSION: 6;
|
|
4
4
|
export declare const DEFAULT_ELECTRON_PERSISTENCE_CHANNEL = "tanstack-db:sqlite-persistence";
|
|
5
5
|
export type ElectronPersistedRow = Record<string, unknown>;
|
|
6
6
|
export type ElectronPersistedKey = string | number;
|
|
7
7
|
export type ElectronPersistenceResolution = {
|
|
8
8
|
mode: PersistedCollectionMode;
|
|
9
9
|
schemaVersion?: number;
|
|
10
|
+
logicalCollectionId?: string;
|
|
10
11
|
};
|
|
11
|
-
export type ElectronPersistenceMethod = `loadSubset` | `loadResumeSnapshot` | `loadCollectionMetadata` | `scanRows` | `applyCommittedTx` | `reconcileCommittedTx` | `ensureIndex` | `markIndexRemoved` | `pullSince` | `getStreamPosition` | `reserveLeadershipTerm`;
|
|
12
|
+
export type ElectronPersistenceMethod = `loadSubset` | `loadResumeSnapshot` | `loadCollectionMetadata` | `scanRows` | `applyCommittedTx` | `reconcileCommittedTx` | `ensureIndex` | `markIndexRemoved` | `pullSince` | `getStreamPosition` | `claimCacheGeneration` | `rotateCacheGeneration` | `renewCacheGenerationClaim` | `releaseCacheGenerationClaim` | `reserveLeadershipTerm`;
|
|
12
13
|
export type ElectronPersistencePayloadMap = {
|
|
13
14
|
loadSubset: {
|
|
14
15
|
options: LoadSubsetOptions;
|
|
15
16
|
ctx?: {
|
|
16
17
|
requiredIndexSignatures?: ReadonlyArray<string>;
|
|
18
|
+
cacheGenerationClaimId?: string;
|
|
17
19
|
};
|
|
18
20
|
};
|
|
19
21
|
loadResumeSnapshot: {
|
|
20
22
|
ctx?: {
|
|
21
23
|
requiredIndexSignatures?: ReadonlyArray<string>;
|
|
22
24
|
includeRows?: boolean;
|
|
25
|
+
cacheGenerationClaimId?: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
loadCollectionMetadata: {
|
|
29
|
+
ctx?: {
|
|
30
|
+
cacheGenerationClaimId?: string;
|
|
23
31
|
};
|
|
24
32
|
};
|
|
25
|
-
loadCollectionMetadata: {};
|
|
26
33
|
scanRows: {
|
|
27
34
|
options?: {
|
|
28
35
|
metadataOnly?: boolean;
|
|
29
36
|
};
|
|
37
|
+
ctx?: {
|
|
38
|
+
cacheGenerationClaimId?: string;
|
|
39
|
+
};
|
|
30
40
|
};
|
|
31
41
|
applyCommittedTx: {
|
|
32
42
|
tx: PersistedTx<ElectronPersistedRow, ElectronPersistedKey>;
|
|
@@ -38,16 +48,48 @@ export type ElectronPersistencePayloadMap = {
|
|
|
38
48
|
ensureIndex: {
|
|
39
49
|
signature: string;
|
|
40
50
|
spec: PersistedIndexSpec;
|
|
51
|
+
ctx?: {
|
|
52
|
+
cacheGenerationClaimId?: string;
|
|
53
|
+
};
|
|
41
54
|
};
|
|
42
55
|
markIndexRemoved: {
|
|
43
56
|
signature: string;
|
|
57
|
+
ctx?: {
|
|
58
|
+
cacheGenerationClaimId?: string;
|
|
59
|
+
};
|
|
44
60
|
};
|
|
45
61
|
pullSince: {
|
|
46
62
|
fromRowVersion: number;
|
|
63
|
+
ctx?: {
|
|
64
|
+
cacheGenerationClaimId?: string;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
getStreamPosition: {
|
|
68
|
+
ctx?: {
|
|
69
|
+
cacheGenerationClaimId?: string;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
claimCacheGeneration: {};
|
|
73
|
+
rotateCacheGeneration: {
|
|
74
|
+
claimId: string;
|
|
75
|
+
resetMetadata?: {
|
|
76
|
+
key: string;
|
|
77
|
+
value: unknown;
|
|
78
|
+
};
|
|
79
|
+
expectedStorageCollectionId?: string;
|
|
80
|
+
};
|
|
81
|
+
renewCacheGenerationClaim: {
|
|
82
|
+
storageCollectionId: string;
|
|
83
|
+
claimId: string;
|
|
84
|
+
};
|
|
85
|
+
releaseCacheGenerationClaim: {
|
|
86
|
+
claimId: string;
|
|
47
87
|
};
|
|
48
|
-
getStreamPosition: {};
|
|
49
88
|
reserveLeadershipTerm: {
|
|
50
89
|
observedTerm: number;
|
|
90
|
+
ctx?: {
|
|
91
|
+
cacheGenerationClaimId?: string;
|
|
92
|
+
};
|
|
51
93
|
};
|
|
52
94
|
};
|
|
53
95
|
export type ElectronPersistenceResultMap = {
|
|
@@ -90,6 +132,10 @@ export type ElectronPersistenceResultMap = {
|
|
|
90
132
|
latestSeq: number;
|
|
91
133
|
latestRowVersion: number;
|
|
92
134
|
};
|
|
135
|
+
claimCacheGeneration: PersistedCacheGenerationClaim;
|
|
136
|
+
rotateCacheGeneration: PersistedCacheGenerationClaim;
|
|
137
|
+
renewCacheGenerationClaim: number | undefined;
|
|
138
|
+
releaseCacheGenerationClaim: null;
|
|
93
139
|
reserveLeadershipTerm: {
|
|
94
140
|
latestTerm: number;
|
|
95
141
|
latestSeq: number;
|
|
@@ -108,6 +154,8 @@ export type ElectronPersistenceRequestByMethod = {
|
|
|
108
154
|
v: number;
|
|
109
155
|
requestId: string;
|
|
110
156
|
collectionId: string;
|
|
157
|
+
/** Required for data operations; preserves eager or managed identity across IPC. */
|
|
158
|
+
storageTarget?: PersistedStorageTarget;
|
|
111
159
|
resolution?: ElectronPersistenceResolution;
|
|
112
160
|
method: Method;
|
|
113
161
|
payload: ElectronPersistencePayloadMap[Method];
|
package/dist/esm/protocol.js
CHANGED
package/dist/esm/protocol.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sources":["../../src/protocol.ts"],"sourcesContent":["import type { LoadSubsetOptions } from '@tanstack/db'\nimport type {\n CommittedTxAnchor,\n PersistedCollectionMode,\n PersistedIndexSpec,\n PersistedKeySetEvidence,\n PersistedTx,\n ReconciledCommittedTx,\n SQLitePullSinceResult,\n} from '@tanstack/db-sqlite-persistence-core'\n\nexport const ELECTRON_PERSISTENCE_PROTOCOL_VERSION =
|
|
1
|
+
{"version":3,"file":"protocol.js","sources":["../../src/protocol.ts"],"sourcesContent":["import type { LoadSubsetOptions } from '@tanstack/db'\nimport type {\n CommittedTxAnchor,\n PersistedCacheGenerationClaim,\n PersistedCollectionMode,\n PersistedIndexSpec,\n PersistedKeySetEvidence,\n PersistedStorageTarget,\n PersistedTx,\n ReconciledCommittedTx,\n SQLitePullSinceResult,\n} from '@tanstack/db-sqlite-persistence-core'\n\nexport const ELECTRON_PERSISTENCE_PROTOCOL_VERSION = 6 as const\nexport const DEFAULT_ELECTRON_PERSISTENCE_CHANNEL = `tanstack-db:sqlite-persistence`\n\nexport type ElectronPersistedRow = Record<string, unknown>\nexport type ElectronPersistedKey = string | number\n\nexport type ElectronPersistenceResolution = {\n mode: PersistedCollectionMode\n schemaVersion?: number\n logicalCollectionId?: string\n}\n\nexport type ElectronPersistenceMethod =\n | `loadSubset`\n | `loadResumeSnapshot`\n | `loadCollectionMetadata`\n | `scanRows`\n | `applyCommittedTx`\n | `reconcileCommittedTx`\n | `ensureIndex`\n | `markIndexRemoved`\n | `pullSince`\n | `getStreamPosition`\n | `claimCacheGeneration`\n | `rotateCacheGeneration`\n | `renewCacheGenerationClaim`\n | `releaseCacheGenerationClaim`\n | `reserveLeadershipTerm`\n\nexport type ElectronPersistencePayloadMap = {\n loadSubset: {\n options: LoadSubsetOptions\n ctx?: {\n requiredIndexSignatures?: ReadonlyArray<string>\n cacheGenerationClaimId?: string\n }\n }\n loadResumeSnapshot: {\n ctx?: {\n requiredIndexSignatures?: ReadonlyArray<string>\n includeRows?: boolean\n cacheGenerationClaimId?: string\n }\n }\n loadCollectionMetadata: { ctx?: { cacheGenerationClaimId?: string } }\n scanRows: {\n options?: {\n metadataOnly?: boolean\n }\n ctx?: { cacheGenerationClaimId?: string }\n }\n applyCommittedTx: {\n tx: PersistedTx<ElectronPersistedRow, ElectronPersistedKey>\n }\n reconcileCommittedTx: {\n tx: PersistedTx<ElectronPersistedRow, ElectronPersistedKey>\n anchor: CommittedTxAnchor\n }\n ensureIndex: {\n signature: string\n spec: PersistedIndexSpec\n ctx?: { cacheGenerationClaimId?: string }\n }\n markIndexRemoved: {\n signature: string\n ctx?: { cacheGenerationClaimId?: string }\n }\n pullSince: {\n fromRowVersion: number\n ctx?: { cacheGenerationClaimId?: string }\n }\n getStreamPosition: { ctx?: { cacheGenerationClaimId?: string } }\n claimCacheGeneration: {}\n rotateCacheGeneration: {\n claimId: string\n resetMetadata?: { key: string; value: unknown }\n expectedStorageCollectionId?: string\n }\n renewCacheGenerationClaim: {\n storageCollectionId: string\n claimId: string\n }\n releaseCacheGenerationClaim: { claimId: string }\n reserveLeadershipTerm: {\n observedTerm: number\n ctx?: { cacheGenerationClaimId?: string }\n }\n}\n\nexport type ElectronPersistenceResultMap = {\n loadSubset: Array<{ key: ElectronPersistedKey; value: ElectronPersistedRow }>\n loadResumeSnapshot: {\n rows: Array<{\n key: ElectronPersistedKey\n value: ElectronPersistedRow\n metadata?: unknown\n }>\n keySet?: PersistedKeySetEvidence\n collectionMetadata: Array<{ key: string; value: unknown }>\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n resetEpoch: number\n }\n loadCollectionMetadata: Array<{ key: string; value: unknown }>\n scanRows: Array<{\n key: ElectronPersistedKey\n value: ElectronPersistedRow\n metadata?: unknown\n }>\n applyCommittedTx: null\n reconcileCommittedTx: ReconciledCommittedTx\n ensureIndex: null\n markIndexRemoved: null\n pullSince: SQLitePullSinceResult<ElectronPersistedKey>\n getStreamPosition: {\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n }\n claimCacheGeneration: PersistedCacheGenerationClaim\n rotateCacheGeneration: PersistedCacheGenerationClaim\n renewCacheGenerationClaim: number | undefined\n releaseCacheGenerationClaim: null\n reserveLeadershipTerm: {\n latestTerm: number\n latestSeq: number\n latestRowVersion: number\n }\n}\n\nexport type ElectronSerializedError = {\n name: string\n message: string\n stack?: string\n code?: string | number\n path?: string | ReadonlyArray<string | number>\n}\n\nexport type ElectronPersistenceRequestByMethod = {\n [Method in ElectronPersistenceMethod]: {\n v: number\n requestId: string\n collectionId: string\n /** Required for data operations; preserves eager or managed identity across IPC. */\n storageTarget?: PersistedStorageTarget\n resolution?: ElectronPersistenceResolution\n method: Method\n payload: ElectronPersistencePayloadMap[Method]\n }\n}\n\nexport type ElectronPersistenceRequest<\n TMethod extends ElectronPersistenceMethod = ElectronPersistenceMethod,\n> = ElectronPersistenceRequestByMethod[TMethod]\n\nexport type ElectronPersistenceRequestEnvelope =\n ElectronPersistenceRequestByMethod[ElectronPersistenceMethod]\n\ntype ElectronPersistenceSuccessResponseByMethod = {\n [Method in ElectronPersistenceMethod]: {\n v: number\n requestId: string\n method: Method\n ok: true\n result: ElectronPersistenceResultMap[Method]\n }\n}\n\ntype ElectronPersistenceErrorResponseByMethod = {\n [Method in ElectronPersistenceMethod]: {\n v: number\n requestId: string\n method: Method\n ok: false\n error: ElectronSerializedError\n }\n}\n\nexport type ElectronPersistenceResponse<\n TMethod extends ElectronPersistenceMethod = ElectronPersistenceMethod,\n> =\n | ElectronPersistenceSuccessResponseByMethod[TMethod]\n | ElectronPersistenceErrorResponseByMethod[TMethod]\n\nexport type ElectronPersistenceResponseEnvelope =\n ElectronPersistenceResponse<ElectronPersistenceMethod>\n\nexport type ElectronPersistenceRequestHandler = (\n request: ElectronPersistenceRequestEnvelope,\n) => Promise<ElectronPersistenceResponseEnvelope>\n\nexport type ElectronPersistenceInvoke = (\n channel: string,\n request: ElectronPersistenceRequestEnvelope,\n) => Promise<ElectronPersistenceResponseEnvelope>\n"],"names":[],"mappings":"AAaO,MAAM,wCAAwC;AAC9C,MAAM,uCAAuC;"}
|
package/dist/esm/renderer.d.ts
CHANGED
|
@@ -9,5 +9,7 @@ export type ElectronSQLitePersistenceOptions = {
|
|
|
9
9
|
channel?: string;
|
|
10
10
|
timeoutMs?: number;
|
|
11
11
|
coordinator?: PersistedCollectionCoordinator;
|
|
12
|
+
/** Set false when a custom main-process adapter does not manage cache generations. */
|
|
13
|
+
managedCacheGenerations?: boolean;
|
|
12
14
|
};
|
|
13
15
|
export declare function createElectronSQLitePersistence(options: ElectronSQLitePersistenceOptions): PersistedCollectionPersistence;
|
package/dist/esm/renderer.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SingleProcessCoordinator, InvalidPersistedCollectionConfigError } from "@tanstack/db-sqlite-persistence-core";
|
|
1
|
+
import { SingleProcessCoordinator, InvalidPersistedCollectionConfigError, resolvePersistedStorageTarget } from "@tanstack/db-sqlite-persistence-core";
|
|
2
2
|
import { ElectronCollectionCoordinator } from "./electron-coordinator.js";
|
|
3
3
|
import { DEFAULT_ELECTRON_PERSISTENCE_CHANNEL, ELECTRON_PERSISTENCE_PROTOCOL_VERSION } from "./protocol.js";
|
|
4
4
|
const DEFAULT_REQUEST_TIMEOUT_MS = 5e3;
|
|
@@ -52,13 +52,24 @@ function createSerializableLoadSubsetOptions(subsetOptions) {
|
|
|
52
52
|
function createRendererRequestExecutor(options) {
|
|
53
53
|
const channel = options.channel ?? DEFAULT_ELECTRON_PERSISTENCE_CHANNEL;
|
|
54
54
|
const timeoutMs = options.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
55
|
-
return async (method,
|
|
55
|
+
return async (method, target, payload, resolution) => {
|
|
56
|
+
const storageTarget = typeof target === `string` ? void 0 : target;
|
|
57
|
+
const collectionId = storageTarget ? resolvePersistedStorageTarget(storageTarget).collectionId : target;
|
|
58
|
+
const isGenerationRequest = method === `claimCacheGeneration` || method === `rotateCacheGeneration` || method === `renewCacheGenerationClaim` || method === `releaseCacheGenerationClaim`;
|
|
59
|
+
const managedTarget = storageTarget?.kind === `managed`;
|
|
60
|
+
const logicalCollectionId = resolution?.logicalCollectionId ?? (managedTarget ? options.claimCollections.get(storageTarget.claimId) : isGenerationRequest ? collectionId : void 0);
|
|
61
|
+
if ((managedTarget || isGenerationRequest) && !logicalCollectionId) {
|
|
62
|
+
throw new InvalidPersistedCollectionConfigError(
|
|
63
|
+
`Electron managed cache request requires a known logical Collection ID`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
56
66
|
const request = {
|
|
57
67
|
v: ELECTRON_PERSISTENCE_PROTOCOL_VERSION,
|
|
58
68
|
requestId: createRequestId(),
|
|
59
69
|
collectionId,
|
|
70
|
+
storageTarget,
|
|
60
71
|
method,
|
|
61
|
-
resolution,
|
|
72
|
+
resolution: managedTarget || isGenerationRequest ? { ...resolution, mode: `sync-present`, logicalCollectionId } : resolution,
|
|
62
73
|
payload
|
|
63
74
|
};
|
|
64
75
|
const response = await withTimeout(
|
|
@@ -85,105 +96,219 @@ function createRendererRequestExecutor(options) {
|
|
|
85
96
|
return response.result;
|
|
86
97
|
};
|
|
87
98
|
}
|
|
88
|
-
function createResolvedRendererAdapter(executeRequest, resolution) {
|
|
89
|
-
|
|
90
|
-
loadSubset: async (
|
|
99
|
+
function createResolvedRendererAdapter(executeRequest, claimCollections, managedCacheGenerations, resolution) {
|
|
100
|
+
const adapter = {
|
|
101
|
+
loadSubset: async (target, subsetOptions, ctx) => {
|
|
102
|
+
const access = resolvePersistedStorageTarget(
|
|
103
|
+
target,
|
|
104
|
+
ctx?.cacheGenerationClaimId
|
|
105
|
+
);
|
|
91
106
|
const result = await executeRequest(
|
|
92
107
|
`loadSubset`,
|
|
93
|
-
|
|
108
|
+
target,
|
|
94
109
|
{
|
|
95
110
|
options: createSerializableLoadSubsetOptions(subsetOptions),
|
|
96
|
-
ctx
|
|
111
|
+
ctx: { ...ctx, cacheGenerationClaimId: access.claimId }
|
|
97
112
|
},
|
|
98
113
|
resolution
|
|
99
114
|
);
|
|
100
115
|
return result;
|
|
101
116
|
},
|
|
102
|
-
loadResumeSnapshot: async (
|
|
117
|
+
loadResumeSnapshot: async (target, ctx) => {
|
|
118
|
+
const access = resolvePersistedStorageTarget(
|
|
119
|
+
target,
|
|
120
|
+
ctx?.cacheGenerationClaimId
|
|
121
|
+
);
|
|
103
122
|
return executeRequest(
|
|
104
123
|
`loadResumeSnapshot`,
|
|
105
|
-
|
|
106
|
-
{ ctx },
|
|
124
|
+
target,
|
|
125
|
+
{ ctx: { ...ctx, cacheGenerationClaimId: access.claimId } },
|
|
107
126
|
resolution
|
|
108
127
|
);
|
|
109
128
|
},
|
|
110
|
-
applyCommittedTx: async (
|
|
129
|
+
applyCommittedTx: async (target, tx) => {
|
|
130
|
+
const access = resolvePersistedStorageTarget(
|
|
131
|
+
target,
|
|
132
|
+
tx.cacheGenerationClaimId
|
|
133
|
+
);
|
|
111
134
|
await executeRequest(
|
|
112
135
|
`applyCommittedTx`,
|
|
113
|
-
|
|
136
|
+
target,
|
|
114
137
|
{
|
|
115
|
-
tx
|
|
138
|
+
tx: { ...tx, cacheGenerationClaimId: access.claimId }
|
|
116
139
|
},
|
|
117
140
|
resolution
|
|
118
141
|
);
|
|
119
142
|
},
|
|
120
|
-
reconcileCommittedTx: async (
|
|
143
|
+
reconcileCommittedTx: async (target, tx, anchor) => {
|
|
144
|
+
const access = resolvePersistedStorageTarget(
|
|
145
|
+
target,
|
|
146
|
+
tx.cacheGenerationClaimId
|
|
147
|
+
);
|
|
121
148
|
return executeRequest(
|
|
122
149
|
`reconcileCommittedTx`,
|
|
123
|
-
|
|
124
|
-
{ tx, anchor },
|
|
150
|
+
target,
|
|
151
|
+
{ tx: { ...tx, cacheGenerationClaimId: access.claimId }, anchor },
|
|
125
152
|
resolution
|
|
126
153
|
);
|
|
127
154
|
},
|
|
128
|
-
loadCollectionMetadata: async (
|
|
155
|
+
loadCollectionMetadata: async (target, ctx) => {
|
|
156
|
+
const access = resolvePersistedStorageTarget(
|
|
157
|
+
target,
|
|
158
|
+
ctx?.cacheGenerationClaimId
|
|
159
|
+
);
|
|
129
160
|
return executeRequest(
|
|
130
161
|
`loadCollectionMetadata`,
|
|
131
|
-
|
|
132
|
-
{},
|
|
162
|
+
target,
|
|
163
|
+
{ ctx: { ...ctx, cacheGenerationClaimId: access.claimId } },
|
|
133
164
|
resolution
|
|
134
165
|
);
|
|
135
166
|
},
|
|
136
|
-
scanRows: async (
|
|
167
|
+
scanRows: async (target, options, ctx) => {
|
|
168
|
+
const access = resolvePersistedStorageTarget(
|
|
169
|
+
target,
|
|
170
|
+
ctx?.cacheGenerationClaimId
|
|
171
|
+
);
|
|
137
172
|
const result = await executeRequest(
|
|
138
173
|
`scanRows`,
|
|
139
|
-
|
|
140
|
-
{ options },
|
|
174
|
+
target,
|
|
175
|
+
{ options, ctx: { ...ctx, cacheGenerationClaimId: access.claimId } },
|
|
141
176
|
resolution
|
|
142
177
|
);
|
|
143
178
|
return result;
|
|
144
179
|
},
|
|
145
|
-
ensureIndex: async (
|
|
180
|
+
ensureIndex: async (target, signature, spec, ctx) => {
|
|
181
|
+
const access = resolvePersistedStorageTarget(
|
|
182
|
+
target,
|
|
183
|
+
ctx?.cacheGenerationClaimId
|
|
184
|
+
);
|
|
146
185
|
await executeRequest(
|
|
147
186
|
`ensureIndex`,
|
|
148
|
-
|
|
187
|
+
target,
|
|
149
188
|
{
|
|
150
189
|
signature,
|
|
151
|
-
spec
|
|
190
|
+
spec,
|
|
191
|
+
ctx: { ...ctx, cacheGenerationClaimId: access.claimId }
|
|
152
192
|
},
|
|
153
193
|
resolution
|
|
154
194
|
);
|
|
155
195
|
},
|
|
156
|
-
markIndexRemoved: async (
|
|
196
|
+
markIndexRemoved: async (target, signature, ctx) => {
|
|
197
|
+
const access = resolvePersistedStorageTarget(
|
|
198
|
+
target,
|
|
199
|
+
ctx?.cacheGenerationClaimId
|
|
200
|
+
);
|
|
157
201
|
await executeRequest(
|
|
158
202
|
`markIndexRemoved`,
|
|
159
|
-
|
|
203
|
+
target,
|
|
160
204
|
{
|
|
161
|
-
signature
|
|
205
|
+
signature,
|
|
206
|
+
ctx: { ...ctx, cacheGenerationClaimId: access.claimId }
|
|
162
207
|
},
|
|
163
208
|
resolution
|
|
164
209
|
);
|
|
165
210
|
},
|
|
166
|
-
pullSince: async (
|
|
211
|
+
pullSince: async (target, fromRowVersion, ctx) => {
|
|
212
|
+
const access = resolvePersistedStorageTarget(
|
|
213
|
+
target,
|
|
214
|
+
ctx?.cacheGenerationClaimId
|
|
215
|
+
);
|
|
167
216
|
const result = await executeRequest(
|
|
168
217
|
`pullSince`,
|
|
169
|
-
|
|
218
|
+
target,
|
|
170
219
|
{
|
|
171
|
-
fromRowVersion
|
|
220
|
+
fromRowVersion,
|
|
221
|
+
ctx: { ...ctx, cacheGenerationClaimId: access.claimId }
|
|
172
222
|
},
|
|
173
223
|
resolution
|
|
174
224
|
);
|
|
175
225
|
return result;
|
|
176
226
|
},
|
|
177
|
-
getStreamPosition: async (
|
|
178
|
-
|
|
227
|
+
getStreamPosition: async (target, ctx) => {
|
|
228
|
+
const access = resolvePersistedStorageTarget(
|
|
229
|
+
target,
|
|
230
|
+
ctx?.cacheGenerationClaimId
|
|
231
|
+
);
|
|
232
|
+
return executeRequest(
|
|
233
|
+
`getStreamPosition`,
|
|
234
|
+
target,
|
|
235
|
+
{ ctx: { ...ctx, cacheGenerationClaimId: access.claimId } },
|
|
236
|
+
resolution
|
|
237
|
+
);
|
|
179
238
|
},
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
239
|
+
claimCacheGeneration: async (collectionId) => {
|
|
240
|
+
const claim = await executeRequest(
|
|
241
|
+
`claimCacheGeneration`,
|
|
242
|
+
collectionId,
|
|
243
|
+
{},
|
|
244
|
+
resolution
|
|
245
|
+
);
|
|
246
|
+
claimCollections.set(claim.claimId, collectionId);
|
|
247
|
+
return claim;
|
|
248
|
+
},
|
|
249
|
+
rotateCacheGeneration: async (collectionId, claimId, resetMetadata, expectedStorageCollectionId) => {
|
|
250
|
+
const claim = await executeRequest(
|
|
251
|
+
`rotateCacheGeneration`,
|
|
252
|
+
collectionId,
|
|
253
|
+
{ claimId, resetMetadata, expectedStorageCollectionId },
|
|
254
|
+
resolution
|
|
255
|
+
);
|
|
256
|
+
claimCollections.delete(claimId);
|
|
257
|
+
claimCollections.set(claim.claimId, collectionId);
|
|
258
|
+
return claim;
|
|
259
|
+
},
|
|
260
|
+
renewCacheGenerationClaim: (storageCollectionId, claimId) => {
|
|
261
|
+
const collectionId = claimCollections.get(claimId);
|
|
262
|
+
if (!collectionId) {
|
|
263
|
+
throw new InvalidPersistedCollectionConfigError(
|
|
264
|
+
`Unknown electron persisted cache claim "${claimId}"`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
return executeRequest(
|
|
268
|
+
`renewCacheGenerationClaim`,
|
|
269
|
+
collectionId,
|
|
270
|
+
{ storageCollectionId, claimId },
|
|
271
|
+
resolution
|
|
272
|
+
);
|
|
273
|
+
},
|
|
274
|
+
releaseCacheGenerationClaim: async (claimId) => {
|
|
275
|
+
const collectionId = claimCollections.get(claimId);
|
|
276
|
+
if (!collectionId) {
|
|
277
|
+
throw new InvalidPersistedCollectionConfigError(
|
|
278
|
+
`Unknown electron persisted cache claim "${claimId}"`
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
await executeRequest(
|
|
282
|
+
`releaseCacheGenerationClaim`,
|
|
283
|
+
collectionId,
|
|
284
|
+
{ claimId },
|
|
285
|
+
resolution
|
|
286
|
+
);
|
|
287
|
+
claimCollections.delete(claimId);
|
|
288
|
+
},
|
|
289
|
+
reserveLeadershipTerm: async (target, observedTerm, ctx) => {
|
|
290
|
+
const access = resolvePersistedStorageTarget(
|
|
291
|
+
target,
|
|
292
|
+
ctx?.cacheGenerationClaimId
|
|
293
|
+
);
|
|
294
|
+
return executeRequest(
|
|
295
|
+
`reserveLeadershipTerm`,
|
|
296
|
+
target,
|
|
297
|
+
{
|
|
298
|
+
observedTerm,
|
|
299
|
+
ctx: { ...ctx, cacheGenerationClaimId: access.claimId }
|
|
300
|
+
},
|
|
301
|
+
resolution
|
|
302
|
+
);
|
|
303
|
+
}
|
|
186
304
|
};
|
|
305
|
+
if (!managedCacheGenerations) {
|
|
306
|
+
adapter.claimCacheGeneration = void 0;
|
|
307
|
+
adapter.rotateCacheGeneration = void 0;
|
|
308
|
+
adapter.renewCacheGenerationClaim = void 0;
|
|
309
|
+
adapter.releaseCacheGenerationClaim = void 0;
|
|
310
|
+
}
|
|
311
|
+
return adapter;
|
|
187
312
|
}
|
|
188
313
|
function resolveInvoke(options) {
|
|
189
314
|
if (options.invoke) {
|
|
@@ -199,28 +324,31 @@ function resolveInvoke(options) {
|
|
|
199
324
|
function createElectronSQLitePersistence(options) {
|
|
200
325
|
const invoke = resolveInvoke(options);
|
|
201
326
|
const coordinator = options.coordinator ?? new SingleProcessCoordinator();
|
|
327
|
+
const claimCollections = /* @__PURE__ */ new Map();
|
|
202
328
|
const executeRequest = createRendererRequestExecutor({
|
|
203
329
|
invoke,
|
|
204
330
|
channel: options.channel,
|
|
205
|
-
timeoutMs: options.timeoutMs
|
|
331
|
+
timeoutMs: options.timeoutMs,
|
|
332
|
+
claimCollections
|
|
206
333
|
});
|
|
207
334
|
const adapterCache = /* @__PURE__ */ new Map();
|
|
208
|
-
const getAdapterForCollection = (mode, schemaVersion) => {
|
|
209
|
-
const
|
|
210
|
-
const cacheKey = `mode:${mode}|${schemaVersionKey}`;
|
|
335
|
+
const getAdapterForCollection = (collectionId, mode, schemaVersion) => {
|
|
336
|
+
const cacheKey = JSON.stringify([collectionId, mode, schemaVersion]);
|
|
211
337
|
const cachedAdapter = adapterCache.get(cacheKey);
|
|
212
338
|
if (cachedAdapter) {
|
|
213
339
|
return cachedAdapter;
|
|
214
340
|
}
|
|
215
|
-
const adapter = createResolvedRendererAdapter(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
341
|
+
const adapter = createResolvedRendererAdapter(
|
|
342
|
+
executeRequest,
|
|
343
|
+
claimCollections,
|
|
344
|
+
options.managedCacheGenerations ?? true,
|
|
345
|
+
{ mode, schemaVersion, logicalCollectionId: collectionId }
|
|
346
|
+
);
|
|
219
347
|
adapterCache.set(cacheKey, adapter);
|
|
220
348
|
return adapter;
|
|
221
349
|
};
|
|
222
350
|
const createCollectionPersistence = (collectionId, mode, schemaVersion) => {
|
|
223
|
-
const adapter = getAdapterForCollection(mode, schemaVersion);
|
|
351
|
+
const adapter = getAdapterForCollection(collectionId, mode, schemaVersion);
|
|
224
352
|
if (coordinator instanceof ElectronCollectionCoordinator) {
|
|
225
353
|
if (collectionId === void 0) {
|
|
226
354
|
coordinator.setAdapter(adapter);
|