js-bao 0.2.11 → 0.2.12

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.
Files changed (67) hide show
  1. package/README.md +174 -0
  2. package/dist/BaseModel-5YQCROYE.js +17 -0
  3. package/dist/BaseModel-5YQCROYE.js.map +1 -0
  4. package/dist/BaseModel-FCNWDJBH.js +17 -0
  5. package/dist/BaseModel-FCNWDJBH.js.map +1 -0
  6. package/dist/BrowserDatabaseFactory-PXOTK2DQ.js +119 -0
  7. package/dist/BrowserDatabaseFactory-PXOTK2DQ.js.map +1 -0
  8. package/dist/BrowserDatabaseFactory-WD4VX2VZ.js +119 -0
  9. package/dist/BrowserDatabaseFactory-WD4VX2VZ.js.map +1 -0
  10. package/dist/IncludeResolver-RCKQGNPZ.js +385 -0
  11. package/dist/IncludeResolver-RCKQGNPZ.js.map +1 -0
  12. package/dist/IncludeResolver-WGSQDMS7.js +385 -0
  13. package/dist/IncludeResolver-WGSQDMS7.js.map +1 -0
  14. package/dist/NodeDatabaseFactory-J4Z36UF3.js +165 -0
  15. package/dist/NodeDatabaseFactory-J4Z36UF3.js.map +1 -0
  16. package/dist/NodeDatabaseFactory-QIEKAXBM.js +10 -0
  17. package/dist/NodeDatabaseFactory-QIEKAXBM.js.map +1 -0
  18. package/dist/NodeSqliteEngine-HJSAYE4E.js +383 -0
  19. package/dist/NodeSqliteEngine-HJSAYE4E.js.map +1 -0
  20. package/dist/NodeSqliteEngine-I5SLWLME.js +383 -0
  21. package/dist/NodeSqliteEngine-I5SLWLME.js.map +1 -0
  22. package/dist/browser.cjs +3779 -3370
  23. package/dist/browser.d.cts +18 -1
  24. package/dist/browser.d.ts +18 -1
  25. package/dist/browser.js +3750 -3341
  26. package/dist/chunk-3PZWHUZO.js +4153 -0
  27. package/dist/chunk-3PZWHUZO.js.map +1 -0
  28. package/dist/chunk-53MS4MN7.js +373 -0
  29. package/dist/chunk-53MS4MN7.js.map +1 -0
  30. package/dist/chunk-65G2P4GL.js +709 -0
  31. package/dist/chunk-65G2P4GL.js.map +1 -0
  32. package/dist/chunk-6UX3YSCW.js +4151 -0
  33. package/dist/chunk-6UX3YSCW.js.map +1 -0
  34. package/dist/chunk-DANSD6BE.js +709 -0
  35. package/dist/chunk-DANSD6BE.js.map +1 -0
  36. package/dist/chunk-DF3JEQXA.js +373 -0
  37. package/dist/chunk-DF3JEQXA.js.map +1 -0
  38. package/dist/chunk-GO3APTPX.js +61 -0
  39. package/dist/chunk-GO3APTPX.js.map +1 -0
  40. package/dist/chunk-ID4U6IQC.js +53 -0
  41. package/dist/chunk-ID4U6IQC.js.map +1 -0
  42. package/dist/chunk-RQVS3LVL.js +165 -0
  43. package/dist/chunk-RQVS3LVL.js.map +1 -0
  44. package/dist/client.cjs +837 -0
  45. package/dist/client.d.cts +1101 -0
  46. package/dist/client.d.ts +1101 -0
  47. package/dist/client.js +806 -0
  48. package/dist/cloudflare-do.cjs +3637 -0
  49. package/dist/cloudflare-do.d.cts +1366 -0
  50. package/dist/cloudflare-do.d.ts +1366 -0
  51. package/dist/cloudflare-do.js +3614 -0
  52. package/dist/cloudflare.cjs +1048 -0
  53. package/dist/cloudflare.d.cts +1381 -0
  54. package/dist/cloudflare.d.ts +1381 -0
  55. package/dist/cloudflare.js +1017 -0
  56. package/dist/codegen.cjs +260 -19
  57. package/dist/environment-TOTQICSE.js +17 -0
  58. package/dist/environment-TOTQICSE.js.map +1 -0
  59. package/dist/index.cjs +1905 -1492
  60. package/dist/index.d.cts +19 -2
  61. package/dist/index.d.ts +19 -2
  62. package/dist/index.js +1870 -1457
  63. package/dist/node.cjs +4779 -4366
  64. package/dist/node.d.cts +18 -1
  65. package/dist/node.d.ts +18 -1
  66. package/dist/node.js +4758 -4345
  67. package/package.json +42 -13
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/models/BaseModel.ts","../src/models/StringSet.ts","../src/types/documentTypes.ts","../src/types/queryTypes.ts","../src/query/CursorManager.ts","../src/utils/sql.ts","../src/utils/patterns.ts","../src/query/DocumentQueryTranslator.ts"],"sourcesContent":["import * as Y from \"yjs\";\nimport { DatabaseEngine } from \"../engines/DatabaseEngine\";\n// Field decorator is no longer used directly in BaseModel for its own 'id' property\n// import { Field } from \"./decorators\";\nimport { FieldOptions } from \"../types/ormTypes\";\nimport { ulid } from \"ulid\"; // Import the ulid library\nimport { StringSet, StringSetChangeTracker } from \"./StringSet\";\nimport {\n SaveOptions,\n DocumentPermissionHint,\n DocumentClosedError,\n DocumentResolutionError,\n} from \"../types/documentTypes\";\n// ModelOptions and FieldOptions might not be directly needed in BaseModel itself\n// if schema access is through getSchema, but good to have for context.\n// import { ModelOptions, FieldOptions } from \"../types/ormTypes\";\nimport {\n DocumentFilter,\n QueryOptions,\n PaginatedResult,\n ProjectionSpec,\n QueryResult,\n} from \"../types/queryTypes\";\nimport { DocumentQueryTranslator } from \"../query/DocumentQueryTranslator\";\nimport { CursorManager } from \"../query/CursorManager\";\nimport { quoteIdentifier, buildSafeAlias } from \"../utils/sql\";\n\n// Aggregation types\nexport interface StringSetMembership {\n field: string;\n contains: string;\n}\n\nexport type GroupByField = string | StringSetMembership;\n\nexport interface AggregationOperation {\n type: \"count\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n field?: string; // Required for sum, avg, min, max; not used for count\n}\n\nexport interface AggregationOptions {\n groupBy: GroupByField[];\n operations: AggregationOperation[];\n filter?: DocumentFilter;\n limit?: number;\n sort?: {\n field: string; // Can be operation result field like 'count', 'sum_fieldName', etc.\n direction: 1 | -1; // 1 for ascending, -1 for descending\n };\n}\n\nexport type AggregationResult = Record<string, any> | Record<string, any>[];\n\nexport interface AggregationAliasDebugInfo {\n field: string;\n contains: string;\n originalAlias: string;\n}\n\ninterface AggregationAliasDetail extends AggregationAliasDebugInfo {\n alias: string;\n membershipKey: string;\n}\n\ninterface AggregationQueryPlan {\n sql: string;\n params: any[];\n aliasMetadata?: AggregationAliasDetail[];\n}\n\n// Logging system for BaseModel\nexport enum LogLevel {\n SILENT = 0,\n ERROR = 1,\n WARN = 2,\n INFO = 3,\n DEBUG = 4,\n VERBOSE = 5,\n}\n\nexport class Logger {\n private static _logLevel: LogLevel = LogLevel.ERROR;\n private static _logCallback:\n | ((message: string, level: LogLevel) => void)\n | null = null;\n\n static setLogLevel(level: LogLevel) {\n this._logLevel = level;\n }\n\n static getLogLevel(): LogLevel {\n return this._logLevel;\n }\n\n static setLogCallback(\n callback: ((message: string, level: LogLevel) => void) | null\n ) {\n this._logCallback = callback;\n }\n\n static error(message: string, ...args: any[]) {\n if (this._logLevel >= LogLevel.ERROR) {\n const fullMessage =\n args.length > 0\n ? `${message} ${args\n .map((arg) =>\n typeof arg === \"object\" ? JSON.stringify(arg) : String(arg)\n )\n .join(\" \")}`\n : message;\n console.error(`[ERROR] ${message}`, ...args);\n if (this._logCallback) {\n this._logCallback(fullMessage, LogLevel.ERROR);\n }\n }\n }\n\n static warn(message: string, ...args: any[]) {\n if (this._logLevel >= LogLevel.WARN) {\n const fullMessage =\n args.length > 0\n ? `${message} ${args\n .map((arg) =>\n typeof arg === \"object\" ? JSON.stringify(arg) : String(arg)\n )\n .join(\" \")}`\n : message;\n console.warn(`[WARN] ${message}`, ...args);\n if (this._logCallback) {\n this._logCallback(fullMessage, LogLevel.WARN);\n }\n }\n }\n\n static info(message: string, ...args: any[]) {\n if (this._logLevel >= LogLevel.INFO) {\n const fullMessage =\n args.length > 0\n ? `${message} ${args\n .map((arg) =>\n typeof arg === \"object\" ? JSON.stringify(arg) : String(arg)\n )\n .join(\" \")}`\n : message;\n console.log(`[INFO] ${message}`, ...args);\n if (this._logCallback) {\n this._logCallback(fullMessage, LogLevel.INFO);\n }\n }\n }\n\n static debug(message: string, ...args: any[]) {\n if (this._logLevel >= LogLevel.DEBUG) {\n const fullMessage =\n args.length > 0\n ? `${message} ${args\n .map((arg) =>\n typeof arg === \"object\" ? JSON.stringify(arg) : String(arg)\n )\n .join(\" \")}`\n : message;\n console.log(`[DEBUG] ${message}`, ...args);\n if (this._logCallback) {\n this._logCallback(fullMessage, LogLevel.DEBUG);\n }\n }\n }\n\n static verbose(message: string, ...args: any[]) {\n if (this._logLevel >= LogLevel.VERBOSE) {\n const fullMessage =\n args.length > 0\n ? `${message} ${args\n .map((arg) =>\n typeof arg === \"object\" ? JSON.stringify(arg) : String(arg)\n )\n .join(\" \")}`\n : message;\n console.log(`[VERBOSE] ${message}`, ...args);\n if (this._logCallback) {\n this._logCallback(fullMessage, LogLevel.VERBOSE);\n }\n }\n }\n}\n\n// Define Custom Error for Unique Constraint Violations\nexport class UniqueConstraintViolationError extends Error {\n public modelName: string;\n public constraintName: string;\n public fields: string[];\n public recordIdAttempted?: string; // ID of the record that failed to save/update\n public conflictingRecordId?: string; // ID of the record that already has the unique value\n\n constructor(\n message: string,\n modelName: string,\n constraintName: string,\n fields: string[],\n recordIdAttempted?: string,\n conflictingRecordId?: string\n ) {\n super(message);\n this.name = \"UniqueConstraintViolationError\";\n this.modelName = modelName;\n this.constraintName = constraintName;\n this.fields = fields;\n this.recordIdAttempted = recordIdAttempted;\n this.conflictingRecordId = conflictingRecordId;\n Object.setPrototypeOf(this, UniqueConstraintViolationError.prototype);\n }\n}\n\nexport class RecordNotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RecordNotFoundError\";\n Object.setPrototypeOf(this, RecordNotFoundError.prototype);\n }\n}\n\n// Renamed from generateUUID and updated to generate ULIDs\nexport function generateULID() {\n return ulid(); // Uses the ulid library\n}\n\nconst SCHEMA_ACCESSORS_KEY = Symbol(\"jsBaoSchemaAccessors\");\n\nexport class BaseModel implements StringSetChangeTracker {\n static modelName?: string;\n private static listenersMap: Map<string, Set<() => void>> = new Map();\n // Default document resolution mappings (session-scoped)\n private static modelNameToDefaultDocId: Map<string, string> = new Map();\n private static globalDefaultDocId: string | undefined;\n private static defaultDocChangedListeners: Set<\n (payload: { previous?: string; current?: string }) => void\n > = new Set();\n private static modelDocMappingChangedListeners: Set<\n (payload: {\n modelName: string;\n previous?: string;\n current?: string;\n }) => void\n > = new Set();\n // These were for tracking initialization state, which is now more centralized in ModelRegistry\n // and the main initializeORM flow. We'll rely on the Model's static `initialize` method.\n // private static initializedModels: Set<string> = new Set();\n // private static initializationPromises: Map<string, Promise<void>> = new Map();\n\n // Default document constants for legacy mode compatibility\n private static readonly DEFAULT_LEGACY_DOC_ID = \"__legacy_default__\";\n // private static readonly DEFAULT_PERMISSION: DocumentPermissionHint = \"read-write\";\n\n // dbInstance will be set per model via its static initialize, but query methods need access.\n // This will be a single instance shared across all models once initialized.\n protected static dbInstance: DatabaseEngine | null = null;\n\n // Multi-document management (now used for both legacy and multi-document modes)\n protected static connectedDocuments: Map<\n string,\n { yDoc: Y.Doc; permissionHint: DocumentPermissionHint }\n > = new Map();\n protected static documentYMaps: Map<string, Y.Map<any>> = new Map(); // Maps docId to YMap for that document\n\n // Copy-on-write state management\n private _localChanges: Record<string, any> | null = null;\n private _isDirty = false;\n private _isLoadingFromYjs = false; // Flag to distinguish loading vs user changes\n\n // StringSet field caching\n private _stringSetFields: Map<string, StringSet> = new Map();\n\n // Multi-document instance metadata\n private _metaDocId: string | null = null;\n private _metaPermissionHint: DocumentPermissionHint | null = null;\n\n /**\n * Returns the document id this instance is associated with, or null if not resolved yet.\n */\n getDocumentId(): string | null {\n return this._metaDocId;\n }\n\n // id is now a plain property. Subclasses will define it with @Field.\n id!: string;\n type!: string; // This should be the modelName from ModelOptions\n\n // Static logging methods\n static setLogLevel(level: LogLevel) {\n Logger.setLogLevel(level);\n }\n\n static getLogLevel(): LogLevel {\n return Logger.getLogLevel();\n }\n\n // ---- Default doc resolution: static APIs ----\n static setModelDefaultDocumentId(modelName: string, docId: string) {\n const previous = this.modelNameToDefaultDocId.get(modelName);\n this.modelNameToDefaultDocId.set(modelName, docId);\n for (const listener of this.modelDocMappingChangedListeners) {\n try {\n listener({ modelName, previous, current: docId });\n } catch {}\n }\n }\n\n static removeModelDefaultDocumentId(modelName: string) {\n const previous = this.modelNameToDefaultDocId.get(modelName);\n this.modelNameToDefaultDocId.delete(modelName);\n for (const listener of this.modelDocMappingChangedListeners) {\n try {\n listener({ modelName, previous, current: undefined });\n } catch {}\n }\n }\n\n static clearModelDefaultDocumentIds() {\n const entries = Array.from(this.modelNameToDefaultDocId.entries());\n this.modelNameToDefaultDocId.clear();\n for (const [modelName, previous] of entries) {\n for (const listener of this.modelDocMappingChangedListeners) {\n try {\n listener({ modelName, previous, current: undefined });\n } catch {}\n }\n }\n }\n\n static setGlobalDefaultDocumentId(docId: string) {\n const previous = this.globalDefaultDocId;\n this.globalDefaultDocId = docId;\n for (const listener of this.defaultDocChangedListeners) {\n try {\n listener({ previous, current: docId });\n } catch {}\n }\n }\n\n static clearGlobalDefaultDocumentId() {\n const previous = this.globalDefaultDocId;\n this.globalDefaultDocId = undefined;\n for (const listener of this.defaultDocChangedListeners) {\n try {\n listener({ previous, current: undefined });\n } catch {}\n }\n }\n\n static getModelDefaultDocumentMapping(): Record<string, string> {\n return Object.fromEntries(this.modelNameToDefaultDocId.entries());\n }\n\n static getDocumentIdForModel(modelName: string): string | undefined {\n return this.modelNameToDefaultDocId.get(modelName);\n }\n\n static getGlobalDefaultDocumentId(): string | undefined {\n return this.globalDefaultDocId;\n }\n\n static onDefaultDocChanged(\n listener: (payload: { previous?: string; current?: string }) => void\n ): () => void {\n this.defaultDocChangedListeners.add(listener);\n return () => this.defaultDocChangedListeners.delete(listener);\n }\n\n static onModelDocMappingChanged(\n listener: (payload: {\n modelName: string;\n previous?: string;\n current?: string;\n }) => void\n ): () => void {\n this.modelDocMappingChangedListeners.add(listener);\n return () => this.modelDocMappingChangedListeners.delete(listener);\n }\n\n // Helper used by DocumentManager to clear mappings for a given docId when disconnected\n static _clearMappingsForDocId(docId: string) {\n const toRemove: string[] = [];\n for (const [modelName, mappedDocId] of this.modelNameToDefaultDocId) {\n if (mappedDocId === docId) {\n toRemove.push(modelName);\n }\n }\n for (const modelName of toRemove) {\n this.removeModelDefaultDocumentId(modelName);\n }\n if (this.globalDefaultDocId === docId) {\n this.clearGlobalDefaultDocumentId();\n }\n }\n\n private static attachFieldAccessorsSet(\n modelClass: typeof BaseModel\n ): Set<string> {\n const existing =\n (modelClass as any)[SCHEMA_ACCESSORS_KEY] ?? new Set<string>();\n (modelClass as any)[SCHEMA_ACCESSORS_KEY] = existing;\n return existing;\n }\n\n public static attachFieldAccessors(\n modelClass: typeof BaseModel,\n fields: Map<string, FieldOptions>\n ) {\n const attached = BaseModel.attachFieldAccessorsSet(modelClass);\n const prototype = modelClass.prototype as BaseModel;\n\n for (const fieldName of fields.keys()) {\n if (fieldName === \"id\") continue;\n if (attached.has(fieldName)) continue;\n\n const existingDescriptor = Object.getOwnPropertyDescriptor(\n prototype,\n fieldName\n );\n if (existingDescriptor && !existingDescriptor.configurable) {\n continue;\n }\n\n Object.defineProperty(prototype, fieldName, {\n configurable: true,\n enumerable: true,\n get(this: BaseModel) {\n return this.getValue(fieldName);\n },\n set(this: BaseModel, value: any) {\n this.setValue(fieldName, value);\n },\n });\n\n attached.add(fieldName);\n }\n }\n\n constructor(data: Partial<any> = {}) {\n if (new.target === BaseModel) {\n throw new Error(\"BaseModel cannot be instantiated directly.\");\n }\n const modelConstructor = this.constructor as typeof BaseModel;\n const schema = (modelConstructor as any).getSchema();\n const verboseEnabled = Logger.getLogLevel() >= LogLevel.VERBOSE;\n\n if (!schema || !schema.fields) {\n throw new Error(\n `[${modelConstructor.name}] Schema not loaded. Ensure the model is properly initialized.`\n );\n }\n\n if (verboseEnabled) {\n Logger.verbose(\n `BaseModel Constructor - ${modelConstructor.name}: Initializing with data:`,\n data\n );\n Logger.verbose(\n `BaseModel Constructor - ${modelConstructor.name}: Schema fields received:`,\n schema.fields\n );\n }\n\n // Handle ID field first (not copy-on-write)\n const idFieldOptions = schema.fields.get(\"id\");\n if (data.id) {\n // ID provided in constructor data\n this.id = data.id;\n } else if (idFieldOptions?.autoAssign) {\n // Auto-assign ID\n this.id = generateULID();\n } else if (idFieldOptions?.default) {\n // Use default ID generator\n this.id =\n typeof idFieldOptions.default === \"function\"\n ? idFieldOptions.default()\n : idFieldOptions.default;\n } else {\n throw new Error(\n `[${modelConstructor.name}] No ID provided and no autoAssign or default configured for id field`\n );\n }\n\n // Check if this is loading an existing record vs creating a new one\n const isLoadingExistingRecord = data.id && Object.keys(data).length === 1;\n\n if (verboseEnabled) {\n Logger.verbose(\n `[BaseModel Constructor - ${modelConstructor.name}] Is loading existing record: ${isLoadingExistingRecord}, ID: ${this.id}`\n );\n Logger.verbose(\n `[BaseModel Constructor - ${modelConstructor.name}] Connected documents:`,\n Array.from(modelConstructor.connectedDocuments.keys())\n );\n }\n\n if (isLoadingExistingRecord) {\n // This is loading an existing record - check if it exists in any connected document\n let recordYMap: Y.Map<any> | undefined = undefined;\n let foundDocId: string | undefined = undefined;\n\n // Search across all connected documents (including legacy default document)\n for (const [docId] of modelConstructor.connectedDocuments) {\n if (verboseEnabled) {\n Logger.verbose(\n `[BaseModel Constructor - ${modelConstructor.name}] Searching in document: ${docId}`\n );\n }\n const documentYMap = modelConstructor.documentYMaps.get(\n `${docId}_${schema.options.name}`\n );\n if (verboseEnabled) {\n Logger.verbose(\n `[BaseModel Constructor - ${\n modelConstructor.name\n }] Document YMap found: ${!!documentYMap}`\n );\n }\n if (documentYMap) {\n const foundRecord = documentYMap.get(this.id) as\n | Y.Map<any>\n | undefined;\n if (verboseEnabled) {\n Logger.verbose(\n `[BaseModel Constructor - ${\n modelConstructor.name\n }] Record found in document ${docId}: ${!!foundRecord}`\n );\n }\n if (foundRecord) {\n recordYMap = foundRecord;\n foundDocId = docId;\n break;\n }\n }\n }\n\n if (recordYMap && foundDocId) {\n // Record exists in Yjs, this is definitely loading an existing record\n this._isLoadingFromYjs = true;\n this._isDirty = false;\n this._localChanges = null;\n\n // Set document metadata\n this._metaDocId = foundDocId;\n const connectedDoc =\n modelConstructor.connectedDocuments.get(foundDocId);\n if (connectedDoc) {\n this._metaPermissionHint = connectedDoc.permissionHint;\n }\n\n if (schema.options && schema.options.name) {\n this.type = schema.options.name;\n }\n\n if (verboseEnabled) {\n Logger.verbose(\n `[BaseModel Constructor - ${modelConstructor.name}] ID INITIALIZED TO:`,\n this.id\n );\n }\n return;\n }\n }\n\n // This is creating a new record or the record doesn't exist in Yjs yet\n this._isLoadingFromYjs = false;\n\n // Do not set a default document for new records.\n // New instances should not remember a document unless loaded from one.\n\n // If constructor data was provided, set the values, which will trigger copy-on-write\n if (data && Object.keys(data).length > 0) {\n for (const [\n fieldKey,\n fieldOptions,\n ] of schema.fields.entries() as IterableIterator<\n [string, FieldOptions]\n >) {\n if (fieldKey === \"id\") continue; // Already handled above\n\n if (data.hasOwnProperty(fieldKey)) {\n // This will trigger setValue and mark as dirty\n this.setValue(fieldKey, (data as any)[fieldKey]);\n } else if (fieldOptions.default !== undefined) {\n // Apply defaults through copy-on-write as well\n const defaultValue =\n typeof fieldOptions.default === \"function\"\n ? fieldOptions.default()\n : fieldOptions.default;\n this.setValue(fieldKey, defaultValue);\n }\n }\n }\n\n if (schema.options && schema.options.name) {\n this.type = schema.options.name;\n } else {\n Logger.warn(\n `[${modelConstructor.name}] Schema missing options.name, 'type' field may not be set correctly.`\n );\n }\n\n if (!this.id) {\n Logger.error(\n `[BaseModel Constructor - ${modelConstructor.name}] ID is STILL UNDEFINED. Current instance state:`,\n JSON.stringify(this)\n );\n throw new Error(\n `[${modelConstructor.name}] ID is missing after initialization. Ensure 'id' field is defined in the model's schema with autoAssign:true or a default value, or an id is provided during instantiation.`\n );\n }\n Logger.verbose(\n `[BaseModel Constructor - ${modelConstructor.name}] ID INITIALIZED TO:`,\n this.id\n );\n\n return;\n }\n\n // Copy-on-write helper methods\n private ensureLocalChanges(): Record<string, any> {\n if (this._localChanges === null) {\n this._localChanges = {};\n }\n return this._localChanges;\n }\n\n private hasLocalChange(fieldKey: string): boolean {\n return this._localChanges !== null && fieldKey in this._localChanges;\n }\n\n private getFromYjs(fieldKey: string): any {\n const modelConstructor = this.constructor as typeof BaseModel;\n const schema = (modelConstructor as any).getSchema();\n const modelName = schema?.options?.name;\n\n const verboseEnabled = Logger.getLogLevel() >= LogLevel.VERBOSE;\n\n if (verboseEnabled) {\n Logger.verbose(\n `[getFromYjs] Called for field '${fieldKey}' on model ${modelName}, instance ID: ${this.id}`\n );\n Logger.verbose(`[getFromYjs] this._metaDocId: ${this._metaDocId}`);\n Logger.verbose(\n `[getFromYjs] documentYMaps available: ${!!modelConstructor.documentYMaps}`\n );\n Logger.verbose(\n `[getFromYjs] connectedDocuments available: ${!!modelConstructor.connectedDocuments}`\n );\n }\n\n let recordYMap: Y.Map<any> | undefined = undefined;\n\n // Use document ID only if the instance remembers one\n const docId = this._metaDocId;\n if (verboseEnabled) {\n Logger.verbose(`[getFromYjs] Using document ID: ${docId}`);\n }\n\n const documentYMapKey = `${docId}_${modelName}`;\n if (verboseEnabled) {\n Logger.verbose(\n `[getFromYjs] Looking for documentYMap with key: ${documentYMapKey}`\n );\n }\n\n const documentYMap = modelConstructor.documentYMaps.get(documentYMapKey);\n if (verboseEnabled) {\n Logger.verbose(`[getFromYjs] DocumentYMap found: ${!!documentYMap}`);\n }\n\n if (documentYMap) {\n if (verboseEnabled) {\n Logger.verbose(\n `[getFromYjs] DocumentYMap keys: [${Array.from(\n documentYMap.keys()\n ).join(\", \")}]`\n );\n }\n recordYMap = documentYMap.get(this.id) as Y.Map<any> | undefined;\n if (verboseEnabled) {\n Logger.verbose(\n `[getFromYjs] RecordYMap found for ID '${this.id}': ${!!recordYMap}`\n );\n }\n\n if (recordYMap) {\n if (verboseEnabled) {\n Logger.verbose(\n `[getFromYjs] RecordYMap keys: [${Array.from(\n recordYMap.keys()\n ).join(\", \")}]`\n );\n }\n const fieldValue = recordYMap.get(fieldKey);\n if (verboseEnabled) {\n Logger.verbose(\n `[getFromYjs] Field '${fieldKey}' value: ${fieldValue}`\n );\n }\n }\n }\n\n if (!recordYMap) {\n if (verboseEnabled) {\n Logger.verbose(\n `[getFromYjs] No recordYMap found, falling back to schema defaults`\n );\n }\n // No Yjs record exists, fall back to schema defaults\n const fieldOptions = schema?.fields?.get(fieldKey);\n if (fieldOptions?.default !== undefined) {\n const defaultValue =\n typeof fieldOptions.default === \"function\"\n ? fieldOptions.default()\n : fieldOptions.default;\n if (verboseEnabled) {\n Logger.verbose(\n `[getFromYjs] Returning schema default: ${defaultValue}`\n );\n }\n return defaultValue;\n }\n if (verboseEnabled) {\n Logger.verbose(`[getFromYjs] No schema default, returning undefined`);\n }\n return undefined;\n }\n\n const fieldValue = recordYMap.get(fieldKey);\n if (verboseEnabled) {\n Logger.verbose(`[getFromYjs] Returning field value: ${fieldValue}`);\n }\n return fieldValue;\n }\n\n private getValue(fieldKey: string): any {\n const verboseEnabled = Logger.getLogLevel() >= LogLevel.VERBOSE;\n if (verboseEnabled) {\n Logger.verbose(\n `[getValue] Called for field '${fieldKey}' on instance ID: ${this.id}`\n );\n }\n\n // Check if this is a StringSet field\n const schema = (this.constructor as any).getSchema();\n const fieldOptions = schema?.fields?.get(fieldKey);\n\n if (fieldOptions?.type === \"stringset\") {\n if (verboseEnabled) {\n Logger.verbose(\n `[getValue] Field '${fieldKey}' is StringSet type, returning StringSet instance`\n );\n }\n return this.getOrCreateStringSet(fieldKey);\n }\n\n if (this.hasLocalChange(fieldKey)) {\n if (verboseEnabled) {\n Logger.verbose(\n `[getValue] Field '${fieldKey}' has local changes: ${\n this._localChanges![fieldKey]\n }`\n );\n }\n return this._localChanges![fieldKey];\n }\n if (verboseEnabled) {\n Logger.verbose(\n `[getValue] Field '${fieldKey}' no local changes, calling getFromYjs`\n );\n }\n const result = this.getFromYjs(fieldKey);\n if (verboseEnabled) {\n Logger.verbose(\n `[getValue] Field '${fieldKey}' returning from getFromYjs: ${result}`\n );\n }\n return result;\n }\n\n private setValue(fieldKey: string, value: any): void {\n // Check if this is a StringSet field\n const schema = (this.constructor as any).getSchema();\n const fieldOptions = schema?.fields?.get(fieldKey);\n\n if (fieldOptions?.type === \"stringset\") {\n throw new Error(\n `Cannot directly assign to StringSet field '${fieldKey}'. Use the StringSet methods (add, remove, clear) instead.`\n );\n }\n\n // Skip validation during loading from Yjs\n if (!this._isLoadingFromYjs) {\n // Assignment-time validation can be added here if needed\n // For now, we'll do validation on save as requested\n }\n\n const changes = this.ensureLocalChanges();\n changes[fieldKey] = value;\n this._isDirty = true;\n }\n\n get isDirty(): boolean {\n return this._isDirty;\n }\n\n get hasUnsavedChanges(): boolean {\n return (\n this._localChanges !== null && Object.keys(this._localChanges).length > 0\n );\n }\n\n private clearLocalChanges(): void {\n this._localChanges = null;\n this._isDirty = false;\n }\n\n discardChanges(): void {\n this.clearLocalChanges();\n }\n\n // Validation methods\n protected validateFieldValue(fieldKey: string, value: any): void {\n const schema = (this.constructor as any).getSchema();\n const fieldOptions = schema.fields.get(fieldKey);\n\n if (!fieldOptions) {\n throw new Error(`Unknown field: ${fieldKey}`);\n }\n\n // Type validation, required checks, etc.\n if (fieldOptions.required && (value === null || value === undefined)) {\n throw new Error(`Field ${fieldKey} is required`);\n }\n }\n\n protected validateBeforeSave(): void {\n const schema = (this.constructor as any).getSchema();\n\n // Cross-field validation, business rules, etc.\n for (const [fieldKey, fieldOptions] of schema.fields.entries()) {\n const currentValue = this.getValue(fieldKey);\n\n if (\n fieldOptions.required &&\n (currentValue === null || currentValue === undefined)\n ) {\n throw new Error(`Field ${fieldKey} is required before save`);\n }\n\n // StringSet specific validation\n if (\n fieldOptions.type === \"stringset\" &&\n currentValue instanceof StringSet\n ) {\n // Validate maxCount\n if (\n fieldOptions.maxCount &&\n currentValue.size > fieldOptions.maxCount\n ) {\n throw new Error(\n `StringSet field '${fieldKey}' exceeds maximum count of ${fieldOptions.maxCount}. Current count: ${currentValue.size}`\n );\n }\n\n // Validate maxLength for each string\n if (fieldOptions.maxLength) {\n for (const value of currentValue) {\n if (value.length > fieldOptions.maxLength) {\n throw new Error(\n `StringSet field '${fieldKey}' contains a string that exceeds maximum length of ${fieldOptions.maxLength}: \"${value}\" (length: ${value.length})`\n );\n }\n }\n }\n }\n }\n }\n\n // State inspection helpers\n getChangedFields(): string[] {\n return this._localChanges ? Object.keys(this._localChanges) : [];\n }\n\n getOriginalValue(fieldKey: string): any {\n return this.getFromYjs(fieldKey);\n }\n\n getCurrentValue(fieldKey: string): any {\n return this.getValue(fieldKey);\n }\n\n hasFieldChanged(fieldKey: string): boolean {\n return this.hasLocalChange(fieldKey);\n }\n\n // StringSet support methods\n markStringSetChange(\n fieldName: string,\n operation: \"add\" | \"remove\" | \"clear\",\n value?: string\n ): void {\n const changes = this.ensureLocalChanges();\n\n if (!changes[fieldName]) {\n changes[fieldName] = {\n type: \"stringset\",\n additions: new Set<string>(),\n removals: new Set<string>(),\n };\n }\n\n const stringSetChanges = changes[fieldName];\n\n if (operation === \"clear\") {\n // Clear operation: remove all current values\n const currentValues = this.getStringSetCurrentValues(fieldName);\n stringSetChanges.additions.clear();\n stringSetChanges.removals = new Set(currentValues);\n } else if (operation === \"add\" && value) {\n // Add operation: remove from removals, add to additions\n stringSetChanges.removals.delete(value);\n stringSetChanges.additions.add(value);\n } else if (operation === \"remove\" && value) {\n // Remove operation: remove from additions, add to removals\n stringSetChanges.additions.delete(value);\n stringSetChanges.removals.add(value);\n }\n\n this._isDirty = true;\n }\n\n private getStringSetCurrentValues(fieldName: string): string[] {\n // Get current values from Yjs\n const yjsData = this.getFromYjs(fieldName);\n if (yjsData && typeof yjsData === \"object\") {\n return Object.keys(yjsData);\n }\n return [];\n }\n\n private getStringSetFromYjs(fieldName: string): string[] {\n const yjsData = this.getFromYjs(fieldName);\n if (yjsData && typeof yjsData === \"object\") {\n // YMap stored as { \"value1\": true, \"value2\": true }\n return Object.keys(yjsData);\n }\n return [];\n }\n\n private getOrCreateStringSet(fieldName: string): StringSet {\n if (!this._stringSetFields.has(fieldName)) {\n // Get initial values from Yjs\n const initialValues = this.getStringSetFromYjs(fieldName);\n\n // Apply any pending changes\n const pendingChanges = this._localChanges?.[fieldName];\n let currentValues = new Set(initialValues);\n\n if (pendingChanges && pendingChanges.type === \"stringset\") {\n // Apply additions\n for (const addition of pendingChanges.additions) {\n currentValues.add(addition);\n }\n // Apply removals\n for (const removal of pendingChanges.removals) {\n currentValues.delete(removal);\n }\n }\n\n const stringSet = new StringSet(\n this,\n fieldName,\n Array.from(currentValues)\n );\n this._stringSetFields.set(fieldName, stringSet);\n }\n\n return this._stringSetFields.get(fieldName)!;\n }\n\n // Legacy initialize method - removed (explicit document required)\n static async initialize(_yDoc: Y.Doc, _db: DatabaseEngine) {\n throw new Error(\n `[${this.name}] initialize(yDoc, db) is no longer supported. Use initializeForDocument(yDoc, db, docId, permission)`\n );\n }\n\n // New method for multi-document initialization\n static async initializeForDocument(\n yDoc: Y.Doc,\n db: DatabaseEngine,\n docId: string,\n permissionHint: DocumentPermissionHint\n ) {\n const schema = (this as any).getSchema?.();\n const verboseEnabled = Logger.getLogLevel() >= LogLevel.VERBOSE;\n if (\n !schema ||\n !schema.options ||\n !schema.options.name ||\n !schema.resolvedUniqueConstraints\n ) {\n throw new Error(\n `[${this.name}] Model schema is not registered, missing options, or missing resolvedUniqueConstraints. Did you forget to use the @Model decorator or has the schema structure changed?`\n );\n }\n const modelName = schema.options.name;\n if (verboseEnabled) {\n Logger.verbose(\n `[${this.name}] Initializing model ${modelName} for document ${docId} (permission: ${permissionHint})...`\n );\n }\n\n // Store database instance (should already be set from main initialization)\n if (!BaseModel.dbInstance) {\n BaseModel.dbInstance = db;\n }\n\n // Store document connection info\n (this as typeof BaseModel).connectedDocuments.set(docId, {\n yDoc,\n permissionHint,\n });\n\n // Get YMap for this document\n const documentYMap = yDoc.getMap(modelName);\n (this as typeof BaseModel).documentYMaps.set(\n `${docId}_${modelName}`,\n documentYMap\n );\n\n const stringSetFieldNames: string[] = [];\n schema.fields.forEach((fieldOptions: any, fieldName: string) => {\n if ((fieldOptions as FieldOptions)?.type === \"stringset\") {\n stringSetFieldNames.push(fieldName);\n }\n });\n const documentRecordCount =\n typeof documentYMap.size === \"number\"\n ? documentYMap.size\n : Array.from(documentYMap.keys()).length;\n const shouldReindexJunctionTables =\n stringSetFieldNames.length > 0 && documentRecordCount > 0;\n\n if (verboseEnabled) {\n Logger.verbose(\n `[${this.name}] Document YMap initialized for ${modelName}/${docId} with keys:`,\n Array.from(documentYMap.keys())\n );\n }\n\n // Ensure database table exists (should already be created during main initialization)\n if (verboseEnabled) {\n Logger.verbose(\n `[${this.name}] Ensuring DB table exists for ${modelName}...`\n );\n }\n await db.createTable(modelName, schema.fields, schema.options);\n\n // Create StringSet junction tables if needed\n if (stringSetFieldNames.length > 0) {\n Logger.info(\n `[${this.name}] Junction table reindex check for ${modelName}/${docId}: found ${stringSetFieldNames.length} StringSet field(s) [${stringSetFieldNames.join(\n \", \"\n )}] with ${documentRecordCount} record(s) in document. ${\n shouldReindexJunctionTables\n ? \"Re-indexing junction tables from document data.\"\n : \"No records to re-index yet; ensuring tables exist.\"\n }`\n );\n for (const fieldName of stringSetFieldNames) {\n await db.createStringSetJunctionTable(modelName, fieldName);\n }\n }\n\n // Clear any existing data for this document to avoid stale indexes when reconnecting\n try {\n await db.deleteByDocumentId(modelName, docId);\n } catch (error) {\n Logger.error(\n `[${this.name}] Error clearing existing data for document ${docId} during initialization:`,\n error\n );\n }\n\n // Load initial data from this document's YMap\n if (verboseEnabled) {\n Logger.verbose(\n `[${this.name}] Loading initial data from document ${docId} YMap for ${modelName}...`\n );\n }\n\n const extractStringSetValues = (value: any): string[] => {\n if (!value) return [];\n if (value instanceof Y.Map) {\n return Array.from(value.entries())\n .filter(([, isMember]) => Boolean(isMember))\n .map(([key]) => key);\n }\n if (Array.isArray(value)) {\n return value.filter((v) => typeof v === \"string\");\n }\n if (typeof value === \"object\") {\n return Object.entries(value)\n .filter(([, isMember]) => Boolean(isMember))\n .map(([key]) => key);\n }\n return [];\n };\n\n const junctionInsertCounts: Record<string, number> = {};\n\n await db.withTransaction(async (transactionalOps) => {\n for (const [recordId, recordData] of documentYMap.entries()) {\n if (!recordId) continue;\n\n let itemData: Record<string, any>;\n const stringSetValuesByField: Record<string, string[]> = {};\n\n // Handle both nested YMaps and legacy plain objects\n if (recordData instanceof Y.Map) {\n // Convert nested YMap to plain object\n itemData = {};\n const unknownFields: string[] = [];\n for (const [fieldKey, value] of recordData.entries()) {\n // Skip StringSet fields - they're handled by junction tables\n const fieldOptions = schema.fields.get(fieldKey);\n if (!fieldOptions) {\n unknownFields.push(fieldKey);\n continue;\n }\n if (fieldOptions.type === \"stringset\") {\n stringSetValuesByField[fieldKey] =\n extractStringSetValues(value);\n continue;\n }\n // Skip undefined values as SQLite cannot bind them\n if (value !== undefined) {\n itemData[fieldKey] = value;\n }\n }\n if (unknownFields.length > 0) {\n Logger.warn(\n `[${this.name}] Ignoring unknown fields [${unknownFields.join(\n \", \"\n )}] when loading record ${recordId} from document ${docId}`\n );\n }\n } else {\n // Legacy plain object support\n const legacyData = recordData as Record<string, any>;\n const filteredData: Record<string, any> = {};\n const unknownFields: string[] = [];\n for (const [fieldKey, value] of Object.entries(legacyData)) {\n const fieldOptions = schema.fields.get(fieldKey);\n if (!fieldOptions) {\n unknownFields.push(fieldKey);\n continue;\n }\n if (fieldOptions.type === \"stringset\") {\n stringSetValuesByField[fieldKey] =\n extractStringSetValues(value);\n continue;\n }\n if (value !== undefined) {\n filteredData[fieldKey] = value;\n }\n }\n if (unknownFields.length > 0) {\n Logger.warn(\n `[${this.name}] Ignoring unknown fields [${unknownFields.join(\n \", \"\n )}] when loading legacy record ${recordId} from document ${docId}`\n );\n }\n itemData = filteredData;\n Logger.warn(\n `[${this.name}] Found legacy plain object during document initialization for ${recordId}`\n );\n }\n\n if (!itemData.id) continue;\n\n try {\n // Add metadata fields\n await transactionalOps.insert(modelName, {\n ...itemData,\n type: modelName,\n _meta_doc_id: docId,\n _meta_permission_hint: permissionHint,\n });\n\n for (const [fieldName, values] of Object.entries(\n stringSetValuesByField\n )) {\n if (!values || values.length === 0) continue;\n try {\n await db.insertStringSetValues(\n modelName,\n fieldName,\n recordId,\n values\n );\n junctionInsertCounts[fieldName] =\n (junctionInsertCounts[fieldName] || 0) + values.length;\n } catch (stringSetError) {\n Logger.error(\n `[${this.name}] Error indexing StringSet field ${fieldName} for record ${recordId} in document ${docId}:`,\n stringSetError\n );\n throw stringSetError;\n }\n }\n } catch (error) {\n // Check if this is a unique constraint violation warning\n if (\n error instanceof Error &&\n error.message.includes(\"UNIQUE constraint\")\n ) {\n console.warn(\n `[${this.name}] Warning: Unique constraint conflict when loading ${recordId} from document ${docId}. ` +\n `This record already exists from another document. Data will still be indexed with document ID for disambiguation.`\n );\n // For unique constraint violations, we could optionally try to insert with a modified unique field\n // or just continue with the warning\n } else {\n Logger.error(\n `[${this.name}] Error inserting item into db (document ${docId} load for ${modelName}):`,\n error,\n itemData\n );\n }\n }\n }\n });\n\n if (stringSetFieldNames.length > 0) {\n const totalInserted = Object.values(junctionInsertCounts).reduce(\n (sum, count) => sum + count,\n 0\n );\n const perFieldSummary = Object.entries(junctionInsertCounts)\n .map(([fieldName, count]) => `${fieldName}: ${count}`)\n .join(\"; \");\n\n if (shouldReindexJunctionTables) {\n Logger.info(\n `[${this.name}] Junction table reindex summary for ${modelName}/${docId}: ${totalInserted} total value(s) processed${\n perFieldSummary ? ` (${perFieldSummary})` : \"\"\n }.`\n );\n } else {\n Logger.info(\n `[${this.name}] Junction table reindex summary for ${modelName}/${docId}: no StringSet values to index yet.`\n );\n }\n }\n\n // Set up observer for this document's YMap with integrated unique constraint conflict resolution.\n // For remote changes, we defer SQLite inserts until after conflict resolution to ensure\n // duplicate records never reach SQLite.\n Logger.verbose(\n `[${this.name}] Setting up YMap observer for document ${docId}/${modelName}...`\n );\n\n // Helper to build unique key for a record\n const buildUniqueKey = (\n recordData: Y.Map<any> | Record<string, any>,\n fields: string[]\n ): string | null => {\n const keyParts: string[] = [];\n for (const field of fields) {\n const value =\n recordData instanceof Y.Map\n ? recordData.get(field)\n : (recordData as Record<string, any>)[field];\n if (value === null || value === undefined) {\n return null; // Null values don't participate in unique constraints\n }\n keyParts.push(String(value));\n }\n return keyParts.join(\"|\");\n };\n\n // Helper to extract item data from record (YMap or plain object)\n const extractItemData = (\n key: string,\n recordData: Y.Map<any> | Record<string, any>\n ): Record<string, any> | null => {\n let itemData: Record<string, any>;\n\n if (recordData instanceof Y.Map) {\n itemData = {};\n const unknownFields: string[] = [];\n for (const [fieldKey, value] of recordData.entries()) {\n const fieldOptions = schema.fields.get(fieldKey);\n if (!fieldOptions) {\n unknownFields.push(fieldKey);\n continue;\n }\n if (fieldOptions.type === \"stringset\") {\n continue;\n }\n if (value !== undefined) {\n itemData[fieldKey] = value;\n }\n }\n if (unknownFields.length > 0) {\n Logger.warn(\n `[${this.name}] Ignoring unknown fields [${unknownFields.join(\n \", \"\n )}] when syncing record ${key} from document ${docId}`\n );\n }\n } else {\n const unknownFields: string[] = [];\n const filteredData: Record<string, any> = {};\n for (const [fieldKey, value] of Object.entries(recordData)) {\n const fieldOptions = schema.fields.get(fieldKey);\n if (!fieldOptions) {\n unknownFields.push(fieldKey);\n continue;\n }\n if (fieldOptions.type === \"stringset\") {\n continue;\n }\n if (value !== undefined) {\n filteredData[fieldKey] = value;\n }\n }\n if (unknownFields.length > 0) {\n Logger.warn(\n `[${this.name}] Ignoring unknown fields [${unknownFields.join(\n \", \"\n )}] when syncing legacy record ${key} from document ${docId}`\n );\n }\n itemData = filteredData;\n }\n\n if (!itemData.id) return null;\n return itemData;\n };\n\n // Resolve unique constraint conflicts across all constraints in a single pass.\n // Returns the set of record IDs that should be discarded (not inserted to SQLite).\n const resolveConflictsForBatch = (\n candidateRecords: Map<string, Y.Map<any> | Record<string, any>>\n ): Set<string> => {\n if (schema.resolvedUniqueConstraints.length === 0) {\n return new Set();\n }\n\n const recordIdsToDiscard = new Set<string>();\n const recordIdsToKeep = new Set<string>();\n\n // Build a combined view of all records (existing + candidates)\n const allRecords = new Map<string, Y.Map<any> | Record<string, any>>();\n for (const [recordId, recordData] of documentYMap.entries()) {\n if (recordData && !candidateRecords.has(recordId)) {\n allRecords.set(recordId, recordData);\n }\n }\n for (const [recordId, recordData] of candidateRecords.entries()) {\n allRecords.set(recordId, recordData);\n }\n\n // For each unique constraint, find conflicts\n for (const constraint of schema.resolvedUniqueConstraints) {\n const recordsByUniqueKey = new Map<string, string[]>();\n\n for (const [recordId, recordData] of allRecords.entries()) {\n if (recordIdsToDiscard.has(recordId)) continue;\n\n const uniqueKey = buildUniqueKey(recordData, constraint.fields);\n if (uniqueKey === null) continue;\n\n if (!recordsByUniqueKey.has(uniqueKey)) {\n recordsByUniqueKey.set(uniqueKey, []);\n }\n recordsByUniqueKey.get(uniqueKey)!.push(recordId);\n }\n\n // Find groups with duplicates\n for (const [uniqueKey, recordIds] of recordsByUniqueKey.entries()) {\n if (recordIds.length <= 1) continue;\n\n Logger.warn(\n `[${this.name}] CRDT conflict detected for unique constraint '${constraint.name}' ` +\n `on key '${uniqueKey.substring(0, 50)}${uniqueKey.length > 50 ? \"...\" : \"\"}': ` +\n `${recordIds.length} records found.`\n );\n\n // Sort by ID (ULIDs are lexicographically sortable by time)\n // Keep the one with the largest ID (most recent)\n recordIds.sort();\n const idToKeep = recordIds[recordIds.length - 1];\n recordIdsToKeep.add(idToKeep);\n\n // Mark all others for discard\n for (let i = 0; i < recordIds.length - 1; i++) {\n recordIdsToDiscard.add(recordIds[i]);\n }\n }\n }\n\n // Remove any IDs from discard set that should be kept\n for (const idToKeep of recordIdsToKeep) {\n recordIdsToDiscard.delete(idToKeep);\n }\n\n return recordIdsToDiscard;\n };\n\n documentYMap.observe(async (event: Y.YMapEvent<any>) => {\n Logger.verbose(\n `[${this.name}] Document YMap change detected for ${modelName}/${docId}:`,\n event\n );\n const currentDbInstance = BaseModel.dbInstance;\n if (!currentDbInstance) {\n Logger.error(\n `[${this.name}] DB instance not available for document YMap observer on ${modelName}/${docId}.`\n );\n return;\n }\n\n const isRemoteChange = !event.transaction.local;\n\n // Collect remote adds for batch conflict resolution\n const remoteAdds = new Map<\n string,\n { recordData: Y.Map<any> | Record<string, any>; itemData: Record<string, any> }\n >();\n const localAddsAndUpdates: Array<{\n key: string;\n action: \"add\" | \"update\";\n recordData: Y.Map<any> | Record<string, any>;\n itemData: Record<string, any>;\n }> = [];\n\n // First pass: collect all changes\n for (const [key, change] of event.changes.keys.entries()) {\n const recordData = documentYMap.get(key);\n\n if (change.action === \"add\" || change.action === \"update\") {\n if (!recordData || !key) continue;\n\n const itemData = extractItemData(key, recordData);\n if (!itemData) continue;\n\n // Set up observer on nested YMap if newly added\n if (change.action === \"add\" && recordData instanceof Y.Map) {\n Logger.verbose(\n `[${this.name}] Setting up observer on newly added nested YMap for record ${key} in document ${docId}`\n );\n (this as typeof BaseModel).setupNestedYMapObserverForDocument(\n key,\n recordData,\n docId,\n permissionHint\n );\n }\n\n if (isRemoteChange && change.action === \"add\") {\n // Defer remote adds for conflict resolution\n remoteAdds.set(key, { recordData, itemData });\n } else {\n // Local changes and updates can be processed immediately\n localAddsAndUpdates.push({ key, action: change.action, recordData, itemData });\n }\n } else if (change.action === \"delete\") {\n Logger.verbose(\n `[${this.name}] Deleting item from db (${modelName}/${docId}):`,\n key\n );\n try {\n await currentDbInstance.delete(modelName, key);\n } catch (error) {\n Logger.error(\n `[${this.name}] Error deleting item from db (${modelName}/${docId}):`,\n error,\n key\n );\n }\n }\n }\n\n // Process local adds and updates immediately (already validated by save())\n for (const { itemData } of localAddsAndUpdates) {\n try {\n Logger.verbose(\n `[${this.name}] Syncing local item to db from document ${docId} (${modelName}):`,\n itemData\n );\n await currentDbInstance.insert(modelName, {\n ...itemData,\n type: modelName,\n _meta_doc_id: docId,\n _meta_permission_hint: permissionHint,\n });\n } catch (error) {\n Logger.error(\n `[${this.name}] Error syncing local item to db from document ${docId} (${modelName}):`,\n error,\n itemData\n );\n }\n }\n\n // Process remote adds with conflict resolution\n if (remoteAdds.size > 0) {\n Logger.verbose(\n `[${this.name}] Processing ${remoteAdds.size} remote add(s) with conflict resolution for ${modelName}/${docId}`\n );\n\n // Build candidate map for conflict resolution\n const candidateRecords = new Map<string, Y.Map<any> | Record<string, any>>();\n for (const [key, { recordData }] of remoteAdds.entries()) {\n candidateRecords.set(key, recordData);\n }\n\n // Resolve conflicts - get IDs to discard\n const idsToDiscard = resolveConflictsForBatch(candidateRecords);\n\n if (idsToDiscard.size > 0) {\n Logger.info(\n `[${this.name}] Discarding ${idsToDiscard.size} duplicate record(s) from remote sync for ${modelName}/${docId}: ${Array.from(idsToDiscard).join(\", \")}`\n );\n }\n\n // Insert only survivors to SQLite\n for (const [key, { itemData }] of remoteAdds.entries()) {\n if (idsToDiscard.has(key)) {\n Logger.verbose(\n `[${this.name}] Skipping SQLite insert for discarded duplicate: ${key}`\n );\n continue;\n }\n\n try {\n Logger.verbose(\n `[${this.name}] Syncing remote item to db from document ${docId} (${modelName}):`,\n itemData\n );\n await currentDbInstance.insert(modelName, {\n ...itemData,\n type: modelName,\n _meta_doc_id: docId,\n _meta_permission_hint: permissionHint,\n });\n } catch (error) {\n Logger.error(\n `[${this.name}] Error syncing remote item to db from document ${docId} (${modelName}):`,\n error,\n itemData\n );\n }\n }\n\n // Remove discarded records from Y.Doc and clean up unique indexes\n if (idsToDiscard.size > 0) {\n yDoc.transact(() => {\n for (const idToDiscard of idsToDiscard) {\n const recordData = documentYMap.get(idToDiscard);\n if (!recordData) continue;\n\n // Remove from unique constraint indexes\n for (const constraint of schema.resolvedUniqueConstraints) {\n const uniqueKey = buildUniqueKey(recordData, constraint.fields);\n if (uniqueKey === null) continue;\n\n const constraintMapName = `_uniqueIdx_${modelName}_${constraint.name}`;\n const constraintMap = yDoc.getMap(constraintMapName);\n const currentIndexValue = constraintMap.get(uniqueKey);\n\n // Only remove from index if it points to the discarded record\n if (currentIndexValue === idToDiscard) {\n constraintMap.delete(uniqueKey);\n Logger.verbose(\n `[${this.name}] Removed discarded record ${idToDiscard} from unique index ${constraintMapName}`\n );\n }\n }\n\n // Remove from document YMap\n documentYMap.delete(idToDiscard);\n Logger.verbose(\n `[${this.name}] Removed discarded record ${idToDiscard} from Y.Doc`\n );\n }\n }, `conflict-resolution-${modelName}-${docId}`);\n\n // Update unique constraint indexes to point to the correct surviving records\n yDoc.transact(() => {\n for (const constraint of schema.resolvedUniqueConstraints) {\n const constraintMapName = `_uniqueIdx_${modelName}_${constraint.name}`;\n const constraintMap = yDoc.getMap(constraintMapName);\n\n for (const [recordId, recordData] of documentYMap.entries()) {\n if (!recordData) continue;\n\n const uniqueKey = buildUniqueKey(recordData, constraint.fields);\n if (uniqueKey === null) continue;\n\n const currentIndexValue = constraintMap.get(uniqueKey);\n if (currentIndexValue !== recordId) {\n constraintMap.set(uniqueKey, recordId);\n Logger.verbose(\n `[${this.name}] Updated unique index ${constraintMapName}['${uniqueKey.substring(0, 30)}...'] to point to ${recordId}`\n );\n }\n }\n }\n }, `update-indexes-${modelName}-${docId}`);\n }\n }\n\n Logger.verbose(\n `[${this.name}] Document YMap observation transaction for ${modelName}/${docId} completed.`\n );\n (this as typeof BaseModel).notifyListeners();\n });\n\n // Set up observers on existing nested YMaps in this document\n Logger.verbose(\n `[${this.name}] Setting up observers on existing nested YMaps for ${modelName}/${docId}...`\n );\n for (const [recordId, recordData] of documentYMap.entries()) {\n if (recordData instanceof Y.Map) {\n Logger.verbose(\n `[${this.name}] Setting up observer on existing nested YMap for record ${recordId} in document ${docId}`\n );\n (this as typeof BaseModel).setupNestedYMapObserverForDocument(\n recordId,\n recordData,\n docId,\n permissionHint\n );\n }\n }\n\n Logger.verbose(\n `[${this.name}] Model ${modelName} initialization complete for document ${docId}.`\n );\n }\n\n // New method to clean up data for a disconnected document\n static async cleanupDocumentData(docId: string) {\n const modelConstructor = this as typeof BaseModel;\n const schema = (modelConstructor as any).getSchema?.();\n if (!schema || !schema.options?.name) {\n Logger.warn(\n `[${this.name}] Cannot cleanup document data: Schema not found for model ${this.name}`\n );\n return;\n }\n\n const modelName = schema.options.name;\n Logger.verbose(\n `[${this.name}] Cleaning up data for document ${docId} from model ${modelName}...`\n );\n\n // Remove document connection info\n modelConstructor.connectedDocuments.delete(docId);\n modelConstructor.documentYMaps.delete(`${docId}_${modelName}`);\n\n Logger.verbose(\n `[${this.name}] Document ${docId} cleanup complete for model ${modelName}.`\n );\n }\n\n static subscribe(callback: () => void): () => void {\n const schema = (this as any).getSchema?.();\n const modelTypeKey = schema?.options?.name || this.name.toLowerCase();\n if (!BaseModel.listenersMap.has(modelTypeKey)) {\n BaseModel.listenersMap.set(modelTypeKey, new Set());\n }\n const listeners = BaseModel.listenersMap.get(modelTypeKey)!;\n listeners.add(callback);\n return () => {\n listeners.delete(callback);\n if (listeners.size === 0) {\n BaseModel.listenersMap.delete(modelTypeKey);\n }\n };\n }\n\n protected static notifyListeners() {\n const schema = (this as any).getSchema?.();\n const modelTypeKey = schema?.options?.name || this.name.toLowerCase();\n const listeners = BaseModel.listenersMap.get(modelTypeKey);\n if (!listeners) return;\n Logger.verbose(\n `[${this.name}] Notifying ${listeners.size} listeners for ${modelTypeKey}`\n );\n listeners.forEach((callback) => {\n try {\n callback();\n } catch (e) {\n Logger.error(\"Error in listener callback:\", e);\n }\n });\n }\n\n /**\n * Legacy migration method - no longer needed in the new multidoc architecture.\n * Data migration is now handled during document initialization.\n */\n static async migrateToNestedYMaps(): Promise<void> {\n const schema = (this as any).getSchema?.();\n if (!schema || !schema.options?.name) {\n throw new Error(\n `[${this.name}] Cannot migrate: Schema not properly initialized`\n );\n }\n\n const modelName = schema.options.name;\n Logger.verbose(\n `[${modelName}] Migration method called but not needed in multidoc architecture`\n );\n\n // In the new architecture, all data uses the multidoc structure from the start\n // Legacy data migration is handled during initializeForDocument if needed\n }\n\n /**\n * Utility to diff current instance data against YJS nested map data\n * Returns object with added, modified, and removed fields\n */\n protected _diffWithYjsData(): {\n added: Record<string, any>;\n modified: Record<string, any>;\n removed: string[];\n } {\n const debugEnabled = Logger.getLogLevel() >= LogLevel.DEBUG;\n Logger.debug(\n `[_diffWithYjsData] Starting diff calculation for ID: ${this.id}`\n );\n Logger.debug(\n `[_diffWithYjsData] hasUnsavedChanges: ${this.hasUnsavedChanges}`\n );\n Logger.debug(`[_diffWithYjsData] _localChanges:`, this._localChanges);\n\n // If no local changes, there's nothing to diff\n if (!this.hasUnsavedChanges) {\n Logger.debug(\n `[_diffWithYjsData] No unsaved changes, returning empty diff`\n );\n return { added: {}, modified: {}, removed: [] };\n }\n\n const modelConstructor = this.constructor as typeof BaseModel;\n const schema = (modelConstructor as any).getSchema();\n const modelName = schema.options.name;\n const docId = this._metaDocId;\n\n Logger.debug(`[_diffWithYjsData] modelName: ${modelName}, docId: ${docId}`);\n\n if (!docId) {\n throw new Error(\n `[${modelName}] Cannot diff with Y.js data: model instance has no document ID`\n );\n }\n\n // Get the document-specific Y.js map\n if (!modelConstructor.documentYMaps) {\n throw new Error(\n `[${modelName}] Multi-document system not initialized. documentYMaps is undefined.`\n );\n }\n\n const documentYMap = modelConstructor.documentYMaps.get(\n `${docId}_${modelName}`\n );\n Logger.debug(`[_diffWithYjsData] documentYMap found: ${!!documentYMap}`);\n\n if (!documentYMap) {\n throw new Error(\n `[${modelName}] YMap not found for document '${docId}'. This should not happen.`\n );\n }\n\n const recordYMap = documentYMap.get(this.id) as Y.Map<any> | undefined;\n Logger.debug(`[_diffWithYjsData] recordYMap found: ${!!recordYMap}`);\n\n const added: Record<string, any> = {};\n const modified: Record<string, any> = {};\n const removed: string[] = [];\n\n if (!recordYMap) {\n Logger.debug(\n `[_diffWithYjsData] No existing recordYMap, treating all local changes as 'added'`\n );\n // If no YJS record exists, all local changes are \"added\"\n if (this._localChanges) {\n for (const [key, value] of Object.entries(this._localChanges)) {\n Logger.debug(`[_diffWithYjsData] Adding field '${key}': ${value}`);\n if (value && value.type === \"stringset\") {\n // Convert StringSet changes to YMap format\n const stringSetData: Record<string, boolean> = {};\n for (const addition of value.additions) {\n stringSetData[addition] = true;\n }\n added[key] = stringSetData;\n } else {\n added[key] = value;\n }\n }\n }\n Logger.debug(`[_diffWithYjsData] Final diff for new record:`, {\n added,\n modified: {},\n removed: [],\n });\n return { added, modified, removed: [] };\n }\n\n Logger.debug(\n `[_diffWithYjsData] Existing record found, comparing local changes with Y.js data`\n );\n if (debugEnabled) {\n Logger.debug(\n `[_diffWithYjsData] Existing recordYMap keys:`,\n Array.from(recordYMap.keys())\n );\n }\n\n // Only diff the fields that have local changes against latest Yjs data\n if (this._localChanges) {\n for (const [key, localValue] of Object.entries(this._localChanges)) {\n Logger.debug(\n `[_diffWithYjsData] Processing field '${key}' with local value: ${localValue}`\n );\n\n if (localValue && localValue.type === \"stringset\") {\n // Handle StringSet changes\n const currentYjsData = recordYMap.get(key) || {};\n const newStringSetData: Record<string, boolean> = {\n ...currentYjsData,\n };\n\n // Apply additions\n for (const addition of localValue.additions) {\n newStringSetData[addition] = true;\n }\n\n // Apply removals\n for (const removal of localValue.removals) {\n delete newStringSetData[removal];\n }\n\n const yjsValue = recordYMap.get(key);\n if (yjsValue === undefined) {\n added[key] = newStringSetData;\n } else if (!this._deepEqual(yjsValue, newStringSetData)) {\n modified[key] = newStringSetData;\n }\n } else {\n // Handle regular field changes\n const yjsValue = recordYMap.get(key);\n Logger.debug(\n `[_diffWithYjsData] Field '${key}' - Y.js value: ${yjsValue}, local value: ${localValue}`\n );\n\n if (yjsValue === undefined) {\n // Field doesn't exist in Yjs, so it's added\n Logger.debug(\n `[_diffWithYjsData] Field '${key}' not in Y.js, adding to 'added'`\n );\n added[key] = localValue;\n } else if (!this._deepEqual(yjsValue, localValue)) {\n // Field exists but value is different, so it's modified\n Logger.debug(\n `[_diffWithYjsData] Field '${key}' different in Y.js, adding to 'modified'`\n );\n modified[key] = localValue;\n } else {\n Logger.debug(`[_diffWithYjsData] Field '${key}' unchanged`);\n }\n // If values are equal, no change needed\n }\n }\n }\n\n // Note: We don't check for \"removed\" fields in copy-on-write mode\n // because we only track what the user explicitly changed\n // If a field needs to be removed, it should be explicitly set to undefined\n\n Logger.debug(`[_diffWithYjsData] Final diff result:`, {\n added,\n modified,\n removed,\n });\n\n Logger.verbose(`[${modelConstructor.name}] Diff for ${this.id}:`, {\n added: Object.keys(added),\n modified: Object.keys(modified),\n removed,\n });\n\n return { added, modified, removed };\n }\n\n /**\n * Deep equality check for comparing field values\n */\n protected _deepEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (a == null || b == null) return a === b;\n if (typeof a !== typeof b) return false;\n if (typeof a !== \"object\") return false;\n\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n if (Array.isArray(a)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!this._deepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!this._deepEqual(a[key], b[key])) return false;\n }\n\n return true;\n }\n\n protected static _buildKeyFromValues(\n fields: string[],\n keyValues: any[],\n modelName: string,\n constraintName: string\n ): string | null {\n if (fields.length === 0) return null;\n if (fields.length !== keyValues.length) {\n Logger.warn(\n `[${modelName}] Constraint '${constraintName}': Mismatch between number of fields (${fields.length}) and values (${keyValues.length}). Cannot build key.`\n );\n return null;\n }\n if (keyValues.some((v) => v === null || v === undefined)) {\n return null;\n }\n if (fields.length === 1) {\n return String(keyValues[0]);\n } else {\n return JSON.stringify(keyValues);\n }\n }\n\n protected _buildUniqueKey(\n fields: string[],\n data: Record<string, any>,\n modelName: string,\n constraintName: string\n ): string | null {\n const values = fields.map((f) => data[f]);\n return (this.constructor as typeof BaseModel)._buildKeyFromValues(\n fields,\n values,\n modelName,\n constraintName\n );\n }\n\n async save(options?: SaveOptions) {\n // ---- START DEBUG LOG -----\n Logger.verbose(\n `[BaseModel.save()] Method entered. ID: ${this.id}, Model: ${\n (this.constructor as any).modelName || this.constructor.name\n }. Timestamp: ${Date.now()}`\n );\n Logger.verbose(`[BaseModel.save()] Current 'this' object:`, this);\n Logger.verbose(`[BaseModel.save()] 'this.id' specifically:`, this.id);\n Logger.verbose(`[BaseModel.save()] Options:`, options);\n // ---- END DEBUG LOG -----\n\n // Early exit if no changes to save\n if (!this._isDirty) {\n Logger.verbose(\n `[${this.constructor.name}] No changes to save for ${this.id}`\n );\n return;\n }\n\n const modelConstructor = this.constructor as typeof BaseModel;\n const schema = (modelConstructor as any).getSchema();\n\n if (\n !schema ||\n !schema.options ||\n !schema.fields ||\n !schema.resolvedUniqueConstraints\n ) {\n throw new Error(\n `Schema (or resolvedUniqueConstraints) not found or invalid for model ${modelConstructor.name} in save.`\n );\n }\n const modelName = schema.options.name;\n\n // Multi-document handling\n let targetDocId: string | null = null;\n let targetYDoc: Y.Doc | null = null;\n let targetYMap: Y.Map<any> | null = null;\n let permissionHint: DocumentPermissionHint | null = null;\n\n // Determine target document (with precedence and closed-doc rules)\n const explicitDocId = options?.targetDocument || null;\n const instanceRememberedDocId = this._metaDocId;\n const modelDefaultDocId = (\n this.constructor as typeof BaseModel\n ).getDocumentIdForModel(modelName);\n const globalDefaultDocId = (\n this.constructor as typeof BaseModel\n ).getGlobalDefaultDocumentId();\n\n const precedence: Array<{\n name: string;\n value: string | null | undefined;\n }> = [\n { name: \"explicit\", value: explicitDocId },\n { name: \"remembered\", value: instanceRememberedDocId },\n { name: \"modelDefault\", value: modelDefaultDocId },\n { name: \"globalDefault\", value: globalDefaultDocId },\n ];\n\n // Resolve in order; if a chosen docId is closed, error immediately without fallback\n for (const source of precedence) {\n if (source.value) {\n targetDocId = source.value;\n const documentInfo = (\n this.constructor as typeof BaseModel\n ).connectedDocuments.get(targetDocId);\n if (!documentInfo) {\n // If source is remembered, and it's closed, do not fall back\n // For any source producing a closed doc, throw with code\n throw new DocumentClosedError(\n `[${modelName}] Document '${targetDocId}' from '${source.name}' is not connected. Please connect it or provide an open document id.`\n );\n }\n // Found an open document; proceed\n break;\n }\n }\n\n if (!targetDocId) {\n throw new DocumentResolutionError(\n `[${modelName}] Unable to resolve a target document id (no explicit, no remembered, no model default, no global default).`\n );\n }\n\n // Validate target document exists and get its info\n const documentInfo = modelConstructor.connectedDocuments.get(targetDocId!);\n if (!documentInfo) {\n throw new DocumentClosedError(\n `[${modelName}] Document '${targetDocId}' is not connected. Please connect the document first.`\n );\n }\n\n targetYDoc = documentInfo.yDoc;\n permissionHint = documentInfo.permissionHint;\n targetYMap =\n modelConstructor.documentYMaps.get(`${targetDocId}_${modelName}`) || null;\n\n if (!targetYMap) {\n throw new Error(\n `[${modelName}] YMap not found for document '${targetDocId}'. This should not happen.`\n );\n }\n\n // Permission checking\n if (permissionHint === \"read\" && !options?.forceWrite) {\n throw new Error(\n `[${modelName}] Cannot save to document '${targetDocId}' with read-only permission. Use forceWrite option to override.`\n );\n }\n\n // Ensure we have a valid target document\n if (!targetYDoc) {\n throw new Error(\n `[${modelName}] Target Y.Doc not found for document '${targetDocId}'. Ensure document connection has completed.`\n );\n }\n\n const yDoc = targetYDoc;\n\n if (!this.id) {\n Logger.error(\n \"[BaseModel.save()] ID is undefined before saving! Instance dump:\",\n JSON.stringify(this)\n );\n throw new Error(\"Cannot save item without an id. Ensure id is set.\");\n }\n\n // Save-time validation\n this.validateBeforeSave();\n\n Logger.debug(`[${modelName}.save] About to get current JS state`);\n Logger.debug(`[${modelName}.save] _localChanges:`, this._localChanges);\n Logger.debug(`[${modelName}.save] _isDirty:`, this._isDirty);\n\n const dataToSave = this.getCurrentJSState();\n Logger.debug(\n `[${modelName}.save] getCurrentJSState() returned:`,\n dataToSave\n );\n\n await yDoc.transact(async () => {\n // Get or create nested YMap for this record\n if (!targetYMap) {\n throw new Error(\n `[${modelName}] Target YMap not found for save operation`\n );\n }\n let recordYMap = targetYMap.get(this.id) as Y.Map<any> | undefined;\n const isUpdate = !!recordYMap;\n\n Logger.debug(`[${modelName}.save] isUpdate: ${isUpdate}`);\n Logger.debug(`[${modelName}.save] recordYMap exists: ${!!recordYMap}`);\n\n if (!recordYMap) {\n recordYMap = new Y.Map();\n Logger.verbose(\n `[${modelName}] Creating new nested YMap for record ${\n this.id\n } in document ${targetDocId || \"legacy\"}`\n );\n // Add the new YMap to the document immediately to avoid Yjs warnings\n targetYMap.set(this.id, recordYMap);\n\n // Ensure id field is always present in nested YMap (required for database sync)\n recordYMap.set(\"id\", this.id);\n }\n\n // Set metadata for new records or when changing documents BEFORE diff calculation\n if (!isUpdate || (this._metaDocId && this._metaDocId !== targetDocId)) {\n this._metaDocId = targetDocId;\n this._metaPermissionHint = permissionHint;\n Logger.debug(`[${modelName}.save] Set _metaDocId to: ${targetDocId}`);\n }\n\n // Get old data for unique constraint handling (if updating)\n let oldData: Record<string, any> | null = null;\n if (isUpdate) {\n oldData = {};\n for (const [key, value] of recordYMap.entries()) {\n oldData[key] = value;\n }\n Logger.verbose(\n `[${modelName}] Retrieved old data for update:`,\n oldData\n );\n Logger.debug(`[${modelName}.save] oldData:`, oldData);\n }\n\n // Perform diff to identify what actually changed\n Logger.debug(`[${modelName}.save] About to calculate diff`);\n const diff = this._diffWithYjsData();\n Logger.debug(`[${modelName}.save] Diff result:`, diff);\n\n const hasChanges =\n Object.keys(diff.added).length > 0 ||\n Object.keys(diff.modified).length > 0 ||\n diff.removed.length > 0;\n\n Logger.debug(`[${modelName}.save] hasChanges: ${hasChanges}`);\n\n if (!hasChanges && isUpdate) {\n Logger.verbose(\n `[${modelName}] No changes detected for ${this.id}, skipping save`\n );\n Logger.debug(`[${modelName}.save] No changes detected, skipping save`);\n return;\n }\n\n // Check unique constraints before making any changes\n for (const constraint of schema.resolvedUniqueConstraints) {\n const newUniqueKey = this._buildUniqueKey(\n constraint.fields,\n dataToSave,\n modelName,\n constraint.name\n );\n Logger.verbose(\n `[${modelName}] Save Check (Item '${this.id}'): Constraint '${\n constraint.name\n }', Built Key: '${\n newUniqueKey ? newUniqueKey.substring(0, 50) : null\n }'`\n );\n if (newUniqueKey === null) {\n Logger.verbose(\n `[${modelName}] Save Check (Item '${this.id}'): Constraint '${constraint.name}' skipped due to null key.`\n );\n continue;\n }\n const constraintMapName = `_uniqueIdx_${modelName}_${constraint.name}`;\n const constraintMap = yDoc.getMap(constraintMapName);\n Logger.verbose(\n `[${modelName}] Save Check (Item '${\n this.id\n }'): GET from '${constraintMapName}' with Key '${newUniqueKey.substring(\n 0,\n 50\n )}'`\n );\n const existingRecordIdWithNewKey = constraintMap.get(newUniqueKey);\n Logger.verbose(\n `[${modelName}] Save Check (Item '${\n this.id\n }'): Found Existing ID: '${existingRecordIdWithNewKey}' for Key '${newUniqueKey.substring(\n 0,\n 50\n )}'`\n );\n if (\n existingRecordIdWithNewKey &&\n existingRecordIdWithNewKey !== this.id\n ) {\n throw new UniqueConstraintViolationError(\n `Unique constraint '${\n constraint.name\n }' violated for model '${modelName}' on fields [${constraint.fields.join(\n \", \"\n )}]. ` +\n `Attempted ID: ${\n this.id\n }. Value(s) starting with '${newUniqueKey.substring(\n 0,\n 50\n )}...' already exist for record ID ${existingRecordIdWithNewKey}.`,\n modelName,\n constraint.name,\n constraint.fields,\n this.id,\n existingRecordIdWithNewKey as string\n );\n }\n }\n\n // Update unique constraint indexes if this is an update with changed unique fields\n if (isUpdate && oldData) {\n for (const constraint of schema.resolvedUniqueConstraints) {\n const oldUniqueKey = this._buildUniqueKey(\n constraint.fields,\n oldData,\n modelName,\n constraint.name\n );\n const newUniqueKey = this._buildUniqueKey(\n constraint.fields,\n dataToSave,\n modelName,\n constraint.name\n );\n if (oldUniqueKey !== null && oldUniqueKey !== newUniqueKey) {\n const constraintMapName = `_uniqueIdx_${modelName}_${constraint.name}`;\n const constraintMap = yDoc.getMap(constraintMapName);\n Logger.verbose(\n `[${modelName}] Save (update): Deleting old unique key '${oldUniqueKey.substring(\n 0,\n 50\n )}...' for constraint '${constraint.name}', item ${this.id}`\n );\n constraintMap.delete(oldUniqueKey);\n }\n }\n }\n\n // Set new unique constraint keys\n for (const constraint of schema.resolvedUniqueConstraints) {\n const newUniqueKey = this._buildUniqueKey(\n constraint.fields,\n dataToSave,\n modelName,\n constraint.name\n );\n if (newUniqueKey !== null) {\n const constraintMapName = `_uniqueIdx_${modelName}_${constraint.name}`;\n const constraintMap = yDoc.getMap(constraintMapName);\n Logger.verbose(\n `[${modelName}] Save Set (Item '${\n this.id\n }'): SET into '${constraintMapName}' with Key '${newUniqueKey.substring(\n 0,\n 50\n )}', Value (Item ID) '${this.id}'`\n );\n constraintMap.set(newUniqueKey, this.id);\n }\n }\n\n // Apply field-level changes to the nested YMap\n Logger.debug(\n `[${modelName}.save] Applying field-level changes for ${this.id}`\n );\n Logger.debug(`[${modelName}.save] Diff result:`, diff);\n\n // Add new fields\n for (const [key, value] of Object.entries(diff.added)) {\n Logger.debug(`[${modelName}.save] Adding field '${key}':`, value);\n recordYMap.set(key, value);\n }\n\n // Modify existing fields\n for (const [key, value] of Object.entries(diff.modified)) {\n Logger.debug(`[${modelName}.save] Modifying field '${key}':`, value);\n recordYMap.set(key, value);\n }\n\n // Remove fields that no longer exist\n for (const key of diff.removed) {\n Logger.debug(`[${modelName}.save] Removing field '${key}'`);\n recordYMap.delete(key);\n }\n\n Logger.debug(\n `[${modelName}.save] After applying changes, recordYMap contents:`,\n Object.fromEntries(recordYMap.entries())\n );\n\n // Set up observer on new nested YMaps for field-level change detection\n if (!isUpdate) {\n if (targetDocId && permissionHint) {\n (\n modelConstructor as typeof BaseModel\n ).setupNestedYMapObserverForDocument(\n this.id,\n recordYMap,\n targetDocId,\n permissionHint\n );\n } else {\n (modelConstructor as typeof BaseModel).setupNestedYMapObserver(\n this.id,\n recordYMap\n );\n }\n } else {\n // For updates, ensure id field is present\n if (!recordYMap.has(\"id\")) {\n Logger.verbose(\n `[${modelName}] Adding id field '${this.id}' to existing nested YMap`\n );\n recordYMap.set(\"id\", this.id);\n }\n }\n\n Logger.verbose(`[${modelName}] Save completed for ${this.id}`);\n\n // Sync StringSet changes to database\n if (BaseModel.dbInstance) {\n Logger.verbose(\n `[${modelName}] Syncing StringSet changes to database for ${this.id}`\n );\n for (const [fieldName, localValue] of Object.entries(\n this._localChanges || {}\n )) {\n if (localValue && localValue.type === \"stringset\") {\n const fieldOptions = schema.fields.get(fieldName);\n if (fieldOptions?.type === \"stringset\") {\n // Insert additions\n if (localValue.additions.size > 0) {\n await BaseModel.dbInstance.insertStringSetValues(\n modelName,\n fieldName,\n this.id,\n Array.from(localValue.additions)\n );\n }\n\n // Remove deletions\n if (localValue.removals.size > 0) {\n await BaseModel.dbInstance.removeStringSetValues(\n modelName,\n fieldName,\n this.id,\n Array.from(localValue.removals)\n );\n }\n }\n }\n }\n Logger.verbose(\n `[${modelName}] StringSet database sync completed for ${this.id}`\n );\n }\n }, `save-record-${modelName}-${this.id}`);\n\n // Clear local changes after successful save\n Logger.debug(\n `[${modelName}.save] About to clear local changes for ${this.id}`\n );\n Logger.debug(\n `[${modelName}.save] _localChanges before clear:`,\n this._localChanges\n );\n this.clearLocalChanges();\n Logger.debug(\n `[${modelName}.save] _localChanges after clear:`,\n this._localChanges\n );\n if (Logger.getLogLevel() >= LogLevel.VERBOSE) {\n Logger.verbose(`[${modelName}.save] Successfully saved ${this.id}`);\n }\n }\n\n async delete() {\n const modelConstructor = this.constructor as typeof BaseModel;\n const schema = (modelConstructor as any).getSchema();\n if (!schema || !schema.options || !schema.resolvedUniqueConstraints) {\n throw new Error(\n `Schema (or resolvedUniqueConstraints) not found or invalid for model ${modelConstructor.name} in delete.`\n );\n }\n const modelName = schema.options.name;\n if (!this.id) {\n throw new Error(\"Cannot delete item without an id.\");\n }\n\n // Multi-document handling\n let sourceYDoc: Y.Doc | null = null;\n let sourceYMap: Y.Map<any> | null = null;\n let docId: string | undefined = undefined;\n\n // Get document info using _metaDocId only\n docId = this._metaDocId ?? undefined;\n const documentInfo = docId\n ? modelConstructor.connectedDocuments.get(docId)\n : undefined;\n if (!documentInfo) {\n throw new Error(\n `[${modelName}] Document '${docId}' is not connected. Cannot delete from disconnected document.`\n );\n }\n\n sourceYDoc = documentInfo.yDoc;\n sourceYMap =\n modelConstructor.documentYMaps.get(`${docId as string}_${modelName}`) ||\n null;\n\n if (!sourceYMap) {\n throw new Error(\n `[${modelName}] YMap not found for document '${docId}'. This should not happen.`\n );\n }\n\n const recordYMap = sourceYMap.get(this.id) as Y.Map<any> | undefined;\n if (!recordYMap) {\n Logger.warn(\n `[${modelName}] Delete: Item ${this.id} not found in YMap${\n docId ? ` for document ${docId}` : \"\"\n }. Cannot remove from unique constraint maps. Attempting main map deletion only.`\n );\n sourceYDoc.transact(() => {\n sourceYMap!.delete(this.id);\n }, `delete-ghost-record-${modelName}-${this.id}`);\n return;\n }\n\n // Convert nested YMap to plain object for unique constraint handling\n const dataToDelete: Record<string, any> = {};\n for (const [key, value] of recordYMap.entries()) {\n dataToDelete[key] = value;\n }\n\n await sourceYDoc.transact(async () => {\n // Remove from unique constraint maps\n for (const constraint of schema.resolvedUniqueConstraints) {\n const uniqueKey = this._buildUniqueKey(\n constraint.fields,\n dataToDelete,\n modelName,\n constraint.name\n );\n if (uniqueKey !== null) {\n const constraintMapName = `_uniqueIdx_${modelName}_${constraint.name}`;\n const constraintMap = sourceYDoc!.getMap(constraintMapName);\n Logger.verbose(\n `[${modelName}] Delete: Removing unique key '${uniqueKey.substring(\n 0,\n 50\n )}...' for constraint '${constraint.name}', item ${this.id}${\n docId ? ` from document ${docId}` : \"\"\n }`\n );\n constraintMap.delete(uniqueKey);\n }\n }\n Logger.verbose(\n `[${modelName}] Deleting nested YMap from main YMap: ${this.id}${\n docId ? ` from document ${docId}` : \"\"\n }`\n );\n sourceYMap!.delete(this.id);\n }, `delete-record-${modelName}-${this.id}`);\n }\n\n // Get current state combining local changes with Yjs data\n protected getCurrentJSState(): Record<string, any> {\n const schema = (this.constructor as any).getSchema();\n if (!schema || !schema.fields) {\n throw new Error(\n `Schema not found or invalid for model ${this.constructor.name} in getCurrentJSState.`\n );\n }\n const result: any = {};\n\n // Debug logging for getCurrentJSState\n Logger.debug(\n `[getCurrentJSState] Starting for model ${this.constructor.name}, ID: ${this.id}`\n );\n\n // Use getValue to get current state (local changes + Yjs)\n for (const fieldKey of schema.fields.keys()) {\n const value = this.getValue(fieldKey);\n if (value !== undefined) {\n const fieldOptions = schema.fields.get(fieldKey);\n if (fieldOptions?.type === \"stringset\" && value instanceof StringSet) {\n result[fieldKey] = value.toArray();\n } else {\n result[fieldKey] = value;\n }\n }\n }\n\n // Ensure required fields\n if (schema.options?.name) {\n result.type = schema.options.name;\n }\n if (this.id !== undefined) {\n result.id = this.id;\n }\n\n // Add metadata fields for multi-document support\n if (this._metaDocId !== null) {\n result._meta_doc_id = this._metaDocId;\n }\n if (this._metaPermissionHint !== null) {\n result._meta_permission_hint = this._metaPermissionHint;\n }\n\n return result;\n }\n\n // Keep toJSON for backward compatibility, but delegate to getCurrentJSState\n protected toJSON(): Record<string, any> {\n return this.getCurrentJSState();\n }\n\n static async find<T extends BaseModel>(\n this: new (...args: any[]) => T,\n id: string\n ): Promise<T | null> {\n const schema = (this as any).getSchema?.();\n if (!schema || !schema.options.name)\n throw new Error(\"Model not properly initialized for find\");\n\n const modelName = schema.options.name;\n Logger.verbose(`[${modelName}] Finding item by id:`, id);\n\n const modelConstructor = this as unknown as typeof BaseModel;\n const debugEnabled = Logger.getLogLevel() >= LogLevel.DEBUG;\n\n Logger.debug(`[${modelName}.find] Using multi-document system`);\n if (debugEnabled) {\n Logger.debug(\n `[${modelName}.find] Connected documents: [${Array.from(\n modelConstructor.connectedDocuments.keys()\n ).join(\", \")}]`\n );\n }\n\n // Search across all connected documents\n for (const [docId] of modelConstructor.connectedDocuments) {\n Logger.debug(`[${modelName}.find] Searching in document: ${docId}`);\n const documentYMapKey = `${docId}_${modelName}`;\n Logger.debug(\n `[${modelName}.find] Looking for documentYMap with key: ${documentYMapKey}`\n );\n\n const documentYMap = modelConstructor.documentYMaps.get(documentYMapKey);\n Logger.debug(`[${modelName}.find] DocumentYMap found: ${!!documentYMap}`);\n\n if (documentYMap) {\n if (debugEnabled) {\n Logger.debug(\n `[${modelName}.find] DocumentYMap keys: [${Array.from(\n documentYMap.keys()\n ).join(\", \")}]`\n );\n }\n const recordYMap = documentYMap.get(id) as Y.Map<any> | undefined;\n Logger.debug(\n `[${modelName}.find] RecordYMap found for ID '${id}': ${!!recordYMap}`\n );\n\n if (recordYMap) {\n if (debugEnabled) {\n Logger.debug(\n `[${modelName}.find] RecordYMap keys: [${Array.from(\n recordYMap.keys()\n ).join(\", \")}]`\n );\n }\n\n // Create instance with the id - constructor will handle loading logic\n Logger.debug(`[${modelName}.find] Creating instance with ID: ${id}`);\n const instance = new this({ id });\n\n // Set the document metadata since we found it in this document\n Logger.debug(`[${modelName}.find] Setting _metaDocId to: ${docId}`);\n (instance as any)._metaDocId = docId;\n const connectedDoc = modelConstructor.connectedDocuments.get(docId);\n if (connectedDoc) {\n Logger.debug(\n `[${modelName}.find] Setting _metaPermissionHint to: ${connectedDoc.permissionHint}`\n );\n (instance as any)._metaPermissionHint = connectedDoc.permissionHint;\n }\n\n Logger.debug(\n `[${modelName}.find] Returning instance with _metaDocId: ${\n (instance as any)._metaDocId\n }`\n );\n return instance;\n }\n }\n }\n\n return null; // Record not found in any connected document\n }\n\n /**\n * Document-style query API - returns paginated results\n */\n static async query<\n T extends BaseModel,\n P extends ProjectionSpec | undefined = undefined\n >(\n this: new (...args: any[]) => T,\n filter: DocumentFilter = {},\n options?: QueryOptions & { projection?: P }\n ): Promise<PaginatedResult<QueryResult<T, P>>> {\n if (!BaseModel.dbInstance) {\n const modelNameForError =\n (this as any).modelName || (this as any).name || \"BaseModel\";\n throw new Error(\n `[${modelNameForError}] Database not initialized for query. Connect at least one document via initJsBao(...).connectDocument or call initializeForDocument(yDoc, db, docId, permissionHint) before running queries.`\n );\n }\n\n const schema = (this as any).getSchema?.();\n if (!schema || !schema.options?.name) {\n throw new Error(\"Model not properly initialized for query\");\n }\n\n const modelName = schema.options.name;\n Logger.verbose(`[${modelName}] Executing query:`, { filter, options });\n\n // Create translator and translate query\n // When includes are present, defer projection to post-processing so that\n // FK fields needed by include resolution are available in the SQL results.\n const hasIncludes = options?.include && options.include.length > 0;\n const translatorOptions =\n hasIncludes && options?.projection\n ? { ...options, projection: undefined }\n : options;\n const translator = new DocumentQueryTranslator(modelName, schema.fields);\n const translatedQuery = translator.translateFind(filter, translatorOptions);\n\n Logger.verbose(`[${modelName}] Translated SQL:`, translatedQuery.sql);\n Logger.verbose(`[${modelName}] SQL params:`, translatedQuery.params);\n\n // Execute query\n const results = await BaseModel.dbInstance.query(\n translatedQuery.sql,\n translatedQuery.params\n );\n\n Logger.verbose(`[${modelName}] Query returned ${results.length} results`);\n\n // Resolve includes (related data loading)\n if (options?.include && options.include.length > 0) {\n const { IncludeResolver } = await import(\"../query/IncludeResolver.js\");\n const resolver = new IncludeResolver(BaseModel.dbInstance!);\n await resolver.resolve(results, options.include, 0, modelName);\n }\n\n // Determine if there are more results for pagination\n const requestedLimit = options?.limit;\n const hasMore = CursorManager.hasMoreResults(\n requestedLimit,\n results.length\n );\n\n // Determine if this is the first page (no cursor was used to get here)\n const isFirstPage = !options?.uniqueStartKey;\n\n // Generate cursors for pagination\n const cursors = CursorManager.generateResultCursors(\n results,\n translatedQuery.sortFields,\n options?.direction || 1,\n hasMore,\n isFirstPage\n );\n\n // Transform results based on projection\n let transformedData: any[];\n\n if (options?.projection && Object.keys(options.projection).length > 0) {\n // Return projected plain objects\n transformedData = results.map((row: any) => {\n const projected: any = {};\n\n // Always include id field for model instances\n if (row.hasOwnProperty(\"id\")) {\n projected.id = row.id;\n }\n\n for (const [field, include] of Object.entries(options.projection!)) {\n if (include === 1 && row.hasOwnProperty(field)) {\n projected[field] = row[field];\n }\n }\n if (row._related) projected._related = row._related;\n return projected;\n });\n } else {\n // Return model instances\n const modelConstructor = this as unknown as typeof BaseModel;\n\n // Multi-document mode: search across all connected documents\n const documentYMaps = modelConstructor.documentYMaps;\n const connectedDocuments = modelConstructor.connectedDocuments;\n\n transformedData = results\n .map((data: any) => {\n // Search for the record across all connected documents\n let foundRecordYMap: Y.Map<any> | undefined;\n let foundDocId: string | undefined;\n\n for (const docId of connectedDocuments.keys()) {\n const documentYMapKey = `${docId}_${modelName}`;\n const documentYMap = documentYMaps.get(documentYMapKey);\n\n if (documentYMap) {\n const recordYMap = documentYMap.get(data.id) as\n | Y.Map<any>\n | undefined;\n if (recordYMap) {\n foundRecordYMap = recordYMap;\n foundDocId = docId;\n break;\n }\n }\n }\n\n if (!foundRecordYMap || !foundDocId) {\n Logger.warn(\n `[${modelName}] Query result item ID ${data.id} not found in any connected document YMap. DB might be out of sync.`\n );\n return null;\n }\n\n // Create instance with the id and set document metadata\n const instance = new this({ id: data.id });\n if (\n instance &&\n typeof instance === \"object\" &&\n instance instanceof BaseModel\n ) {\n (instance as any)._metaDocId = foundDocId;\n (instance as any)._metaPermissionHint = \"read-write\"; // Default permission\n if (data._related) (instance as any)._related = data._related;\n }\n return instance;\n })\n .filter(Boolean) as T[];\n }\n\n return {\n data: transformedData,\n nextCursor: cursors.nextCursor,\n prevCursor: cursors.prevCursor,\n hasMore,\n };\n }\n\n /**\n * Main aggregation API - performs grouping, faceting, and statistical operations\n * @param options Aggregation configuration with groupBy, operations, filter, limit, and sort\n * @returns Nested object structure with aggregation results\n *\n * @example\n * // Simple facet count\n * const tagCounts = await Model.aggregate({\n * groupBy: ['tags'],\n * operations: [{ type: 'count' }]\n * });\n * // Result: { red: 15, blue: 8, green: 12 }\n *\n * @example\n * // Multi-dimensional grouping with multiple operations\n * const categoryStats = await Model.aggregate({\n * groupBy: ['category', 'status'],\n * operations: [\n * { type: 'count' },\n * { type: 'sum', field: 'amount' },\n * { type: 'avg', field: 'score' }\n * ],\n * filter: { active: true },\n * sort: { field: 'count', direction: 'desc' },\n * limit: 10\n * });\n *\n * @example\n * // StringSet membership grouping\n * const urgentCounts = await Model.aggregate({\n * groupBy: [{ field: 'tags', contains: 'urgent' }],\n * operations: [{ type: 'count' }]\n * });\n * // Result: { true: 5, false: 23 }\n */\n static async aggregate<T extends BaseModel>(\n this: new (...args: any[]) => T,\n options: AggregationOptions\n ): Promise<AggregationResult> {\n if (!BaseModel.dbInstance) {\n const modelNameForError =\n (this as any).modelName || (this as any).name || \"BaseModel\";\n throw new Error(\n `[${modelNameForError}] Database not initialized for aggregation. Connect at least one document via initJsBao(...).connectDocument or call initializeForDocument(yDoc, db, docId, permissionHint) before running aggregations.`\n );\n }\n\n const schema = (this as any).getSchema?.();\n if (!schema || !schema.options?.name) {\n throw new Error(\"Model not properly initialized for aggregation\");\n }\n\n const modelName = schema.options.name;\n Logger.verbose(`[${modelName}] Executing structured aggregation:`, options);\n\n // Validate operations\n for (const operation of options.operations) {\n if (operation.type !== \"count\" && !operation.field) {\n throw new Error(\n `Operation '${operation.type}' requires a field parameter`\n );\n }\n if (operation.type === \"count\" && operation.field) {\n throw new Error(`Operation 'count' should not have a field parameter`);\n }\n }\n\n // Validate groupBy fields\n for (const groupBy of options.groupBy) {\n if (typeof groupBy === \"string\") {\n if (!schema.fields.has(groupBy)) {\n throw new Error(`Unknown field '${groupBy}' in groupBy`);\n }\n } else {\n if (!schema.fields.has(groupBy.field)) {\n throw new Error(\n `Unknown field '${groupBy.field}' in StringSet membership groupBy`\n );\n }\n const fieldOptions = schema.fields.get(groupBy.field);\n if (fieldOptions?.type !== \"stringset\") {\n throw new Error(\n `Field '${groupBy.field}' is not a StringSet field but used in membership groupBy`\n );\n }\n }\n }\n\n const aggregationQuery = (this as any).buildAggregationQuery(\n options,\n schema,\n modelName\n );\n\n Logger.verbose(\n `[${modelName}] Generated aggregation SQL:`,\n aggregationQuery.sql\n );\n Logger.verbose(\n `[${modelName}] Aggregation params:`,\n aggregationQuery.params\n );\n\n const results = await BaseModel.dbInstance.query(\n aggregationQuery.sql,\n aggregationQuery.params\n );\n\n Logger.verbose(\n `[${modelName}] Aggregation returned ${results.length} results`\n );\n\n // Process results into nested structure\n const processedResult = (this as any).processAggregationResults(\n results,\n options,\n aggregationQuery.aliasMetadata\n );\n\n if (\n aggregationQuery.aliasMetadata &&\n aggregationQuery.aliasMetadata.length > 0\n ) {\n const debugMap: Record<string, AggregationAliasDebugInfo> = {};\n for (const detail of aggregationQuery.aliasMetadata) {\n debugMap[detail.alias] = {\n field: detail.field,\n contains: detail.contains,\n originalAlias: detail.originalAlias,\n };\n }\n\n Object.defineProperty(processedResult, \"aliasDebugMap\", {\n value: debugMap,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n }\n\n return processedResult;\n }\n\n /**\n * Build SQL query for structured aggregation\n */\n protected static buildAggregationQuery(\n options: AggregationOptions,\n schema: any,\n modelName: string\n ): AggregationQueryPlan {\n const translator = new DocumentQueryTranslator(modelName, schema.fields);\n\n // Separate regular fields from StringSet operations\n const regularGroupBy: string[] = [];\n const stringSetFacets: string[] = [];\n const stringSetMemberships: StringSetMembership[] = [];\n\n for (const groupBy of options.groupBy) {\n if (typeof groupBy === \"string\") {\n const fieldOptions = schema.fields.get(groupBy);\n if (fieldOptions?.type === \"stringset\") {\n stringSetFacets.push(groupBy);\n } else {\n regularGroupBy.push(groupBy);\n }\n } else {\n stringSetMemberships.push(groupBy);\n }\n }\n\n // Handle different aggregation scenarios\n if (\n stringSetFacets.length > 0 &&\n regularGroupBy.length === 0 &&\n stringSetMemberships.length === 0\n ) {\n // Pure StringSet facet aggregation\n return this.buildStringSetFacetQuery(\n stringSetFacets,\n options,\n translator,\n modelName\n );\n } else if (stringSetMemberships.length > 0 || regularGroupBy.length > 0) {\n // Regular field aggregation (with possible StringSet membership)\n return this.buildRegularAggregationQuery(\n regularGroupBy,\n stringSetMemberships,\n options,\n translator,\n modelName\n );\n } else {\n throw new Error(\"Invalid aggregation configuration\");\n }\n }\n\n /**\n * Get the proper database table name (should match database engine naming)\n */\n protected static getDatabaseTableName(modelName: string): string {\n // This should match the naming convention used by DatabaseEngine.getTableName()\n return `model_${modelName.toLowerCase()}`;\n }\n\n /**\n * Get the proper database junction table name for StringSet fields\n */\n protected static getDatabaseJunctionTableName(\n modelName: string,\n fieldName: string\n ): string {\n // This should match the naming convention used by DatabaseEngine for junction tables\n return `${this.getDatabaseTableName(modelName)}_${fieldName}`;\n }\n\n private static buildMembershipKey(field: string, contains: string): string {\n return `${field}::${contains}`;\n }\n\n /**\n * Build query for StringSet facet counts\n */\n protected static buildStringSetFacetQuery(\n stringSetFields: string[],\n options: AggregationOptions,\n translator: DocumentQueryTranslator,\n modelName: string\n ): AggregationQueryPlan {\n if (stringSetFields.length > 1) {\n throw new Error(\n \"Multiple StringSet facet fields not supported in single aggregation\"\n );\n }\n\n const fieldName = stringSetFields[0];\n const junctionTable = this.getDatabaseJunctionTableName(\n modelName,\n fieldName\n );\n const quotedJunctionTable = quoteIdentifier(junctionTable);\n const mainTable = this.getDatabaseTableName(modelName);\n const quotedMainTable = quoteIdentifier(mainTable);\n const recordIdColumn = `${modelName.toLowerCase()}_id`;\n const quotedRecordIdColumn = quoteIdentifier(recordIdColumn);\n const quotedValueColumn = quoteIdentifier(\"value\");\n const groupKeyAlias = quoteIdentifier(\"group_key\");\n\n // Base query for StringSet facets\n let sql = `\n SELECT \n ${quotedJunctionTable}.${quotedValueColumn} AS ${groupKeyAlias},\n COUNT(*) as count\n FROM ${quotedJunctionTable}\n INNER JOIN ${quotedMainTable} ON ${quotedJunctionTable}.${quotedRecordIdColumn} = ${quotedMainTable}.${quoteIdentifier(\n \"id\"\n )}\n `;\n\n let params: any[] = [];\n\n // Add WHERE clause for filtering\n if (options.filter && Object.keys(options.filter).length > 0) {\n const whereClause = translator.translateFind(options.filter, {});\n // Extract the WHERE condition from the full query\n const whereMatch = whereClause.sql.match(\n /WHERE\\s+(.+?)(?:\\s+ORDER\\s+BY|\\s+LIMIT|\\s*$)/i\n );\n if (whereMatch && whereMatch[1]) {\n sql += ` WHERE ${whereMatch[1]}`;\n params = whereClause.params;\n }\n }\n\n sql += ` GROUP BY ${quotedJunctionTable}.${quotedValueColumn}`;\n\n // Add sorting\n if (options.sort) {\n const sortField =\n options.sort.field === \"count\"\n ? \"COUNT(*)\"\n : quoteIdentifier(options.sort.field);\n const sqlDirection = options.sort.direction === 1 ? \"ASC\" : \"DESC\";\n sql += ` ORDER BY ${sortField} ${sqlDirection}`;\n }\n\n // Add limit\n if (options.limit) {\n sql += ` LIMIT ${options.limit}`;\n }\n\n return { sql, params };\n }\n\n /**\n * Build query for regular field aggregation\n */\n protected static buildRegularAggregationQuery(\n regularGroupBy: string[],\n stringSetMemberships: StringSetMembership[],\n options: AggregationOptions,\n translator: DocumentQueryTranslator,\n modelName: string\n ): AggregationQueryPlan {\n const mainTable = this.getDatabaseTableName(modelName);\n const quotedMainTable = quoteIdentifier(mainTable);\n const recordIdColumn = `${modelName.toLowerCase()}_id`;\n const quotedRecordIdColumn = quoteIdentifier(recordIdColumn);\n const quotedIdColumn = quoteIdentifier(\"id\");\n const quotedValueColumn = quoteIdentifier(\"value\");\n\n // Build SELECT clause with group by fields and aggregation operations\n const selectParts: string[] = [];\n const aliasMetadata: AggregationAliasDetail[] = [];\n const usedAliases = new Set<string>();\n\n // Add regular group by fields\n for (const field of regularGroupBy) {\n selectParts.push(`${quotedMainTable}.${quoteIdentifier(field)}`);\n }\n\n // Add StringSet membership fields\n for (const membership of stringSetMemberships) {\n const membershipKey = this.buildMembershipKey(\n membership.field,\n membership.contains\n );\n const originalAlias = `has_${membership.field}_${membership.contains}`;\n let aliasPrefix = `has_${membership.field}`;\n let alias = buildSafeAlias(aliasPrefix, membershipKey);\n let counter = 1;\n while (usedAliases.has(alias)) {\n alias = buildSafeAlias(`${aliasPrefix}_${counter++}`, membershipKey);\n }\n usedAliases.add(alias);\n const quotedAlias = quoteIdentifier(alias);\n selectParts.push(\n `CASE WHEN ${quotedAlias}.${quotedRecordIdColumn} IS NOT NULL THEN 'true' ELSE 'false' END AS ${quotedAlias}`\n );\n aliasMetadata.push({\n alias,\n membershipKey,\n field: membership.field,\n contains: membership.contains,\n originalAlias,\n });\n }\n\n // Add aggregation operations\n for (const operation of options.operations) {\n switch (operation.type) {\n case \"count\":\n selectParts.push(\"COUNT(*) AS count\");\n break;\n case \"sum\": {\n const fieldName = operation.field!;\n selectParts.push(\n `SUM(${quotedMainTable}.${quoteIdentifier(\n fieldName\n )}) AS ${quoteIdentifier(`sum_${fieldName}`)}`\n );\n break;\n }\n case \"avg\": {\n const fieldName = operation.field!;\n selectParts.push(\n `AVG(${quotedMainTable}.${quoteIdentifier(\n fieldName\n )}) AS ${quoteIdentifier(`avg_${fieldName}`)}`\n );\n break;\n }\n case \"min\": {\n const fieldName = operation.field!;\n selectParts.push(\n `MIN(${quotedMainTable}.${quoteIdentifier(\n fieldName\n )}) AS ${quoteIdentifier(`min_${fieldName}`)}`\n );\n break;\n }\n case \"max\": {\n const fieldName = operation.field!;\n selectParts.push(\n `MAX(${quotedMainTable}.${quoteIdentifier(\n fieldName\n )}) AS ${quoteIdentifier(`max_${fieldName}`)}`\n );\n break;\n }\n }\n }\n\n let sql = `SELECT ${selectParts.join(\", \")} FROM ${quotedMainTable}`;\n\n // Add LEFT JOINs for StringSet membership checks\n aliasMetadata.forEach((detail, index) => {\n const membership = stringSetMemberships[index];\n const junctionTable = this.getDatabaseJunctionTableName(\n modelName,\n membership.field\n );\n const quotedJunctionTable = quoteIdentifier(junctionTable);\n const quotedAlias = quoteIdentifier(detail.alias);\n sql += ` LEFT JOIN ${quotedJunctionTable} AS ${quotedAlias} ON ${quotedAlias}.${quotedRecordIdColumn} = ${quotedMainTable}.${quotedIdColumn} AND ${quotedAlias}.${quotedValueColumn} = ?`;\n });\n\n let params: any[] = [];\n\n // Add parameters for StringSet membership values\n for (const membership of stringSetMemberships) {\n params.push(membership.contains);\n }\n\n // Add WHERE clause for filtering\n if (options.filter && Object.keys(options.filter).length > 0) {\n const whereClause = translator.translateFind(options.filter, {});\n // Extract the WHERE condition from the full query\n const whereMatch = whereClause.sql.match(\n /WHERE\\s+(.+?)(?:\\s+ORDER\\s+BY|\\s+LIMIT|\\s*$)/i\n );\n if (whereMatch && whereMatch[1]) {\n sql += ` WHERE ${whereMatch[1]}`;\n params = params.concat(whereClause.params);\n }\n }\n\n // Add GROUP BY clause\n const groupByParts: string[] = [];\n for (const field of regularGroupBy) {\n groupByParts.push(`${quotedMainTable}.${quoteIdentifier(field)}`);\n }\n aliasMetadata.forEach((detail) => {\n const quotedAlias = quoteIdentifier(detail.alias);\n groupByParts.push(`${quotedAlias}.${quotedRecordIdColumn}`);\n });\n\n if (groupByParts.length > 0) {\n sql += ` GROUP BY ${groupByParts.join(\", \")}`;\n }\n\n // Add sorting\n if (options.sort) {\n const requestedField = options.sort.field;\n let sortExpression: string;\n if (requestedField === \"count\") {\n sortExpression = \"COUNT(*)\";\n } else {\n const membershipDetail = aliasMetadata.find(\n (detail) =>\n detail.alias === requestedField ||\n detail.originalAlias === requestedField ||\n detail.membershipKey === requestedField\n );\n if (membershipDetail) {\n sortExpression = quoteIdentifier(membershipDetail.alias);\n } else if (\n requestedField.startsWith(\"sum_\") ||\n requestedField.startsWith(\"avg_\") ||\n requestedField.startsWith(\"min_\") ||\n requestedField.startsWith(\"max_\")\n ) {\n sortExpression = quoteIdentifier(requestedField);\n } else {\n sortExpression = `${quotedMainTable}.${quoteIdentifier(\n requestedField\n )}`;\n }\n }\n const sqlDirection = options.sort.direction === 1 ? \"ASC\" : \"DESC\";\n sql += ` ORDER BY ${sortExpression} ${sqlDirection}`;\n }\n\n // Add limit\n if (options.limit) {\n sql += ` LIMIT ${options.limit}`;\n }\n\n return { sql, params, aliasMetadata };\n }\n\n /**\n * Process aggregation results into nested structure\n */\n protected static processAggregationResults(\n results: any[],\n options: AggregationOptions,\n aliasMetadata?: AggregationAliasDetail[]\n ): AggregationResult {\n if (results.length === 0) {\n return {};\n }\n\n const membershipAliasLookup = new Map<string, string>();\n if (aliasMetadata) {\n for (const detail of aliasMetadata) {\n membershipAliasLookup.set(detail.membershipKey, detail.alias);\n membershipAliasLookup.set(detail.originalAlias, detail.alias);\n }\n }\n\n // For simple StringSet facets, return flat object\n if (\n options.groupBy.length === 1 &&\n typeof options.groupBy[0] === \"string\" &&\n results[0].hasOwnProperty(\"group_key\")\n ) {\n const facetResult: Record<string, any> = {};\n for (const row of results) {\n const key = row.group_key;\n facetResult[key] = {};\n\n // Add operation results\n for (const operation of options.operations) {\n if (operation.type === \"count\") {\n facetResult[key].count = row.count;\n } else {\n const operationKey = `${operation.type}_${operation.field}`;\n facetResult[key][operationKey] = row[operationKey];\n }\n }\n\n // If only count operation, flatten to just the count value\n if (\n options.operations.length === 1 &&\n options.operations[0].type === \"count\"\n ) {\n facetResult[key] = row.count;\n }\n }\n return facetResult;\n }\n\n // For multi-dimensional grouping, build nested structure\n const nestedResult: Record<string, any> = {};\n\n for (const row of results) {\n let current = nestedResult;\n\n // Build nested path based on group by fields\n for (let i = 0; i < options.groupBy.length; i++) {\n const groupBy = options.groupBy[i];\n let key: string;\n\n if (typeof groupBy === \"string\") {\n key = String(row[groupBy]);\n } else {\n // StringSet membership\n const membershipKey = this.buildMembershipKey(\n groupBy.field,\n groupBy.contains\n );\n const resolvedAlias =\n membershipAliasLookup.get(membershipKey) ||\n membershipAliasLookup.get(\n `has_${groupBy.field}_${groupBy.contains}`\n );\n if (!resolvedAlias) {\n throw new Error(\n `Missing alias metadata for StringSet membership ${groupBy.field}:${groupBy.contains}`\n );\n }\n key = row[resolvedAlias];\n }\n\n if (i === options.groupBy.length - 1) {\n // Last level - add operation results\n current[key] = {};\n for (const operation of options.operations) {\n if (operation.type === \"count\") {\n current[key].count = row.count;\n } else {\n const operationKey = `${operation.type}_${operation.field}`;\n current[key][operationKey] = row[operationKey];\n }\n }\n\n // If only count operation, flatten to just the count value\n if (\n options.operations.length === 1 &&\n options.operations[0].type === \"count\"\n ) {\n current[key] = row.count;\n }\n } else {\n // Intermediate level - create nested object\n if (!current[key]) {\n current[key] = {};\n }\n current = current[key];\n }\n }\n }\n\n return nestedResult;\n }\n\n /**\n * Document-style query API - returns single result or null\n */\n static async queryOne<\n T extends BaseModel,\n P extends ProjectionSpec | undefined = undefined\n >(\n this: new (...args: any[]) => T,\n filter: DocumentFilter = {},\n options?: Omit<QueryOptions, \"limit\" | \"uniqueStartKey\" | \"direction\"> & {\n projection?: P;\n }\n ): Promise<QueryResult<T, P> | null> {\n // Use query with limit 1 and extract first result\n const result = await (this as any).query(filter, { ...options, limit: 1 });\n\n return result.data.length > 0 ? result.data[0] : null;\n }\n\n /**\n * Document-style count API\n */\n static async count(\n this: new (...args: any[]) => any,\n filter: DocumentFilter = {},\n options?: Pick<QueryOptions, \"documents\">\n ): Promise<number> {\n if (!BaseModel.dbInstance) {\n const modelNameForError =\n (this as any).modelName || (this as any).name || \"BaseModel\";\n throw new Error(\n `[${modelNameForError}] Database not initialized for count. Connect at least one document via initJsBao(...).connectDocument or call initializeForDocument(yDoc, db, docId, permissionHint) before running counts.`\n );\n }\n\n const schema = (this as any).getSchema?.();\n if (!schema || !schema.options?.name) {\n throw new Error(\"Model not properly initialized for count\");\n }\n\n const modelName = schema.options.name;\n Logger.verbose(`[${modelName}] Executing count:`, { filter, options });\n\n // Create translator and translate count query\n const translator = new DocumentQueryTranslator(modelName, schema.fields);\n const translatedQuery = translator.translateCount(filter, options);\n\n Logger.verbose(`[${modelName}] Translated count SQL:`, translatedQuery.sql);\n Logger.verbose(`[${modelName}] Count SQL params:`, translatedQuery.params);\n\n // Execute query\n const results = await BaseModel.dbInstance.query(\n translatedQuery.sql,\n translatedQuery.params\n );\n\n const count = results[0]?.count || 0;\n Logger.verbose(`[${modelName}] Count returned:`, count);\n\n return count;\n }\n\n static async findAll<T extends BaseModel>(\n this: new (...args: any[]) => T\n ): Promise<T[]> {\n const schema = (this as any).getSchema?.();\n if (!schema || !schema.options.name)\n throw new Error(\"Model not properly initialized for findAll\");\n\n const modelName = schema.options.name;\n const verboseEnabled = Logger.getLogLevel() >= LogLevel.VERBOSE;\n if (verboseEnabled) {\n Logger.verbose(`[${modelName}] Finding all items`);\n }\n\n const modelConstructor = this as unknown as typeof BaseModel;\n const allInstances: T[] = [];\n\n // Check if multi-document system is initialized\n if (\n modelConstructor.documentYMaps &&\n modelConstructor.connectedDocuments &&\n modelConstructor.connectedDocuments.size > 0\n ) {\n if (verboseEnabled) {\n Logger.verbose(`[${modelName}.findAll] Using multi-document system`);\n }\n\n // Iterate through all connected documents\n for (const [docId] of modelConstructor.connectedDocuments) {\n if (verboseEnabled) {\n Logger.verbose(\n `[${modelName}.findAll] Searching in document: ${docId}`\n );\n }\n\n const documentYMapKey = `${docId}_${modelName}`;\n const documentYMap =\n modelConstructor.documentYMaps.get(documentYMapKey);\n\n if (documentYMap) {\n if (verboseEnabled) {\n Logger.verbose(\n `[${modelName}.findAll] DocumentYMap found for ${docId}, keys: [${Array.from(\n documentYMap.keys()\n ).join(\", \")}]`\n );\n }\n\n // Iterate through all records in this document\n for (const [recordId, recordYMap] of documentYMap.entries()) {\n if (recordYMap instanceof Y.Map) {\n // Create instance with the id - constructor will handle loading logic\n const instance = new this({ id: recordId });\n\n // Set document metadata\n (instance as any)._metaDocId = docId;\n const connectedDoc =\n modelConstructor.connectedDocuments.get(docId);\n if (connectedDoc) {\n (instance as any)._metaPermissionHint =\n connectedDoc.permissionHint;\n }\n\n allInstances.push(instance);\n } else {\n // Legacy support for plain objects (during migration)\n Logger.warn(\n `[${modelName}] Found legacy plain object in document ${docId}, consider migrating data`\n );\n allInstances.push(new this(recordYMap));\n }\n }\n }\n }\n }\n\n if (verboseEnabled) {\n Logger.verbose(\n `[${modelName}.findAll] Found ${allInstances.length} total instances`\n );\n }\n return allInstances;\n }\n\n static async findByUnique<T extends BaseModel>(\n this: typeof BaseModel & (new (...args: any[]) => T),\n constraintName: string,\n value: any | any[]\n ): Promise<T | null> {\n const modelConstructor = this;\n const schema = (modelConstructor as any).getSchema();\n const currentModelName =\n (modelConstructor as any).modelName ||\n schema?.options?.name ||\n \"BaseModel\";\n if (!schema || !schema.options || !schema.resolvedUniqueConstraints) {\n throw new Error(\n `[${currentModelName}] Schema or unique constraints not loaded for findByUnique.`\n );\n }\n\n const constraint = schema.resolvedUniqueConstraints.find(\n (c: any) => c.name === constraintName\n );\n if (!constraint) {\n throw new Error(\n `[${currentModelName}] Unique constraint named '${constraintName}' not found.`\n );\n }\n const keyValues = Array.isArray(value) ? value : [value];\n const uniqueKeyString = modelConstructor._buildKeyFromValues(\n constraint.fields,\n keyValues,\n currentModelName,\n constraint.name\n );\n if (uniqueKeyString === null) {\n Logger.verbose(\n `[${currentModelName}] findByUnique for '${constraintName}': unique key could not be built. Returning null.`\n );\n return null;\n }\n\n // Check if multi-document system is available\n if (\n modelConstructor.documentYMaps &&\n modelConstructor.connectedDocuments &&\n modelConstructor.connectedDocuments.size > 0\n ) {\n Logger.verbose(\n `[${currentModelName}.findByUnique] Using multi-document system`\n );\n\n // Search through all connected documents\n for (const [docId] of modelConstructor.connectedDocuments) {\n const documentInfo = modelConstructor.connectedDocuments.get(docId);\n if (!documentInfo) continue;\n\n const yDoc = documentInfo.yDoc;\n const constraintMapName = `_uniqueIdx_${currentModelName}_${constraint.name}`;\n const constraintMap = yDoc.getMap(constraintMapName);\n const recordId = constraintMap.get(uniqueKeyString) as\n | string\n | undefined;\n\n if (recordId) {\n // Found the record ID, now check if the record exists in this document\n const documentYMapKey = `${docId}_${currentModelName}`;\n const documentYMap =\n modelConstructor.documentYMaps.get(documentYMapKey);\n\n if (documentYMap) {\n const recordYMap = documentYMap.get(recordId) as\n | Y.Map<any>\n | undefined;\n if (recordYMap && recordYMap instanceof Y.Map) {\n // Create instance with the id and document metadata\n const instance = new (modelConstructor as new (\n ...args: any[]\n ) => T)({\n id: recordId,\n });\n\n // Set document metadata\n (instance as any)._metaDocId = docId;\n (instance as any)._metaPermissionHint =\n documentInfo.permissionHint;\n\n Logger.verbose(\n `[${currentModelName}.findByUnique] Found record '${recordId}' in document '${docId}'`\n );\n return instance;\n }\n }\n }\n }\n\n Logger.verbose(\n `[${currentModelName}.findByUnique] Record not found in any connected document`\n );\n return null;\n }\n\n // Fallback to legacy single document mode\n const legacyDocId = BaseModel.DEFAULT_LEGACY_DOC_ID;\n const legacyDocumentMap = modelConstructor.documentYMaps?.get(legacyDocId);\n const legacyDocInfo = modelConstructor.connectedDocuments?.get(legacyDocId);\n if (!legacyDocumentMap || !legacyDocInfo) {\n throw new Error(\n `[${currentModelName}] No Y.Doc is connected for this model. Connect a document via initJsBao(...).connectDocument or call initializeForDocument(yDoc, db, docId, permissionHint) before using legacy findByUnique.`\n );\n }\n\n const constraintMapName = `_uniqueIdx_${currentModelName}_${constraint.name}`;\n const constraintMap = legacyDocInfo.yDoc.getMap(constraintMapName);\n const recordId = constraintMap.get(uniqueKeyString) as string | undefined;\n if (!recordId) {\n return null;\n }\n\n // Get the nested YMap\n const recordYMap = legacyDocumentMap.get(recordId) as\n | Y.Map<any>\n | undefined;\n if (!recordYMap) {\n return null;\n }\n\n if (recordYMap instanceof Y.Map) {\n // Create instance with the id - constructor will handle loading logic\n const instance = new (modelConstructor as new (...args: any[]) => T)({\n id: recordId,\n });\n\n return instance;\n } else {\n // Legacy plain object support\n return new (modelConstructor as new (...args: any[]) => T)(recordYMap);\n }\n }\n\n static async upsertByUnique<T extends BaseModel>(\n this: typeof BaseModel & (new (...args: any[]) => T),\n constraintName: string,\n uniqueLookupValue: any | any[],\n dataToUpsert: Partial<\n Omit<InstanceType<new (...args: any[]) => T>, keyof BaseModel | \"toJSON\">\n > & { id?: string },\n options?: {\n objectMustExist?: boolean;\n objectMustNotExist?: boolean;\n targetDocument?: string;\n }\n ): Promise<T> {\n const modelConstructor = this;\n const schema = (modelConstructor as any).getSchema();\n const currentModelName =\n (modelConstructor as any).modelName ||\n schema?.options?.name ||\n \"BaseModel\";\n if (!schema || !schema.options || !schema.resolvedUniqueConstraints) {\n throw new Error(\n `[${currentModelName}] Schema or unique constraints not loaded for upsertByUnique.`\n );\n }\n // Check for proper initialization\n const connectedDocuments = modelConstructor.connectedDocuments;\n\n // Require at least one connected document\n if (!connectedDocuments || connectedDocuments.size === 0) {\n throw new Error(\n `[${currentModelName}] No documents are connected. Connect at least one document via initJsBao(...).connectDocument or call initializeForDocument(yDoc, db, docId, permissionHint) before calling upsertByUnique.`\n );\n }\n const constraint = schema.resolvedUniqueConstraints.find(\n (c: any) => c.name === constraintName\n );\n if (!constraint) {\n throw new Error(\n `[${currentModelName}] Unique constraint named '${constraintName}' not found for upsert.`\n );\n }\n const keyValuesForLookup = Array.isArray(uniqueLookupValue)\n ? uniqueLookupValue\n : [uniqueLookupValue];\n constraint.fields.forEach((field: string, index: number) => {\n if (!dataToUpsert.hasOwnProperty(field)) {\n throw new Error(\n `[${currentModelName}] upsertByUnique: dataToUpsert is missing required unique field '${field}' from constraint '${constraintName}'.`\n );\n }\n const dataValue = (dataToUpsert as any)[field];\n const lookupValue = keyValuesForLookup[index];\n if (dataValue !== lookupValue) {\n throw new Error(\n `[${currentModelName}] upsertByUnique: Mismatch between dataToUpsert.'${field}' (value: ${dataValue}) ` +\n `and uniqueLookupValue for constraint '${constraintName}' (value: ${lookupValue}).`\n );\n }\n });\n const uniqueKeyString = modelConstructor._buildKeyFromValues(\n constraint.fields,\n keyValuesForLookup,\n currentModelName,\n constraint.name\n );\n if (uniqueKeyString === null) {\n throw new Error(\n `[${currentModelName}] upsertByUnique for '${constraintName}': unique key cannot be built due to null/undefined values. Upsert cannot proceed reliably.`\n );\n }\n const constraintMapName = `_uniqueIdx_${currentModelName}_${constraint.name}`;\n let existingRecord: T | null = null;\n\n // Search for existing record\n if (connectedDocuments && connectedDocuments.size > 0) {\n // Search across all connected documents\n for (const docId of connectedDocuments.keys()) {\n const docInfo = connectedDocuments.get(docId);\n if (docInfo) {\n const constraintMap = docInfo.yDoc.getMap(constraintMapName);\n const recordId = constraintMap.get(uniqueKeyString) as\n | string\n | undefined;\n if (recordId) {\n existingRecord = (await modelConstructor.find(\n recordId\n )) as T | null;\n break; // Found existing record, stop searching\n }\n }\n }\n } else {\n // No legacy fallback; cannot resolve without connected documents\n }\n if (options?.objectMustExist) {\n if (!existingRecord) {\n throw new RecordNotFoundError(\n `[${currentModelName}] upsertByUnique (objectMustExist): Record with constraint '${constraintName}' ` +\n `and value(s) starting with '${uniqueKeyString.substring(\n 0,\n 50\n )}...' not found.`\n );\n }\n Logger.verbose(\n `[${currentModelName}] upsertByUnique (objectMustExist): Updating existing record ${existingRecord.id}`\n );\n Object.assign(existingRecord, dataToUpsert);\n\n // For existing records, use targetDocument if provided, otherwise use the record's existing document\n if (options?.targetDocument) {\n await existingRecord.save({ targetDocument: options.targetDocument });\n } else {\n await existingRecord.save();\n }\n return existingRecord;\n }\n if (options?.objectMustNotExist) {\n if (existingRecord) {\n throw new UniqueConstraintViolationError(\n `[${currentModelName}] upsertByUnique (objectMustNotExist): Record with constraint '${constraintName}' ` +\n `and value(s) starting with '${uniqueKeyString.substring(\n 0,\n 50\n )}...' already exists with ID ${existingRecord.id}.`,\n currentModelName,\n constraintName,\n constraint.fields,\n (dataToUpsert as any).id,\n existingRecord.id\n );\n }\n Logger.verbose(\n `[${currentModelName}] upsertByUnique (objectMustNotExist): Creating new record.`\n );\n const newInstance = new (modelConstructor as new (...args: any[]) => T)(\n dataToUpsert as any\n );\n if (!newInstance.id) {\n throw new Error(\n `[${currentModelName}] upsertByUnique: ID must be provided in dataToUpsert or auto-generated by constructor for new records.`\n );\n }\n\n // For new records, targetDocument must be specified\n if (!options?.targetDocument) {\n throw new Error(\n `[${currentModelName}] upsertByUnique: targetDocument is required when creating new records.`\n );\n }\n\n await newInstance.save({ targetDocument: options.targetDocument });\n return newInstance;\n }\n if (existingRecord) {\n Logger.verbose(\n `[${currentModelName}] upsertByUnique (default): Updating existing record ${existingRecord.id}`\n );\n Object.assign(existingRecord, dataToUpsert);\n\n // For existing records, use targetDocument if provided, otherwise use the record's existing document\n if (options?.targetDocument) {\n await existingRecord.save({ targetDocument: options.targetDocument });\n } else {\n await existingRecord.save();\n }\n return existingRecord;\n } else {\n Logger.verbose(\n `[${currentModelName}] upsertByUnique (default): Creating new record.`\n );\n const newInstance = new (modelConstructor as new (...args: any[]) => T)(\n dataToUpsert as any\n );\n if (!newInstance.id) {\n throw new Error(\n `[${currentModelName}] upsertByUnique: ID must be provided in dataToUpsert or auto-generated by constructor for new records.`\n );\n }\n\n // For new records, targetDocument must be specified\n if (!options?.targetDocument) {\n throw new Error(\n `[${currentModelName}] upsertByUnique: targetDocument is required when creating new records.`\n );\n }\n\n await newInstance.save({ targetDocument: options.targetDocument });\n return newInstance;\n }\n }\n\n /**\n * Execute a callback with automatic transaction handling for all modified models\n */\n static async withTransaction<T>(callback: () => Promise<T> | T): Promise<T> {\n // Collect all models that get modified during the callback\n const modifiedModels: Set<BaseModel> = new Set();\n\n // Hook into setValue to track modifications\n const originalSetValue = BaseModel.prototype.setValue;\n BaseModel.prototype.setValue = function (fieldKey: string, value: any) {\n modifiedModels.add(this);\n return originalSetValue.call(this, fieldKey, value);\n };\n\n try {\n const result = await callback();\n\n // Save all modified models in a single transaction\n if (modifiedModels.size > 0) {\n Logger.verbose(\n `[BaseModel] Transaction saving ${modifiedModels.size} modified models`\n );\n\n // Get yDoc from any initialized model\n let yDoc: Y.Doc | null = null;\n const firstModel = Array.from(modifiedModels)[0];\n const modelConstructor = firstModel.constructor as typeof BaseModel;\n\n // Try to get document from any connected document\n if (\n modelConstructor.connectedDocuments &&\n modelConstructor.connectedDocuments.size > 0\n ) {\n yDoc = Array.from(modelConstructor.connectedDocuments.values())[0]\n .yDoc;\n }\n\n if (yDoc) {\n await yDoc.transact(async () => {\n for (const model of modifiedModels) {\n if (model.isDirty) {\n await model.save();\n }\n }\n }, \"batch-model-transaction\");\n } else {\n // Fallback: save models individually if no yDoc found\n for (const model of modifiedModels) {\n if (model.isDirty) {\n await model.save();\n }\n }\n }\n }\n\n return result;\n } finally {\n // Restore original setValue\n BaseModel.prototype.setValue = originalSetValue;\n }\n }\n\n /**\n * Sets up deep observation on a nested YMap to sync field-level changes to the database\n */\n protected static setupNestedYMapObserver(\n recordId: string,\n recordYMap: Y.Map<any>\n ) {\n const modelConstructor = this as typeof BaseModel;\n const schema = (modelConstructor as any).getSchema();\n const modelName = schema?.options?.name;\n\n if (!modelName) {\n Logger.error(\n `[${modelConstructor.name}] Cannot setup nested YMap observer: model name not found`\n );\n return;\n }\n\n Logger.verbose(\n `[${modelName}] Setting up nested YMap observer for record ${recordId}`\n );\n\n recordYMap.observe(async (event: Y.YMapEvent<any>) => {\n Logger.verbose(\n `[${modelName}] Nested YMap change detected for record ${recordId}:`,\n event\n );\n\n const currentDbInstance = BaseModel.dbInstance;\n if (!currentDbInstance) {\n Logger.error(\n `[${modelName}] DB instance not available for nested YMap observer on record ${recordId}`\n );\n return;\n }\n\n // Convert the updated nested YMap to a plain object for database sync\n const updatedData: Record<string, any> = {};\n const unknownFields: string[] = [];\n for (const [key, value] of recordYMap.entries()) {\n // Skip StringSet fields - they're handled by junction tables\n const fieldOptions = schema?.fields?.get(key);\n if (!fieldOptions) {\n unknownFields.push(key);\n continue;\n }\n if (fieldOptions.type === \"stringset\") {\n continue;\n }\n // Skip undefined values as SQLite cannot bind them\n if (value !== undefined) {\n updatedData[key] = value;\n }\n }\n if (unknownFields.length > 0) {\n Logger.warn(\n `[${modelName}] Ignoring unknown fields [${unknownFields.join(\n \", \"\n )}] when syncing nested record ${recordId}`\n );\n }\n\n // Ensure we have the required fields\n if (!updatedData.id) {\n Logger.warn(\n `[${modelName}] Nested YMap change for ${recordId} missing id field, skipping DB sync`\n );\n return;\n }\n\n try {\n Logger.verbose(\n `[${modelName}] Syncing nested YMap changes to database for record ${recordId}:`,\n updatedData\n );\n await currentDbInstance.insert(modelName, {\n ...updatedData,\n type: modelName,\n });\n Logger.verbose(\n `[${modelName}] Database sync completed for nested YMap changes on record ${recordId}`\n );\n } catch (error) {\n Logger.error(\n `[${modelName}] Error syncing nested YMap changes to database for record ${recordId}:`,\n error,\n updatedData\n );\n }\n\n // Notify listeners of the change\n modelConstructor.notifyListeners();\n });\n }\n\n /**\n * Sets up deep observation on a nested YMap for a specific document to sync field-level changes to the database\n */\n protected static setupNestedYMapObserverForDocument(\n recordId: string,\n recordYMap: Y.Map<any>,\n docId: string,\n permissionHint: DocumentPermissionHint\n ) {\n const modelConstructor = this as typeof BaseModel;\n const schema = (modelConstructor as any).getSchema();\n const modelName = schema?.options?.name;\n\n if (!modelName) {\n Logger.error(\n `[${modelConstructor.name}] Cannot setup nested YMap observer: model name not found`\n );\n return;\n }\n\n Logger.verbose(\n `[${modelName}] Setting up nested YMap observer for record ${recordId} in document ${docId}`\n );\n\n recordYMap.observe(async (event: Y.YMapEvent<any>) => {\n Logger.verbose(\n `[${modelName}] Nested YMap change detected for record ${recordId} in document ${docId}:`,\n event\n );\n\n const currentDbInstance = BaseModel.dbInstance;\n if (!currentDbInstance) {\n Logger.error(\n `[${modelName}] DB instance not available for nested YMap observer on record ${recordId} in document ${docId}`\n );\n return;\n }\n\n // Convert the updated nested YMap to a plain object for database sync\n const updatedData: Record<string, any> = {};\n const unknownFields: string[] = [];\n for (const [key, value] of recordYMap.entries()) {\n // Skip StringSet fields - they're handled by junction tables\n const fieldOptions = schema?.fields?.get(key);\n if (!fieldOptions) {\n unknownFields.push(key);\n continue;\n }\n if (fieldOptions.type === \"stringset\") {\n continue;\n }\n // Skip undefined values as SQLite cannot bind them\n if (value !== undefined) {\n updatedData[key] = value;\n }\n }\n if (unknownFields.length > 0) {\n Logger.warn(\n `[${modelName}] Ignoring unknown fields [${unknownFields.join(\n \", \"\n )}] when syncing nested record ${recordId} in document ${docId}`\n );\n }\n\n // Ensure we have the required fields\n if (!updatedData.id) {\n Logger.warn(\n `[${modelName}] Nested YMap change for ${recordId} in document ${docId} missing id field, skipping DB sync`\n );\n return;\n }\n\n try {\n Logger.verbose(\n `[${modelName}] Syncing nested YMap changes to database for record ${recordId} in document ${docId}:`,\n updatedData\n );\n await currentDbInstance.insert(modelName, {\n ...updatedData,\n type: modelName,\n _meta_doc_id: docId,\n _meta_permission_hint: permissionHint,\n });\n Logger.verbose(\n `[${modelName}] Database sync completed for nested YMap changes on record ${recordId} in document ${docId}`\n );\n } catch (error) {\n Logger.error(\n `[${modelName}] Error syncing nested YMap changes to database for record ${recordId} in document ${docId}:`,\n error,\n updatedData\n );\n }\n\n // Notify listeners of the change\n modelConstructor.notifyListeners();\n });\n }\n}\n","export interface StringSetChangeTracker {\n markStringSetChange(\n fieldName: string,\n operation: \"add\" | \"remove\" | \"clear\",\n value?: string\n ): void;\n}\n\nexport class StringSet {\n private _values: Set<string>;\n private _model: StringSetChangeTracker;\n private _fieldName: string;\n\n constructor(\n model: StringSetChangeTracker,\n fieldName: string,\n initialValues: string[] = []\n ) {\n this._model = model;\n this._fieldName = fieldName;\n this._values = new Set(initialValues);\n }\n\n /**\n * Add a string to the set\n */\n add(value: string): void {\n if (typeof value !== \"string\") {\n throw new Error(\"StringSet can only contain string values\");\n }\n\n if (!this._values.has(value)) {\n this._values.add(value);\n this._model.markStringSetChange(this._fieldName, \"add\", value);\n }\n }\n\n /**\n * Remove a string from the set\n */\n remove(value: string): void {\n if (this._values.has(value)) {\n this._values.delete(value);\n this._model.markStringSetChange(this._fieldName, \"remove\", value);\n }\n }\n\n /**\n * Check if the set contains a string\n */\n has(value: string): boolean {\n return this._values.has(value);\n }\n\n /**\n * Clear all strings from the set\n */\n clear(): void {\n if (this._values.size > 0) {\n this._values.clear();\n this._model.markStringSetChange(this._fieldName, \"clear\");\n }\n }\n\n /**\n * Get the number of strings in the set\n */\n get size(): number {\n return this._values.size;\n }\n\n /**\n * Get an iterator of all values\n */\n values(): IterableIterator<string> {\n return this._values.values();\n }\n\n /**\n * Make the StringSet iterable\n */\n [Symbol.iterator](): IterableIterator<string> {\n return this._values[Symbol.iterator]();\n }\n\n /**\n * Convert to array\n */\n toArray(): string[] {\n return Array.from(this._values);\n }\n\n /**\n * Union with another StringSet\n */\n union(other: StringSet): StringSet {\n const result = new StringSet(this._model, this._fieldName, this.toArray());\n for (const value of other) {\n result._values.add(value); // Direct add to avoid change tracking\n }\n return result;\n }\n\n /**\n * Intersection with another StringSet\n */\n intersection(other: StringSet): StringSet {\n const result = new StringSet(this._model, this._fieldName);\n for (const value of this._values) {\n if (other.has(value)) {\n result._values.add(value); // Direct add to avoid change tracking\n }\n }\n return result;\n }\n\n /**\n * Difference with another StringSet (values in this set but not in other)\n */\n difference(other: StringSet): StringSet {\n const result = new StringSet(this._model, this._fieldName);\n for (const value of this._values) {\n if (!other.has(value)) {\n result._values.add(value); // Direct add to avoid change tracking\n }\n }\n return result;\n }\n\n /**\n * Get the current state including pending changes\n * This is used internally by the model to determine the current view\n */\n _getCurrentState(): Set<string> {\n return new Set(this._values);\n }\n\n /**\n * Update the internal state (used when loading from Yjs or applying changes)\n */\n _updateInternalState(values: string[]): void {\n this._values = new Set(values);\n }\n}\n","import * as Y from \"yjs\";\n\n// Document permission levels\nexport type DocumentPermissionHint = \"read\" | \"read-write\";\n\n// Connected document information\nexport interface ConnectedDocument {\n docId: string;\n yDoc: Y.Doc;\n permissionHint: DocumentPermissionHint;\n}\n\n// Save options for multi-document support\nexport interface SaveOptions {\n targetDocument?: string;\n forceWrite?: boolean;\n}\n\n// Document management interface\nexport interface DocumentManager {\n connectDocument(\n docId: string,\n yDoc: Y.Doc,\n permissionHint: DocumentPermissionHint\n ): Promise<void>;\n disconnectDocument(docId: string): Promise<void>;\n getConnectedDocuments(): Map<string, ConnectedDocument>;\n isDocumentConnected(docId: string): boolean;\n}\n\n// Document connection event types\nexport interface DocumentConnectionEvent {\n type: \"connect\" | \"disconnect\";\n docId: string;\n document?: ConnectedDocument;\n}\n\n// Type for document connection callback\nexport type DocumentConnectionCallback = (\n event: DocumentConnectionEvent\n) => void;\n\n// Error classes with stable codes for programmatic handling\nexport class DocumentClosedError extends Error {\n code: string = \"ERR_DOC_CLOSED\";\n constructor(message: string) {\n super(message);\n this.name = \"DocumentClosedError\";\n }\n}\n\nexport class DocumentResolutionError extends Error {\n code: string = \"ERR_DOC_UNRESOLVED\";\n constructor(message: string) {\n super(message);\n this.name = \"DocumentResolutionError\";\n }\n}\n","// Document Query API Type Definitions\n\n// Basic comparison operators\nexport interface ComparisonOperators<T = any> {\n $eq?: T;\n $ne?: T;\n $gt?: T;\n $gte?: T;\n $lt?: T;\n $lte?: T;\n $in?: T[];\n $nin?: T[];\n}\n\n// StringSet-specific operators\nexport interface StringSetOperators {\n /**\n * Exact membership: StringSet contains this specific string\n */\n $contains?: string;\n $all?: string[]; // StringSet contains all of these strings\n $size?: number | ComparisonOperators<number>; // StringSet size comparison\n}\n\n// Substring matching operators (allowed on string and stringset fields only)\nexport interface SubstringOperators {\n /** Prefix match */\n $startsWith?: string;\n /** Suffix match */\n $endsWith?: string;\n /** Substring anywhere */\n $containsText?: string;\n}\n\n// Existence and pattern operators\nexport interface ExistenceOperators {\n $exists?: boolean;\n}\n\n// All field operators combined\nexport type FieldOperators<T = any> = ComparisonOperators<T> &\n ExistenceOperators &\n StringSetOperators &\n SubstringOperators;\n\n// Logical operators\nexport interface LogicalOperators {\n $and?: DocumentFilter[];\n $or?: DocumentFilter[];\n}\n\n// Document filter - can be field conditions or logical operators\nexport type DocumentFilter = {\n [field: string]: any | FieldOperators<any>;\n} & LogicalOperators;\n\n// Sort direction\nexport type SortDirection = 1 | -1;\n\n// Sort specification\nexport type SortSpec = {\n [field: string]: SortDirection;\n};\n\n// Projection specification - 1 to include, 0 to exclude\nexport type ProjectionSpec = {\n [field: string]: 1 | 0;\n};\n\n// Include specification for loading related data\nexport interface IncludeSpec {\n model: string; // target model type name\n type: \"refersTo\" | \"hasMany\" | \"refersToMany\";\n sourceField?: string; // refersTo: field on parent holding target ID\n foreignKey?: string; // hasMany: field on target holding parent ID\n localField?: string; // hasMany: field on parent to match (default: \"id\")\n as?: string; // key name in _related (default: model name)\n projection?: ProjectionSpec; // field projection on related records\n limit?: number; // per-parent limit (hasMany only)\n sort?: SortSpec; // sort order (hasMany only)\n filter?: DocumentFilter; // additional filter on related records\n include?: IncludeSpec[]; // nested includes (max depth 3)\n}\n\n// Query options for find operations\nexport interface QueryOptions {\n // Sorting\n sort?: SortSpec;\n\n // Projection - return only specified fields\n projection?: ProjectionSpec;\n\n // Document scoping - restrict results to specific document IDs\n documents?: string | string[];\n\n // Pagination\n limit?: number;\n uniqueStartKey?: string; // Base64 encoded cursor\n direction?: 1 | -1; // 1 for forward, -1 for backward\n\n // Related data loading\n include?: IncludeSpec[];\n}\n\n// Cursor data structure (what gets encoded in uniqueStartKey)\nexport interface CursorData {\n values: Record<string, any>; // Field values for cursor position\n sortFields: string[]; // Fields used for sorting\n direction: 1 | -1; // Direction of pagination\n}\n\n// Paginated result structure\nexport interface PaginatedResult<T> {\n data: T[];\n nextCursor?: string;\n prevCursor?: string;\n hasMore: boolean;\n}\n\n// Query translation result (internal use)\nexport interface TranslatedQuery {\n sql: string;\n params: any[];\n sortFields: string[];\n sortDirections?: (1 | -1)[];\n}\n\n// Error types for query validation\nexport class DocumentQueryError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"DocumentQueryError\";\n Object.setPrototypeOf(this, DocumentQueryError.prototype);\n }\n}\n\nexport class InvalidOperatorError extends DocumentQueryError {\n public field: string;\n public operator: string;\n public fieldType?: string;\n\n constructor(\n message: string,\n field: string,\n operator: string,\n fieldType?: string\n ) {\n super(message);\n this.name = \"InvalidOperatorError\";\n this.field = field;\n this.operator = operator;\n this.fieldType = fieldType;\n Object.setPrototypeOf(this, InvalidOperatorError.prototype);\n }\n}\n\nexport class InvalidFieldError extends DocumentQueryError {\n public field: string;\n public modelName: string;\n\n constructor(message: string, field: string, modelName: string) {\n super(message);\n this.name = \"InvalidFieldError\";\n this.field = field;\n this.modelName = modelName;\n Object.setPrototypeOf(this, InvalidFieldError.prototype);\n }\n}\n\nexport class InvalidCursorError extends DocumentQueryError {\n public cursor: string;\n\n constructor(message: string, cursor: string) {\n super(message);\n this.name = \"InvalidCursorError\";\n this.cursor = cursor;\n Object.setPrototypeOf(this, InvalidCursorError.prototype);\n }\n}\n\n// Type helper for extracting projected result type\nexport type ProjectedResult<T, P extends ProjectionSpec> = {\n [K in keyof P]: K extends keyof T ? T[K] : never;\n};\n\n// Type helper for query result - either full model or projected object\nexport type QueryResult<\n T,\n P extends ProjectionSpec | undefined\n> = P extends ProjectionSpec ? ProjectedResult<T, P> : T;\n","import { CursorData, InvalidCursorError, SortSpec } from \"../types/queryTypes\";\n\n// Browser-compatible base64 encoding/decoding\nconst base64Encode = (str: string): string => {\n if (typeof btoa !== \"undefined\") {\n // Browser environment\n return btoa(str);\n } else if (typeof Buffer !== \"undefined\") {\n // Node.js environment\n return Buffer.from(str, \"utf-8\").toString(\"base64\");\n } else {\n throw new Error(\"No base64 encoding available\");\n }\n};\n\nconst base64Decode = (str: string): string => {\n if (typeof atob !== \"undefined\") {\n // Browser environment\n return atob(str);\n } else if (typeof Buffer !== \"undefined\") {\n // Node.js environment\n return Buffer.from(str, \"base64\").toString(\"utf-8\");\n } else {\n throw new Error(\"No base64 decoding available\");\n }\n};\n\nexport class CursorManager {\n /**\n * Encode cursor data to base64 string\n */\n static encodeCursor(cursorData: CursorData): string {\n try {\n const jsonString = JSON.stringify(cursorData);\n return base64Encode(jsonString);\n } catch (error) {\n throw new InvalidCursorError(\n `Failed to encode cursor: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n JSON.stringify(cursorData)\n );\n }\n }\n\n /**\n * Decode base64 cursor string to cursor data\n */\n static decodeCursor(cursor: string): CursorData {\n try {\n const jsonString = base64Decode(cursor);\n const parsed = JSON.parse(jsonString);\n\n // Validate cursor structure\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(\"Cursor must be an object\");\n }\n\n if (!parsed.values || typeof parsed.values !== \"object\") {\n throw new Error(\"Cursor must have values object\");\n }\n\n if (!Array.isArray(parsed.sortFields)) {\n throw new Error(\"Cursor must have sortFields array\");\n }\n\n if (parsed.direction !== 1 && parsed.direction !== -1) {\n throw new Error(\"Cursor direction must be 1 or -1\");\n }\n\n return parsed as CursorData;\n } catch (error) {\n throw new InvalidCursorError(\n `Failed to decode cursor: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n cursor\n );\n }\n }\n\n /**\n * Generate cursor from a record and sort specification\n */\n static generateCursor(\n record: Record<string, any>,\n sortFields: string[],\n direction: 1 | -1\n ): string {\n const values: Record<string, any> = {};\n\n // Extract values for all sort fields\n for (const field of sortFields) {\n if (record.hasOwnProperty(field)) {\n values[field] = record[field];\n } else {\n throw new Error(\n `Cannot generate cursor: record missing sort field '${field}'`\n );\n }\n }\n\n const cursorData: CursorData = {\n values,\n sortFields,\n direction,\n };\n\n return this.encodeCursor(cursorData);\n }\n\n /**\n * Build SQL pagination conditions based on cursor\n * Uses lexicographic ordering for stable pagination with multiple sort fields\n */\n static buildPaginationConditions(\n cursor: CursorData,\n currentSortFields: string[],\n sortDirections: (1 | -1)[],\n requestedDirection: 1 | -1,\n fieldFormatter: (field: string) => string = (field) => field\n ): { sql: string; params: any[] } {\n // Validate that sort fields match\n if (!this.arraysEqual(cursor.sortFields, currentSortFields)) {\n throw new InvalidCursorError(\n `Cursor sort fields [${cursor.sortFields.join(\n \", \"\n )}] don't match query sort fields [${currentSortFields.join(\", \")}]`,\n JSON.stringify(cursor)\n );\n }\n\n const conditions: string[] = [];\n const params: any[] = [];\n\n // Build lexicographic comparison conditions\n // For multiple sort fields, we need to handle cases like:\n // WHERE (field1 > ?) OR (field1 = ? AND field2 > ?) OR (field1 = ? AND field2 = ? AND field3 > ?)\n\n const sortFields = cursor.sortFields;\n const direction = requestedDirection;\n\n for (let i = 0; i < sortFields.length; i++) {\n const fieldConditions: string[] = [];\n const fieldParams: any[] = [];\n\n // Add equality conditions for all previous fields\n for (let j = 0; j < i; j++) {\n const field = sortFields[j];\n const value = cursor.values[field];\n fieldConditions.push(`${fieldFormatter(field)} = ?`);\n fieldParams.push(value);\n }\n\n // Add comparison condition for current field\n const currentField = sortFields[i];\n const currentValue = cursor.values[currentField];\n const fieldSortDir = sortDirections[i] ?? 1; // default ASC for id\n // Determine comparison operator based on field sort direction and requested pagination direction\n // Forward: ASC uses '>', DESC uses '<'; Backward: invert\n const forwardOp = fieldSortDir === 1 ? \">\" : \"<\";\n const operator =\n direction === 1 ? forwardOp : forwardOp === \">\" ? \"<\" : \">\";\n\n fieldConditions.push(`${fieldFormatter(currentField)} ${operator} ?`);\n fieldParams.push(currentValue);\n\n // Combine conditions for this level\n const levelCondition = fieldConditions.join(\" AND \");\n conditions.push(`(${levelCondition})`);\n params.push(...fieldParams);\n }\n\n // Combine all conditions with OR, wrapped in parens so the\n // pagination clause stays grouped when AND'd with other WHERE conditions.\n const sql = `(${conditions.join(\" OR \")})`;\n\n return { sql, params };\n }\n\n /**\n * Extract sort fields from sort specification, ensuring 'id' is always included for stability\n */\n static extractSortFields(sort?: SortSpec): string[] {\n const fields: string[] = [];\n\n if (sort && Object.keys(sort).length > 0) {\n fields.push(...Object.keys(sort));\n }\n\n // Always include 'id' for stable sorting if not already present\n if (!fields.includes(\"id\")) {\n fields.push(\"id\");\n }\n\n return fields;\n }\n\n /**\n * Build ORDER BY clause from sort specification\n */\n static buildOrderClause(\n sort?: SortSpec,\n fieldFormatter: (field: string) => string = (field) => field\n ): {\n sql: string;\n fields: string[];\n directions: (1 | -1)[];\n } {\n const fields = this.extractSortFields(sort);\n const clauses: string[] = [];\n const directions: (1 | -1)[] = [];\n\n if (sort && Object.keys(sort).length > 0) {\n for (const [field, dir] of Object.entries(sort)) {\n const sqlDirection = dir === 1 ? \"ASC\" : \"DESC\";\n clauses.push(`${fieldFormatter(field)} ${sqlDirection}`);\n directions.push(dir as 1 | -1);\n }\n }\n\n // Add id for stable sorting if not already included in sort spec\n if (!sort || !sort.hasOwnProperty(\"id\")) {\n clauses.push(`${fieldFormatter(\"id\")} ASC`);\n directions.push(1);\n } else if (sort && sort.hasOwnProperty(\"id\")) {\n // If user specified id explicitly, ensure direction array includes it\n directions.push((sort as any)[\"id\"] as 1 | -1);\n }\n\n return {\n sql: clauses.join(\", \"),\n fields,\n directions,\n };\n }\n\n /**\n * Determine if there are more results available for pagination\n */\n static hasMoreResults(\n requestedLimit: number | undefined,\n actualResultCount: number\n ): boolean {\n if (!requestedLimit || requestedLimit <= 0) {\n return false; // No limit specified, so no more results\n }\n\n return actualResultCount >= requestedLimit;\n }\n\n /**\n * Generate next and previous cursors from result set\n */\n static generateResultCursors(\n results: Record<string, any>[],\n sortFields: string[],\n _requestedDirection: 1 | -1,\n hasMore: boolean,\n isFirstPage: boolean = false\n ): { nextCursor?: string; prevCursor?: string } {\n if (results.length === 0) {\n return {};\n }\n\n const cursors: { nextCursor?: string; prevCursor?: string } = {};\n\n // Generate next cursor from last result (if there are more results)\n if (hasMore && results.length > 0) {\n const lastResult = results[results.length - 1];\n cursors.nextCursor = this.generateCursor(lastResult, sortFields, 1);\n }\n\n // Generate previous cursor from first result (only if NOT on first page)\n if (results.length > 0 && !isFirstPage) {\n const firstResult = results[0];\n cursors.prevCursor = this.generateCursor(firstResult, sortFields, -1);\n }\n\n return cursors;\n }\n\n /**\n * Utility to compare arrays for equality\n */\n private static arraysEqual<T>(a: T[], b: T[]): boolean {\n if (a.length !== b.length) return false;\n return a.every((val, index) => val === b[index]);\n }\n}\n","const IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Determine if the supplied identifier matches our permitted character policy.\n * Identifiers must start with a letter or underscore and may contain\n * alphanumeric characters or underscores thereafter.\n */\nexport function isValidIdentifier(name: string): boolean {\n return IDENTIFIER_PATTERN.test(name);\n}\n\n/**\n * Enforce identifier policy at definition time to prevent invalid names\n * from ever reaching SQL generation.\n */\nexport function assertValidIdentifier(\n name: string,\n context: string\n): void {\n if (!isValidIdentifier(name)) {\n throw new Error(\n `${context}: Identifier \"${name}\" must match ${IDENTIFIER_PATTERN.source}`\n );\n }\n}\n\n/**\n * Quote an identifier for SQL usage using double quotes, escaping any embedded\n * double quotes by doubling them. Assumes identifier validation has already\n * occurred.\n */\nexport function quoteIdentifier(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Quote a qualified identifier composed of multiple segments (e.g. table.column).\n */\nexport function quoteQualifiedIdentifier(parts: string[]): string {\n return parts.map(quoteIdentifier).join(\".\");\n}\n\n/**\n * Produce a deterministic, SQL-safe alias suffix derived from arbitrary input.\n * The resulting string always matches our identifier policy when prefixed with\n * a valid identifier segment.\n */\nexport function deterministicIdentifierHash(value: string): string {\n let hash = 0;\n for (let i = 0; i < value.length; i++) {\n hash = (hash << 5) - hash + value.charCodeAt(i);\n hash |= 0; // Force 32-bit integer\n }\n const positiveHash = hash === 0 ? 0 : Math.abs(hash);\n return positiveHash.toString(36);\n}\n\n/**\n * Build a safe alias using a prefix that already conforms to the identifier\n * policy along with a deterministic hash of the raw descriptor.\n */\nexport function buildSafeAlias(prefix: string, rawDescriptor: string): string {\n const suffix = deterministicIdentifierHash(rawDescriptor);\n const candidate = `${prefix}_${suffix}`;\n assertValidIdentifier(candidate, \"Alias generation\");\n return candidate;\n}\n\nexport { IDENTIFIER_PATTERN };\n","export type SubstringMode = \"startsWith\" | \"endsWith\" | \"containsText\";\n\n// Escape %, _, and \\ for use with ESCAPE '\\'\nexport function escapeLikeLiteral(input: string): string {\n return input.replace(/\\\\/g, \"\\\\\\\\\").replace(/%/g, \"\\\\%\").replace(/_/g, \"\\\\_\");\n}\n\nexport function buildLikePattern(value: string, mode: SubstringMode): string | null {\n const trimmed = (value ?? \"\").trim();\n if (trimmed.length === 0) return null; // no-op\n if (trimmed.length > 1024) {\n throw new Error(\"substring value exceeds 1024 characters\");\n }\n const escaped = escapeLikeLiteral(trimmed);\n switch (mode) {\n case \"startsWith\":\n return `${escaped}%`;\n case \"endsWith\":\n return `%${escaped}`;\n case \"containsText\":\n return `%${escaped}%`;\n }\n}\n\nexport function shouldLogLikeEscapes(): boolean {\n try {\n // @ts-ignore\n if (typeof process !== \"undefined\" && process.env) {\n // @ts-ignore\n return !!process.env.JS_BAO_DEBUG_LIKE_ESCAPES;\n }\n } catch {}\n return false;\n}\n\n","import {\n DocumentFilter,\n QueryOptions,\n TranslatedQuery,\n InvalidOperatorError,\n InvalidFieldError,\n ProjectionSpec,\n} from \"../types/queryTypes\";\nimport { FieldOptions } from \"../types/ormTypes\";\nimport { CursorManager } from \"./CursorManager\";\nimport { quoteIdentifier } from \"../utils/sql\";\nimport { buildLikePattern, shouldLogLikeEscapes } from \"../utils/patterns\";\n\nconst SYSTEM_FIELDS = new Set([\"id\", \"type\"]);\n\nexport class DocumentQueryTranslator {\n private modelName: string;\n private schema: Map<string, FieldOptions>;\n private tableName: string;\n private quotedTableName: string;\n private fieldSqlCache: Map<string, string>;\n\n constructor(modelName: string, schema: Map<string, FieldOptions>) {\n this.modelName = modelName;\n this.schema = schema;\n this.tableName = `model_${modelName.toLowerCase()}`;\n this.quotedTableName = quoteIdentifier(this.tableName);\n this.fieldSqlCache = new Map();\n }\n\n private getQuotedField(fieldName: string): string {\n if (!this.fieldSqlCache.has(fieldName)) {\n if (!this.schema.has(fieldName) && !SYSTEM_FIELDS.has(fieldName)) {\n throw new InvalidFieldError(\n `Unknown field: ${fieldName} in model ${this.modelName}`,\n fieldName,\n this.modelName\n );\n }\n this.fieldSqlCache.set(fieldName, quoteIdentifier(fieldName));\n }\n return this.fieldSqlCache.get(fieldName)!;\n }\n\n /**\n * Translate document filter and options to SQL for find operations\n */\n translateFind(\n filter: DocumentFilter,\n options?: QueryOptions\n ): TranslatedQuery {\n // Validate projection fields if specified\n if (options?.projection) {\n this.validateProjection(options.projection);\n }\n\n const whereClause = this.translateFilter(filter);\n const orderClause = CursorManager.buildOrderClause(options?.sort, (field) =>\n this.getQuotedField(field)\n );\n const limitClause = this.buildLimitClause(options);\n const paginationClause = this.buildPaginationClause(\n options,\n orderClause.fields,\n orderClause.directions\n );\n\n // Build SELECT clause\n const selectClause = this.buildSelectClause(options?.projection);\n\n // Combine clauses\n let sql = `SELECT ${selectClause} FROM ${this.quotedTableName}`;\n const params: any[] = [];\n\n // Add WHERE conditions\n const conditions: string[] = [];\n if (whereClause.sql) {\n conditions.push(whereClause.sql);\n params.push(...whereClause.params);\n }\n if (paginationClause.sql) {\n conditions.push(paginationClause.sql);\n params.push(...paginationClause.params);\n }\n\n const documentClause = this.buildDocumentClause(options?.documents);\n if (documentClause) {\n conditions.push(documentClause.sql);\n params.push(...documentClause.params);\n }\n\n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(\" AND \")}`;\n }\n\n // Add ORDER BY\n if (orderClause.sql) {\n sql += ` ORDER BY ${orderClause.sql}`;\n }\n\n // Add LIMIT\n if (limitClause.sql) {\n sql += ` LIMIT ${limitClause.sql}`;\n }\n\n return {\n sql,\n params,\n sortFields: orderClause.fields,\n sortDirections: orderClause.directions,\n };\n }\n\n /**\n * Translate document filter to SQL for count operations\n */\n translateCount(\n filter: DocumentFilter,\n options?: Pick<QueryOptions, \"documents\">\n ): { sql: string; params: any[] } {\n const whereClause = this.translateFilter(filter);\n const documentClause = this.buildDocumentClause(options?.documents);\n\n const conditions: string[] = [];\n const params: any[] = [];\n\n if (whereClause.sql) {\n conditions.push(whereClause.sql);\n params.push(...whereClause.params);\n }\n if (documentClause) {\n conditions.push(documentClause.sql);\n params.push(...documentClause.params);\n }\n\n let sql = `SELECT COUNT(*) as count FROM ${this.quotedTableName}`;\n if (conditions.length > 0) {\n sql += ` WHERE ${conditions.join(\" AND \")}`;\n }\n\n return {\n sql,\n params,\n };\n }\n\n /**\n * Translate document filter to SQL WHERE clause\n */\n translateFilter(filter: DocumentFilter): {\n sql: string;\n params: any[];\n } {\n if (!filter || Object.keys(filter).length === 0) {\n return { sql: \"\", params: [] };\n }\n\n const conditions: string[] = [];\n const params: any[] = [];\n\n for (const [key, value] of Object.entries(filter)) {\n if (key === \"$and\") {\n const andClause = this.translateLogicalOperator(\n \"AND\",\n value as DocumentFilter[]\n );\n if (andClause.sql) {\n conditions.push(`(${andClause.sql})`);\n params.push(...andClause.params);\n }\n } else if (key === \"$or\") {\n const orClause = this.translateLogicalOperator(\n \"OR\",\n value as DocumentFilter[]\n );\n if (orClause.sql) {\n conditions.push(`(${orClause.sql})`);\n params.push(...orClause.params);\n }\n } else {\n // Regular field condition\n const fieldClause = this.translateFieldCondition(key, value);\n if (fieldClause.sql) {\n conditions.push(fieldClause.sql);\n params.push(...fieldClause.params);\n }\n }\n }\n\n return {\n sql: conditions.join(\" AND \"),\n params,\n };\n }\n\n /**\n * Translate logical operators ($and, $or)\n */\n private translateLogicalOperator(\n operator: \"AND\" | \"OR\",\n filters: DocumentFilter[]\n ): { sql: string; params: any[] } {\n if (!Array.isArray(filters) || filters.length === 0) {\n return { sql: \"\", params: [] };\n }\n\n const clauses: string[] = [];\n const params: any[] = [];\n\n for (const filter of filters) {\n const clause = this.translateFilter(filter);\n if (clause.sql) {\n clauses.push(clause.sql);\n params.push(...clause.params);\n }\n }\n\n if (clauses.length === 0) {\n return { sql: \"\", params: [] };\n }\n\n return {\n sql: clauses.join(` ${operator} `),\n params,\n };\n }\n\n /**\n * Translate field condition to SQL\n */\n private translateFieldCondition(\n fieldName: string,\n condition: any\n ): { sql: string; params: any[] } {\n const column = this.getQuotedField(fieldName);\n\n // Handle null/undefined values\n if (condition === null || condition === undefined) {\n return { sql: `${column} IS NULL`, params: [] };\n }\n\n // Simple equality for primitive values\n if (this.isPrimitiveValue(condition)) {\n this.validateFieldValue(fieldName, condition);\n return {\n sql: `${column} = ?`,\n params: [this.convertValueForSQLite(condition)],\n };\n }\n\n // Operator-based conditions\n if (typeof condition === \"object\" && !Array.isArray(condition)) {\n return this.translateFieldOperators(fieldName, condition);\n }\n\n // Array values (treat as $in)\n if (Array.isArray(condition)) {\n this.validateArrayValues(fieldName, condition);\n const placeholders = condition.map(() => \"?\").join(\",\");\n const convertedValues = condition.map((v) =>\n this.convertValueForSQLite(v)\n );\n return {\n sql: `${column} IN (${placeholders})`,\n params: convertedValues,\n };\n }\n\n throw new InvalidOperatorError(\n `Unsupported condition type for field ${fieldName}`,\n fieldName,\n \"unknown\"\n );\n }\n\n /**\n * Translate field operators to SQL\n */\n private translateFieldOperators(\n fieldName: string,\n operators: Record<string, any>\n ): { sql: string; params: any[] } {\n const conditions: string[] = [];\n const params: any[] = [];\n\n const fieldOptions = this.schema.get(fieldName);\n const fieldType = fieldOptions?.type;\n const column = this.getQuotedField(fieldName);\n\n // Handle substring operators (always case-insensitive)\n const substringOps = [\"$startsWith\", \"$endsWith\", \"$containsText\"] as const;\n const presentSubstringOps = substringOps.filter((op) =>\n Object.prototype.hasOwnProperty.call(operators, op)\n );\n\n if (presentSubstringOps.length > 1) {\n throw new InvalidOperatorError(\n `Only one of $startsWith, $endsWith, $containsText may be used per field`,\n fieldName,\n presentSubstringOps[1] as string,\n fieldType\n );\n }\n\n if (presentSubstringOps.length === 1) {\n const op = presentSubstringOps[0] as (typeof substringOps)[number];\n const value = (operators as any)[op];\n if (fieldType !== \"string\" && fieldType !== \"stringset\") {\n throw new InvalidOperatorError(\n `${op} operator is only supported for string and stringset fields, field ${fieldName} is type ${fieldType}`,\n fieldName,\n op as string,\n fieldType\n );\n }\n if (typeof value !== \"string\") {\n throw new InvalidOperatorError(\n `${op} operator requires a string value for field ${fieldName}`,\n fieldName,\n op as string,\n fieldType\n );\n }\n\n let pattern: string | null;\n try {\n const mode =\n op === \"$startsWith\"\n ? \"startsWith\"\n : op === \"$endsWith\"\n ? \"endsWith\"\n : \"containsText\";\n pattern = buildLikePattern(value, mode);\n } catch (e: any) {\n throw new InvalidOperatorError(\n e.message || \"invalid substring value\",\n fieldName,\n op as string,\n fieldType\n );\n }\n if (pattern !== null) {\n if (shouldLogLikeEscapes()) {\n try {\n console.debug(\n `[Substring] field=${fieldName} op=${op} pattern=${pattern} ci=true`\n );\n } catch {}\n }\n if (fieldType === \"string\") {\n const likeSql = `${column} LIKE ? ESCAPE '\\\\' COLLATE NOCASE`;\n conditions.push(likeSql);\n params.push(pattern);\n } else {\n // StringSet via EXISTS on junction\n const junctionTableName = `${this.tableName}_${fieldName}`;\n const foreignKeyColumn = `${this.modelName.toLowerCase()}_id`;\n const quotedJunctionTable = quoteIdentifier(junctionTableName);\n const quotedForeignKey = quoteIdentifier(foreignKeyColumn);\n const quotedValueColumn = quoteIdentifier(\"value\");\n const quotedPrimaryKey = quoteIdentifier(\"id\");\n const likeSql = `EXISTS (SELECT 1 FROM ${quotedJunctionTable} WHERE ${quotedJunctionTable}.${quotedForeignKey} = ${this.quotedTableName}.${quotedPrimaryKey} AND ${quotedJunctionTable}.${quotedValueColumn} LIKE ? ESCAPE '\\\\' COLLATE NOCASE)`;\n conditions.push(likeSql);\n params.push(pattern);\n }\n }\n }\n\n // Handle remaining operators (excluding substring ops)\n for (const [operator, value] of Object.entries(operators)) {\n if ((substringOps as readonly string[]).includes(operator)) {\n continue;\n }\n const opClause = this.translateOperator(fieldName, operator, value);\n if (opClause.sql) {\n conditions.push(opClause.sql);\n params.push(...opClause.params);\n }\n }\n\n return {\n sql: conditions.join(\" AND \"),\n params,\n };\n }\n\n /**\n * Translate individual operator to SQL\n */\n private translateOperator(\n fieldName: string,\n operator: string,\n value: any\n ): { sql: string; params: any[] } {\n const fieldOptions = this.schema.get(fieldName);\n const fieldType = fieldOptions?.type;\n const column = this.getQuotedField(fieldName);\n\n switch (operator) {\n case \"$eq\":\n this.validateFieldValue(fieldName, value);\n return {\n sql: `${column} = ?`,\n params: [this.convertValueForSQLite(value)],\n };\n\n case \"$ne\":\n this.validateFieldValue(fieldName, value);\n return {\n sql: `${column} != ?`,\n params: [this.convertValueForSQLite(value)],\n };\n\n case \"$gt\":\n this.validateOperatorForType(operator, fieldType, [\n \"id\",\n \"string\",\n \"number\",\n \"date\",\n ]);\n this.validateFieldValue(fieldName, value);\n return {\n sql: `${column} > ?`,\n params: [this.convertValueForSQLite(value)],\n };\n\n case \"$gte\":\n this.validateOperatorForType(operator, fieldType, [\n \"id\",\n \"string\",\n \"number\",\n \"date\",\n ]);\n this.validateFieldValue(fieldName, value);\n return {\n sql: `${column} >= ?`,\n params: [this.convertValueForSQLite(value)],\n };\n\n case \"$lt\":\n this.validateOperatorForType(operator, fieldType, [\n \"id\",\n \"string\",\n \"number\",\n \"date\",\n ]);\n this.validateFieldValue(fieldName, value);\n return {\n sql: `${column} < ?`,\n params: [this.convertValueForSQLite(value)],\n };\n\n case \"$lte\":\n this.validateOperatorForType(operator, fieldType, [\n \"id\",\n \"string\",\n \"number\",\n \"date\",\n ]);\n this.validateFieldValue(fieldName, value);\n return {\n sql: `${column} <= ?`,\n params: [this.convertValueForSQLite(value)],\n };\n\n case \"$in\":\n if (!Array.isArray(value)) {\n throw new InvalidOperatorError(\n `$in operator requires an array value for field ${fieldName}`,\n fieldName,\n operator,\n fieldType\n );\n }\n this.validateArrayValues(fieldName, value);\n if (value.length === 0) {\n return { sql: \"1 = 0\", params: [] }; // Always false for empty array\n }\n const placeholders = value.map(() => \"?\").join(\",\");\n const convertedValues = value.map((v) => this.convertValueForSQLite(v));\n return {\n sql: `${column} IN (${placeholders})`,\n params: convertedValues,\n };\n\n case \"$nin\":\n if (!Array.isArray(value)) {\n throw new InvalidOperatorError(\n `$nin operator requires an array value for field ${fieldName}`,\n fieldName,\n operator,\n fieldType\n );\n }\n this.validateArrayValues(fieldName, value);\n if (value.length === 0) {\n return { sql: \"\", params: [] }; // No condition for empty array\n }\n const ninPlaceholders = value.map(() => \"?\").join(\",\");\n const convertedNinValues = value.map((v) =>\n this.convertValueForSQLite(v)\n );\n return {\n sql: `${column} NOT IN (${ninPlaceholders})`,\n params: convertedNinValues,\n };\n\n case \"$exists\":\n if (typeof value !== \"boolean\") {\n throw new InvalidOperatorError(\n `$exists operator requires a boolean value for field ${fieldName}`,\n fieldName,\n operator,\n fieldType\n );\n }\n return value\n ? { sql: `${column} IS NOT NULL`, params: [] }\n : { sql: `${column} IS NULL`, params: [] };\n\n case \"$contains\":\n // $contains is specifically for stringset fields\n if (fieldType !== \"stringset\") {\n throw new InvalidOperatorError(\n `$contains operator is only supported for stringset fields, field ${fieldName} is type ${fieldType}`,\n fieldName,\n operator,\n fieldType\n );\n }\n if (typeof value !== \"string\") {\n throw new InvalidOperatorError(\n `$contains operator requires a string value for stringset field ${fieldName}`,\n fieldName,\n operator,\n fieldType\n );\n }\n // For StringSet fields, we need to join with the junction table\n const junctionTableName = `${this.tableName}_${fieldName}`;\n const foreignKeyColumn = `${this.modelName.toLowerCase()}_id`;\n const quotedJunctionTable = quoteIdentifier(junctionTableName);\n const quotedForeignKey = quoteIdentifier(foreignKeyColumn);\n const quotedValueColumn = quoteIdentifier(\"value\");\n const quotedPrimaryKey = quoteIdentifier(\"id\");\n return {\n sql: `EXISTS (SELECT 1 FROM ${quotedJunctionTable} WHERE ${quotedJunctionTable}.${quotedForeignKey} = ${this.quotedTableName}.${quotedPrimaryKey} AND ${quotedJunctionTable}.${quotedValueColumn} = ?)`,\n params: [value],\n };\n\n default:\n throw new InvalidOperatorError(\n `Unsupported operator: ${operator} for field ${fieldName}`,\n fieldName,\n operator,\n fieldType\n );\n }\n }\n\n /**\n * Build SELECT clause based on projection\n */\n private buildSelectClause(projection?: ProjectionSpec): string {\n if (!projection || Object.keys(projection).length === 0) {\n return \"*\";\n }\n\n const includeFields: string[] = [];\n const excludeFields: string[] = [];\n let hasIncludes = false;\n let hasExcludes = false;\n\n for (const [field, include] of Object.entries(projection)) {\n if (include === 1) {\n includeFields.push(field);\n hasIncludes = true;\n } else if (include === 0) {\n excludeFields.push(field);\n hasExcludes = true;\n }\n }\n\n // Can't mix includes and excludes (except for _id in MongoDB, but we don't have that concept)\n if (hasIncludes && hasExcludes) {\n throw new InvalidOperatorError(\n \"Cannot mix inclusion and exclusion in projection\",\n \"projection\",\n \"mixed\"\n );\n }\n\n if (hasIncludes) {\n // Always include id for model instances\n if (!includeFields.includes(\"id\")) {\n includeFields.unshift(\"id\");\n }\n const quoted = includeFields.map((field) => this.getQuotedField(field));\n return quoted.join(\", \");\n } else if (hasExcludes) {\n // Get all schema fields and exclude the specified ones\n const allFields = Array.from(this.schema.keys());\n const selectedFields = allFields.filter(\n (field) => !excludeFields.includes(field)\n );\n const quoted = selectedFields.map((field) => this.getQuotedField(field));\n return quoted.join(\", \");\n }\n\n return \"*\";\n }\n\n /**\n * Build LIMIT clause\n */\n private buildLimitClause(options?: QueryOptions): { sql: string } {\n if (options?.limit && options.limit > 0) {\n return { sql: options.limit.toString() };\n }\n return { sql: \"\" };\n }\n\n /**\n * Build pagination WHERE clause from cursor\n */\n private buildPaginationClause(\n options?: QueryOptions,\n sortFields?: string[],\n sortDirections?: (1 | -1)[]\n ): { sql: string; params: any[] } {\n if (!options?.uniqueStartKey || !sortFields || !sortDirections) {\n return { sql: \"\", params: [] };\n }\n\n try {\n const cursor = CursorManager.decodeCursor(options.uniqueStartKey);\n const direction = options.direction || 1;\n\n return CursorManager.buildPaginationConditions(\n cursor,\n sortFields,\n sortDirections,\n direction,\n (field) => this.getQuotedField(field)\n );\n } catch (error) {\n console.warn(\"Invalid cursor provided, ignoring pagination:\", error);\n return { sql: \"\", params: [] };\n }\n }\n\n /**\n * Validate that field exists in schema\n */\n private validateField(fieldName: string): void {\n if (!this.schema.has(fieldName) && !SYSTEM_FIELDS.has(fieldName)) {\n throw new InvalidFieldError(\n `Unknown field: ${fieldName} in model ${this.modelName}`,\n fieldName,\n this.modelName\n );\n }\n }\n\n /**\n * Validate projection fields\n */\n private validateProjection(projection: ProjectionSpec): void {\n for (const fieldName of Object.keys(projection)) {\n this.validateField(fieldName);\n }\n }\n\n /**\n * Validate operator is supported for field type\n */\n private validateOperatorForType(\n operator: string,\n fieldType: string | undefined,\n allowedTypes: string[]\n ): void {\n if (!fieldType) {\n console.warn(`Field type not specified, allowing operator ${operator}`);\n return;\n }\n\n if (!allowedTypes.includes(fieldType)) {\n throw new InvalidOperatorError(\n `Operator ${operator} is not supported for field type ${fieldType}. Allowed types: ${allowedTypes.join(\n \", \"\n )}`,\n \"unknown\",\n operator,\n fieldType\n );\n }\n }\n\n /**\n * Validate field value matches expected type\n */\n private validateFieldValue(fieldName: string, value: any): void {\n const fieldOptions = this.schema.get(fieldName);\n if (!fieldOptions || !fieldOptions.type) {\n return; // Skip validation if no type info\n }\n\n const expectedType = fieldOptions.type;\n const actualType = this.getValueType(value);\n\n if (!this.isTypeCompatible(expectedType, actualType, value)) {\n throw new InvalidOperatorError(\n `Field ${fieldName} expects ${expectedType}, got ${actualType}`,\n fieldName,\n \"type_mismatch\",\n expectedType\n );\n }\n }\n\n /**\n * Validate array values for $in/$nin operators\n */\n private validateArrayValues(fieldName: string, values: any[]): void {\n for (const value of values) {\n this.validateFieldValue(fieldName, value);\n }\n }\n\n /**\n * Check if value is a primitive (not an object with operators)\n */\n private isPrimitiveValue(value: any): boolean {\n if (value === null || value === undefined) {\n return true;\n }\n\n const type = typeof value;\n return (\n type === \"string\" ||\n type === \"number\" ||\n type === \"boolean\" ||\n value instanceof Date\n );\n }\n\n /**\n * Get the type of a value for validation\n */\n private getValueType(value: any): string {\n if (value === null || value === undefined) {\n return \"null\";\n }\n if (value instanceof Date) {\n return \"date\";\n }\n return typeof value;\n }\n\n /**\n * Check if value type is compatible with field type\n */\n private isTypeCompatible(\n expectedType: string,\n actualType: string,\n value: any\n ): boolean {\n if (actualType === \"null\") {\n return true; // null is compatible with any type\n }\n\n switch (expectedType) {\n case \"id\":\n return actualType === \"string\"; // id fields are strings\n case \"string\":\n return actualType === \"string\";\n case \"number\":\n return actualType === \"number\" && !isNaN(value);\n case \"boolean\":\n return actualType === \"boolean\";\n case \"date\":\n return (\n actualType === \"date\" ||\n (actualType === \"string\" && !isNaN(Date.parse(value)))\n );\n default:\n return true; // Unknown types are allowed\n }\n }\n\n /**\n * Convert value for SQLite compatibility\n */\n private convertValueForSQLite(value: any): any {\n // Convert boolean to integer for SQLite\n if (typeof value === \"boolean\") {\n return value ? 1 : 0;\n }\n return value;\n }\n\n private normalizeDocumentIds(documents?: string | string[]): string[] | null {\n if (documents == null) {\n return null;\n }\n\n const docArray = Array.isArray(documents) ? documents : [documents];\n const normalized = docArray\n .map((doc) => `${doc}`.trim())\n .filter((doc) => doc.length > 0);\n\n if (normalized.length === 0) {\n return [];\n }\n\n return Array.from(new Set(normalized));\n }\n\n private buildDocumentClause(\n documents?: string | string[]\n ): { sql: string; params: any[] } | null {\n const normalized = this.normalizeDocumentIds(documents);\n if (normalized === null) {\n return null;\n }\n\n if (normalized.length === 0) {\n return { sql: \"1 = 0\", params: [] };\n }\n\n const placeholders = normalized.map(() => \"?\").join(\", \");\n return {\n sql: `${quoteIdentifier(\"_meta_doc_id\")} IN (${placeholders})`,\n params: normalized,\n };\n }\n}\n"],"mappings":"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","names":["LogLevel","fieldValue","documentInfo","constraintMapName","constraintMap","recordId","recordYMap"]}