import * as plugins from './plugins.js'; import { SmartdataCollection } from './classes.collection.js'; import { SmartdataDb } from './classes.db.js'; /** * Per-SmartdataDb collection cache. * * Historically this class keyed its cache by class name alone, which meant * the first SmartdataDb to request a collection of a given class name * "won" — every subsequent call from a different SmartdataDb instance * received the cached collection bound to the first db. That silently * broke multi-tenant SaaS apps (one db per tenant), tests instantiating * multiple SmartdataDbs in sequence, and any in-process db cluster switch. * * The cache is now keyed by `(SmartdataDb instance, className)` using a * WeakMap of db → Map. Entries are GC'd * with their parent db automatically. */ export class CollectionFactory { private perDbCollections: WeakMap>> = new WeakMap(); public getCollection = (nameArg: string, dbArg: SmartdataDb): SmartdataCollection => { if (!(dbArg instanceof SmartdataDb)) { // Preserve the historical behavior of returning undefined-ish for // non-db args. All in-repo callers already guard on instanceof // before using the result (see classes.collection.ts). return undefined as unknown as SmartdataCollection; } let dbMap = this.perDbCollections.get(dbArg); if (!dbMap) { dbMap = new Map(); this.perDbCollections.set(dbArg, dbMap); } let coll = dbMap.get(nameArg); if (!coll) { coll = new SmartdataCollection(nameArg, dbArg); dbMap.set(nameArg, coll); } return coll; }; /** * @deprecated Internal back-compat shim. The previous field was a public * Record but was not part of the * documented public API. WeakMap is not iterable, so this getter returns * an empty object — anyone actually relying on the old shape would get * clean nothing rather than wrong-db data. Will be removed in 8.0. */ public get collections(): { [key: string]: SmartdataCollection } { return {}; } }