{"version":3,"file":"pooled-live-query.cjs","sources":["../../../src/query/pooled-live-query.ts"],"sourcesContent":["import { SortedMap } from '../SortedMap.js'\nimport { CleanupQueue } from '../collection/cleanup-queue.js'\nimport { UNSUBSCRIBED_GC_FLOOR_MS } from '../collection/lifecycle.js'\nimport { makeComparator } from '../utils/comparison.js'\nimport { isVirtualPropName } from '../virtual-props.js'\nimport { getPersistedReadinessSource } from '../persisted-readiness.js'\nimport { getWhereExpression } from './ir.js'\nimport { equalityConjunct, equalityKey, readPath } from './equality-conjunct.js'\nimport { compileExpression, toBooleanPredicate } from './compiler/evaluators.js'\nimport { buildCompareOptions } from './compiler/order-by.js'\nimport { createLiveQueryCollection } from './live-query-collection.js'\nimport type { BasicExpression, OrderBy, QueryIR } from './ir.js'\nimport type { BaseQueryBuilder } from './builder/index.js'\nimport type { Collection, CollectionImpl } from '../collection/index.js'\nimport type { ChangeMessage, CollectionStatus } from '../types.js'\nimport type {\n  CollectionEventHandler,\n  CollectionStatusChangeEvent,\n} from '../collection/events.js'\n\n/**\n * Live queries that filter one source Collection only by `eq(field, literal)`\n * share one partition of that source per filtered field set. Each query reads\n * the group for its literal tuple, so mounting many queries of one shape\n * costs a lookup each instead of a compiled graph and a source subscription.\n *\n * A group holds the rows the partition's source subscription has published,\n * keyed by the same normalized equality that `eq` uses: a Date equals its\n * timestamp, `NaN` equals `NaN`, `-0` equals `0`, and nullish values match no\n * literal.\n */\n\ntype Row = Record<string, unknown>\ntype Listener = (changes: Array<ChangeMessage<Row, string | number>>) => void\ntype StatusListener = CollectionEventHandler<`status:change`>\n\ninterface PartitionGroup {\n  key: string\n  // Key order, as in a live-query Collection without orderBy.\n  rows: SortedMap<string | number, Row>\n  listeners: Set<Listener>\n  revision: number\n  layoutRevision: number\n}\n\nconst partitionsBySource = new WeakMap<object, Map<string, Partition>>()\n\n// What a view reads for a value with no rows and no watchers. Real groups\n// draw revisions from their partition's clock, which starts above 0.\nconst EMPTY_GROUP: PartitionGroup = {\n  key: ``,\n  rows: new SortedMap(),\n  listeners: new Set(),\n  revision: 0,\n  layoutRevision: 0,\n}\n\n// Length-prefixed, so no two part lists share an encoding.\nfunction appendGroupKeyPart(groupKey: string, part: string): string {\n  return `${groupKey}${part.length}:${part}`\n}\n\nclass Partition {\n  private readonly groups = new Map<string, PartitionGroup>()\n  // Revisions for every group, so a recreated group never repeats one.\n  private clock = 0\n  private subscription: { unsubscribe: () => void } | undefined\n  private stopStatusEvents: (() => void) | undefined\n  // One source status listener serves every view of this partition.\n  readonly statusListeners = new Set<StatusListener>()\n  private listenerCount = 0\n  private gcTime = 0\n  /** Set when the source starts cleanup; groups keep their last rows. */\n  terminated = false\n\n  constructor(\n    private readonly source: CollectionImpl<any, any, any, any, any>,\n    private readonly paths: Array<Array<string>>,\n    // Row order for an `orderBy` shape; key order otherwise.\n    private readonly compareRows: ((a: Row, b: Row) => number) | undefined,\n    // The partition's entry in its source's map, which a mount looks up.\n    private readonly registry: { add: () => void; remove: () => void },\n  ) {}\n\n  groupKeyOf(row: Row | undefined): string | undefined {\n    if (row === undefined) return undefined\n    let groupKey = ``\n    for (const path of this.paths) {\n      const key = equalityKey(readPath(row, path))\n      if (key === undefined) return undefined\n      groupKey = appendGroupKeyPart(groupKey, key)\n    }\n    return groupKey\n  }\n\n  // Whether two versions of a row hold the same value in every field.\n  private sameFields(a: Row, b: Row): boolean {\n    return this.paths.every((path) =>\n      Object.is(readPath(a, path), readPath(b, path)),\n    )\n  }\n\n  group(key: string): PartitionGroup {\n    let group = this.groups.get(key)\n    if (!group) {\n      const revision = ++this.clock\n      group = {\n        key,\n        rows: new SortedMap(this.compareRows),\n        listeners: new Set(),\n        revision,\n        layoutRevision: revision,\n      }\n      this.groups.set(key, group)\n    }\n    return group\n  }\n\n  /** A group for reading, without creating one. */\n  peek(key: string): PartitionGroup {\n    return this.groups.get(key) ?? EMPTY_GROUP\n  }\n\n  // A group with no rows and no watchers holds nothing anyone can read.\n  private dropIfUnused(group: PartitionGroup): void {\n    if (group.rows.size === 0 && group.listeners.size === 0) {\n      this.groups.delete(group.key)\n    }\n  }\n\n  /**\n   * Keep the shared source subscription open. Each view brings its query's\n   * `gcTime`; the partition keeps the longest, so it never releases before\n   * one of its views' own live-query Collection would have.\n   */\n  retain(gcTime?: number): void {\n    if (gcTime !== undefined) {\n      // As for a Collection, a non-positive or non-finite gcTime disables GC.\n      const delay = gcTime > 0 && Number.isFinite(gcTime) ? gcTime : Infinity\n      this.gcTime = Math.max(this.gcTime, delay)\n    }\n    if (this.terminated) return\n    this.subscribe()\n    // Like a Collection that synced before anything subscribed, a view built\n    // during a render gets a grace period to subscribe when it commits.\n    this.scheduleRelease(UNSUBSCRIBED_GC_FLOOR_MS)\n  }\n\n  subscribe(): void {\n    if (!this.terminated && !this.subscription) {\n      // A released partition that subscribes again serves new mounts too.\n      this.registry.add()\n      this.subscription = this.source.subscribeChanges(\n        (changes) =>\n          this.apply(changes as Array<ChangeMessage<Row, string | number>>),\n        { includeInitialState: true },\n      )\n      const stopStatus = this.source.on(`status:change`, (event) => {\n        this.deliverStatus(event)\n      })\n      // Like a live query, a pooled view fails for good when its source\n      // starts cleanup, before the adapter's cleanup settles; queries\n      // mounted later get a new partition.\n      const stopCleanupStart = this.source._onCleanupStart(() => {\n        const previousStatus = this.source.status\n        this.terminate()\n        this.deliverStatus({\n          type: `status:change`,\n          collection: this.source as unknown as Collection,\n          previousStatus,\n          status: `error`,\n        })\n      })\n      this.stopStatusEvents = () => {\n        stopStatus()\n        stopCleanupStart()\n      }\n    }\n  }\n\n  private deliverStatus(event: CollectionStatusChangeEvent): void {\n    const delivered = this.terminated\n      ? { ...event, status: `error` as const }\n      : event\n    for (const listener of [...this.statusListeners]) listener(delivered)\n    if (this.terminated) {\n      this.stopStatusEvents?.()\n      this.stopStatusEvents = undefined\n    }\n  }\n\n  addListener(group: PartitionGroup, listener: Listener): void {\n    this.subscribe()\n    group.listeners.add(listener)\n    this.listenerCount++\n  }\n\n  removeListener(group: PartitionGroup, listener: Listener): void {\n    if (!group.listeners.delete(listener)) return\n    this.listenerCount--\n    this.dropIfUnused(group)\n    this.scheduleRelease(0)\n  }\n\n  private terminate(): void {\n    this.terminated = true\n    CleanupQueue.getInstance().cancel(this)\n    this.release()\n  }\n\n  private release(): void {\n    this.subscription?.unsubscribe()\n    this.subscription = undefined\n    this.registry.remove()\n  }\n\n  // Releases on the Collections' shared GC queue, after the longest\n  // `gcTime` of this partition's views.\n  private scheduleRelease(minDelay: number): void {\n    if (this.listenerCount > 0 || !Number.isFinite(this.gcTime)) return\n    const delay = Math.max(this.gcTime, minDelay)\n    CleanupQueue.getInstance().schedule(this, delay, this.releaseIfUnused)\n  }\n\n  private readonly releaseIfUnused = (): void => {\n    if (this.listenerCount > 0) return\n    this.stopStatusEvents?.()\n    this.stopStatusEvents = undefined\n    // Views read groups by key, so a later subscription refills new ones.\n    this.groups.clear()\n    this.release()\n  }\n\n  private apply(changes: Array<ChangeMessage<Row, string | number>>): void {\n    const touched = new Map<\n      PartitionGroup,\n      Array<ChangeMessage<Row, string | number>>\n    >()\n    const record = (\n      group: PartitionGroup,\n      change: ChangeMessage<Row, string | number>,\n    ) => {\n      const list = touched.get(group)\n      if (list) list.push(change)\n      else touched.set(group, [change])\n      if (change.type !== `update`) group.layoutRevision = ++this.clock\n    }\n    for (const change of changes) {\n      const next =\n        change.type === `delete` ? undefined : this.groupKeyOf(change.value)\n      const previous =\n        change.type === `insert`\n          ? undefined\n          : change.type === `update` &&\n              change.previousValue !== undefined &&\n              this.sameFields(change.value, change.previousValue)\n            ? next\n            : this.groupKeyOf(\n                change.type === `delete` ? change.value : change.previousValue,\n              )\n      if (previous !== undefined && previous !== next) {\n        const group = this.group(previous)\n        const old = group.rows.get(change.key)\n        if (group.rows.delete(change.key)) {\n          record(group, { type: `delete`, key: change.key, value: old! })\n        }\n      }\n      if (next !== undefined) {\n        const group = this.group(next)\n        const existed = group.rows.has(change.key)\n        group.rows.set(change.key, change.value)\n        record(\n          group,\n          existed\n            ? change.type === `update`\n              ? change\n              : { ...change, type: `update` }\n            : { type: `insert`, key: change.key, value: change.value },\n        )\n      }\n    }\n    for (const [group, groupChanges] of touched) {\n      group.revision = ++this.clock\n      for (const listener of [...group.listeners]) listener(groupChanges)\n      this.dropIfUnused(group)\n    }\n  }\n}\n\ntype Conjunct = { path: Array<string>; pathKey: string; literalKey: string }\n\ntype PoolableShape = {\n  paths: Array<Array<string>>\n  shapeKey: string\n  groupKey: string\n  // Conjuncts each view evaluates over its group's rows.\n  residual: Array<BasicExpression>\n  orderBy: OrderBy | undefined\n}\n\n// Whether an expression reads only this query's own row fields, so a view\n// can evaluate it with the compiler's evaluator.\nfunction readsOnlyRow(expression: BasicExpression, alias: string): boolean {\n  if (expression.type === `val`) return true\n  if (expression.type === `ref`) {\n    const [root, field] = expression.path\n    return root === alias && field !== undefined && !isVirtualPropName(field)\n  }\n  return expression.args.every((arg) => readsOnlyRow(arg, alias))\n}\n\n// Splits a conjunct into `eq(alias.field, literal)` groups and residual\n// conjuncts; false for an expression a view cannot evaluate.\nfunction collectConjuncts(\n  expression: BasicExpression,\n  alias: string,\n  out: Array<Conjunct>,\n  residual: Array<BasicExpression>,\n): boolean {\n  if (expression.type === `func` && expression.name === `and`) {\n    for (const arg of expression.args) {\n      if (!collectConjuncts(arg, alias, out, residual)) return false\n    }\n    return true\n  }\n  const conjunct = equalityConjunctOf(expression, alias)\n  if (conjunct) out.push(conjunct)\n  else if (readsOnlyRow(expression, alias)) residual.push(expression)\n  else return false\n  return true\n}\n\nfunction equalityConjunctOf(\n  expression: BasicExpression,\n  alias: string,\n): Conjunct | undefined {\n  const conjunct = equalityConjunct(expression, (ref) =>\n    ref.path[0] === alias ? ref.path.slice(1) : undefined,\n  )\n  return conjunct && { ...conjunct, pathKey: JSON.stringify(conjunct.path) }\n}\n\n// Whether a row passes every residual conjunct, as a WHERE filter decides.\nfunction rowPredicate(\n  residual: Array<BasicExpression>,\n  alias: string,\n): (row: Row) => boolean {\n  const conjuncts = residual.map((expression) => compileExpression(expression))\n  // One namespaced row, reused so a check allocates nothing.\n  const namespaced: Record<string, unknown> = {}\n  return (row) => {\n    namespaced[alias] = row\n    return conjuncts.every((conjunct) =>\n      toBooleanPredicate(conjunct(namespaced as any)),\n    )\n  }\n}\n\n/**\n * The equality conjuncts of a query that a partition can serve, or undefined\n * when any other clause or operand is present.\n */\nfunction poolableShape(query: QueryIR): PoolableShape | undefined {\n  if (\n    query.from.type !== `collectionRef` ||\n    query.select ||\n    query.join ||\n    query.groupBy ||\n    query.having ||\n    query.limit !== undefined ||\n    query.offset !== undefined ||\n    query.distinct ||\n    query.singleResult ||\n    query.fnSelect ||\n    query.fnWhere?.length ||\n    query.fnHaving?.length ||\n    !query.where?.length\n  ) {\n    return undefined\n  }\n  const conjuncts: Array<Conjunct> = []\n  const residual: Array<BasicExpression> = []\n  for (const where of query.where) {\n    if (\n      !collectConjuncts(\n        getWhereExpression(where),\n        query.from.alias,\n        conjuncts,\n        residual,\n      )\n    ) {\n      return undefined\n    }\n  }\n  // A partition needs at least one equality to group by.\n  if (conjuncts.length === 0) return undefined\n  const orderBy = query.orderBy?.length ? query.orderBy : undefined\n  const orderKey = orderBy\n    ? orderByKey(orderBy, query.from.alias, query.from.collection)\n    : ``\n  if (orderKey === undefined) return undefined\n  // Most shapes have one or two fields; a general sort costs more than both.\n  if (conjuncts.length === 2) {\n    if (conjuncts[1]!.pathKey < conjuncts[0]!.pathKey) conjuncts.reverse()\n  } else if (conjuncts.length > 2) {\n    conjuncts.sort((a, b) => (a.pathKey < b.pathKey ? -1 : 1))\n  }\n  const paths: Array<Array<string>> = []\n  let shapeKey = ``\n  let groupKey = ``\n  for (const { path, pathKey, literalKey } of conjuncts) {\n    paths.push(path)\n    // Each JSON path delimits itself, so concatenation stays unambiguous.\n    shapeKey += pathKey\n    groupKey = appendGroupKeyPart(groupKey, literalKey)\n  }\n  // Groups of one shape share a row order, so the order is part of it.\n  if (orderKey) shapeKey += `|${orderKey}`\n  return { paths, shapeKey, groupKey, residual, orderBy }\n}\n\n// A key for an `orderBy` over this query's own row fields, or undefined for\n// one a partition cannot share by value, such as a custom string comparator.\nfunction orderByKey(\n  orderBy: OrderBy,\n  alias: string,\n  source: CollectionImpl<any, any, any, any, any>,\n): string | undefined {\n  let key = ``\n  for (const clause of orderBy) {\n    const { expression } = clause\n    if (\n      expression.type !== `ref` ||\n      !readsOnlyRow(expression, alias) ||\n      expression.path.length < 2\n    ) {\n      return undefined\n    }\n    const options = buildCompareOptions(clause, source)\n    if (options.stringSort === `custom`) return undefined\n    key += JSON.stringify([expression.path.slice(1), options])\n  }\n  return key\n}\n\n// Orders rows as a live-query Collection's `orderBy` does; the group's\n// SortedMap breaks ties by key.\nfunction rowComparator(\n  orderBy: OrderBy,\n  alias: string,\n  source: CollectionImpl<any, any, any, any, any>,\n): (a: Row, b: Row) => number {\n  const terms = orderBy.map((clause) => ({\n    read: compileExpression(clause.expression),\n    compare: makeComparator(buildCompareOptions(clause, source)),\n  }))\n  // One namespaced row, reused so a comparison allocates nothing.\n  const namespaced: Record<string, unknown> = {}\n  return (a, b) => {\n    for (const { read, compare } of terms) {\n      namespaced[alias] = a\n      const left = read(namespaced as any)\n      namespaced[alias] = b\n      const result = compare(left, read(namespaced as any))\n      if (result !== 0) return result\n    }\n    return 0\n  }\n}\n\n/**\n * One query's view of its group, read by the live-query observer. Users get\n * `publicCollection` instead, which builds the query's live-query Collection\n * on first use and forwards every member to it.\n */\nclass PooledLiveQuery {\n  readonly isLoadingSubset = false\n  // No persisted readiness, single-result config, or layout channel.\n  readonly config = undefined\n  readonly _subscribeLayoutChanges = undefined\n  private collection: Collection<any, any, any> | undefined = undefined\n  private listenerCount = 0\n  private collectionHold: { unsubscribe: () => void } | undefined = undefined\n\n  constructor(\n    private readonly source: CollectionImpl<any, any, any, any, any>,\n    private readonly query: BaseQueryBuilder,\n    private readonly partition: Partition,\n    private readonly groupKey: string,\n    private readonly gcTime: number,\n    // The query's conjuncts beyond its group's equalities, if any.\n    private readonly passes: ((row: Row) => boolean) | undefined,\n  ) {\n    partition.retain(gcTime)\n  }\n\n  get status(): CollectionStatus {\n    return this.partition.terminated ? `error` : this.source.status\n  }\n\n  // Read by key: the partition drops a group nobody watches once it empties.\n  private get group(): PartitionGroup {\n    return this.partition.peek(this.groupKey)\n  }\n\n  get _stateRevision(): number {\n    return this.group.revision\n  }\n\n  get _layoutRevision(): number {\n    return this.group.layoutRevision\n  }\n\n  entries(): Iterable<[string | number, Row]> {\n    const rows = this.group.rows.entries()\n    const passes = this.passes\n    return passes ? [...rows].filter(([, row]) => passes(row)) : rows\n  }\n\n  subscribeChanges(\n    callback: Listener,\n    options: { includeInitialState?: boolean } = {},\n  ): { unsubscribe: () => void } {\n    // A released partition refills its group here, so seed the filter after.\n    this.partition.subscribe()\n    const listener = this.passes ? this.filterChanges(callback) : callback\n    const group = this.partition.group(this.groupKey)\n    this.partition.addListener(group, listener)\n    this.listenerCount++\n    this.holdCollection()\n    if (options.includeInitialState) {\n      callback(\n        Array.from(this.entries(), ([key, value]) => ({\n          type: `insert`,\n          key,\n          value,\n        })),\n      )\n    }\n    let subscribed = true\n    return {\n      unsubscribe: () => {\n        if (!subscribed) return\n        subscribed = false\n        this.partition.removeListener(group, listener)\n        if (--this.listenerCount === 0) {\n          this.collectionHold?.unsubscribe()\n          this.collectionHold = undefined\n        }\n      },\n    }\n  }\n\n  // While the view is observed, its built Collection stays subscribed, as\n  // the Collection would be if it served the observer itself.\n  private holdCollection(): void {\n    if (this.collection && this.listenerCount > 0) {\n      this.collectionHold ??= this.collection.subscribeChanges(() => {})\n    }\n  }\n\n  // Turns the group's changes into this query's, tracking which rows have\n  // passed its residual conjuncts for this subscription.\n  private filterChanges(callback: Listener): Listener {\n    const passes = this.passes!\n    const visible = new Map(this.entries())\n    return (changes) => {\n      const out: Array<ChangeMessage<Row, string | number>> = []\n      for (const change of changes) {\n        const { key, value } = change\n        const previous = visible.get(key)\n        const next = change.type !== `delete` && passes(value)\n        if (next) visible.set(key, value)\n        else visible.delete(key)\n        if (previous && next) {\n          out.push({ type: `update`, key, value, previousValue: previous })\n        } else if (previous) {\n          out.push({ type: `delete`, key, value: previous })\n        } else if (next) {\n          out.push({ type: `insert`, key, value })\n        }\n      }\n      if (out.length > 0) callback(out)\n    }\n  }\n\n  on(...args: Parameters<CollectionImpl[`on`]>): () => void {\n    const [event, listener] = args\n    if (event !== `status:change`) return this.source.on(...args)\n    const listeners = this.partition.statusListeners\n    listeners.add(listener as StatusListener)\n    return () => listeners.delete(listener as StatusListener)\n  }\n\n  preload(): Promise<void> {\n    return this.source.preload()\n  }\n\n  cleanup(): Promise<void> {\n    return this.collection?.cleanup() ?? Promise.resolve()\n  }\n\n  private proxy: Collection<any, any, any> | undefined = undefined\n\n  /** This view as the Collection it stands in for. */\n  get publicCollection(): Collection<any, any, any> {\n    return (this.proxy ??= new Proxy(\n      this,\n      forwardToCollection,\n    ) as unknown as Collection<any, any, any>)\n  }\n\n  materialize(): Collection<any, any, any> {\n    if (!this.collection) {\n      this.collection = createLiveQueryCollection({\n        query: this.query,\n        startSync: true,\n        gcTime: this.gcTime,\n      })\n      this.holdCollection()\n    }\n    return this.collection\n  }\n}\n\n// The observer reads the view itself; users get the live-query Collection.\nconst forwardToCollection: ProxyHandler<PooledLiveQuery> = {\n  get(view, property) {\n    const collection = view.materialize()\n    const value = Reflect.get(collection, property, collection)\n    return typeof value === `function` ? value.bind(collection) : value\n  },\n  has(view, property) {\n    return Reflect.has(view.materialize(), property)\n  },\n  // So `instanceof` and query sources accept it as the Collection it is.\n  getPrototypeOf(view) {\n    return Reflect.getPrototypeOf(view.materialize())\n  },\n}\n\n/**\n * The identity of a query a partition can serve with no residual conjunct:\n * its source and its `eq` fields and literals, which determine its rows.\n * Undefined for any other query, which keeps the full structural identity.\n */\nexport function getPooledQueryIdentity(\n  query: BaseQueryBuilder,\n): string | undefined {\n  const ir = query._getQuery()\n  if (ir.from.type !== `collectionRef`) return undefined\n  const shape = poolableShape(ir)\n  if (!shape || shape.residual.length > 0) return undefined\n  return JSON.stringify([ir.from.collection.id, shape.shapeKey, shape.groupKey])\n}\n\n/**\n * A pooled view for a query a partition can serve, or undefined. The view is\n * typed as the Collection it stands in for.\n */\nexport function createPooledLiveQuery(\n  query: BaseQueryBuilder,\n  // A live-query Collection's default when the adapter gives none.\n  { gcTime = 5_000 }: { gcTime?: number } = {},\n): Collection<any, any, any> | undefined {\n  const ir = query._getQuery()\n  const shape = poolableShape(ir)\n  if (!shape || ir.from.type !== `collectionRef`) return undefined\n  const source = ir.from.collection\n  // Persisted restore and on-demand loading need the live-query Collection.\n  if (\n    source.config.syncMode === `on-demand` ||\n    getPersistedReadinessSource(source.config)\n  ) {\n    return undefined\n  }\n  let partitions = partitionsBySource.get(source)\n  if (!partitions) {\n    partitions = new Map()\n    partitionsBySource.set(source, partitions)\n  }\n  const { shapeKey } = shape\n  let partition = partitions.get(shapeKey)\n  if (!partition) {\n    const owner = partitions\n    // A released partition may subscribe again; it must not then replace or\n    // remove a newer partition created under its key.\n    const created: Partition = new Partition(\n      source,\n      shape.paths,\n      shape.orderBy && rowComparator(shape.orderBy, ir.from.alias, source),\n      {\n        add: () => {\n          if (!owner.has(shapeKey)) owner.set(shapeKey, created)\n        },\n        remove: () => {\n          if (owner.get(shapeKey) === created) owner.delete(shapeKey)\n        },\n      },\n    )\n    partition = created\n    partitions.set(shapeKey, partition)\n  }\n  // Observers read the view directly; users get its `publicCollection`.\n  return new PooledLiveQuery(\n    source,\n    query,\n    partition,\n    shape.groupKey,\n    gcTime,\n    shape.residual.length > 0\n      ? rowPredicate(shape.residual, ir.from.alias)\n      : undefined,\n  ) as unknown as Collection<any, any, any>\n}\n"],"names":["SortedMap","compareRows","registry","clock","releaseIfUnused","stopStatusEvents","equalityKey","readPath","sameFields","dropIfUnused","scheduleRelease","UNSUBSCRIBED_GC_FLOOR_MS","deliverStatus","CleanupQueue","isVirtualPropName","equalityConjunct","compileExpression","toBooleanPredicate","getWhereExpression","orderBy","buildCompareOptions","makeComparator","passes","collectionHold","filterChanges","holdCollection","createLiveQueryCollection","ir","getPersistedReadinessSource"],"mappings":"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"}