@signalium/query 1.0.15 → 1.0.17

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.
@@ -246,7 +246,7 @@ class AsyncQueryStore {
246
246
  }
247
247
  }
248
248
  } else {
249
- const newRefIds = new Uint32Array(refIds);
249
+ const newRefIds = new Uint32Array([...refIds]);
250
250
  if (prevRefIds !== void 0) {
251
251
  for (let i = 0; i < prevRefIds.length; i++) {
252
252
  const refId = prevRefIds[i];
@@ -1 +1 @@
1
- {"version":3,"file":"async.js","sources":["../../../../src/stores/async.ts"],"sourcesContent":["import { EntityStore } from '../EntityMap.js';\nimport { CachedQuery, CachedQueryExtra, QueryDefinition, QueryStore } from '../QueryClient.js';\nimport {\n DEFAULT_GC_TIME,\n DEFAULT_MAX_COUNT,\n optimisticInsertRefsKeyFor,\n queueKeyFor,\n refCountKeyFor,\n refIdsKeyFor,\n streamOrphanRefsKeyFor,\n updatedAtKeyFor,\n valueKeyFor,\n} from './shared.js';\n\n// -----------------------------------------------------------------------------\n// Async QueryStore Interfaces\n// -----------------------------------------------------------------------------\n\nexport interface AsyncPersistentStore {\n has(key: string): Promise<boolean>;\n\n getString(key: string): Promise<string | undefined>;\n setString(key: string, value: string): Promise<void>;\n\n getNumber(key: string): Promise<number | undefined>;\n setNumber(key: string, value: number): Promise<void>;\n\n getBuffer(key: string): Promise<Uint32Array | undefined>;\n setBuffer(key: string, value: Uint32Array): Promise<void>;\n\n delete(key: string): Promise<void>;\n}\n\nexport type StoreMessage =\n | {\n type: 'saveQuery';\n queryDefId: string;\n queryKey: number;\n value: unknown;\n updatedAt: number;\n refIds?: number[];\n extra?: CachedQueryExtra;\n }\n | { type: 'saveEntity'; entityKey: number; value: unknown; refIds?: number[] }\n | { type: 'activateQuery'; queryDefId: string; queryKey: number }\n | { type: 'deleteQuery'; queryKey: number };\n\nexport interface AsyncQueryStoreConfig {\n isWriter: boolean;\n connect: (handleMessage: (msg: StoreMessage) => void) => {\n sendMessage: (msg: StoreMessage) => void;\n };\n delegate?: AsyncPersistentStore; // Only provided for writer\n}\n// -----------------------------------------------------------------------------\n// Async QueryStore Implementation\n// -----------------------------------------------------------------------------\n\nexport class AsyncQueryStore implements QueryStore {\n private readonly isWriter: boolean;\n private readonly delegate?: AsyncPersistentStore;\n private readonly sendMessage: (msg: StoreMessage) => void;\n private readonly messageQueue: StoreMessage[] = [];\n private readonly queues: Map<string, Uint32Array> = new Map();\n private queueProcessorPromise?: Promise<void>;\n private resolveQueueWait?: () => void;\n\n constructor(config: AsyncQueryStoreConfig) {\n this.isWriter = config.isWriter;\n this.delegate = config.delegate;\n\n // Connect and get sendMessage function\n const { sendMessage } = config.connect(this.handleMessage.bind(this));\n this.sendMessage = sendMessage;\n\n // Start queue processor if this is a writer\n if (this.isWriter) {\n if (!this.delegate) {\n throw new Error('Writer must have a delegate');\n }\n this.startQueueProcessor();\n }\n }\n\n private handleMessage(msg: StoreMessage): void {\n if (this.isWriter) {\n // Enqueue the message for serial processing\n this.enqueueMessage(msg);\n }\n // Readers don't handle incoming messages\n }\n\n private enqueueMessage(msg: StoreMessage): void {\n this.messageQueue.push(msg);\n // Wake up the queue processor if it's waiting\n if (this.resolveQueueWait) {\n this.resolveQueueWait();\n this.resolveQueueWait = undefined;\n }\n }\n\n private startQueueProcessor(): void {\n this.queueProcessorPromise = this.processQueue();\n }\n\n private async processQueue(): Promise<void> {\n while (true) {\n // Wait for messages if queue is empty\n while (this.messageQueue.length === 0) {\n await new Promise<void>(resolve => {\n this.resolveQueueWait = resolve;\n });\n }\n\n // Process one message at a time\n const msg = this.messageQueue.shift()!;\n\n try {\n await this.processMessage(msg);\n } catch (error) {\n console.error('Error processing message:', error);\n }\n }\n }\n\n private async processMessage(msg: StoreMessage): Promise<void> {\n switch (msg.type) {\n case 'saveQuery':\n await this.writerSaveQuery(msg.queryDefId, msg.queryKey, msg.value, msg.updatedAt, msg.refIds, msg.extra);\n break;\n case 'saveEntity':\n await this.writerSaveEntity(msg.entityKey, msg.value, msg.refIds);\n break;\n case 'activateQuery':\n await this.writerActivateQuery(msg.queryDefId, msg.queryKey);\n break;\n case 'deleteQuery':\n await this.writerDeleteValue(msg.queryKey);\n break;\n }\n }\n\n async loadQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n entityMap: EntityStore,\n ): Promise<CachedQuery | undefined> {\n if (!this.delegate) {\n return undefined;\n }\n\n const updatedAt = await this.delegate.getNumber(updatedAtKeyFor(queryKey));\n\n if (updatedAt === undefined || updatedAt < Date.now() - (queryDef.cache?.gcTime ?? DEFAULT_GC_TIME)) {\n return undefined;\n }\n\n const valueStr = await this.delegate.getString(valueKeyFor(queryKey));\n\n if (valueStr === undefined) {\n return undefined;\n }\n\n const entityIds = await this.delegate.getBuffer(refIdsKeyFor(queryKey));\n\n if (entityIds !== undefined) {\n await this.preloadEntities(entityIds, entityMap);\n }\n\n // Load extra data (stream orphans and optimistic inserts)\n const streamOrphanRefs = await this.delegate.getBuffer(streamOrphanRefsKeyFor(queryKey));\n const optimisticInsertRefs = await this.delegate.getBuffer(optimisticInsertRefsKeyFor(queryKey));\n\n // Preload entities for extra data\n if (streamOrphanRefs !== undefined) {\n await this.preloadEntities(streamOrphanRefs, entityMap);\n }\n if (optimisticInsertRefs !== undefined) {\n await this.preloadEntities(optimisticInsertRefs, entityMap);\n }\n\n let extra: CachedQueryExtra | undefined;\n if (streamOrphanRefs !== undefined || optimisticInsertRefs !== undefined) {\n extra = {};\n if (streamOrphanRefs !== undefined) {\n extra.streamOrphanRefs = Array.from(streamOrphanRefs);\n }\n if (optimisticInsertRefs !== undefined) {\n extra.optimisticInsertRefs = Array.from(optimisticInsertRefs);\n }\n }\n\n this.activateQuery(queryDef, queryKey);\n\n return {\n value: JSON.parse(valueStr) as Record<string, unknown>,\n refIds: entityIds === undefined ? undefined : new Set(entityIds ?? []),\n updatedAt,\n extra,\n };\n }\n\n private async preloadEntities(entityIds: Uint32Array, entityMap: EntityStore): Promise<void> {\n if (!this.delegate) {\n return;\n }\n\n for (const entityId of entityIds) {\n const entityValue = await this.delegate.getString(valueKeyFor(entityId));\n\n if (entityValue === undefined) {\n continue;\n }\n\n const entity = JSON.parse(entityValue) as Record<string, unknown>;\n entityMap.setPreloadedEntity(entityId, entity);\n\n const childIds = await this.delegate.getBuffer(refIdsKeyFor(entityId));\n\n if (childIds === undefined) {\n continue;\n }\n\n await this.preloadEntities(childIds, entityMap);\n }\n }\n\n saveQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: Set<number>,\n extra?: CachedQueryExtra,\n ): void {\n const message: StoreMessage = {\n type: 'saveQuery',\n queryDefId: queryDef.id,\n queryKey,\n value,\n updatedAt,\n refIds: refIds ? Array.from(refIds) : undefined,\n extra,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n saveEntity(entityKey: number, value: unknown, refIds?: Set<number>): void {\n const message: StoreMessage = {\n type: 'saveEntity',\n entityKey,\n value,\n refIds: refIds ? Array.from(refIds) : undefined,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n activateQuery(queryDef: QueryDefinition<any, any, any>, queryKey: number): void {\n const message: StoreMessage = {\n type: 'activateQuery',\n queryDefId: queryDef.id,\n queryKey,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n deleteQuery(queryKey: number): void {\n const message: StoreMessage = {\n type: 'deleteQuery',\n queryKey,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n // Writer-specific methods below\n\n private async writerSaveQuery(\n queryDefId: string,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: number[],\n extra?: CachedQueryExtra,\n ): Promise<void> {\n await this.setValue(queryKey, value, refIds ? new Set(refIds) : undefined);\n await this.delegate!.setNumber(updatedAtKeyFor(queryKey), updatedAt);\n\n // Save extra data\n if (extra?.streamOrphanRefs !== undefined && extra.streamOrphanRefs.length > 0) {\n await this.delegate!.setBuffer(streamOrphanRefsKeyFor(queryKey), new Uint32Array(extra.streamOrphanRefs));\n } else {\n await this.delegate!.delete(streamOrphanRefsKeyFor(queryKey));\n }\n\n if (extra?.optimisticInsertRefs !== undefined && extra.optimisticInsertRefs.length > 0) {\n await this.delegate!.setBuffer(optimisticInsertRefsKeyFor(queryKey), new Uint32Array(extra.optimisticInsertRefs));\n } else {\n await this.delegate!.delete(optimisticInsertRefsKeyFor(queryKey));\n }\n\n await this.writerActivateQuery(queryDefId, queryKey);\n }\n\n private async writerSaveEntity(entityKey: number, value: unknown, refIds?: number[]): Promise<void> {\n await this.setValue(entityKey, value, refIds ? new Set(refIds) : undefined);\n }\n\n private async writerActivateQuery(queryDefId: string, queryKey: number): Promise<void> {\n if (!(await this.delegate!.has(valueKeyFor(queryKey)))) {\n // Query not in store, nothing to do\n return;\n }\n\n let queue = this.queues.get(queryDefId);\n\n if (queue === undefined) {\n // For now, use default max count. In a real implementation,\n // we'd need to pass queryDef or maxCount through the message\n const maxCount = DEFAULT_MAX_COUNT;\n queue = await this.delegate!.getBuffer(queueKeyFor(queryDefId));\n\n if (queue === undefined) {\n queue = new Uint32Array(maxCount);\n await this.delegate!.setBuffer(queueKeyFor(queryDefId), queue);\n } else if (queue.length !== maxCount) {\n queue = new Uint32Array(queue.buffer, 0, maxCount);\n await this.delegate!.setBuffer(queueKeyFor(queryDefId), queue);\n }\n\n this.queues.set(queryDefId, queue);\n }\n\n const indexOfKey = queue.indexOf(queryKey);\n\n // Item already in queue, move to front\n if (indexOfKey >= 0) {\n if (indexOfKey === 0) {\n // Already at front, nothing to do\n return;\n }\n // Shift items right to make space at front\n queue.copyWithin(1, 0, indexOfKey);\n queue[0] = queryKey;\n return;\n }\n\n // Item not in queue, add to front and evict tail\n const evicted = queue[queue.length - 1];\n queue.copyWithin(1, 0, queue.length - 1);\n queue[0] = queryKey;\n\n if (evicted !== 0) {\n await this.writerDeleteValue(evicted);\n await this.delegate!.delete(updatedAtKeyFor(evicted));\n }\n }\n\n private async setValue(id: number, value: unknown, refIds?: Set<number>): Promise<void> {\n const delegate = this.delegate!;\n\n await delegate.setString(valueKeyFor(id), JSON.stringify(value));\n\n const refIdsKey = refIdsKeyFor(id);\n\n const prevRefIds = await delegate.getBuffer(refIdsKey);\n\n if (refIds === undefined || refIds.size === 0) {\n await delegate.delete(refIdsKey);\n\n // Decrement all previous refs\n if (prevRefIds !== undefined) {\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n await this.decrementRefCount(refId);\n }\n }\n } else {\n // Convert the set to a Uint32Array and capture all the refIds before we\n // delete previous ones from the set\n const newRefIds = new Uint32Array(refIds);\n\n if (prevRefIds !== undefined) {\n // Process new refs: increment if not in old\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n\n if (refIds.has(refId)) {\n refIds.delete(refId);\n } else {\n await this.decrementRefCount(refId);\n }\n }\n }\n\n // No previous refs, increment all unique new refs\n for (const refId of refIds) {\n await this.incrementRefCount(refId);\n }\n\n await delegate.setBuffer(refIdsKey, newRefIds);\n }\n }\n\n private async writerDeleteValue(id: number): Promise<void> {\n const delegate = this.delegate!;\n\n await delegate.delete(valueKeyFor(id));\n await delegate.delete(refCountKeyFor(id));\n\n const refIds = await delegate.getBuffer(refIdsKeyFor(id));\n await delegate.delete(refIdsKeyFor(id)); // Clean up the refIds key\n\n if (refIds === undefined) {\n return;\n }\n\n // Decrement ref counts for all referenced entities\n for (const refId of refIds) {\n if (refId !== 0) {\n await this.decrementRefCount(refId);\n }\n }\n }\n\n private async incrementRefCount(refId: number): Promise<void> {\n const delegate = this.delegate!;\n const refCountKey = refCountKeyFor(refId);\n const currentCount = (await delegate.getNumber(refCountKey)) ?? 0;\n const newCount = currentCount + 1;\n await delegate.setNumber(refCountKey, newCount);\n }\n\n private async decrementRefCount(refId: number): Promise<void> {\n const delegate = this.delegate!;\n const refCountKey = refCountKeyFor(refId);\n const currentCount = await delegate.getNumber(refCountKey);\n\n if (currentCount === undefined) {\n // Already deleted or never existed\n return;\n }\n\n const newCount = currentCount - 1;\n\n if (newCount === 0) {\n // Entity exists, cascade delete it\n await this.writerDeleteValue(refId);\n } else {\n await delegate.setNumber(refCountKey, newCount);\n }\n }\n}\n"],"names":["updatedAtKeyFor","DEFAULT_GC_TIME","valueKeyFor","refIdsKeyFor","streamOrphanRefsKeyFor","optimisticInsertRefsKeyFor","DEFAULT_MAX_COUNT","queueKeyFor","refCountKeyFor"],"mappings":"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"}
1
+ {"version":3,"file":"async.js","sources":["../../../../src/stores/async.ts"],"sourcesContent":["import { EntityStore } from '../EntityMap.js';\nimport { CachedQuery, CachedQueryExtra, QueryDefinition, QueryStore } from '../QueryClient.js';\nimport {\n DEFAULT_GC_TIME,\n DEFAULT_MAX_COUNT,\n optimisticInsertRefsKeyFor,\n queueKeyFor,\n refCountKeyFor,\n refIdsKeyFor,\n streamOrphanRefsKeyFor,\n updatedAtKeyFor,\n valueKeyFor,\n} from './shared.js';\n\n// -----------------------------------------------------------------------------\n// Async QueryStore Interfaces\n// -----------------------------------------------------------------------------\n\nexport interface AsyncPersistentStore {\n has(key: string): Promise<boolean>;\n\n getString(key: string): Promise<string | undefined>;\n setString(key: string, value: string): Promise<void>;\n\n getNumber(key: string): Promise<number | undefined>;\n setNumber(key: string, value: number): Promise<void>;\n\n getBuffer(key: string): Promise<Uint32Array | undefined>;\n setBuffer(key: string, value: Uint32Array): Promise<void>;\n\n delete(key: string): Promise<void>;\n}\n\nexport type StoreMessage =\n | {\n type: 'saveQuery';\n queryDefId: string;\n queryKey: number;\n value: unknown;\n updatedAt: number;\n refIds?: number[];\n extra?: CachedQueryExtra;\n }\n | { type: 'saveEntity'; entityKey: number; value: unknown; refIds?: number[] }\n | { type: 'activateQuery'; queryDefId: string; queryKey: number }\n | { type: 'deleteQuery'; queryKey: number };\n\nexport interface AsyncQueryStoreConfig {\n isWriter: boolean;\n connect: (handleMessage: (msg: StoreMessage) => void) => {\n sendMessage: (msg: StoreMessage) => void;\n };\n delegate?: AsyncPersistentStore; // Only provided for writer\n}\n// -----------------------------------------------------------------------------\n// Async QueryStore Implementation\n// -----------------------------------------------------------------------------\n\nexport class AsyncQueryStore implements QueryStore {\n private readonly isWriter: boolean;\n private readonly delegate?: AsyncPersistentStore;\n private readonly sendMessage: (msg: StoreMessage) => void;\n private readonly messageQueue: StoreMessage[] = [];\n private readonly queues: Map<string, Uint32Array> = new Map();\n private queueProcessorPromise?: Promise<void>;\n private resolveQueueWait?: () => void;\n\n constructor(config: AsyncQueryStoreConfig) {\n this.isWriter = config.isWriter;\n this.delegate = config.delegate;\n\n // Connect and get sendMessage function\n const { sendMessage } = config.connect(this.handleMessage.bind(this));\n this.sendMessage = sendMessage;\n\n // Start queue processor if this is a writer\n if (this.isWriter) {\n if (!this.delegate) {\n throw new Error('Writer must have a delegate');\n }\n this.startQueueProcessor();\n }\n }\n\n private handleMessage(msg: StoreMessage): void {\n if (this.isWriter) {\n // Enqueue the message for serial processing\n this.enqueueMessage(msg);\n }\n // Readers don't handle incoming messages\n }\n\n private enqueueMessage(msg: StoreMessage): void {\n this.messageQueue.push(msg);\n // Wake up the queue processor if it's waiting\n if (this.resolveQueueWait) {\n this.resolveQueueWait();\n this.resolveQueueWait = undefined;\n }\n }\n\n private startQueueProcessor(): void {\n this.queueProcessorPromise = this.processQueue();\n }\n\n private async processQueue(): Promise<void> {\n while (true) {\n // Wait for messages if queue is empty\n while (this.messageQueue.length === 0) {\n await new Promise<void>(resolve => {\n this.resolveQueueWait = resolve;\n });\n }\n\n // Process one message at a time\n const msg = this.messageQueue.shift()!;\n\n try {\n await this.processMessage(msg);\n } catch (error) {\n console.error('Error processing message:', error);\n }\n }\n }\n\n private async processMessage(msg: StoreMessage): Promise<void> {\n switch (msg.type) {\n case 'saveQuery':\n await this.writerSaveQuery(msg.queryDefId, msg.queryKey, msg.value, msg.updatedAt, msg.refIds, msg.extra);\n break;\n case 'saveEntity':\n await this.writerSaveEntity(msg.entityKey, msg.value, msg.refIds);\n break;\n case 'activateQuery':\n await this.writerActivateQuery(msg.queryDefId, msg.queryKey);\n break;\n case 'deleteQuery':\n await this.writerDeleteValue(msg.queryKey);\n break;\n }\n }\n\n async loadQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n entityMap: EntityStore,\n ): Promise<CachedQuery | undefined> {\n if (!this.delegate) {\n return undefined;\n }\n\n const updatedAt = await this.delegate.getNumber(updatedAtKeyFor(queryKey));\n\n if (updatedAt === undefined || updatedAt < Date.now() - (queryDef.cache?.gcTime ?? DEFAULT_GC_TIME)) {\n return undefined;\n }\n\n const valueStr = await this.delegate.getString(valueKeyFor(queryKey));\n\n if (valueStr === undefined) {\n return undefined;\n }\n\n const entityIds = await this.delegate.getBuffer(refIdsKeyFor(queryKey));\n\n if (entityIds !== undefined) {\n await this.preloadEntities(entityIds, entityMap);\n }\n\n // Load extra data (stream orphans and optimistic inserts)\n const streamOrphanRefs = await this.delegate.getBuffer(streamOrphanRefsKeyFor(queryKey));\n const optimisticInsertRefs = await this.delegate.getBuffer(optimisticInsertRefsKeyFor(queryKey));\n\n // Preload entities for extra data\n if (streamOrphanRefs !== undefined) {\n await this.preloadEntities(streamOrphanRefs, entityMap);\n }\n if (optimisticInsertRefs !== undefined) {\n await this.preloadEntities(optimisticInsertRefs, entityMap);\n }\n\n let extra: CachedQueryExtra | undefined;\n if (streamOrphanRefs !== undefined || optimisticInsertRefs !== undefined) {\n extra = {};\n if (streamOrphanRefs !== undefined) {\n extra.streamOrphanRefs = Array.from(streamOrphanRefs);\n }\n if (optimisticInsertRefs !== undefined) {\n extra.optimisticInsertRefs = Array.from(optimisticInsertRefs);\n }\n }\n\n this.activateQuery(queryDef, queryKey);\n\n return {\n value: JSON.parse(valueStr) as Record<string, unknown>,\n refIds: entityIds === undefined ? undefined : new Set(entityIds ?? []),\n updatedAt,\n extra,\n };\n }\n\n private async preloadEntities(entityIds: Uint32Array, entityMap: EntityStore): Promise<void> {\n if (!this.delegate) {\n return;\n }\n\n for (const entityId of entityIds) {\n const entityValue = await this.delegate.getString(valueKeyFor(entityId));\n\n if (entityValue === undefined) {\n continue;\n }\n\n const entity = JSON.parse(entityValue) as Record<string, unknown>;\n entityMap.setPreloadedEntity(entityId, entity);\n\n const childIds = await this.delegate.getBuffer(refIdsKeyFor(entityId));\n\n if (childIds === undefined) {\n continue;\n }\n\n await this.preloadEntities(childIds, entityMap);\n }\n }\n\n saveQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: Set<number>,\n extra?: CachedQueryExtra,\n ): void {\n const message: StoreMessage = {\n type: 'saveQuery',\n queryDefId: queryDef.id,\n queryKey,\n value,\n updatedAt,\n refIds: refIds ? Array.from(refIds) : undefined,\n extra,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n saveEntity(entityKey: number, value: unknown, refIds?: Set<number>): void {\n const message: StoreMessage = {\n type: 'saveEntity',\n entityKey,\n value,\n refIds: refIds ? Array.from(refIds) : undefined,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n activateQuery(queryDef: QueryDefinition<any, any, any>, queryKey: number): void {\n const message: StoreMessage = {\n type: 'activateQuery',\n queryDefId: queryDef.id,\n queryKey,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n deleteQuery(queryKey: number): void {\n const message: StoreMessage = {\n type: 'deleteQuery',\n queryKey,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n // Writer-specific methods below\n\n private async writerSaveQuery(\n queryDefId: string,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: number[],\n extra?: CachedQueryExtra,\n ): Promise<void> {\n await this.setValue(queryKey, value, refIds ? new Set(refIds) : undefined);\n await this.delegate!.setNumber(updatedAtKeyFor(queryKey), updatedAt);\n\n // Save extra data\n if (extra?.streamOrphanRefs !== undefined && extra.streamOrphanRefs.length > 0) {\n await this.delegate!.setBuffer(streamOrphanRefsKeyFor(queryKey), new Uint32Array(extra.streamOrphanRefs));\n } else {\n await this.delegate!.delete(streamOrphanRefsKeyFor(queryKey));\n }\n\n if (extra?.optimisticInsertRefs !== undefined && extra.optimisticInsertRefs.length > 0) {\n await this.delegate!.setBuffer(optimisticInsertRefsKeyFor(queryKey), new Uint32Array(extra.optimisticInsertRefs));\n } else {\n await this.delegate!.delete(optimisticInsertRefsKeyFor(queryKey));\n }\n\n await this.writerActivateQuery(queryDefId, queryKey);\n }\n\n private async writerSaveEntity(entityKey: number, value: unknown, refIds?: number[]): Promise<void> {\n await this.setValue(entityKey, value, refIds ? new Set(refIds) : undefined);\n }\n\n private async writerActivateQuery(queryDefId: string, queryKey: number): Promise<void> {\n if (!(await this.delegate!.has(valueKeyFor(queryKey)))) {\n // Query not in store, nothing to do\n return;\n }\n\n let queue = this.queues.get(queryDefId);\n\n if (queue === undefined) {\n // For now, use default max count. In a real implementation,\n // we'd need to pass queryDef or maxCount through the message\n const maxCount = DEFAULT_MAX_COUNT;\n queue = await this.delegate!.getBuffer(queueKeyFor(queryDefId));\n\n if (queue === undefined) {\n queue = new Uint32Array(maxCount);\n await this.delegate!.setBuffer(queueKeyFor(queryDefId), queue);\n } else if (queue.length !== maxCount) {\n queue = new Uint32Array(queue.buffer, 0, maxCount);\n await this.delegate!.setBuffer(queueKeyFor(queryDefId), queue);\n }\n\n this.queues.set(queryDefId, queue);\n }\n\n const indexOfKey = queue.indexOf(queryKey);\n\n // Item already in queue, move to front\n if (indexOfKey >= 0) {\n if (indexOfKey === 0) {\n // Already at front, nothing to do\n return;\n }\n // Shift items right to make space at front\n queue.copyWithin(1, 0, indexOfKey);\n queue[0] = queryKey;\n return;\n }\n\n // Item not in queue, add to front and evict tail\n const evicted = queue[queue.length - 1];\n queue.copyWithin(1, 0, queue.length - 1);\n queue[0] = queryKey;\n\n if (evicted !== 0) {\n await this.writerDeleteValue(evicted);\n await this.delegate!.delete(updatedAtKeyFor(evicted));\n }\n }\n\n private async setValue(id: number, value: unknown, refIds?: Set<number>): Promise<void> {\n const delegate = this.delegate!;\n\n await delegate.setString(valueKeyFor(id), JSON.stringify(value));\n\n const refIdsKey = refIdsKeyFor(id);\n\n const prevRefIds = await delegate.getBuffer(refIdsKey);\n\n if (refIds === undefined || refIds.size === 0) {\n await delegate.delete(refIdsKey);\n\n // Decrement all previous refs\n if (prevRefIds !== undefined) {\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n await this.decrementRefCount(refId);\n }\n }\n } else {\n // Convert the set to a Uint32Array and capture all the refIds before we\n // delete previous ones from the set\n // NOTE: Using spread operator because Hermes (React Native) doesn't correctly\n // handle new Uint32Array(Set) - it produces an empty array instead of converting\n const newRefIds = new Uint32Array([...refIds]);\n\n if (prevRefIds !== undefined) {\n // Process new refs: increment if not in old\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n\n if (refIds.has(refId)) {\n refIds.delete(refId);\n } else {\n await this.decrementRefCount(refId);\n }\n }\n }\n\n // No previous refs, increment all unique new refs\n for (const refId of refIds) {\n await this.incrementRefCount(refId);\n }\n\n await delegate.setBuffer(refIdsKey, newRefIds);\n }\n }\n\n private async writerDeleteValue(id: number): Promise<void> {\n const delegate = this.delegate!;\n\n await delegate.delete(valueKeyFor(id));\n await delegate.delete(refCountKeyFor(id));\n\n const refIds = await delegate.getBuffer(refIdsKeyFor(id));\n await delegate.delete(refIdsKeyFor(id)); // Clean up the refIds key\n\n if (refIds === undefined) {\n return;\n }\n\n // Decrement ref counts for all referenced entities\n for (const refId of refIds) {\n if (refId !== 0) {\n await this.decrementRefCount(refId);\n }\n }\n }\n\n private async incrementRefCount(refId: number): Promise<void> {\n const delegate = this.delegate!;\n const refCountKey = refCountKeyFor(refId);\n const currentCount = (await delegate.getNumber(refCountKey)) ?? 0;\n const newCount = currentCount + 1;\n await delegate.setNumber(refCountKey, newCount);\n }\n\n private async decrementRefCount(refId: number): Promise<void> {\n const delegate = this.delegate!;\n const refCountKey = refCountKeyFor(refId);\n const currentCount = await delegate.getNumber(refCountKey);\n\n if (currentCount === undefined) {\n // Already deleted or never existed\n return;\n }\n\n const newCount = currentCount - 1;\n\n if (newCount === 0) {\n // Entity exists, cascade delete it\n await this.writerDeleteValue(refId);\n } else {\n await delegate.setNumber(refCountKey, newCount);\n }\n }\n}\n"],"names":["updatedAtKeyFor","DEFAULT_GC_TIME","valueKeyFor","refIdsKeyFor","streamOrphanRefsKeyFor","optimisticInsertRefsKeyFor","DEFAULT_MAX_COUNT","queueKeyFor","refCountKeyFor"],"mappings":"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"}
@@ -156,7 +156,7 @@ class SyncQueryStore {
156
156
  }
157
157
  }
158
158
  } else {
159
- const newRefIds = new Uint32Array(refIds);
159
+ const newRefIds = new Uint32Array([...refIds]);
160
160
  if (prevRefIds !== void 0) {
161
161
  for (let i = 0; i < prevRefIds.length; i++) {
162
162
  const refId = prevRefIds[i];
@@ -1 +1 @@
1
- {"version":3,"file":"sync.js","sources":["../../../../src/stores/sync.ts"],"sourcesContent":["import { EntityStore } from '../EntityMap.js';\nimport { CachedQuery, CachedQueryExtra, QueryDefinition, QueryStore } from '../QueryClient.js';\nimport {\n optimisticInsertRefsKeyFor,\n refCountKeyFor,\n refIdsKeyFor,\n streamOrphanRefsKeyFor,\n updatedAtKeyFor,\n valueKeyFor,\n} from './shared.js';\n\nexport interface SyncPersistentStore {\n has(key: string): boolean;\n\n getString(key: string): string | undefined;\n setString(key: string, value: string): void;\n\n getNumber(key: string): number | undefined;\n setNumber(key: string, value: number): void;\n\n getBuffer(key: string): Uint32Array | undefined;\n setBuffer(key: string, value: Uint32Array): void;\n\n delete(key: string): void;\n}\n\nconst DEFAULT_MAX_COUNT = 50;\nconst DEFAULT_GC_TIME = 1000 * 60 * 60 * 24; // 24 hours\n\nexport class MemoryPersistentStore implements SyncPersistentStore {\n private readonly kv: Record<string, unknown> = Object.create(null);\n\n has(key: string): boolean {\n return key in this.kv;\n }\n\n getString(key: string): string | undefined {\n return this.kv[key] as string | undefined;\n }\n\n setString(key: string, value: string): void {\n this.kv[key] = value;\n }\n\n getNumber(key: string): number | undefined {\n return this.kv[key] as number | undefined;\n }\n\n setNumber(key: string, value: number): void {\n this.kv[key] = value;\n }\n\n getBuffer(key: string): Uint32Array | undefined {\n return this.kv[key] as Uint32Array | undefined;\n }\n\n setBuffer(key: string, value: Uint32Array): void {\n this.kv[key] = value;\n }\n\n delete(key: string): void {\n delete this.kv[key];\n }\n}\n\n// Query Type keys\nexport const queueKeyFor = (queryDefId: string) => `sq:doc:queue:${queryDefId}`;\n\nexport class SyncQueryStore implements QueryStore {\n queues: Map<string, Uint32Array> = new Map();\n\n constructor(private readonly kv: SyncPersistentStore) {}\n\n loadQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n entityMap: EntityStore,\n ): CachedQuery | undefined {\n const updatedAt = this.kv.getNumber(updatedAtKeyFor(queryKey));\n\n if (updatedAt === undefined || updatedAt < Date.now() - (queryDef.cache?.gcTime ?? DEFAULT_GC_TIME)) {\n return;\n }\n\n const valueStr = this.kv.getString(valueKeyFor(queryKey));\n\n if (valueStr === undefined) {\n return;\n }\n\n const entityIds = this.kv.getBuffer(refIdsKeyFor(queryKey));\n\n if (entityIds !== undefined) {\n this.preloadEntities(entityIds, entityMap);\n }\n\n // Load extra data (stream orphans and optimistic inserts)\n const streamOrphanRefs = this.kv.getBuffer(streamOrphanRefsKeyFor(queryKey));\n const optimisticInsertRefs = this.kv.getBuffer(optimisticInsertRefsKeyFor(queryKey));\n\n // Preload entities for extra data\n if (streamOrphanRefs !== undefined) {\n this.preloadEntities(streamOrphanRefs, entityMap);\n }\n if (optimisticInsertRefs !== undefined) {\n this.preloadEntities(optimisticInsertRefs, entityMap);\n }\n\n let extra: CachedQueryExtra | undefined;\n if (streamOrphanRefs !== undefined || optimisticInsertRefs !== undefined) {\n extra = {};\n if (streamOrphanRefs !== undefined) {\n extra.streamOrphanRefs = Array.from(streamOrphanRefs);\n }\n if (optimisticInsertRefs !== undefined) {\n extra.optimisticInsertRefs = Array.from(optimisticInsertRefs);\n }\n }\n\n this.activateQuery(queryDef, queryKey);\n\n return {\n value: JSON.parse(valueStr) as Record<string, unknown>,\n refIds: entityIds === undefined ? undefined : new Set(entityIds ?? []),\n updatedAt,\n extra,\n };\n }\n\n private preloadEntities(entityIds: Uint32Array, entityMap: EntityStore): void {\n for (const entityId of entityIds) {\n const entityValue = this.kv.getString(valueKeyFor(entityId));\n\n if (entityValue === undefined) {\n continue;\n }\n\n const entity = JSON.parse(entityValue) as Record<string, unknown>;\n entityMap.setPreloadedEntity(entityId, entity);\n\n const childIds = this.kv.getBuffer(refIdsKeyFor(entityId));\n\n if (childIds === undefined) {\n continue;\n }\n\n this.preloadEntities(childIds, entityMap);\n }\n }\n\n saveQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: Set<number>,\n extra?: CachedQueryExtra,\n ): void {\n this.setValue(queryKey, value, refIds);\n this.kv.setNumber(updatedAtKeyFor(queryKey), updatedAt);\n\n // Save extra data\n if (extra?.streamOrphanRefs !== undefined && extra.streamOrphanRefs.length > 0) {\n this.kv.setBuffer(streamOrphanRefsKeyFor(queryKey), new Uint32Array(extra.streamOrphanRefs));\n } else {\n this.kv.delete(streamOrphanRefsKeyFor(queryKey));\n }\n\n if (extra?.optimisticInsertRefs !== undefined && extra.optimisticInsertRefs.length > 0) {\n this.kv.setBuffer(optimisticInsertRefsKeyFor(queryKey), new Uint32Array(extra.optimisticInsertRefs));\n } else {\n this.kv.delete(optimisticInsertRefsKeyFor(queryKey));\n }\n\n this.activateQuery(queryDef, queryKey);\n }\n\n saveEntity(entityKey: number, value: unknown, refIds?: Set<number>): void {\n this.setValue(entityKey, value, refIds);\n }\n\n activateQuery(queryDef: QueryDefinition<any, any, any>, queryKey: number): void {\n if (!this.kv.has(valueKeyFor(queryKey))) {\n // Query not in store, nothing to do. This can happen if the query has\n // been evicted from the cache, but is still active in memory.\n return;\n }\n\n let queue = this.queues.get(queryDef.id);\n\n if (queue === undefined) {\n const maxCount = queryDef.cache?.maxCount ?? DEFAULT_MAX_COUNT;\n queue = this.kv.getBuffer(queueKeyFor(queryDef.id));\n\n if (queue === undefined) {\n queue = new Uint32Array(maxCount);\n this.kv.setBuffer(queueKeyFor(queryDef.id), queue);\n } else if (queue.length !== maxCount) {\n queue = new Uint32Array(queue.buffer, 0, maxCount);\n this.kv.setBuffer(queueKeyFor(queryDef.id), queue);\n }\n\n this.queues.set(queryDef.id, queue);\n }\n\n const indexOfKey = queue.indexOf(queryKey);\n\n // Item already in queue, move to front\n if (indexOfKey >= 0) {\n if (indexOfKey === 0) {\n // Already at front, nothing to do\n return;\n }\n // Shift items right to make space at front\n queue.copyWithin(1, 0, indexOfKey);\n queue[0] = queryKey;\n return;\n }\n\n // Item not in queue, add to front and evict tail\n const evicted = queue[queue.length - 1];\n queue.copyWithin(1, 0, queue.length - 1);\n queue[0] = queryKey;\n\n if (evicted !== 0) {\n this.deleteQuery(evicted);\n this.kv.delete(updatedAtKeyFor(evicted));\n }\n }\n\n private setValue(id: number, value: unknown, refIds?: Set<number>): void {\n const kv = this.kv;\n\n kv.setString(valueKeyFor(id), JSON.stringify(value));\n\n const refIdsKey = refIdsKeyFor(id);\n\n const prevRefIds = kv.getBuffer(refIdsKey);\n\n if (refIds === undefined || refIds.size === 0) {\n kv.delete(refIdsKey);\n\n // Decrement all previous refs\n if (prevRefIds !== undefined) {\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n this.decrementRefCount(refId);\n }\n }\n } else {\n // Convert the set to a Uint32Array and capture all the refIds before we\n // delete previous ones from the set\n const newRefIds = new Uint32Array(refIds);\n\n if (prevRefIds !== undefined) {\n // Process new refs: increment if not in old\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n\n if (refIds.has(refId)) {\n refIds.delete(refId);\n } else {\n this.decrementRefCount(refId);\n }\n }\n }\n\n // No previous refs, increment all unique new refs\n for (const refId of refIds) {\n this.incrementRefCount(refId);\n }\n\n kv.setBuffer(refIdsKey, newRefIds);\n }\n }\n\n deleteQuery(id: number): void {\n const kv = this.kv;\n\n kv.delete(valueKeyFor(id));\n kv.delete(refCountKeyFor(id));\n\n const refIds = kv.getBuffer(refIdsKeyFor(id));\n kv.delete(refIdsKeyFor(id)); // Clean up the refIds key\n\n if (refIds === undefined) {\n return;\n }\n\n // Decrement ref counts for all referenced entities\n for (const refId of refIds) {\n if (refId !== 0) {\n this.decrementRefCount(refId);\n }\n }\n }\n\n private incrementRefCount(refId: number): void {\n const refCountKey = refCountKeyFor(refId);\n const currentCount = this.kv.getNumber(refCountKey) ?? 0;\n const newCount = currentCount + 1;\n this.kv.setNumber(refCountKey, newCount);\n }\n\n private decrementRefCount(refId: number): void {\n const refCountKey = refCountKeyFor(refId);\n const currentCount = this.kv.getNumber(refCountKey);\n\n if (currentCount === undefined) {\n // Already deleted or never existed\n return;\n }\n\n const newCount = currentCount - 1;\n\n if (newCount === 0) {\n // Entity exists, cascade delete it\n this.deleteQuery(refId);\n } else {\n this.kv.setNumber(refCountKey, newCount);\n }\n }\n}\n"],"names":["updatedAtKeyFor","valueKeyFor","refIdsKeyFor","streamOrphanRefsKeyFor","optimisticInsertRefsKeyFor","refCountKeyFor"],"mappings":"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"}
1
+ {"version":3,"file":"sync.js","sources":["../../../../src/stores/sync.ts"],"sourcesContent":["import { EntityStore } from '../EntityMap.js';\nimport { CachedQuery, CachedQueryExtra, QueryDefinition, QueryStore } from '../QueryClient.js';\nimport {\n optimisticInsertRefsKeyFor,\n refCountKeyFor,\n refIdsKeyFor,\n streamOrphanRefsKeyFor,\n updatedAtKeyFor,\n valueKeyFor,\n} from './shared.js';\n\nexport interface SyncPersistentStore {\n has(key: string): boolean;\n\n getString(key: string): string | undefined;\n setString(key: string, value: string): void;\n\n getNumber(key: string): number | undefined;\n setNumber(key: string, value: number): void;\n\n getBuffer(key: string): Uint32Array | undefined;\n setBuffer(key: string, value: Uint32Array): void;\n\n delete(key: string): void;\n}\n\nconst DEFAULT_MAX_COUNT = 50;\nconst DEFAULT_GC_TIME = 1000 * 60 * 60 * 24; // 24 hours\n\nexport class MemoryPersistentStore implements SyncPersistentStore {\n private readonly kv: Record<string, unknown> = Object.create(null);\n\n has(key: string): boolean {\n return key in this.kv;\n }\n\n getString(key: string): string | undefined {\n return this.kv[key] as string | undefined;\n }\n\n setString(key: string, value: string): void {\n this.kv[key] = value;\n }\n\n getNumber(key: string): number | undefined {\n return this.kv[key] as number | undefined;\n }\n\n setNumber(key: string, value: number): void {\n this.kv[key] = value;\n }\n\n getBuffer(key: string): Uint32Array | undefined {\n return this.kv[key] as Uint32Array | undefined;\n }\n\n setBuffer(key: string, value: Uint32Array): void {\n this.kv[key] = value;\n }\n\n delete(key: string): void {\n delete this.kv[key];\n }\n}\n\n// Query Type keys\nexport const queueKeyFor = (queryDefId: string) => `sq:doc:queue:${queryDefId}`;\n\nexport class SyncQueryStore implements QueryStore {\n queues: Map<string, Uint32Array> = new Map();\n\n constructor(private readonly kv: SyncPersistentStore) {}\n\n loadQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n entityMap: EntityStore,\n ): CachedQuery | undefined {\n const updatedAt = this.kv.getNumber(updatedAtKeyFor(queryKey));\n\n if (updatedAt === undefined || updatedAt < Date.now() - (queryDef.cache?.gcTime ?? DEFAULT_GC_TIME)) {\n return;\n }\n\n const valueStr = this.kv.getString(valueKeyFor(queryKey));\n\n if (valueStr === undefined) {\n return;\n }\n\n const entityIds = this.kv.getBuffer(refIdsKeyFor(queryKey));\n\n if (entityIds !== undefined) {\n this.preloadEntities(entityIds, entityMap);\n }\n\n // Load extra data (stream orphans and optimistic inserts)\n const streamOrphanRefs = this.kv.getBuffer(streamOrphanRefsKeyFor(queryKey));\n const optimisticInsertRefs = this.kv.getBuffer(optimisticInsertRefsKeyFor(queryKey));\n\n // Preload entities for extra data\n if (streamOrphanRefs !== undefined) {\n this.preloadEntities(streamOrphanRefs, entityMap);\n }\n if (optimisticInsertRefs !== undefined) {\n this.preloadEntities(optimisticInsertRefs, entityMap);\n }\n\n let extra: CachedQueryExtra | undefined;\n if (streamOrphanRefs !== undefined || optimisticInsertRefs !== undefined) {\n extra = {};\n if (streamOrphanRefs !== undefined) {\n extra.streamOrphanRefs = Array.from(streamOrphanRefs);\n }\n if (optimisticInsertRefs !== undefined) {\n extra.optimisticInsertRefs = Array.from(optimisticInsertRefs);\n }\n }\n\n this.activateQuery(queryDef, queryKey);\n\n return {\n value: JSON.parse(valueStr) as Record<string, unknown>,\n refIds: entityIds === undefined ? undefined : new Set(entityIds ?? []),\n updatedAt,\n extra,\n };\n }\n\n private preloadEntities(entityIds: Uint32Array, entityMap: EntityStore): void {\n for (const entityId of entityIds) {\n const entityValue = this.kv.getString(valueKeyFor(entityId));\n\n if (entityValue === undefined) {\n continue;\n }\n\n const entity = JSON.parse(entityValue) as Record<string, unknown>;\n entityMap.setPreloadedEntity(entityId, entity);\n\n const childIds = this.kv.getBuffer(refIdsKeyFor(entityId));\n\n if (childIds === undefined) {\n continue;\n }\n\n this.preloadEntities(childIds, entityMap);\n }\n }\n\n saveQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: Set<number>,\n extra?: CachedQueryExtra,\n ): void {\n this.setValue(queryKey, value, refIds);\n this.kv.setNumber(updatedAtKeyFor(queryKey), updatedAt);\n\n // Save extra data\n if (extra?.streamOrphanRefs !== undefined && extra.streamOrphanRefs.length > 0) {\n this.kv.setBuffer(streamOrphanRefsKeyFor(queryKey), new Uint32Array(extra.streamOrphanRefs));\n } else {\n this.kv.delete(streamOrphanRefsKeyFor(queryKey));\n }\n\n if (extra?.optimisticInsertRefs !== undefined && extra.optimisticInsertRefs.length > 0) {\n this.kv.setBuffer(optimisticInsertRefsKeyFor(queryKey), new Uint32Array(extra.optimisticInsertRefs));\n } else {\n this.kv.delete(optimisticInsertRefsKeyFor(queryKey));\n }\n\n this.activateQuery(queryDef, queryKey);\n }\n\n saveEntity(entityKey: number, value: unknown, refIds?: Set<number>): void {\n this.setValue(entityKey, value, refIds);\n }\n\n activateQuery(queryDef: QueryDefinition<any, any, any>, queryKey: number): void {\n if (!this.kv.has(valueKeyFor(queryKey))) {\n // Query not in store, nothing to do. This can happen if the query has\n // been evicted from the cache, but is still active in memory.\n return;\n }\n\n let queue = this.queues.get(queryDef.id);\n\n if (queue === undefined) {\n const maxCount = queryDef.cache?.maxCount ?? DEFAULT_MAX_COUNT;\n queue = this.kv.getBuffer(queueKeyFor(queryDef.id));\n\n if (queue === undefined) {\n queue = new Uint32Array(maxCount);\n this.kv.setBuffer(queueKeyFor(queryDef.id), queue);\n } else if (queue.length !== maxCount) {\n queue = new Uint32Array(queue.buffer, 0, maxCount);\n this.kv.setBuffer(queueKeyFor(queryDef.id), queue);\n }\n\n this.queues.set(queryDef.id, queue);\n }\n\n const indexOfKey = queue.indexOf(queryKey);\n\n // Item already in queue, move to front\n if (indexOfKey >= 0) {\n if (indexOfKey === 0) {\n // Already at front, nothing to do\n return;\n }\n // Shift items right to make space at front\n queue.copyWithin(1, 0, indexOfKey);\n queue[0] = queryKey;\n return;\n }\n\n // Item not in queue, add to front and evict tail\n const evicted = queue[queue.length - 1];\n queue.copyWithin(1, 0, queue.length - 1);\n queue[0] = queryKey;\n\n if (evicted !== 0) {\n this.deleteQuery(evicted);\n this.kv.delete(updatedAtKeyFor(evicted));\n }\n }\n\n private setValue(id: number, value: unknown, refIds?: Set<number>): void {\n const kv = this.kv;\n\n kv.setString(valueKeyFor(id), JSON.stringify(value));\n\n const refIdsKey = refIdsKeyFor(id);\n\n const prevRefIds = kv.getBuffer(refIdsKey);\n\n if (refIds === undefined || refIds.size === 0) {\n kv.delete(refIdsKey);\n\n // Decrement all previous refs\n if (prevRefIds !== undefined) {\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n this.decrementRefCount(refId);\n }\n }\n } else {\n // Convert the set to a Uint32Array and capture all the refIds before we\n // delete previous ones from the set\n // NOTE: Using spread operator because Hermes (React Native) doesn't correctly\n // handle new Uint32Array(Set) - it produces an empty array instead of converting\n const newRefIds = new Uint32Array([...refIds]);\n\n if (prevRefIds !== undefined) {\n // Process new refs: increment if not in old\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n\n if (refIds.has(refId)) {\n refIds.delete(refId);\n } else {\n this.decrementRefCount(refId);\n }\n }\n }\n\n // No previous refs, increment all unique new refs\n for (const refId of refIds) {\n this.incrementRefCount(refId);\n }\n\n kv.setBuffer(refIdsKey, newRefIds);\n }\n }\n\n deleteQuery(id: number): void {\n const kv = this.kv;\n\n kv.delete(valueKeyFor(id));\n kv.delete(refCountKeyFor(id));\n\n const refIds = kv.getBuffer(refIdsKeyFor(id));\n kv.delete(refIdsKeyFor(id)); // Clean up the refIds key\n\n if (refIds === undefined) {\n return;\n }\n\n // Decrement ref counts for all referenced entities\n for (const refId of refIds) {\n if (refId !== 0) {\n this.decrementRefCount(refId);\n }\n }\n }\n\n private incrementRefCount(refId: number): void {\n const refCountKey = refCountKeyFor(refId);\n const currentCount = this.kv.getNumber(refCountKey) ?? 0;\n const newCount = currentCount + 1;\n this.kv.setNumber(refCountKey, newCount);\n }\n\n private decrementRefCount(refId: number): void {\n const refCountKey = refCountKeyFor(refId);\n const currentCount = this.kv.getNumber(refCountKey);\n\n if (currentCount === undefined) {\n // Already deleted or never existed\n return;\n }\n\n const newCount = currentCount - 1;\n\n if (newCount === 0) {\n // Entity exists, cascade delete it\n this.deleteQuery(refId);\n } else {\n this.kv.setNumber(refCountKey, newCount);\n }\n }\n}\n"],"names":["updatedAtKeyFor","valueKeyFor","refIdsKeyFor","streamOrphanRefsKeyFor","optimisticInsertRefsKeyFor","refCountKeyFor"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"QueryResult.d.ts","sourceRoot":"","sources":["../../src/QueryResult.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"QueryResult.d.ts","sourceRoot":"","sources":["../../src/QueryResult.ts"],"names":[],"mappings":"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"}
@@ -301,7 +301,7 @@ function defineUnion(...types) {
301
301
  return new ValidatorDef(2, mask | Mask.UNION, void 0, values);
302
302
  }
303
303
  if (shape === void 0) {
304
- return ValidatorDef.cloneWith(definition, mask | Mask.UNION, values);
304
+ return ValidatorDef.cloneWith(definition, mask, values);
305
305
  }
306
306
  return new ValidatorDef(1, mask | Mask.UNION, shape, values);
307
307
  }
@@ -844,7 +844,7 @@ function parseValue(value, propDef, path, skipFallbacks = false, warn = noopWarn
844
844
  }
845
845
  return value;
846
846
  }
847
- if ((valueType & Mask.UNION) !== 0) {
847
+ if ((propMask & Mask.UNION) !== 0) {
848
848
  return parseUnionValue(
849
849
  valueType,
850
850
  value,
@@ -1844,7 +1844,17 @@ class QueryResultImpl {
1844
1844
  );
1845
1845
  }
1846
1846
  const shape = this.def.shape;
1847
- state.value = shape instanceof ValidatorDef ? parseEntities(cached.value, shape, this.queryClient, /* @__PURE__ */ new Set()) : parseValue(cached.value, shape, this.def.id);
1847
+ if (shape instanceof ValidatorDef) {
1848
+ if (this.def.type === QueryType.InfiniteQuery && Array.isArray(cached.value)) {
1849
+ state.value = cached.value.map(
1850
+ (page) => parseEntities(page, shape, this.queryClient, /* @__PURE__ */ new Set())
1851
+ );
1852
+ } else {
1853
+ state.value = parseEntities(cached.value, shape, this.queryClient, /* @__PURE__ */ new Set());
1854
+ }
1855
+ } else {
1856
+ state.value = parseValue(cached.value, shape, this.def.id);
1857
+ }
1848
1858
  }
1849
1859
  } catch (error) {
1850
1860
  this.queryClient.deleteCachedQuery(this.storageKey);