{"version":3,"file":"source-id-bindings.cjs","sources":["../../src/source-id-bindings.ts"],"sourcesContent":["import { getPreparedLiveQuerySources } from '@tanstack/db'\nimport type { DbClient } from '@tanstack/db'\n\nexport { resumeDeferredLiveQueryCollections as resumeSyncStarts } from '@tanstack/db'\n\nconst sourceObjectTokens = new WeakMap<object, number>()\nlet nextSourceObjectToken = 0\n\nexport function getSourceObjectToken(source: object): number {\n  let id = sourceObjectTokens.get(source)\n  if (id === undefined) {\n    id = ++nextSourceObjectToken\n    sourceObjectTokens.set(source, id)\n  }\n  return id\n}\n\nexport function getPreparedSources(\n  preparedValue: unknown,\n  client?: DbClient,\n  hookName?: string,\n): Array<{ id: string }> {\n  return getPreparedLiveQuerySources(\n    preparedValue,\n    !client && hookName\n      ? (alias) => {\n          throw new Error(\n            `[${hookName}] Collection descriptor \"${alias}\" requires a DbClient when the query is consumed. Wrap this component in <DbProvider client={client}> or use a concrete Collection.`,\n          )\n        }\n      : undefined,\n  )\n}\n\n/** The source object each Collection ID named while one hook is mounted. */\nexport type SourceIdBindings = {\n  unscoped: Map<string, number>\n  byClient: WeakMap<DbClient, Map<string, number>>\n}\n\nexport function createSourceIdBindings(): SourceIdBindings {\n  return { unscoped: new Map(), byClient: new WeakMap() }\n}\n\n/**\n * Derived query identity names each source by its Collection ID. While a hook\n * is mounted, an ID must keep naming one source object in each client scope,\n * or the hook could reuse a live query that reads the old source. Claims the\n * prepared value's sources, or calls `release` and throws on a collision so a\n * rejected render keeps no sync-start deferral.\n */\nexport function claimSourceIds(\n  bindings: SourceIdBindings,\n  preparedValue: unknown,\n  client: DbClient | undefined,\n  hookName: string,\n  release: () => void,\n): void {\n  const prior = client ? bindings.byClient.get(client) : bindings.unscoped\n  const seen = new Map<string, number>()\n  for (const source of getPreparedSources(preparedValue, client, hookName)) {\n    const token = getSourceObjectToken(source)\n    const previous = seen.get(source.id) ?? prior?.get(source.id)\n    if (previous !== undefined && previous !== token) {\n      release()\n      throw new Error(\n        `[${hookName}] Source Collection \"${source.id}\" was replaced by a different Collection with the same ID while this hook is mounted. Unmount the hook and clean up its previous source and client scope before reusing the ID.`,\n      )\n    }\n    seen.set(source.id, token)\n  }\n  const claimed = prior ?? new Map<string, number>()\n  for (const [id, token] of seen) claimed.set(id, token)\n  if (client) bindings.byClient.set(client, claimed)\n}\n"],"names":["getPreparedLiveQuerySources"],"mappings":";;;AAKA,MAAM,yCAAyB,QAAA;AAC/B,IAAI,wBAAwB;AAErB,SAAS,qBAAqB,QAAwB;AAC3D,MAAI,KAAK,mBAAmB,IAAI,MAAM;AACtC,MAAI,OAAO,QAAW;AACpB,SAAK,EAAE;AACP,uBAAmB,IAAI,QAAQ,EAAE;AAAA,EACnC;AACA,SAAO;AACT;AAEO,SAAS,mBACd,eACA,QACA,UACuB;AACvB,SAAOA,GAAAA;AAAAA,IACL;AAAA,IACA,CAAC,UAAU,WACP,CAAC,UAAU;AACT,YAAM,IAAI;AAAA,QACR,IAAI,QAAQ,4BAA4B,KAAK;AAAA,MAAA;AAAA,IAEjD,IACA;AAAA,EAAA;AAER;AAQO,SAAS,yBAA2C;AACzD,SAAO,EAAE,UAAU,oBAAI,IAAA,GAAO,UAAU,oBAAI,UAAQ;AACtD;AASO,SAAS,eACd,UACA,eACA,QACA,UACA,SACM;AACN,QAAM,QAAQ,SAAS,SAAS,SAAS,IAAI,MAAM,IAAI,SAAS;AAChE,QAAM,2BAAW,IAAA;AACjB,aAAW,UAAU,mBAAmB,eAAe,QAAQ,QAAQ,GAAG;AACxE,UAAM,QAAQ,qBAAqB,MAAM;AACzC,UAAM,WAAW,KAAK,IAAI,OAAO,EAAE,KAAK,OAAO,IAAI,OAAO,EAAE;AAC5D,QAAI,aAAa,UAAa,aAAa,OAAO;AAChD,cAAA;AACA,YAAM,IAAI;AAAA,QACR,IAAI,QAAQ,wBAAwB,OAAO,EAAE;AAAA,MAAA;AAAA,IAEjD;AACA,SAAK,IAAI,OAAO,IAAI,KAAK;AAAA,EAC3B;AACA,QAAM,UAAU,SAAS,oBAAI,IAAA;AAC7B,aAAW,CAAC,IAAI,KAAK,KAAK,KAAM,SAAQ,IAAI,IAAI,KAAK;AACrD,MAAI,OAAQ,UAAS,SAAS,IAAI,QAAQ,OAAO;AACnD;;;;;;;;;"}