babymongo 0.2.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"babymongo-browser.min.js","sources":["../node_modules/events/events.js","../src/errors.js","../src/client/ProxyChangeStream.js","../src/client/ProxyCursor.js","../src/client/ProxyCollection.js","../src/client/ProxyDB.js","../src/client/MongoClient.js","../node_modules/@belteshazzar/binjson/src/binjson.js","../src/utils.js","../node_modules/stemmer/index.js","../node_modules/@belteshazzar/binjson/src/textindex.js","../src/server/aggregationExpressions.js","../src/server/queryMatcher.js","../src/server/ChangeStream.js","../src/PerformanceTimer.js","../src/client/WorkerBridge.js"],"sourcesContent":["// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\nmodule.exports.once = once;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nfunction checkListener(listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n}\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction _getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return _getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n var args = [];\n for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n var doError = (type === 'error');\n\n var events = this._events;\n if (events !== undefined)\n doError = (doError && events.error === undefined);\n else if (!doError)\n return false;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n var er;\n if (args.length > 0)\n er = args[0];\n if (er instanceof Error) {\n // Note: The comments on the `throw` lines are intentional, they show\n // up in Node's output if this results in an unhandled exception.\n throw er; // Unhandled 'error' event\n }\n // At least give some kind of context to the user\n var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n err.context = er;\n throw err; // Unhandled 'error' event\n }\n\n var handler = events[type];\n\n if (handler === undefined)\n return false;\n\n if (typeof handler === 'function') {\n ReflectApply(handler, this, args);\n } else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n ReflectApply(listeners[i], this, args);\n }\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n checkListener(listener);\n\n events = target._events;\n if (events === undefined) {\n events = target._events = Object.create(null);\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener !== undefined) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign `events` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (existing === undefined) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] =\n prepend ? [listener, existing] : [existing, listener];\n // If we've already got an array, just append.\n } else if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n\n // Check for listener leak\n m = _getMaxListeners(target);\n if (m > 0 && existing.length > m && !existing.warned) {\n existing.warned = true;\n // No error code for this since it is a Warning\n // eslint-disable-next-line no-restricted-syntax\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + String(type) + ' listeners ' +\n 'added. Use emitter.setMaxListeners() to ' +\n 'increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n ProcessEmitWarning(w);\n }\n }\n\n return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction onceWrapper() {\n if (!this.fired) {\n this.target.removeListener(this.type, this.wrapFn);\n this.fired = true;\n if (arguments.length === 0)\n return this.listener.call(this.target);\n return this.listener.apply(this.target, arguments);\n }\n}\n\nfunction _onceWrap(target, type, listener) {\n var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n var wrapped = onceWrapper.bind(state);\n wrapped.listener = listener;\n state.wrapFn = wrapped;\n return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n checkListener(listener);\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n checkListener(listener);\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n checkListener(listener);\n\n events = this._events;\n if (events === undefined)\n return this;\n\n list = events[type];\n if (list === undefined)\n return this;\n\n if (list === listener || list.listener === listener) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length - 1; i >= 0; i--) {\n if (list[i] === listener || list[i].listener === listener) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (position === 0)\n list.shift();\n else {\n spliceOne(list, position);\n }\n\n if (list.length === 1)\n events[type] = list[0];\n\n if (events.removeListener !== undefined)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events, i;\n\n events = this._events;\n if (events === undefined)\n return this;\n\n // not listening for removeListener, no need to emit\n if (events.removeListener === undefined) {\n if (arguments.length === 0) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n } else if (events[type] !== undefined) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n var key;\n for (i = 0; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = Object.create(null);\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners !== undefined) {\n // LIFO order\n for (i = listeners.length - 1; i >= 0; i--) {\n this.removeListener(type, listeners[i]);\n }\n }\n\n return this;\n };\n\nfunction _listeners(target, type, unwrap) {\n var events = target._events;\n\n if (events === undefined)\n return [];\n\n var evlistener = events[type];\n if (evlistener === undefined)\n return [];\n\n if (typeof evlistener === 'function')\n return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n return unwrap ?\n unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events !== undefined) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener !== undefined) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n var copy = new Array(n);\n for (var i = 0; i < n; ++i)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction spliceOne(list, index) {\n for (; index + 1 < list.length; index++)\n list[index] = list[index + 1];\n list.pop();\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\n\nfunction once(emitter, name) {\n return new Promise(function (resolve, reject) {\n function errorListener(err) {\n emitter.removeListener(name, resolver);\n reject(err);\n }\n\n function resolver() {\n if (typeof emitter.removeListener === 'function') {\n emitter.removeListener('error', errorListener);\n }\n resolve([].slice.call(arguments));\n };\n\n eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });\n if (name !== 'error') {\n addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });\n }\n });\n}\n\nfunction addErrorHandlerIfEventEmitter(emitter, handler, flags) {\n if (typeof emitter.on === 'function') {\n eventTargetAgnosticAddListener(emitter, 'error', handler, flags);\n }\n}\n\nfunction eventTargetAgnosticAddListener(emitter, name, listener, flags) {\n if (typeof emitter.on === 'function') {\n if (flags.once) {\n emitter.once(name, listener);\n } else {\n emitter.on(name, listener);\n }\n } else if (typeof emitter.addEventListener === 'function') {\n // EventTarget does not have `error` event semantics like Node\n // EventEmitters, we do not listen for `error` events here.\n emitter.addEventListener(name, function wrapListener(arg) {\n // IE does not have builtin `{ once: true }` support so we\n // have to do it manually.\n if (flags.once) {\n emitter.removeEventListener(name, wrapListener);\n }\n listener(arg);\n });\n } else {\n throw new TypeError('The \"emitter\" argument must be of type EventEmitter. Received type ' + typeof emitter);\n }\n}\n","/**\n * MongoDB Error Classes\n * \n * Structured error hierarchy compatible with MongoDB driver\n */\n\n/**\n * Error codes matching MongoDB error codes\n */\nexport const ErrorCodes = {\n\t// General errors\n\tOK: 0,\n\tINTERNAL_ERROR: 1,\n\tBAD_VALUE: 2,\n\tNO_SUCH_KEY: 4,\n\tGRAPH_CONTAINS_CYCLE: 5,\n\tHOST_UNREACHABLE: 6,\n\tHOST_NOT_FOUND: 7,\n\tUNKNOWN_ERROR: 8,\n\tFAILED_TO_PARSE: 17287, // Using test-compatible error code\n\tCANNOT_MUTATE_OBJECT: 10,\n\tUSER_NOT_FOUND: 11,\n\tUNSUPPORTED_FORMAT: 12,\n\tUNAUTHORIZED: 13,\n\tTYPE_MISMATCH: 14,\n\tOVERFLOW: 15,\n\tINVALID_LENGTH: 16,\n\tPROTOCOL_ERROR: 17,\n\tAUTHENTICATION_FAILED: 18,\n\tILLEGAL_OPERATION: 20,\n\tNAMESPACE_NOT_FOUND: 26,\n\tINDEX_NOT_FOUND: 27,\n\tPATH_NOT_VIABLE: 28,\n\tCANNOT_CREATE_INDEX: 67,\n\tINDEX_ALREADY_EXISTS: 68,\n\tINDEX_EXISTS: 68,\n\tCOMMAND_NOT_FOUND: 59,\n\tNAMESPACE_EXISTS: 48,\n\tINVALID_NAMESPACE: 73,\n\tINDEX_OPTIONS_CONFLICT: 85,\n\tINVALID_INDEX_SPECIFICATION_OPTION: 197,\n\t\n\t// Write errors\n\tWRITE_CONFLICT: 112,\n\tDUPLICATE_KEY: 11000,\n\tDUPLICATE_KEY_UPDATE: 11001,\n\t\n\t// Validation errors\n\tDOCUMENT_VALIDATION_FAILURE: 121,\n\t\n\t// Query errors\n\tBAD_QUERY: 2,\n\tCANNOT_INDEX_PARALLEL_ARRAYS: 171,\n\t\n\t// Cursor errors\n\tCURSOR_NOT_FOUND: 43,\n\t\n\t// Collection errors\n\tCOLLECTION_IS_EMPTY: 26,\n CANNOT_DO_EXCLUSION_ON_FIELD_ID_IN_INCLUSION_PROJECTION: 31254,\n\t\n\t// Not implemented (custom code)\n\tNOT_IMPLEMENTED: 999,\n\tOPERATION_NOT_SUPPORTED: 998\n};\n\n/**\n * Base class for all MongoDB errors\n */\nexport class MongoError extends Error {\n\tconstructor(message, options = {}) {\n\t\tsuper(message);\n\t\tthis.name = 'MongoError';\n\t\tthis.code = options.code || ErrorCodes.UNKNOWN_ERROR;\n\t\tthis.codeName = this._getCodeName(this.code);\n\t\t\n\t\t// Backward compatibility: add $err property matching old error format\n\t\tthis.$err = message;\n\t\t\n\t\t// Additional context\n\t\tif (options.collection) this.collection = options.collection;\n\t\tif (options.database) this.database = options.database;\n\t\tif (options.operation) this.operation = options.operation;\n\t\tif (options.query) this.query = options.query;\n\t\tif (options.document) this.document = options.document;\n\t\tif (options.field) this.field = options.field;\n\t\tif (options.index) this.index = options.index;\n\t\t\n\t\t// Capture stack trace\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, this.constructor);\n\t\t}\n\t}\n\t\n\t_getCodeName(code) {\n\t\tconst codeToName = {\n\t\t\t0: 'OK',\n\t\t\t1: 'InternalError',\n\t\t\t2: 'BadValue',\n\t\t\t4: 'NoSuchKey',\n\t\t\t5: 'GraphContainsCycle',\n\t\t\t6: 'HostUnreachable',\n\t\t\t7: 'HostNotFound',\n\t\t\t8: 'UnknownError',\n\t\t\t10: 'CannotMutateObject',\n\t\t\t11: 'UserNotFound',\n\t\t\t12: 'UnsupportedFormat',\n\t\t\t13: 'Unauthorized',\n\t\t\t14: 'TypeMismatch',\n\t\t\t15: 'Overflow',\n\t\t\t16: 'InvalidLength',\n\t\t\t17: 'ProtocolError',\n\t\t\t18: 'AuthenticationFailed',\n\t\t\t20: 'IllegalOperation',\n\t\t\t26: 'NamespaceNotFound',\n\t\t\t27: 'IndexNotFound',\n\t\t\t28: 'PathNotViable',\n\t\t\t43: 'CursorNotFound',\n\t\t\t48: 'NamespaceExists',\n\t\t\t59: 'CommandNotFound',\n\t\t\t67: 'CannotCreateIndex',\n\t\t\t68: 'IndexExists',\n\t\t\t73: 'InvalidNamespace',\n\t\t\t85: 'IndexOptionsConflict',\n\t\t\t112: 'WriteConflict',\n\t\t\t121: 'DocumentValidationFailure',\n\t\t\t171: 'CannotIndexParallelArrays',\n\t\t\t197: 'InvalidIndexSpecificationOption',\n\t\t\t998: 'OperationNotSupported',\n\t\t\t999: 'NotImplemented',\n\t\t\t11000: 'DuplicateKey',\n\t\t\t11001: 'DuplicateKeyUpdate',\n\t\t\t17287: 'FailedToParse'\n\t\t};\n\t\treturn codeToName[code] || 'UnknownError';\n\t}\n\t\n\ttoJSON() {\n\t\tconst json = {\n\t\t\tname: this.name,\n\t\t\tmessage: this.message,\n\t\t\tcode: this.code,\n\t\t\tcodeName: this.codeName\n\t\t};\n\t\t\n\t\t// Include all enumerable properties\n\t\tif (this.collection) json.collection = this.collection;\n\t\tif (this.database) json.database = this.database;\n\t\tif (this.operation) json.operation = this.operation;\n\t\tif (this.index) json.index = this.index;\n\t\tif (this.indexName) json.indexName = this.indexName;\n\t\tif (this.field) json.field = this.field;\n\t\tif (this.query) json.query = this.query;\n\t\tif (this.document) json.document = this.document;\n\t\tif (this.namespace) json.namespace = this.namespace;\n\t\tif (this.cursorId) json.cursorId = this.cursorId;\n\t\tif (this.feature) json.feature = this.feature;\n\t\tif (this.keyPattern) json.keyPattern = this.keyPattern;\n\t\tif (this.keyValue) json.keyValue = this.keyValue;\n\t\tif (this.writeErrors) json.writeErrors = this.writeErrors;\n\t\t\n\t\treturn json;\n\t}\n}\n\n/**\n * Server-side errors\n */\nexport class MongoServerError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'MongoServerError';\n\t}\n}\n\n/**\n * Driver-side errors (client errors)\n */\nexport class MongoDriverError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'MongoDriverError';\n\t\tthis.code = options.code || ErrorCodes.INTERNAL_ERROR;\n\t}\n}\n\n/**\n * Write operation errors\n */\nexport class WriteError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'WriteError';\n\t\tthis.code = options.code || ErrorCodes.WRITE_CONFLICT;\n\t}\n}\n\n/**\n * Duplicate key error\n */\nexport class DuplicateKeyError extends WriteError {\n\tconstructor(key, options = {}) {\n\t\tconst keyStr = JSON.stringify(key);\n\t\tconst message = `E11000 duplicate key error${options.collection ? ` collection: ${options.collection}` : ''} index: ${keyStr} dup key: ${keyStr}`;\n\t\tsuper(message, { ...options, code: ErrorCodes.DUPLICATE_KEY });\n\t\tthis.name = 'DuplicateKeyError';\n\t\tthis.keyPattern = key;\n\t\tthis.keyValue = options.keyValue || key;\n\t}\n}\n\n/**\n * Document validation errors\n */\nexport class ValidationError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'ValidationError';\n\t\tthis.code = options.code || ErrorCodes.DOCUMENT_VALIDATION_FAILURE;\n\t\tthis.validationErrors = options.validationErrors || [];\n\t}\n}\n\n/**\n * Index-related errors\n */\nexport class IndexError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'IndexError';\n\t}\n}\n\n/**\n * Index already exists error\n */\nexport class IndexExistsError extends IndexError {\n\tconstructor(indexName, options = {}) {\n\t\tsuper(`Index with name '${indexName}' already exists`, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.INDEX_EXISTS\n\t\t});\n\t\tthis.name = 'IndexExistsError';\n\t\tthis.indexName = indexName;\n\t}\n}\n\n/**\n * Index not found error\n */\nexport class IndexNotFoundError extends IndexError {\n\tconstructor(indexName, options = {}) {\n\t\tsuper(`Index '${indexName}' not found`, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.INDEX_NOT_FOUND,\n\t\t\tindex: indexName\n\t\t});\n\t\tthis.name = 'IndexNotFoundError';\n\t\tthis.indexName = indexName;\n\t}\n}\n\n/**\n * Cannot create index error\n */\nexport class CannotCreateIndexError extends IndexError {\n\tconstructor(reason, options = {}) {\n\t\tsuper(`Cannot create index: ${reason}`, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.CANNOT_CREATE_INDEX\n\t\t});\n\t\tthis.name = 'CannotCreateIndexError';\n\t}\n}\n\n/**\n * Query errors\n */\nexport class QueryError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'QueryError';\n\t\tthis.code = options.code || ErrorCodes.BAD_QUERY;\n\t}\n}\n\n/**\n * Type mismatch error\n */\nexport class TypeMismatchError extends MongoError {\n\tconstructor(field, expectedType, actualType, options = {}) {\n\t\tsuper(\n\t\t\t`Type mismatch for field '${field}': expected ${expectedType}, got ${actualType}`,\n\t\t\t{ ...options, code: ErrorCodes.TYPE_MISMATCH, field }\n\t\t);\n\t\tthis.name = 'TypeMismatchError';\n\t\tthis.expectedType = expectedType;\n\t\tthis.actualType = actualType;\n\t}\n}\n\n/**\n * Namespace errors\n */\nexport class NamespaceError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'NamespaceError';\n\t}\n}\n\n/**\n * Namespace not found\n */\nexport class NamespaceNotFoundError extends NamespaceError {\n\tconstructor(namespace, options = {}) {\n\t\tsuper(`Namespace '${namespace}' not found`, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.NAMESPACE_NOT_FOUND\n\t\t});\n\t\tthis.name = 'NamespaceNotFoundError';\n\t\tthis.namespace = namespace;\n\t}\n}\n\n/**\n * Invalid namespace\n */\nexport class InvalidNamespaceError extends NamespaceError {\n\tconstructor(namespace, reason, options = {}) {\n\t\t// Handle case where reason is actually options\n\t\tif (typeof reason === 'object' && !options) {\n\t\t\toptions = reason;\n\t\t\treason = undefined;\n\t\t}\n\t\tconst msg = reason ? `Invalid namespace '${namespace}': ${reason}` : `Invalid namespace '${namespace}'`;\n\t\tsuper(msg, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.INVALID_NAMESPACE\n\t\t});\n\t\tthis.name = 'InvalidNamespaceError';\n\t\tthis.namespace = namespace;\n\t}\n}\n\n/**\n * Cursor errors\n */\nexport class CursorError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'CursorError';\n\t}\n}\n\n/**\n * Cursor not found\n */\nexport class CursorNotFoundError extends CursorError {\n\tconstructor(cursorId, options = {}) {\n\t\tsuper(`Cursor ${cursorId} not found`, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.CURSOR_NOT_FOUND\n\t\t});\n\t\tthis.name = 'CursorNotFoundError';\n\t\tthis.cursorId = cursorId;\n\t}\n}\n\n/**\n * Not implemented error\n */\nexport class NotImplementedError extends MongoError {\n\tconstructor(feature, options = {}) {\n\t\tsuper(`${feature} is not implemented in babymongo`, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.NOT_IMPLEMENTED\n\t\t});\n\t\tthis.name = 'NotImplementedError';\n\t\tthis.feature = feature;\n\t}\n}\n\n/**\n * Operation not supported\n */\nexport class OperationNotSupportedError extends MongoError {\n\tconstructor(operation, reason, options = {}) {\n\t\t// Handle case where reason is actually options\n\t\tif (typeof reason === 'object' && !options) {\n\t\t\toptions = reason;\n\t\t\treason = undefined;\n\t\t}\n\t\tconst msg = reason ? `Operation '${operation}' is not supported: ${reason}` : `Operation '${operation}' is not supported`;\n\t\tsuper(msg, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.OPERATION_NOT_SUPPORTED,\n\t\t\toperation\n\t\t});\n\t\tthis.name = 'OperationNotSupportedError';\n\t}\n}\n\n/**\n * Bad value error\n */\nexport class BadValueError extends MongoError {\n\tconstructor(field, value, reason, options = {}) {\n\t\tsuper(`Bad value for field '${field}': ${reason}`, {\n\t\t\t...options,\n\t\t\tcode: ErrorCodes.BAD_VALUE,\n\t\t\tfield\n\t\t});\n\t\tthis.name = 'BadValueError';\n\t\tthis.value = value;\n\t}\n}\n\n/**\n * Bulk write error\n */\nexport class BulkWriteError extends MongoError {\n\tconstructor(writeErrors = [], options = {}) {\n\t\tconst message = `Bulk write operation error: ${writeErrors.length} error(s)`;\n\t\tsuper(message, options);\n\t\tthis.name = 'BulkWriteError';\n\t\tthis.writeErrors = writeErrors;\n\t\tthis.code = options.code || ErrorCodes.WRITE_CONFLICT;\n\t}\n}\n\n/**\n * Network error (for API compatibility, not functional in babymongo)\n */\nexport class MongoNetworkError extends MongoError {\n\tconstructor(message, options = {}) {\n\t\tsuper(message, options);\n\t\tthis.name = 'MongoNetworkError';\n\t\tthis.code = options.code || ErrorCodes.HOST_UNREACHABLE;\n\t}\n}\n\n/**\n * Helper function to create appropriate error\n */\nexport function createError(type, ...args) {\n\tswitch (type) {\n\t\tcase 'duplicate_key':\n\t\t\treturn new DuplicateKeyError(...args);\n\t\tcase 'validation':\n\t\t\treturn new ValidationError(...args);\n\t\tcase 'index_exists':\n\t\t\treturn new IndexExistsError(...args);\n\t\tcase 'index_not_found':\n\t\t\treturn new IndexNotFoundError(...args);\n\t\tcase 'cannot_create_index':\n\t\t\treturn new CannotCreateIndexError(...args);\n\t\tcase 'query':\n\t\t\treturn new QueryError(...args);\n\t\tcase 'type_mismatch':\n\t\t\treturn new TypeMismatchError(...args);\n\t\tcase 'namespace_not_found':\n\t\t\treturn new NamespaceNotFoundError(...args);\n\t\tcase 'invalid_namespace':\n\t\t\treturn new InvalidNamespaceError(...args);\n\t\tcase 'cursor_not_found':\n\t\t\treturn new CursorNotFoundError(...args);\n\t\tcase 'not_implemented':\n\t\t\treturn new NotImplementedError(...args);\n\t\tcase 'operation_not_supported':\n\t\t\treturn new OperationNotSupportedError(...args);\n\t\tcase 'bad_value':\n\t\t\treturn new BadValueError(...args);\n\t\tcase 'write':\n\t\t\treturn new WriteError(...args);\n\t\tdefault:\n\t\t\treturn new MongoError(...args);\n\t}\n}\n","import { EventEmitter } from 'events';\nimport { NotImplementedError } from '../errors.js';\n\n/**\n * ProxyChangeStream listens for forwarded events from the worker.\n */\nexport class ProxyChangeStream extends EventEmitter {\n static create({ bridge, database, collection, streamId, pipeline = [], options = {} }) {\n const stream = new ProxyChangeStream({ bridge, streamId });\n \n if (!streamId) {\n // Determine target type based on what we're watching\n let target, method;\n if (database === null || database === undefined) {\n // Client-level watch (all databases and collections)\n target = 'client';\n method = 'watch';\n } else if (collection === null || collection === undefined) {\n // Database-level watch\n target = 'db';\n method = 'watch';\n } else {\n // Collection-level watch\n target = 'collection';\n method = 'watch';\n }\n \n // Request a change stream from worker asynchronously\n bridge.sendRequest({\n target,\n database,\n collection,\n method,\n args: [pipeline, options]\n }).then((resp) => {\n if (resp && resp.streamId) {\n stream.streamId = resp.streamId; // Update stream with the ID\n }\n }).catch(() => {\n // Ignore errors during async initialization\n });\n }\n\n return stream;\n }\n\n constructor({ bridge, streamId }) {\n super();\n this.bridge = bridge;\n this.streamId = streamId;\n this.closed = false;\n this._pendingNext = []; // Track pending next() promises\n\n this._onEvent = this._onEvent.bind(this);\n this.bridge.on('event', this._onEvent);\n }\n\n _onEvent(eventName, payload) {\n if (eventName !== 'changeStream') return;\n if (!payload || payload.streamId !== this.streamId) return;\n\n const { type, data } = payload;\n if (type === 'change') this.emit('change', data);\n if (type === 'error') this.emit('error', data);\n if (type === 'close') {\n this.emit('close');\n this._cleanup();\n }\n }\n\n _cleanup() {\n this.bridge.off('event', this._onEvent);\n }\n\n async close() {\n if (this.closed) return;\n this.closed = true;\n \n // Resolve all pending next() calls with null\n for (const pending of this._pendingNext) {\n pending.resolve(null);\n }\n this._pendingNext = [];\n \n // Send close request to server (don't await to avoid blocking)\n this.bridge.sendRequest({\n target: 'changestream',\n streamId: this.streamId,\n method: 'close'\n }).catch(() => {\n // Ignore errors from server-side close\n });\n \n // Emit close event locally\n this.emit('close');\n \n // Cleanup\n this._cleanup();\n }\n\n async next() {\n // If already closed, return null immediately\n if (this.closed) {\n return null;\n }\n \n // Return a promise that resolves when the next change event arrives\n return new Promise((resolve, reject) => {\n const onChange = (change) => {\n this._removePending(pending);\n this.off('change', onChange);\n this.off('error', onError);\n this.off('close', onClose);\n resolve(change);\n };\n const onError = (error) => {\n this._removePending(pending);\n this.off('change', onChange);\n this.off('error', onError);\n this.off('close', onClose);\n reject(error);\n };\n const onClose = () => {\n this._removePending(pending);\n this.off('change', onChange);\n this.off('error', onError);\n this.off('close', onClose);\n resolve(null);\n };\n \n // Track this pending promise\n const pending = { resolve, reject };\n this._pendingNext.push(pending);\n \n this.on('change', onChange);\n this.on('error', onError);\n this.on('close', onClose);\n });\n }\n \n _removePending(pending) {\n const index = this._pendingNext.indexOf(pending);\n if (index !== -1) {\n this._pendingNext.splice(index, 1);\n }\n }\n\n /**\n * Async iterator support for for-await-of loops\n */\n async *[Symbol.asyncIterator]() {\n while (!this.closed) {\n const change = await this.next();\n if (change === null) {\n break;\n }\n yield change;\n }\n }\n}\n","/**\n * ProxyCursor lives on the main thread and batches getMore calls to the worker.\n */\nexport class ProxyCursor {\n constructor({ bridge, cursorId, batch = [], exhausted = false, batchSize = 100, requestPromise, requestPayload }) {\n this.bridge = bridge;\n this.cursorId = cursorId;\n this.buffer = Array.isArray(batch) ? batch : [];\n this.exhausted = exhausted || false;\n this._batchSize = batchSize;\n this._requestPromise = requestPromise || null;\n this._requestPayload = requestPayload || null; // Store payload for delayed execution\n this._initialized = !requestPromise && !requestPayload; // If no requestPromise or payload, already initialized\n }\n\n async _ensureInitialized() {\n if (this._initialized) return;\n \n // If we have a payload (delayed execution), build the request with cursor modifiers\n if (this._requestPayload) {\n const cursorOpts = {};\n if (this._limit !== undefined) cursorOpts.limit = this._limit;\n if (this._skip !== undefined) cursorOpts.skip = this._skip;\n if (this._sort !== undefined) cursorOpts.sort = this._sort;\n if (this._min !== undefined) cursorOpts.min = this._min;\n if (this._max !== undefined) cursorOpts.max = this._max;\n if (this._hint !== undefined) cursorOpts.hint = this._hint;\n if (this._comment !== undefined) cursorOpts.comment = this._comment;\n if (this._maxTimeMS !== undefined) cursorOpts.maxTimeMS = this._maxTimeMS;\n if (this._maxScan !== undefined) cursorOpts.maxScan = this._maxScan;\n if (this._returnKey !== undefined) cursorOpts.returnKey = this._returnKey;\n if (this._showRecordId !== undefined) cursorOpts.showRecordId = this._showRecordId;\n if (this._collation !== undefined) cursorOpts.collation = this._collation;\n \n // Attach cursor options to the payload\n this._requestPayload.cursorOpts = cursorOpts;\n \n const res = await this.bridge.sendRequest(this._requestPayload);\n this.cursorId = res.cursorId;\n this.buffer = res.batch || [];\n this.exhausted = res.exhausted || false;\n this._batchSize = res.batchSize || 100;\n this._requestPayload = null;\n this._initialized = true;\n } else if (this._requestPromise) {\n // Legacy path for already-initiated requests\n const res = await this._requestPromise;\n this.cursorId = res.cursorId;\n this.buffer = res.batch || [];\n this.exhausted = res.exhausted || false;\n this._batchSize = res.batchSize || 100;\n this._requestPromise = null;\n this._initialized = true;\n }\n }\n\n async hasNext() {\n if (this._closed) return false;\n await this._ensureInitialized();\n if (this.buffer.length > 0) return true;\n if (this.exhausted) return false;\n await this._getMore();\n return this.buffer.length > 0;\n }\n\n async next() {\n const has = await this.hasNext();\n if (!has) return null;\n return this.buffer.shift();\n }\n\n async toArray() {\n await this._ensureInitialized();\n const results = [...this.buffer];\n this.buffer = [];\n while (!this.exhausted) {\n await this._getMore();\n results.push(...this.buffer);\n this.buffer = [];\n }\n return results;\n }\n\n async count() {\n // Fetch all documents and return count\n const arr = await this.toArray();\n return arr.length;\n }\n\n // Cursor modifiers that return this for chaining\n limit(n) {\n this._limit = n;\n return this;\n }\n\n skip(n) {\n this._skip = n;\n return this;\n }\n\n sort(spec) {\n this._sort = spec;\n return this;\n }\n\n batchSize(n) {\n this._batchSize = n;\n return this;\n }\n\n // Cursor metadata methods\n async close() {\n this._closed = true;\n await this._closeRemote();\n // Return false to match MongoDB behavior (false means not already closed)\n return false;\n }\n\n isClosed() {\n return this._closed || false;\n }\n\n comment(str) {\n this._comment = str;\n return this;\n }\n\n hint(spec) {\n this._hint = spec;\n return this;\n }\n\n explain(verbosity = 'queryPlanner') {\n // Return a basic explanation without sending to worker\n // Since we already have the cursor initialized, we can provide basic info\n const result = {\n queryPlanner: {\n plannerVersion: 1,\n namespace: `unknown`,\n indexFilterSet: false,\n parsedQuery: {},\n winningPlan: {\n stage: 'COLLSCAN'\n }\n },\n ok: 1\n };\n \n if (verbosity === 'executionStats' || verbosity === 'allPlansExecution') {\n result.executionStats = {\n executionSuccess: true,\n nReturned: 0,\n executionTimeMillis: 0\n };\n }\n \n return result;\n }\n\n async itcount() {\n // Iterate and count - must respect limit/skip\n let count = 0;\n while (await this.hasNext()) {\n await this.next();\n count++;\n }\n return count;\n }\n\n size() {\n // Return count of documents currently in buffer (without fetching more)\n return this.buffer.length;\n }\n\n min(spec) {\n this._min = spec;\n this._minIndexBounds = spec;\n return this;\n }\n\n max(spec) {\n this._max = spec;\n this._maxIndexBounds = spec;\n return this;\n }\n\n maxTimeMS(ms) {\n this._maxTimeMS = ms;\n return this;\n }\n\n maxScan(n) {\n this._maxScan = n;\n return this;\n }\n\n noCursorTimeout() {\n this._noCursorTimeout = true;\n return this;\n }\n\n objsLeftInBatch() {\n return this.buffer.length;\n }\n\n pretty() {\n this._pretty = true;\n return this;\n }\n\n readConcern(level) {\n this._readConcern = level;\n return this;\n }\n\n readPref(mode, tagSet) {\n this._readPref = { mode, tagSet };\n return this;\n }\n\n returnKey(bool = true) {\n this._returnKey = bool;\n return this;\n }\n\n showRecordId(bool = true) {\n this._showRecordId = bool;\n return this;\n }\n\n allowDiskUse(bool = true) {\n this._allowDiskUse = bool;\n return this;\n }\n\n collation(spec) {\n this._collation = spec;\n return this;\n }\n\n async forEach(fn) {\n while (await this.hasNext()) {\n const doc = await this.next();\n await fn(doc);\n }\n }\n\n async map(fn) {\n const results = [];\n while (await this.hasNext()) {\n const doc = await this.next();\n results.push(await fn(doc));\n }\n return results;\n }\n\n // Support async iteration\n async *[Symbol.asyncIterator]() {\n while (await this.hasNext()) {\n yield await this.next();\n }\n }\n\n async _getMore() {\n if (this.exhausted) return;\n const resp = await this.bridge.sendRequest({\n target: 'cursor',\n cursorId: this.cursorId,\n method: 'getMore',\n args: [{ batchSize: this._batchSize }]\n });\n this.buffer = resp?.batch || [];\n this.exhausted = !!resp?.exhausted;\n if (this.exhausted) {\n // Optionally inform worker to clean up (close)\n await this._closeRemote();\n }\n }\n\n async _closeRemote() {\n if (!this.cursorId) return;\n try {\n await this.bridge.sendRequest({\n target: 'cursor',\n cursorId: this.cursorId,\n method: 'close'\n });\n } catch (_) {\n // Swallow cleanup errors\n }\n this.cursorId = null;\n }\n}\n","import { ProxyChangeStream } from './ProxyChangeStream.js';\nimport { ProxyCursor } from './ProxyCursor.js';\nimport { NotImplementedError, QueryError, ErrorCodes } from '../errors.js';\n\n/**\n * ProxyCollection lives on the main thread and forwards operations to the worker Server.\n */\nexport class ProxyCollection {\n constructor({ dbName, name, bridge, db }) {\n this.dbName = dbName;\n this.name = name;\n this.bridge = bridge;\n this._db = db; // Reference to ProxyDB for registering new collections\n this.indexes = []; // Track indexes locally\n\n return new Proxy(this, {\n get: (target, prop, receiver) => {\n if (prop in target) return Reflect.get(target, prop, receiver);\n if (typeof prop === 'symbol' || String(prop).startsWith('_')) return undefined;\n if (prop === 'watch') {\n return (...args) => target._watch(...args);\n }\n // Special handling for methods that return cursors - return cursor immediately\n if (prop === 'find' || prop === 'aggregate') {\n return (...args) => target._cursorMethod(String(prop), args);\n }\n return (...args) => target._call(String(prop), args);\n }\n });\n }\n\n _cursorMethod(method, args = []) {\n // Validate projection for find() calls to catch errors early\n if (method === 'find' && args.length >= 2) {\n this._validateProjection(args[1]);\n }\n \n // Return cursor immediately - it will fetch data asynchronously with delayed execution\n const requestPayload = {\n target: 'collection',\n database: this.dbName,\n collection: this.name,\n method,\n args\n };\n\n const cursor = new ProxyCursor({\n bridge: this.bridge,\n requestPayload\n });\n\n // For aggregate, also make the cursor thenable so await works like in older API\n if (method === 'aggregate') {\n cursor.then = function(onFulfilled, onRejected) {\n return this.toArray().then(onFulfilled, onRejected);\n };\n }\n\n return cursor;\n }\n\n _validateProjection(projection) {\n if (!projection || Object.keys(projection).length === 0) return;\n \n const keys = Object.keys(projection);\n let hasInclusion = false;\n let hasExclusion = false;\n\n for (const key of keys) {\n if (key === '_id') continue; // _id can appear with either style\n if (projection[key]) hasInclusion = true; else hasExclusion = true;\n if (hasInclusion && hasExclusion) break;\n }\n\n if (hasInclusion && hasExclusion) {\n throw new QueryError(\"Cannot do exclusion on field in inclusion projection\", {\n code: ErrorCodes.CANNOT_DO_EXCLUSION_ON_FIELD_ID_IN_INCLUSION_PROJECTION,\n collection: this.name\n });\n }\n }\n\n _call(method, args = []) {\n const promise = this.bridge.sendRequest({\n target: 'collection',\n database: this.dbName,\n collection: this.name,\n method,\n args\n }).then((res) => {\n if (res && res.cursorId) {\n return new ProxyCursor({\n bridge: this.bridge,\n cursorId: res.cursorId,\n batch: res.batch,\n exhausted: res.exhausted,\n batchSize: res.batchSize\n });\n }\n // If copyTo, register the destination collection locally\n if (method === 'copyTo' && args.length > 0) {\n // Access the destination collection to register it\n // This assumes we have access to the database proxy\n // We'll need to pass db reference to ProxyCollection\n if (this._db) {\n this._db.collection(args[0]);\n }\n }\n // If createIndex, cache the index info\n if (method === 'createIndex') {\n const indexSpec = args[0];\n const indexOptions = args[1] || {};\n const indexName = indexOptions.name || Object.entries(indexSpec)\n .map(([k, v]) => `${k}_${v}`)\n .join('_');\n \n // Only add if not already present\n if (!this.indexes.find(idx => idx.name === indexName)) {\n this.indexes.push({\n name: indexName,\n key: indexSpec,\n ...indexOptions\n });\n }\n }\n // If dropIndex or dropIndexes, update cache\n if (method === 'dropIndex') {\n const indexName = args[0];\n this.indexes = this.indexes.filter(idx => idx.name !== indexName);\n }\n if (method === 'dropIndexes') {\n this.indexes = [];\n }\n // If drop (collection), clear all cached indexes\n if (method === 'drop') {\n this.indexes = [];\n }\n return res;\n });\n return promise;\n }\n\n getIndexes() {\n // Return cached indexes synchronously\n return this.indexes;\n }\n\n _watch(pipeline = [], options = {}) {\n return ProxyChangeStream.create({\n bridge: this.bridge,\n database: this.dbName,\n collection: this.name,\n pipeline,\n options\n });\n }\n}\n","import { ProxyCollection } from './ProxyCollection.js';\nimport { ProxyChangeStream } from './ProxyChangeStream.js';\n\n/**\n * ProxyDB lives on the main thread and forwards operations to the worker Server.\n */\nexport class ProxyDB {\n constructor({ dbName, bridge, options = {} }) {\n this.dbName = dbName;\n this.bridge = bridge;\n this.options = options;\n this.collections = new Map();\n\n // Proxy to auto-create collections on property access\n const dbMethodNames = new Set([\n 'getCollectionNames',\n 'getCollectionInfos',\n 'createCollection',\n 'dropCollection',\n 'dropDatabase',\n 'collection',\n 'getCollection',\n 'watch'\n ]);\n\n this._methodNames = dbMethodNames;\n\n return new Proxy(this, {\n get: (target, prop, receiver) => {\n if (prop in target) return Reflect.get(target, prop, receiver);\n if (typeof prop === 'symbol' || String(prop).startsWith('_')) return undefined;\n\n if (dbMethodNames.has(prop)) {\n // Special handling for collection management methods\n if (prop === 'createCollection') {\n return (...args) => {\n const collName = args[0];\n target.collection(collName, receiver); // Pass proxy receiver\n return target._call(String(prop), args); // Still send to worker\n };\n }\n if (prop === 'dropCollection') {\n return (...args) => {\n const collName = args[0];\n target.collections.delete(collName); // Remove synchronously\n return target._call(String(prop), args); // Still send to worker\n };\n }\n if (prop === 'dropDatabase') {\n return (...args) => {\n target.collections.clear(); // Clear all collections synchronously\n return target._call(String(prop), args); // Still send to worker\n };\n }\n if (prop === 'watch') {\n return (...args) => target._watch(...args);\n }\n return (...args) => target._call(String(prop), args);\n }\n\n // Dynamic collection access\n return target.collection(prop, receiver); // Pass proxy receiver\n }\n });\n }\n\n collection(name, dbProxy) {\n if (this.collections.has(name)) return this.collections.get(name);\n const col = new ProxyCollection({\n dbName: this.dbName,\n name,\n bridge: this.bridge,\n db: dbProxy || this // Pass DB proxy if available, otherwise this\n });\n this.collections.set(name, col);\n return col;\n }\n\n getCollectionNames() {\n // Return collection names from local cache\n return Array.from(this.collections.keys());\n }\n\n async close() {\n // No-op on proxy; the worker owns lifecycle\n return undefined;\n }\n\n // Direct forwarding for DB-level methods\n _call(method, args = []) {\n const promise = this.bridge.sendRequest({\n target: 'db',\n database: this.dbName,\n method,\n args\n }).then((res) => {\n // Note: Do NOT re-add createCollection here - it's already added synchronously in the proxy handler\n // Same for dropCollection - already removed in proxy handler\n \n if (res && res.streamId) {\n return ProxyChangeStream.create({\n bridge: this.bridge,\n database: this.dbName,\n collection: null,\n streamId: res.streamId\n });\n }\n return res;\n });\n return promise;\n }\n\n _watch(pipeline = [], options = {}) {\n return ProxyChangeStream.create({\n bridge: this.bridge,\n database: this.dbName,\n collection: null,\n pipeline,\n options\n });\n }\n}\n","import { EventEmitter } from 'events';\r\nimport { ProxyDB } from './ProxyDB.js';\r\nimport { ProxyChangeStream } from './ProxyChangeStream.js';\r\n\r\nexport class MongoClient extends EventEmitter {\r\n constructor(uri = 'mongodb://localhost:27017', options = {}) {\r\n super();\r\n this.uri = uri;\r\n this.options = Object.freeze({ ...options }); // Make immutable\r\n this._isConnected = false;\r\n this._defaultDb = this._parseDefaultDbName(uri);\r\n this._databases = new Map(); // Track database instances\r\n \r\n // workerBridge is required\r\n if (!options.workerBridge) {\r\n throw new Error('workerBridge is required. Create one with: const bridge = await WorkerBridge.create()');\r\n }\r\n \r\n this._bridge = options.workerBridge;\r\n this._ownsBridge = false; // Never own the bridge - user manages lifecycle\r\n }\r\n\r\n static async connect(uri, options = {}) {\r\n const client = new MongoClient(uri, options);\r\n await client.connect();\r\n return client;\r\n }\r\n\r\n async connect() {\r\n if (this._isConnected) return this;\r\n this._isConnected = true;\r\n this.emit('open', this);\r\n return this;\r\n }\r\n\r\n // Note that db on real MongoClient is synchronous\r\n db(name, opts = {}) {\r\n // Use default from URI if no name provided\r\n const dbName = name || this._defaultDb;\r\n if (!dbName) {\r\n throw new Error('No database name provided and no default in connection string');\r\n }\r\n \r\n // Return cached database instance if it exists\r\n if (this._databases.has(dbName)) {\r\n return this._databases.get(dbName);\r\n }\r\n\r\n // Always use ProxyDB with worker\r\n const database = new ProxyDB({\r\n dbName,\r\n bridge: this._bridge,\r\n options: { ...this.options, ...opts }\r\n });\r\n\r\n this._databases.set(dbName, database);\r\n return database;\r\n }\r\n\r\n async close() {\r\n if (this._bridge && this._ownsBridge) {\r\n // Only terminate if we own the bridge (not shared)\r\n await this._bridge.terminate();\r\n this._bridge = null;\r\n }\r\n this._isConnected = false;\r\n this.emit('close');\r\n }\r\n\r\n // async _loadExistingDatabases() {\r\n // const discoveredNames = await this._discoverDatabases();\r\n // console.log('Discovered databases:', discoveredNames);\r\n // const names = new Set(discoveredNames);\r\n\r\n // // Ensure default DB from URI is loaded when provided\r\n // if (this._defaultDb) {\r\n // names.add(this._defaultDb);\r\n // }\r\n\r\n // for (const dbName of names) {\r\n // if (this._databases.has(dbName)) continue;\r\n // const database = new DB({ ...this.options, dbName });\r\n // this._databases.set(dbName, database);\r\n // }\r\n // }\r\n\r\n // async _discoverDatabases() {\r\n // const dbNames = new Set();\r\n // const baseFolder = this.options.rootPath || '/babymongo';\r\n\r\n // const hasOPFS = !!(globalThis.navigator && globalThis.navigator.storage && typeof globalThis.navigator.storage.getDirectory === 'function');\r\n // if (!hasOPFS) {\r\n // return Array.from(dbNames);\r\n // }\r\n\r\n // try {\r\n // let dir = await globalThis.navigator.storage.getDirectory();\r\n // const parts = baseFolder.split('/').filter(Boolean);\r\n // for (const part of parts) {\r\n // dir = await dir.getDirectoryHandle(part, { create: true });\r\n // }\r\n\r\n // for await (const [name, handle] of dir.entries()) {\r\n // if (handle && handle.kind === 'directory') {\r\n // dbNames.add(name);\r\n // }\r\n // }\r\n // } catch (err) {\r\n // console.warn('Failed to discover databases', err);\r\n // }\r\n\r\n // return Array.from(dbNames);\r\n // }\r\n\r\n async close(force = false) {\r\n if (!this._isConnected) return;\r\n \r\n // Close all database connections (which closes all collections and indexes)\r\n for (const [_, database] of this._databases) {\r\n await database.close();\r\n }\r\n this._databases.clear();\r\n \r\n this._isConnected = false;\r\n this.emit('close');\r\n }\r\n\r\n // Session management stubs\r\n startSession(options = {}) {\r\n // Return minimal session object for compatibility\r\n return {\r\n id: crypto.randomUUID(),\r\n endSession: () => {},\r\n withTransaction: async (fn) => await fn(this)\r\n };\r\n }\r\n\r\n async withSession(optionsOrExecutor, executor) {\r\n const session = this.startSession(\r\n typeof optionsOrExecutor === 'function' ? {} : optionsOrExecutor\r\n );\r\n const fn = typeof optionsOrExecutor === 'function' ? optionsOrExecutor : executor;\r\n \r\n try {\r\n return await fn(session);\r\n } finally {\r\n session.endSession();\r\n }\r\n }\r\n\r\n // Configuration getters\r\n get readConcern() { return this.options.readConcern; }\r\n get writeConcern() { return this.options.writeConcern; }\r\n get readPreference() { return this.options.readPreference; }\r\n\r\n /**\r\n * Watch for changes across all databases and collections\r\n * @param {Array} pipeline - Aggregation pipeline to filter changes\r\n * @param {Object} options - Watch options\r\n * @returns {ProxyChangeStream} A change stream instance\r\n */\r\n watch(pipeline = [], options = {}) {\r\n return ProxyChangeStream.create({\r\n bridge: this._bridge,\r\n database: null, // null means watch all databases\r\n collection: null,\r\n pipeline,\r\n options\r\n });\r\n }\r\n\r\n _parseDefaultDbName(uri) {\r\n // Parse mongodb://host:port/dbname format\r\n const match = uri.match(/\\/([^/?]+)/);\r\n return match ? match[1] : null;\r\n }\r\n\r\n _parseUriParams(uri) {\r\n // Parse query parameters from URI\r\n // e.g., ?useWorker=true becomes { useWorker: true }\r\n const params = {};\r\n const queryIndex = uri.indexOf('?');\r\n if (queryIndex === -1) return params;\r\n \r\n const queryString = uri.substring(queryIndex + 1);\r\n const pairs = queryString.split('&');\r\n for (const pair of pairs) {\r\n const [key, value] = pair.split('=');\r\n if (key) {\r\n // Convert string booleans to actual booleans\r\n if (value === 'true') params[key] = true;\r\n else if (value === 'false') params[key] = false;\r\n else if (!isNaN(value)) params[key] = Number(value);\r\n else params[key] = decodeURIComponent(value || '');\r\n }\r\n }\r\n return params;\r\n }\r\n}","/**\n * Binary JSON Encoder/Decoder\n * \n * Encodes JavaScript values to a compact binary format compatible with\n * Origin Private File System (OPFS).\n */\n\nconst TYPE = {\n NULL: 0x00,\n FALSE: 0x01,\n TRUE: 0x02,\n INT: 0x03,\n FLOAT: 0x04,\n STRING: 0x05,\n OID: 0x06,\n DATE: 0x07,\n POINTER: 0x08,\n BINARY: 0x09,\n ARRAY: 0x10,\n OBJECT: 0x11\n};\n\n\n/**\n * ObjectId class - MongoDB-compatible 24-character hex string identifier\n * Format: 8-char timestamp + 16-char random data\n */\nclass ObjectId {\n constructor(id) {\n if (id === undefined || id === null) {\n // Generate new ObjectId\n this.id = ObjectId.generate();\n } else if (typeof id === 'string') {\n // Create from hex string\n if (!ObjectId.isValid(id)) {\n throw new Error(`Argument passed in must be a string of 24 hex characters, got: ${id}`);\n }\n this.id = id.toLowerCase();\n } else if (id instanceof Uint8Array && id.length === 12) {\n this.id = Array.from(id).map(b => b.toString(16).padStart(2, '0')).join('');\n } else if (id instanceof ObjectId) {\n // Copy constructor\n this.id = id.id;\n } else {\n throw new Error(`Argument passed in must be a string of 24 hex characters or an ObjectId`);\n }\n }\n\n /**\n * Returns the ObjectId as a 24-character hex string\n */\n toString() {\n return this.id;\n }\n\n /**\n * Returns the ObjectId as a 24-character hex string (alias for toString)\n */\n toHexString() {\n return this.id;\n }\n\n /**\n * Returns the timestamp portion of the ObjectId as a Date\n */\n getTimestamp() {\n const timestamp = parseInt(this.id.substring(0, 8), 16);\n return new Date(timestamp * 1000);\n }\n\n equals(other) {\n if (!(other instanceof ObjectId)) {\n throw new Error('Can only compare with another ObjectId');\n }\n return this.id === other.id;\n }\n\n /**\n * Compares this ObjectId with another for equality\n */\n compare(other) {\n if (!(other instanceof ObjectId)) {\n throw new Error('Can only compare with another ObjectId');\n }\n\n return this.id.localeCompare(other.id);\n }\n\n /**\n * Returns the ObjectId in JSON format (as hex string)\n */\n toJSON() {\n return this.id;\n }\n\n /**\n * Custom inspect for Node.js console.log\n */\n inspect() {\n return `ObjectId(\"${this.id}\")`;\n }\n\n toBytes() {\n const bytes = new Uint8Array(12);\n for (let i = 0; i < 12; i++) {\n bytes[i] = parseInt(this.id.substring(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n }\n\n /**\n * Validates if a string is a valid ObjectId hex string\n */\n static isValid(id) {\n if (!id) return false;\n if (typeof id !== 'string') return false;\n if (id.length !== 24) return false;\n return /^[0-9a-fA-F]{24}$/.test(id);\n }\n\n /**\n * Creates an ObjectId from a timestamp\n */\n static createFromTime(timestamp) {\n const ts = Math.floor(timestamp / 1000);\n const tsHex = ('00000000' + ts.toString(16)).slice(-8);\n const tail = '0000000000000000'; // Zero out the random portion\n return new ObjectId(tsHex + tail);\n }\n\n /**\n * Generates a new ObjectId hex string\n * Format: 8-char timestamp (4 bytes) + 16-char random data (8 bytes)\n */\n static generate() {\n const ts = Math.floor(Date.now() / 1000);\n \n // Generate 8 random bytes\n const rand = typeof crypto !== 'undefined' && crypto.getRandomValues ? new Uint8Array(8) : null;\n let tail = '';\n \n if (rand) {\n crypto.getRandomValues(rand);\n for (let i = 0; i < rand.length; i++) {\n tail += ('0' + rand[i].toString(16)).slice(-2);\n }\n } else {\n // Fallback for environments without crypto\n // Generate two 8-character hex strings\n tail = Math.random().toString(16).slice(2).padEnd(8, '0').slice(0, 8) +\n Math.random().toString(16).slice(2).padEnd(8, '0').slice(0, 8);\n }\n \n const tsHex = ('00000000' + ts.toString(16)).slice(-8);\n return (tsHex + tail).slice(0, 24);\n }\n}\n\n/**\n * Pointer class - represents a 64-bit file offset pointer\n * Used to store file offsets for referenced data structures\n */\nclass Pointer {\n constructor(offset) {\n if (offset === undefined || offset === null) {\n throw new Error('Pointer offset must be a number');\n }\n if (typeof offset !== 'number') {\n throw new Error('Pointer offset must be a number');\n }\n if (!Number.isInteger(offset)) {\n throw new Error('Pointer offset must be an integer');\n }\n if (offset < 0) {\n throw new Error('Pointer offset must be non-negative');\n }\n if (offset > Number.MAX_SAFE_INTEGER) {\n throw new Error('Pointer offset exceeds maximum safe integer');\n }\n this.offset = offset;\n }\n\n /**\n * Returns the pointer offset as a number\n */\n valueOf() {\n return this.offset;\n }\n\n /**\n * Returns the pointer offset as a string\n */\n toString() {\n return this.offset.toString();\n }\n\n /**\n * Returns the pointer in JSON format (as number)\n */\n toJSON() {\n return this.offset;\n }\n\n /**\n * Custom inspect for Node.js console.log\n */\n inspect() {\n return `Pointer(${this.offset})`;\n }\n\n /**\n * Compares this Pointer with another for equality\n */\n equals(other) {\n if (!(other instanceof Pointer)) {\n return false;\n }\n return this.offset === other.offset;\n }\n}\n\n/**\n * Encode a JavaScript value to binary format\n */\nfunction encode(value) {\n const buffers = [];\n\n function encodeValue(val) {\n if (val === null) {\n buffers.push(new Uint8Array([TYPE.NULL]));\n } else if (val === false) {\n buffers.push(new Uint8Array([TYPE.FALSE]));\n } else if (val === true) {\n buffers.push(new Uint8Array([TYPE.TRUE]));\n } else if (val instanceof ObjectId) {\n buffers.push(new Uint8Array([TYPE.OID]));\n buffers.push(val.toBytes());\n } else if (val instanceof Date) {\n buffers.push(new Uint8Array([TYPE.DATE]));\n const buffer = new ArrayBuffer(8);\n const view = new DataView(buffer);\n view.setBigInt64(0, BigInt(val.getTime()), true); // little-endian\n buffers.push(new Uint8Array(buffer));\n } else if (val instanceof Pointer) {\n buffers.push(new Uint8Array([TYPE.POINTER]));\n const buffer = new ArrayBuffer(8);\n const view = new DataView(buffer);\n view.setBigUint64(0, BigInt(val.offset), true); // little-endian\n buffers.push(new Uint8Array(buffer));\n } else if (val instanceof Uint8Array) {\n buffers.push(new Uint8Array([TYPE.BINARY]));\n // Store length as 32-bit integer\n const lengthBuffer = new ArrayBuffer(4);\n const lengthView = new DataView(lengthBuffer);\n lengthView.setUint32(0, val.length, true);\n buffers.push(new Uint8Array(lengthBuffer));\n buffers.push(val);\n } else if (typeof val === 'number') {\n if (Number.isInteger(val) && Number.isSafeInteger(val)) {\n // 64-bit signed integer (stored as BigInt64)\n buffers.push(new Uint8Array([TYPE.INT]));\n const buffer = new ArrayBuffer(8);\n const view = new DataView(buffer);\n view.setBigInt64(0, BigInt(val), true); // little-endian\n buffers.push(new Uint8Array(buffer));\n } else {\n // 64-bit float\n buffers.push(new Uint8Array([TYPE.FLOAT]));\n const buffer = new ArrayBuffer(8);\n const view = new DataView(buffer);\n view.setFloat64(0, val, true); // little-endian\n buffers.push(new Uint8Array(buffer));\n }\n } else if (typeof val === 'string') {\n buffers.push(new Uint8Array([TYPE.STRING]));\n const encoded = new TextEncoder().encode(val);\n // Store length as 32-bit integer\n const lengthBuffer = new ArrayBuffer(4);\n const lengthView = new DataView(lengthBuffer);\n lengthView.setUint32(0, encoded.length, true);\n buffers.push(new Uint8Array(lengthBuffer));\n buffers.push(encoded);\n } else if (Array.isArray(val)) {\n // Encode array to temporary buffer to determine size\n const tempBuffers = [];\n \n // Store array length as 32-bit integer\n const lengthBuffer = new ArrayBuffer(4);\n const lengthView = new DataView(lengthBuffer);\n lengthView.setUint32(0, val.length, true);\n tempBuffers.push(new Uint8Array(lengthBuffer));\n \n // Encode each element into temp buffer\n const startLength = buffers.length;\n for (const item of val) {\n encodeValue(item);\n }\n // Collect encoded elements\n const elementBuffers = buffers.splice(startLength);\n tempBuffers.push(...elementBuffers);\n \n // Calculate total size of array content\n const contentSize = tempBuffers.reduce((sum, buf) => sum + buf.length, 0);\n \n // Now write: TYPE + SIZE + CONTENT\n buffers.push(new Uint8Array([TYPE.ARRAY]));\n const sizeBuffer = new ArrayBuffer(4);\n const sizeView = new DataView(sizeBuffer);\n sizeView.setUint32(0, contentSize, true);\n buffers.push(new Uint8Array(sizeBuffer));\n buffers.push(...tempBuffers);\n } else if (typeof val === 'object') {\n // Encode object to temporary buffer to determine size\n const tempBuffers = [];\n \n const keys = Object.keys(val);\n // Store number of keys as 32-bit integer\n const lengthBuffer = new ArrayBuffer(4);\n const lengthView = new DataView(lengthBuffer);\n lengthView.setUint32(0, keys.length, true);\n tempBuffers.push(new Uint8Array(lengthBuffer));\n \n // Encode each key-value pair into temp buffer\n const startLength = buffers.length;\n for (const key of keys) {\n // Encode key as string (without type byte)\n const encoded = new TextEncoder().encode(key);\n const keyLengthBuffer = new ArrayBuffer(4);\n const keyLengthView = new DataView(keyLengthBuffer);\n keyLengthView.setUint32(0, encoded.length, true);\n buffers.push(new Uint8Array(keyLengthBuffer));\n buffers.push(encoded);\n // Encode value\n encodeValue(val[key]);\n }\n // Collect encoded key-value pairs\n const kvBuffers = buffers.splice(startLength);\n tempBuffers.push(...kvBuffers);\n \n // Calculate total size of object content\n const contentSize = tempBuffers.reduce((sum, buf) => sum + buf.length, 0);\n \n // Now write: TYPE + SIZE + CONTENT\n buffers.push(new Uint8Array([TYPE.OBJECT]));\n const sizeBuffer = new ArrayBuffer(4);\n const sizeView = new DataView(sizeBuffer);\n sizeView.setUint32(0, contentSize, true);\n buffers.push(new Uint8Array(sizeBuffer));\n buffers.push(...tempBuffers);\n } else {\n throw new Error(`Unsupported type: ${typeof val}`);\n }\n }\n\n encodeValue(value);\n\n // Combine all buffers\n const totalLength = buffers.reduce((sum, buf) => sum + buf.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const buf of buffers) {\n result.set(buf, offset);\n offset += buf.length;\n }\n\n return result;\n}\n\n/**\n * Decode binary data to JavaScript value\n */\nfunction decode(data) {\n let offset = 0;\n\n function decodeValue() {\n if (offset >= data.length) {\n throw new Error('Unexpected end of data');\n }\n\n const type = data[offset++];\n\n switch (type) {\n case TYPE.NULL:\n return null;\n \n case TYPE.FALSE:\n return false;\n \n case TYPE.TRUE:\n return true;\n \n case TYPE.INT: {\n if (offset + 4 > data.length) {\n throw new Error('Unexpected end of data for INT');\n }\n const view = new DataView(data.buffer, data.byteOffset + offset, 8);\n const value = view.getBigInt64(0, true);\n offset += 8;\n if (value < BigInt(Number.MIN_SAFE_INTEGER) || value > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error('Decoded integer exceeds safe range');\n }\n return Number(value);\n }\n \n case TYPE.FLOAT: {\n if (offset + 8 > data.length) {\n throw new Error('Unexpected end of data for FLOAT');\n }\n const view = new DataView(data.buffer, data.byteOffset + offset, 8);\n const value = view.getFloat64(0, true);\n offset += 8;\n return value;\n }\n \n case TYPE.STRING: {\n if (offset + 4 > data.length) {\n throw new Error('Unexpected end of data for STRING length');\n }\n const lengthView = new DataView(data.buffer, data.byteOffset + offset, 4);\n const length = lengthView.getUint32(0, true);\n offset += 4;\n \n if (offset + length > data.length) {\n throw new Error('Unexpected end of data for STRING content');\n }\n const stringData = data.slice(offset, offset + length);\n offset += length;\n return new TextDecoder().decode(stringData);\n }\n \n case TYPE.OID: {\n if (offset + 12 > data.length) {\n throw new Error('Unexpected end of data for OID');\n }\n const oidBytes = data.slice(offset, offset + 12);\n offset += 12;\n return new ObjectId(oidBytes);\n }\n\n case TYPE.DATE: {\n if (offset + 8 > data.length) {\n throw new Error('Unexpected end of data for DATE');\n }\n const view = new DataView(data.buffer, data.byteOffset + offset, 8);\n const timestamp = view.getBigInt64(0, true);\n offset += 8;\n return new Date(Number(timestamp));\n }\n \n case TYPE.POINTER: {\n if (offset + 8 > data.length) {\n throw new Error('Unexpected end of data for POINTER');\n }\n const view = new DataView(data.buffer, data.byteOffset + offset, 8);\n const pointerOffset = view.getBigUint64(0, true);\n offset += 8;\n // Validate offset is within safe integer range\n if (pointerOffset > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new Error('Pointer offset out of valid range');\n }\n return new Pointer(Number(pointerOffset));\n }\n \n case TYPE.BINARY: {\n if (offset + 4 > data.length) {\n throw new Error('Unexpected end of data for BINARY length');\n }\n const lengthView = new DataView(data.buffer, data.byteOffset + offset, 4);\n const length = lengthView.getUint32(0, true);\n offset += 4;\n \n if (offset + length > data.length) {\n throw new Error('Unexpected end of data for BINARY content');\n }\n const binaryData = data.slice(offset, offset + length);\n offset += length;\n return binaryData;\n }\n \n case TYPE.ARRAY: {\n if (offset + 4 > data.length) {\n throw new Error('Unexpected end of data for ARRAY size');\n }\n // Read size in bytes\n const sizeView = new DataView(data.buffer, data.byteOffset + offset, 4);\n const size = sizeView.getUint32(0, true);\n offset += 4;\n \n if (offset + size > data.length) {\n throw new Error('Unexpected end of data for ARRAY content');\n }\n \n // Read array length\n const lengthView = new DataView(data.buffer, data.byteOffset + offset, 4);\n const length = lengthView.getUint32(0, true);\n offset += 4;\n \n const arr = [];\n for (let i = 0; i < length; i++) {\n arr.push(decodeValue());\n }\n return arr;\n }\n \n case TYPE.OBJECT: {\n if (offset + 4 > data.length) {\n throw new Error('Unexpected end of data for OBJECT size');\n }\n // Read size in bytes\n const sizeView = new DataView(data.buffer, data.byteOffset + offset, 4);\n const size = sizeView.getUint32(0, true);\n offset += 4;\n \n if (offset + size > data.length) {\n throw new Error('Unexpected end of data for OBJECT content');\n }\n \n // Read number of keys\n const lengthView = new DataView(data.buffer, data.byteOffset + offset, 4);\n const length = lengthView.getUint32(0, true);\n offset += 4;\n \n const obj = {};\n for (let i = 0; i < length; i++) {\n // Decode key\n if (offset + 4 > data.length) {\n throw new Error('Unexpected end of data for OBJECT key length');\n }\n const keyLengthView = new DataView(data.buffer, data.byteOffset + offset, 4);\n const keyLength = keyLengthView.getUint32(0, true);\n offset += 4;\n \n if (offset + keyLength > data.length) {\n throw new Error('Unexpected end of data for OBJECT key');\n }\n const keyData = data.slice(offset, offset + keyLength);\n offset += keyLength;\n const key = new TextDecoder().decode(keyData);\n \n // Decode value\n obj[key] = decodeValue();\n }\n return obj;\n }\n \n default:\n throw new Error(`Unknown type byte: 0x${type.toString(16)}`);\n }\n }\n\n return decodeValue();\n}\n\n/**\n * OPFS File Operations using FileSystemSyncAccessHandle\n * \n * IMPORTANT: This class wraps FileSystemSyncAccessHandle which is only available\n * in Web Workers. It provides synchronous file operations with explicit flush control.\n */\nclass BinJsonFile {\n constructor(syncAccessHandle) {\n if (!syncAccessHandle) {\n throw new Error('FileSystemSyncAccessHandle is required');\n }\n this.syncAccessHandle = syncAccessHandle;\n }\n\n\n /**\n * Read a range of bytes from the file\n */\n #readRange(start, length) {\n const buffer = new Uint8Array(length);\n const bytesRead = this.syncAccessHandle.read(buffer, { at: start });\n if (bytesRead < length) {\n // Return only the bytes that were actually read\n return buffer.slice(0, bytesRead);\n }\n return buffer;\n }\n\n /**\n * Get the current file size\n */\n getFileSize() {\n return this.syncAccessHandle.getSize();\n }\n\n /**\n * Write data to file, truncating existing content\n * @param {*} data - Data to encode and write\n */\n write(data) {\n // Encode data to binary\n const binaryData = encode(data);\n \n // Truncate file to 0 bytes (clear existing content)\n this.syncAccessHandle.truncate(0);\n \n // Write data at beginning of file\n this.syncAccessHandle.write(binaryData, { at: 0 });\n }\n\n /**\n * Read and decode data from file starting at optional pointer offset\n * @param {Pointer} pointer - Optional offset to start reading from (default: 0)\n * @returns {*} - Decoded data\n */\n read(pointer = new Pointer(0)) {\n const fileSize = this.getFileSize();\n \n if (fileSize === 0) {\n throw new Error('File is empty');\n }\n\n const pointerValue = pointer.valueOf();\n \n // Validate pointer offset\n if (pointerValue < 0 || pointerValue >= fileSize) {\n throw new Error(`Pointer offset ${pointer} out of file bounds [0, ${fileSize})`);\n }\n \n // Read from pointer offset to end of file\n const binaryData = this.#readRange(pointerValue, fileSize - pointerValue);\n \n // Decode and return the first value\n return decode(binaryData);\n }\n\n /**\n * Append data to file without truncating existing content\n * @param {*} data - Data to encode and append\n */\n append(data) {\n // Encode new data to binary\n const binaryData = encode(data);\n \n // Get current file size\n const existingSize = this.getFileSize();\n \n // Write new data at end of file\n this.syncAccessHandle.write(binaryData, { at: existingSize });\n }\n\n /**\n * Explicitly flush any pending writes to disk\n */\n flush() {\n this.syncAccessHandle.flush();\n }\n\n /**\n * Generator to scan through all records in the file\n * Each record is decoded and yielded one at a time\n */\n *scan() {\n const fileSize = this.getFileSize();\n \n if (fileSize === 0) {\n return;\n }\n \n let offset = 0;\n \n // Scan through and yield each top-level value\n while (offset < fileSize) {\n // Helper function to determine how many bytes a value occupies\n const getValueSize = (readPosition) => {\n // Read 1 byte for type\n let tempData = this.#readRange(readPosition, 1);\n let pos = 1;\n const type = tempData[0];\n \n switch (type) {\n case TYPE.NULL:\n case TYPE.FALSE:\n case TYPE.TRUE:\n return 1;\n \n case TYPE.INT:\n case TYPE.FLOAT:\n case TYPE.DATE:\n case TYPE.POINTER:\n return 1 + 8;\n\n case TYPE.OID:\n return 1 + 12;\n \n case TYPE.STRING: {\n // Read length (4 bytes)\n tempData = this.#readRange(readPosition + 1, 4);\n const view = new DataView(tempData.buffer, tempData.byteOffset, 4);\n const length = view.getUint32(0, true);\n return 1 + 4 + length;\n }\n \n case TYPE.BINARY: {\n // Read length (4 bytes)\n tempData = this.#readRange(readPosition + 1, 4);\n const view = new DataView(tempData.buffer, tempData.byteOffset, 4);\n const length = view.getUint32(0, true);\n return 1 + 4 + length;\n }\n \n case TYPE.ARRAY: {\n // Read size in bytes (4 bytes)\n tempData = this.#readRange(readPosition + 1, 4);\n const view = new DataView(tempData.buffer, tempData.byteOffset, 4);\n const size = view.getUint32(0, true);\n return 1 + 4 + size; // type + size + content\n }\n \n case TYPE.OBJECT: {\n // Read size in bytes (4 bytes)\n tempData = this.#readRange(readPosition + 1, 4);\n const view = new DataView(tempData.buffer, tempData.byteOffset, 4);\n const size = view.getUint32(0, true);\n return 1 + 4 + size; // type + size + content\n }\n \n default:\n throw new Error(`Unknown type byte: 0x${type.toString(16)}`);\n }\n };\n \n // Determine size of the current value\n const valueSize = getValueSize(offset);\n \n // Read only the bytes needed for this value\n const valueData = this.#readRange(offset, valueSize);\n offset += valueSize;\n \n // Decode and yield this value\n yield decode(valueData);\n }\n }\n}\n\n/**\n * Check if a file exists in OPFS\n * @param {FileSystemFileHandle} fileHandle - The file handle to check\n * @returns {boolean} - True if file exists and is readable\n */\nfunction exists(fileHandle) {\n try {\n // If we have a handle, the file exists\n return fileHandle !== null && fileHandle !== undefined;\n } catch {\n return false;\n }\n}\n\n/**\n * Delete a file from OPFS\n * @param {FileSystemDirectoryHandle} dirHandle - The directory handle\n * @param {string} filename - Name of the file to delete\n */\nasync function deleteFile(dirHandle, filename) {\n try {\n await dirHandle.removeEntry(filename);\n } catch (error) {\n if (error.name === 'NotFoundError') {\n // File doesn't exist, nothing to delete\n return;\n }\n throw error;\n }\n}\n\n/**\n * Get or create a file handle from a directory\n * @param {FileSystemDirectoryHandle} dirHandle - The directory handle\n * @param {string} filename - Name of the file\n * @param {Object} options - Options for getFileHandle\n * @returns {FileSystemFileHandle} - The file handle\n */\nasync function getFileHandle(dirHandle, filename, options = {}) {\n return dirHandle.getFileHandle(filename, options);\n}\n\nexport {\n TYPE,\n ObjectId,\n Pointer,\n encode,\n decode,\n BinJsonFile,\n exists,\n deleteFile,\n getFileHandle\n};\n","/**\n * Utility functions for MicroMongoDB\n */\n\nimport { ObjectId } from '@belteshazzar/binjson';\n\n/**\n * Compare two values for equality, handling ObjectId instances\n */\nfunction valuesEqual(a, b) {\n\t// Handle ObjectId comparison\n\tif (a instanceof ObjectId || b instanceof ObjectId) {\n\t\tif (a instanceof ObjectId && b instanceof ObjectId) {\n\t\t\treturn a.equals(b);\n\t\t}\n\t\tif (a instanceof ObjectId && typeof b === 'string') {\n\t\t\treturn a.equals(b);\n\t\t}\n\t\tif (b instanceof ObjectId && typeof a === 'string') {\n\t\t\treturn b.equals(a);\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t// Regular equality\n\treturn a == b;\n}\n\n/**\n * Deep copy an object or array\n */\nexport function copy(o) {\n\t// Handle primitives that shouldn't be deep-copied\n\tif (typeof o !== 'object' || o === null) {\n\t\treturn o;\n\t}\n\t\n\t// Handle ObjectId\n\tif (o instanceof ObjectId) {\n\t\treturn new ObjectId(o.id);\n\t}\n\t\n\t// Handle Date\n\tif (o instanceof Date) {\n\t\treturn new Date(o.getTime());\n\t}\n\t\n\tvar out, v, key;\n\tout = Array.isArray(o) ? [] : {};\n\tfor (key in o) {\n\t\tv = o[key];\n\t\tout[key] = (typeof v === \"object\" && v !== null) ? copy(v) : v;\n\t}\n\treturn out;\n}\n\n/**\n * Get a property from an object using dot notation\n * Supports array element access via numeric indices (e.g., \"items.0.name\")\n */\nexport function getProp(obj, name) {\n\tvar path = name.split(\".\");\n\tvar result = obj[path[0]];\n\tfor (var i = 1; i < path.length; i++) {\n\t\tif (result == undefined || result == null) return result;\n\t\t\n\t\t// Check if this path segment is a numeric index\n\t\tvar pathSegment = path[i];\n\t\tvar numericIndex = parseInt(pathSegment, 10);\n\t\t\n\t\t// If it's a valid array index, use it\n\t\tif (isArray(result) && !isNaN(numericIndex) && numericIndex >= 0 && numericIndex < result.length) {\n\t\t\tresult = result[numericIndex];\n\t\t} else {\n\t\t\tresult = result[pathSegment];\n\t\t}\n\t}\n\treturn result;\n}\n\n/**\n * Get field values for query matching, handling MongoDB-style array traversal\n * When a path traverses an array, this returns all matching values from array elements\n * Returns an array of values if array traversal occurred, otherwise the single value\n * \n * Example:\n * doc = { items: [{ price: 10 }, { price: 20 }] }\n * getFieldValues(doc, 'items.price') -> [10, 20]\n */\nexport function getFieldValues(obj, name) {\n\tvar path = name.split(\".\");\n\tvar results = [obj];\n\t\n\tfor (var i = 0; i < path.length; i++) {\n\t\tvar pathSegment = path[i];\n\t\tvar numericIndex = parseInt(pathSegment, 10);\n\t\tvar newResults = [];\n\t\t\n\t\tfor (var j = 0; j < results.length; j++) {\n\t\t\tvar current = results[j];\n\t\t\tif (current == undefined || current == null) continue;\n\t\t\t\n\t\t\t// If this is a numeric index and current is an array, access that element\n\t\t\tif (isArray(current) && !isNaN(numericIndex) && numericIndex >= 0) {\n\t\t\t\tif (numericIndex < current.length) {\n\t\t\t\t\tnewResults.push(current[numericIndex]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If current is an array but path segment is not numeric, traverse all elements\n\t\t\telse if (isArray(current)) {\n\t\t\t\tfor (var k = 0; k < current.length; k++) {\n\t\t\t\t\tif (current[k] != undefined && current[k] != null && typeof current[k] === 'object') {\n\t\t\t\t\t\tnewResults.push(current[k][pathSegment]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Otherwise, normal property access\n\t\t\telse if (typeof current === 'object') {\n\t\t\t\tnewResults.push(current[pathSegment]);\n\t\t\t}\n\t\t}\n\t\t\n\t\tresults = newResults;\n\t}\n\t\n\t// Filter out undefined values\n\tresults = results.filter(function(v) { return v !== undefined; });\n\t\n\t// If we have multiple values, return the array\n\t// If we have exactly one, return it directly\n\t// If we have none, return undefined\n\tif (results.length === 0) return undefined;\n\tif (results.length === 1) return results[0];\n\treturn results;\n}\n\n/**\n * Set a property on an object using dot notation\n * Creates intermediate objects as needed\n * Supports array element access via numeric indices\n * Supports $[] operator to update all array elements\n */\nexport function setProp(obj, name, value) {\n\t// Check if path contains $[] operator\n\tif (name.indexOf('$[]') !== -1) {\n\t\treturn setPropWithAllPositional(obj, name, value);\n\t}\n\t\n\tvar path = name.split(\".\");\n\tvar current = obj;\n\t\n\tfor (var i = 0; i < path.length - 1; i++) {\n\t\tvar pathSegment = path[i];\n\t\tvar numericIndex = parseInt(pathSegment, 10);\n\t\t\n\t\t// If this is a numeric index and current is an array\n\t\tif (isArray(current) && !isNaN(numericIndex) && numericIndex >= 0) {\n\t\t\t// Ensure the array is large enough\n\t\t\twhile (current.length <= numericIndex) {\n\t\t\t\tcurrent.push(undefined);\n\t\t\t}\n\t\t\t// If the element doesn't exist, create an object\n\t\t\tif (current[numericIndex] == undefined || current[numericIndex] == null) {\n\t\t\t\t// Look ahead to see if next segment is numeric (array) or not (object)\n\t\t\t\tvar nextSegment = path[i + 1];\n\t\t\t\tvar nextNumeric = parseInt(nextSegment, 10);\n\t\t\t\tif (!isNaN(nextNumeric) && nextNumeric >= 0) {\n\t\t\t\t\tcurrent[numericIndex] = [];\n\t\t\t\t} else {\n\t\t\t\t\tcurrent[numericIndex] = {};\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrent = current[numericIndex];\n\t\t}\n\t\t// Regular property access\n\t\telse {\n\t\t\tif (current[pathSegment] == undefined || current[pathSegment] == null) {\n\t\t\t\t// Look ahead to see if next segment is numeric (array) or not (object)\n\t\t\t\tvar nextSegment = path[i + 1];\n\t\t\t\tvar nextNumeric = parseInt(nextSegment, 10);\n\t\t\t\tif (!isNaN(nextNumeric) && nextNumeric >= 0) {\n\t\t\t\t\tcurrent[pathSegment] = [];\n\t\t\t\t} else {\n\t\t\t\t\tcurrent[pathSegment] = {};\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrent = current[pathSegment];\n\t\t}\n\t}\n\t\n\t// Set the final value\n\tvar lastSegment = path[path.length - 1];\n\tvar lastNumericIndex = parseInt(lastSegment, 10);\n\t\n\tif (isArray(current) && !isNaN(lastNumericIndex) && lastNumericIndex >= 0) {\n\t\twhile (current.length <= lastNumericIndex) {\n\t\t\tcurrent.push(undefined);\n\t\t}\n\t\tcurrent[lastNumericIndex] = value;\n\t} else {\n\t\tcurrent[lastSegment] = value;\n\t}\n}\n\n/**\n * Set a property using the $[] all positional operator\n * Updates all elements in an array\n */\nfunction setPropWithAllPositional(obj, name, value) {\n\tvar path = name.split(\".\");\n\tvar current = obj;\n\t\n\t// Navigate to the $[] operator\n\tfor (var i = 0; i < path.length; i++) {\n\t\tvar pathSegment = path[i];\n\t\t\n\t\tif (pathSegment === '$[]') {\n\t\t\t// Current should be an array - update all elements\n\t\t\tif (!Array.isArray(current)) {\n\t\t\t\tthrow new Error(\"The positional operator did not find the match needed from the query.\");\n\t\t\t}\n\t\t\t\n\t\t\t// Build the remaining path after $[]\n\t\t\tvar remainingPath = path.slice(i + 1).join('.');\n\t\t\t\n\t\t\t// Update all array elements\n\t\t\tfor (var j = 0; j < current.length; j++) {\n\t\t\t\tif (remainingPath) {\n\t\t\t\t\t// There's more path after $[], recursively set on each element\n\t\t\t\t\tsetProp(current[j], remainingPath, value);\n\t\t\t\t} else {\n\t\t\t\t\t// $[] is the last segment, replace each element with value\n\t\t\t\t\tcurrent[j] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t\n\t\t// Navigate to the next level\n\t\tvar numericIndex = parseInt(pathSegment, 10);\n\t\t\n\t\tif (isArray(current) && !isNaN(numericIndex) && numericIndex >= 0) {\n\t\t\tcurrent = current[numericIndex];\n\t\t} else {\n\t\t\tif (current[pathSegment] == undefined || current[pathSegment] == null) {\n\t\t\t\t// Create intermediate object or array\n\t\t\t\tvar nextSegment = i + 1 < path.length ? path[i + 1] : null;\n\t\t\t\tif (nextSegment === '$[]') {\n\t\t\t\t\tcurrent[pathSegment] = [];\n\t\t\t\t} else {\n\t\t\t\t\tvar nextNumeric = parseInt(nextSegment, 10);\n\t\t\t\t\tif (!isNaN(nextNumeric) && nextNumeric >= 0) {\n\t\t\t\t\t\tcurrent[pathSegment] = [];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcurrent[pathSegment] = {};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurrent = current[pathSegment];\n\t\t}\n\t}\n}\n\n/**\n * Check if value is an array\n */\nexport function isArray(o) {\n\treturn Array == o.constructor;\n}\n\n/**\n * Convert object to array of key-value pairs\n */\nexport function toArray(obj) {\n\tvar arr = [];\n\tfor (var key in obj) {\n\t\tif (obj.hasOwnProperty(key)) {\n\t\t\tvar el = {};\n\t\t\tel[key] = obj[key];\n\t\t\tarr.push(el);\n\t\t}\n\t}\n\treturn arr;\n}\n\n/**\n * Check if a value is in an array\n */\nexport function isIn(val, values) {\n\tfor (var i = 0; i < values.length; i++) {\n\t\tif (valuesEqual(values[i], val)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Check if two arrays match\n */\nexport function arrayMatches(x, y) {\n\tif (x.length != y.length) return false;\n\tfor (var i = 0; i < x.length; i++) {\n\t\tif (valuesEqual(x[i], y[i])) continue;\n\t\tif (typeof (x[i]) != typeof (y[i])) return false;\n\t\tif (typeof (x[i]) == \"object\" && x[i] !== null) {\n\t\t\tif (isArray(x[i])) {\n\t\t\t\tif (!arrayMatches(x[i], y[i])) return false;\n\t\t\t} else {\n\t\t\t\tif (!objectMatches(x[i], y[i])) return false;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!valuesEqual(x[i], y[i])) return false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Check if two objects match\n */\nexport function objectMatches(x, y) {\n\tfor (var p in x) {\n\t\tif (!x.hasOwnProperty(p)) continue;\n\t\tif (!y.hasOwnProperty(p)) return false;\n\t\tif (valuesEqual(x[p], y[p])) continue;\n\t\tif (typeof (x[p]) != typeof (y[p])) return false;\n\t\tif (typeof (x[p]) == \"object\" && x[p] !== null) {\n\t\t\tif (isArray(x[p])) {\n\t\t\t\tif (!arrayMatches(x[p], y[p])) return false;\n\t\t\t} else {\n\t\t\t\tif (!objectMatches(x[p], y[p])) return false;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!valuesEqual(x[p], y[p])) return false;\n\t\t}\n\t}\n\tfor (var p in y) {\n\t\tif (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Apply projection to a document\n */\nexport function applyProjection(projection, doc) {\n\tvar result = {};\n\tvar keys = Object.keys(projection);\n\tif (keys.length == 0) return doc;\n\t\n\t// Check for mixed inclusion/exclusion (except _id which can be excluded in inclusion projection)\n\tvar hasInclusion = false;\n\tvar hasExclusion = false;\n\tfor (var i = 0; i < keys.length; i++) {\n\t\tif (keys[i] === '_id') continue; // _id is special\n\t\tif (projection[keys[i]]) hasInclusion = true;\n\t\telse hasExclusion = true;\n\t}\n\t\n\tif (hasInclusion && hasExclusion) {\n\t\tthrow { $err: \"Can't canonicalize query: BadValue Projection cannot have a mix of inclusion and exclusion.\", code: 17287 };\n\t}\n\t\n\tif (projection[keys[0]] || hasInclusion) {\n\t\t// Inclusion projection\n\t\t// Include _id unless explicitly excluded\n\t\tif (projection._id !== 0 && projection._id !== false) {\n\t\t\tresult._id = copy(doc._id);\n\t\t}\n\t\t\n\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\tif (keys[i] === '_id') continue;\n\t\t\tif (!projection[keys[i]]) continue;\n\t\t\t\n\t\t\tvar fieldPath = keys[i];\n\t\t\tvar value = getProp(doc, fieldPath);\n\t\t\t\n\t\t\tif (value !== undefined) {\n\t\t\t\t// Use setProp to create nested structure\n\t\t\t\tsetProp(result, fieldPath, copy(value));\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Exclusion projection - start with a copy of the document\n\t\tfor (var key in doc) {\n\t\t\tif (doc.hasOwnProperty(key)) {\n\t\t\t\t// Deep copy the value\n\t\t\t\tvar val = doc[key];\n\t\t\t\tif (typeof val === 'object' && val !== null && !isArray(val)) {\n\t\t\t\t\tresult[key] = copy(val);\n\t\t\t\t} else if (isArray(val)) {\n\t\t\t\t\tresult[key] = val.slice(); // shallow copy array\n\t\t\t\t} else {\n\t\t\t\t\tresult[key] = val;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Remove excluded fields\n\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\tif (projection[keys[i]]) continue; // Skip if value is truthy\n\t\t\t\n\t\t\tvar fieldPath = keys[i];\n\t\t\tvar pathParts = fieldPath.split('.');\n\t\t\t\n\t\t\t// Navigate to the parent object and delete the final property\n\t\t\tif (pathParts.length === 1) {\n\t\t\t\tdelete result[fieldPath];\n\t\t\t} else {\n\t\t\t\tvar parent = result;\n\t\t\t\tfor (var j = 0; j < pathParts.length - 1; j++) {\n\t\t\t\t\tif (parent == undefined || parent == null) break;\n\t\t\t\t\tparent = parent[pathParts[j]];\n\t\t\t\t}\n\t\t\t\tif (parent != undefined && parent != null) {\n\t\t\t\t\tdelete parent[pathParts[pathParts.length - 1]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\n/**\n * Convert bbox to GeoJSON\n */\nexport function bboxToGeojson(bbox) {\n\tconst minLon = bbox[0][0];\n\tconst maxLat = bbox[0][1];\n\tconst maxLon = bbox[1][0];\n\tconst minLat = bbox[1][1];\n\treturn {\n\t\ttype: 'FeatureCollection',\n\t\tfeatures: [{\n\t\t\ttype: 'Feature',\n\t\t\tproperties: {},\n\t\t\tgeometry: {\n\t\t\t\ttype: 'Polygon',\n\t\t\t\tcoordinates: [[\n\t\t\t\t\t[minLon, maxLat],\n\t\t\t\t\t[minLon, minLat],\n\t\t\t\t\t[maxLon, minLat],\n\t\t\t\t\t[maxLon, maxLat],\n\t\t\t\t\t[minLon, maxLat]\n\t\t\t\t]]\n\t\t\t}\n\t\t}]\n\t};\n}\n","// Standard suffix manipulations.\n/** @type {Record<string, string>} */\nconst step2list = {\n ational: 'ate',\n tional: 'tion',\n enci: 'ence',\n anci: 'ance',\n izer: 'ize',\n bli: 'ble',\n alli: 'al',\n entli: 'ent',\n eli: 'e',\n ousli: 'ous',\n ization: 'ize',\n ation: 'ate',\n ator: 'ate',\n alism: 'al',\n iveness: 'ive',\n fulness: 'ful',\n ousness: 'ous',\n aliti: 'al',\n iviti: 'ive',\n biliti: 'ble',\n logi: 'log'\n}\n\n/** @type {Record<string, string>} */\nconst step3list = {\n icate: 'ic',\n ative: '',\n alize: 'al',\n iciti: 'ic',\n ical: 'ic',\n ful: '',\n ness: ''\n}\n\n// Consonant-vowel sequences.\nconst consonant = '[^aeiou]'\nconst vowel = '[aeiouy]'\nconst consonants = '(' + consonant + '[^aeiouy]*)'\nconst vowels = '(' + vowel + '[aeiou]*)'\n\nconst gt0 = new RegExp('^' + consonants + '?' + vowels + consonants)\nconst eq1 = new RegExp(\n '^' + consonants + '?' + vowels + consonants + vowels + '?$'\n)\nconst gt1 = new RegExp('^' + consonants + '?(' + vowels + consonants + '){2,}')\nconst vowelInStem = new RegExp('^' + consonants + '?' + vowel)\nconst consonantLike = new RegExp('^' + consonants + vowel + '[^aeiouwxy]$')\n\n// Exception expressions.\nconst sfxLl = /ll$/\nconst sfxE = /^(.+?)e$/\nconst sfxY = /^(.+?)y$/\nconst sfxIon = /^(.+?(s|t))(ion)$/\nconst sfxEdOrIng = /^(.+?)(ed|ing)$/\nconst sfxAtOrBlOrIz = /(at|bl|iz)$/\nconst sfxEED = /^(.+?)eed$/\nconst sfxS = /^.+?[^s]s$/\nconst sfxSsesOrIes = /^.+?(ss|i)es$/\nconst sfxMultiConsonantLike = /([^aeiouylsz])\\1$/\nconst step2 =\n /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/\nconst step3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/\nconst step4 =\n /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/\n\n/**\n * Get the stem from a given value.\n *\n * @param {string} value\n * Value to stem.\n * @returns {string}\n * Stem for `value`\n */\n// eslint-disable-next-line complexity\nexport function stemmer(value) {\n let result = String(value).toLowerCase()\n\n // Exit early.\n if (result.length < 3) {\n return result\n }\n\n /** @type {boolean} */\n let firstCharacterWasLowerCaseY = false\n\n // Detect initial `y`, make sure it never matches.\n if (\n result.codePointAt(0) === 121 // Lowercase Y\n ) {\n firstCharacterWasLowerCaseY = true\n result = 'Y' + result.slice(1)\n }\n\n // Step 1a.\n if (sfxSsesOrIes.test(result)) {\n // Remove last two characters.\n result = result.slice(0, -2)\n } else if (sfxS.test(result)) {\n // Remove last character.\n result = result.slice(0, -1)\n }\n\n /** @type {RegExpMatchArray|null} */\n let match\n\n // Step 1b.\n if ((match = sfxEED.exec(result))) {\n if (gt0.test(match[1])) {\n // Remove last character.\n result = result.slice(0, -1)\n }\n } else if ((match = sfxEdOrIng.exec(result)) && vowelInStem.test(match[1])) {\n result = match[1]\n\n if (sfxAtOrBlOrIz.test(result)) {\n // Append `e`.\n result += 'e'\n } else if (sfxMultiConsonantLike.test(result)) {\n // Remove last character.\n result = result.slice(0, -1)\n } else if (consonantLike.test(result)) {\n // Append `e`.\n result += 'e'\n }\n }\n\n // Step 1c.\n if ((match = sfxY.exec(result)) && vowelInStem.test(match[1])) {\n // Remove suffixing `y` and append `i`.\n result = match[1] + 'i'\n }\n\n // Step 2.\n if ((match = step2.exec(result)) && gt0.test(match[1])) {\n result = match[1] + step2list[match[2]]\n }\n\n // Step 3.\n if ((match = step3.exec(result)) && gt0.test(match[1])) {\n result = match[1] + step3list[match[2]]\n }\n\n // Step 4.\n if ((match = step4.exec(result))) {\n if (gt1.test(match[1])) {\n result = match[1]\n }\n } else if ((match = sfxIon.exec(result)) && gt1.test(match[1])) {\n result = match[1]\n }\n\n // Step 5.\n if (\n (match = sfxE.exec(result)) &&\n (gt1.test(match[1]) ||\n (eq1.test(match[1]) && !consonantLike.test(match[1])))\n ) {\n result = match[1]\n }\n\n if (sfxLl.test(result) && gt1.test(result)) {\n result = result.slice(0, -1)\n }\n\n // Turn initial `Y` back to `y`.\n if (firstCharacterWasLowerCaseY) {\n result = 'y' + result.slice(1)\n }\n\n return result\n}\n","import { stemmer } from 'stemmer';\nimport { BPlusTree } from './bplustree.js';\nimport { getFileHandle } from './binjson.js';\n\n// Common English stop words that don't add semantic value to searches\nconst STOPWORDS = new Set([\n 'a', 'about', 'after', 'all', 'also', 'am', 'an', 'and', 'another', 'any', 'are', \n 'around', 'as', 'at', 'be', 'because', 'been', 'before', 'being', 'between', 'both', \n 'but', 'by', 'came', 'can', 'come', 'could', 'did', 'do', 'each', 'for', 'from', \n 'get', 'got', 'has', 'had', 'he', 'have', 'her', 'here', 'him', 'himself', 'his', \n 'how', 'i', 'if', 'in', 'into', 'is', 'it', 'like', 'make', 'many', 'me', 'might', \n 'more', 'most', 'much', 'must', 'my', 'never', 'now', 'of', 'on', 'only', 'or', \n 'other', 'our', 'out', 'over', 'said', 'same', 'see', 'should', 'since', 'some', \n 'still', 'such', 'take', 'than', 'that', 'the', 'their', 'them', 'then', 'there', \n 'these', 'they', 'this', 'those', 'through', 'to', 'too', 'under', 'up', 'very', \n 'was', 'way', 'we', 'well', 'were', 'what', 'where', 'which', 'while', 'who', \n 'with', 'would', 'you', 'your'\n]);\n\n/**\n * Tokenize text into individual words\n * @param {string} text - The text to tokenize\n * @returns {string[]} Array of words\n */\nexport function tokenize(text) {\n if (typeof text !== 'string') {\n return [];\n }\n // Split on non-word characters and filter out empty strings\n const words = text.toLowerCase()\n .split(/\\W+/)\n .filter(word => word.length > 0);\n \n // Filter stop words\n return words.filter(word => !STOPWORDS.has(word));\n}\n\n/**\n * TextIndex - A text index implementation using Porter stemmer algorithm\n * \n * This class provides full-text search capabilities by indexing terms\n * and associating them with document IDs. It uses the Porter stemmer\n * algorithm to normalize words to their root forms.\n */\nexport class TextIndex {\n constructor(options = {}) {\n const {\n order = 16,\n trees\n } = options;\n\n this.order = order;\n this.index = trees?.index || null;\n this.documentTerms = trees?.documentTerms || null;\n this.documentLengths = trees?.documentLengths || null;\n this.isOpen = false;\n }\n\n async open() {\n if (this.isOpen) {\n throw new Error('TextIndex is already open');\n }\n\n if (!this.index || !this.documentTerms || !this.documentLengths) {\n throw new Error('Trees must be initialized before opening');\n }\n\n await Promise.all([\n this.index.open(),\n this.documentTerms.open(),\n this.documentLengths.open()\n ]);\n\n this.isOpen = true;\n }\n\n async close() {\n if (!this.isOpen) {\n return;\n }\n\n await Promise.all([\n this.index.close(),\n this.documentTerms.close(),\n this.documentLengths.close()\n ]);\n\n this.isOpen = false;\n }\n\n _ensureOpen() {\n if (!this.isOpen) {\n throw new Error('TextIndex is not open');\n }\n }\n\n /**\n * Add terms from text to the index for a given document ID\n * @param {string} docId - The document identifier\n * @param {string} text - The text content to index\n */\n async add(docId, text) {\n this._ensureOpen();\n\n if (!docId) {\n throw new Error('Document ID is required');\n }\n\n const words = tokenize(text);\n const termFrequency = new Map();\n\n words.forEach(word => {\n const stem = stemmer(word);\n termFrequency.set(stem, (termFrequency.get(stem) || 0) + 1);\n });\n\n for (const [stem, frequency] of termFrequency.entries()) {\n const postings = (await this.index.search(stem)) || {};\n postings[docId] = frequency;\n await this.index.add(stem, postings);\n }\n\n const existingTerms = (await this.documentTerms.search(docId)) || {};\n const mergedTerms = { ...existingTerms };\n termFrequency.forEach((frequency, stem) => {\n mergedTerms[stem] = frequency;\n });\n\n const docLength = Object.values(mergedTerms).reduce((sum, count) => sum + count, 0);\n\n await this.documentTerms.add(docId, mergedTerms);\n await this.documentLengths.add(docId, docLength);\n }\n\n /**\n * Remove all indexed terms for a given document ID\n * @param {string} docId - The document identifier to remove\n * @returns {boolean} True if document was found and removed, false otherwise\n */\n async remove(docId) {\n this._ensureOpen();\n\n const terms = await this.documentTerms.search(docId);\n if (!terms) {\n return false;\n }\n\n for (const [term] of Object.entries(terms)) {\n const postings = (await this.index.search(term)) || {};\n delete postings[docId];\n\n if (Object.keys(postings).length === 0) {\n await this.index.delete(term);\n } else {\n await this.index.add(term, postings);\n }\n }\n\n await this.documentTerms.delete(docId);\n await this.documentLengths.delete(docId);\n return true;\n }\n\n /**\n * Query the index for documents containing the given terms with relevance scoring\n * @param {string} queryText - The search query text\n * @param {Object} options - Query options\n * @param {boolean} options.scored - If true, return scored results; if false, return just IDs (default: true)\n * @param {boolean} options.requireAll - If true, require ALL terms; if false, rank by relevance (default: false)\n * @returns {Array} Array of document IDs (if scored=false) or objects with {id, score} (if scored=true)\n */\n async query(queryText, options = { scored: true, requireAll: false }) {\n this._ensureOpen();\n\n const words = tokenize(queryText);\n if (words.length === 0) {\n return [];\n }\n\n const stemmedTerms = words.map(word => stemmer(word));\n const uniqueTerms = [...new Set(stemmedTerms)];\n\n if (options.requireAll) {\n const docSets = [];\n for (const term of uniqueTerms) {\n const termDocs = await this.index.search(term);\n docSets.push(new Set(Object.keys(termDocs || {})));\n }\n\n if (docSets.length === 0) {\n return [];\n }\n\n const intersection = new Set(docSets[0]);\n for (let i = 1; i < docSets.length; i++) {\n for (const docId of [...intersection]) {\n if (!docSets[i].has(docId)) {\n intersection.delete(docId);\n }\n }\n }\n\n return Array.from(intersection);\n }\n\n const docLengthEntries = await this.documentLengths.toArray();\n const docLengthMap = new Map(docLengthEntries.map(({ key, value }) => [String(key), value || 1]));\n const totalDocs = docLengthEntries.length;\n\n const idf = new Map();\n for (const term of uniqueTerms) {\n const termDocs = await this.index.search(term);\n const docsWithTerm = termDocs ? Object.keys(termDocs).length : 0;\n if (docsWithTerm > 0) {\n idf.set(term, Math.log(totalDocs / docsWithTerm));\n }\n }\n\n const docScores = new Map();\n for (const term of uniqueTerms) {\n const termDocs = await this.index.search(term);\n if (!termDocs) {\n continue;\n }\n\n for (const [docId, termFreq] of Object.entries(termDocs)) {\n const docLength = docLengthMap.get(docId) || 1;\n const tf = termFreq / docLength;\n const termIdf = idf.get(term) || 0;\n const prev = docScores.get(docId) || 0;\n docScores.set(docId, prev + tf * termIdf);\n }\n }\n\n for (const [docId, score] of docScores.entries()) {\n const docTerms = (await this.documentTerms.search(docId)) || {};\n const matchingTerms = uniqueTerms.filter(term => !!docTerms[term]).length;\n const coverage = matchingTerms / uniqueTerms.length;\n docScores.set(docId, score * (1 + coverage));\n }\n\n const results = Array.from(docScores.entries())\n .map(([id, score]) => ({ id, score }))\n .sort((a, b) => b.score - a.score);\n\n if (options.scored === false) {\n return results.map(r => r.id);\n }\n \n return results;\n }\n\n /**\n * Get the number of unique terms in the index\n * @returns {number} Number of unique terms\n */\n async getTermCount() {\n this._ensureOpen();\n const terms = await this.index.toArray();\n return terms.length;\n }\n\n /**\n * Get the number of documents in the index\n * @returns {number} Number of indexed documents\n */\n async getDocumentCount() {\n this._ensureOpen();\n const docs = await this.documentTerms.toArray();\n return docs.length;\n }\n\n /**\n * Clear all data from the index\n */\n async clear() {\n this._ensureOpen();\n\n const [terms, docs, lengths] = await Promise.all([\n this.index.toArray(),\n this.documentTerms.toArray(),\n this.documentLengths.toArray()\n ]);\n\n // Run deletes sequentially to avoid overlapping writes on the same underlying file\n for (const entry of terms) {\n await this.index.delete(entry.key);\n }\n\n for (const entry of docs) {\n await this.documentTerms.delete(entry.key);\n }\n\n for (const entry of lengths) {\n await this.documentLengths.delete(entry.key);\n }\n }\n\n /**\n * Compact all internal B+ trees using provided destination tree instances.\n * The destination trees should be freshly created (unopened) with new sync handles.\n * After compaction completes, the destination sync handles will be closed.\n * @param {Object} options - Compaction options \n * @param {BPlusTree} options.index - Fresh destination tree for index data\n * @param {BPlusTree} options.documentTerms - Fresh destination tree for document terms\n * @param {BPlusTree} options.documentLengths - Fresh destination tree for document lengths\n * @returns {Promise<{terms: object, documents: object, lengths: object}>}\n */\n async compact({ index: destIndex, documentTerms: destDocTerms, documentLengths: destDocLengths }) {\n this._ensureOpen();\n\n if (!destIndex || !destDocTerms || !destDocLengths) {\n throw new Error('Destination trees must be provided for compaction');\n }\n\n // Compact the trees. Note: BPlusTree.compact() will close the destination sync handle\n // when finished, so these destination trees should be disposable after this call\n const termsResult = await this.index.compact(destIndex.file.syncAccessHandle);\n const documentsResult = await this.documentTerms.compact(destDocTerms.file.syncAccessHandle);\n const lengthsResult = await this.documentLengths.compact(destDocLengths.file.syncAccessHandle);\n\n // Close the old trees - now the index is closed\n await this.close();\n this.isOpen = false;\n\n return {\n terms: termsResult,\n documents: documentsResult,\n lengths: lengthsResult\n };\n }\n\n}\n\n// Re-export the stemmer so consumers can share the exact same implementation\nexport { stemmer };\n","/**\n * Aggregation Expression Evaluator\n * \n * Implements MongoDB aggregation expression operators for use in\n * $project, $addFields, $set, $group, and other pipeline stages.\n */\n\nimport { getProp } from '../utils.js';\n\n/**\n * Evaluate an aggregation expression against a document\n * @param {*} expr - The expression to evaluate (can be literal, field reference, or expression object)\n * @param {Object} doc - The document to evaluate against\n * @returns {*} The evaluated result\n */\nexport function evaluateExpression(expr, doc) {\n\t// Literal values (strings not starting with $, numbers, booleans, null)\n\tif (expr === null || expr === undefined) {\n\t\treturn expr;\n\t}\n\t\n\tif (typeof expr === 'boolean' || typeof expr === 'number') {\n\t\treturn expr;\n\t}\n\t\n\t// Field reference ($fieldName) or variable reference ($$variableName)\n\tif (typeof expr === 'string') {\n\t\tif (expr.startsWith('$$')) {\n\t\t\t// Special system variables for $redact\n\t\t\tif (expr === '$$KEEP' || expr === '$$PRUNE' || expr === '$$DESCEND') {\n\t\t\t\treturn expr;\n\t\t\t}\n\t\t\t// Variable reference ($$var)\n\t\t\treturn getProp(doc, expr.substring(2));\n\t\t} else if (expr.charAt(0) === '$') {\n\t\t\t// Field reference ($field)\n\t\t\treturn getProp(doc, expr.substring(1));\n\t\t}\n\t\treturn expr; // Literal string\n\t}\n\t\n\t// Expression object\n\tif (typeof expr === 'object') {\n\t\t// Check if it's an array literal\n\t\tif (Array.isArray(expr)) {\n\t\t\treturn expr.map(item => evaluateExpression(item, doc));\n\t\t}\n\t\t\n\t\t// Expression operator\n\t\tconst keys = Object.keys(expr);\n\t\tif (keys.length === 0) {\n\t\t\treturn expr; // Empty object literal\n\t\t}\n\t\t\n\t\tconst operator = keys[0];\n\t\t\n\t\t// Check if this is an operator (starts with $) or an object literal\n\t\tif (operator.charAt(0) === '$') {\n\t\t\t// This is an expression operator\n\t\t\tconst operand = expr[operator];\n\t\t\treturn evaluateOperator(operator, operand, doc);\n\t\t} else {\n\t\t\t// This is an object literal - evaluate each field\n\t\t\tconst result = {};\n\t\t\tfor (const key of keys) {\n\t\t\t\tresult[key] = evaluateExpression(expr[key], doc);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\t\n\treturn expr;\n}\n\n/**\n * Evaluate a specific operator\n */\nfunction evaluateOperator(operator, operand, doc) {\n\tswitch (operator) {\n\t\t// Arithmetic operators\n\t\tcase '$add': return evalAdd(operand, doc);\n\t\tcase '$subtract': return evalSubtract(operand, doc);\n\t\tcase '$multiply': return evalMultiply(operand, doc);\n\t\tcase '$divide': return evalDivide(operand, doc);\n\t\tcase '$mod': return evalMod(operand, doc);\n\t\tcase '$pow': return evalPow(operand, doc);\n\t\tcase '$sqrt': return evalSqrt(operand, doc);\n\t\tcase '$abs': return evalAbs(operand, doc);\n\t\tcase '$ceil': return evalCeil(operand, doc);\n\t\tcase '$floor': return evalFloor(operand, doc);\n\t\tcase '$trunc': return evalTrunc(operand, doc);\n\t\tcase '$round': return evalRound(operand, doc);\n\t\t\n\t\t// String operators\n\t\tcase '$concat': return evalConcat(operand, doc);\n\t\tcase '$substr': return evalSubstr(operand, doc);\n\t\tcase '$toLower': return evalToLower(operand, doc);\n\t\tcase '$toUpper': return evalToUpper(operand, doc);\n\t\tcase '$trim': return evalTrim(operand, doc);\n\t\tcase '$ltrim': return evalLtrim(operand, doc);\n\t\tcase '$rtrim': return evalRtrim(operand, doc);\n\t\tcase '$split': return evalSplit(operand, doc);\n\t\tcase '$strLenCP': return evalStrLenCP(operand, doc);\n\t\tcase '$strcasecmp': return evalStrcasecmp(operand, doc);\n\t\tcase '$indexOfCP': return evalIndexOfCP(operand, doc);\n\t\tcase '$replaceOne': return evalReplaceOne(operand, doc);\n\t\tcase '$replaceAll': return evalReplaceAll(operand, doc);\n\t\t\n\t\t// Comparison operators\n\t\tcase '$cmp': return evalCmp(operand, doc);\n\t\tcase '$eq': return evalEq(operand, doc);\n\t\tcase '$ne': return evalNe(operand, doc);\n\t\tcase '$gt': return evalGt(operand, doc);\n\t\tcase '$gte': return evalGte(operand, doc);\n\t\tcase '$lt': return evalLt(operand, doc);\n\t\tcase '$lte': return evalLte(operand, doc);\n\t\t\n\t\t// Logical operators\n\t\tcase '$and': return evalAnd(operand, doc);\n\t\tcase '$or': return evalOr(operand, doc);\n\t\tcase '$not': return evalNot(operand, doc);\n\t\t\n\t\t// Conditional operators\n\t\tcase '$cond': return evalCond(operand, doc);\n\t\tcase '$ifNull': return evalIfNull(operand, doc);\n\t\tcase '$switch': return evalSwitch(operand, doc);\n\t\t\n\t\t// Date operators\n\t\tcase '$year': return evalYear(operand, doc);\n\t\tcase '$month': return evalMonth(operand, doc);\n\t\tcase '$dayOfMonth': return evalDayOfMonth(operand, doc);\n\t\tcase '$dayOfWeek': return evalDayOfWeek(operand, doc);\n\t\tcase '$dayOfYear': return evalDayOfYear(operand, doc);\n\t\tcase '$hour': return evalHour(operand, doc);\n\t\tcase '$minute': return evalMinute(operand, doc);\n\t\tcase '$second': return evalSecond(operand, doc);\n\t\tcase '$millisecond': return evalMillisecond(operand, doc);\n\t\tcase '$week': return evalWeek(operand, doc);\n\t\tcase '$isoWeek': return evalIsoWeek(operand, doc);\n\t\tcase '$isoWeekYear': return evalIsoWeekYear(operand, doc);\n\t\tcase '$dateToString': return evalDateToString(operand, doc);\n\t\tcase '$toDate': return evalToDate(operand, doc);\n\t\t\n\t\t// Array operators\n\t\tcase '$arrayElemAt': return evalArrayElemAt(operand, doc);\n\t\tcase '$concatArrays': return evalConcatArrays(operand, doc);\n\t\tcase '$filter': return evalFilter(operand, doc);\n\t\tcase '$in': return evalIn(operand, doc);\n\t\tcase '$indexOfArray': return evalIndexOfArray(operand, doc);\n\t\tcase '$isArray': return evalIsArray(operand, doc);\n\t\tcase '$map': return evalMap(operand, doc);\n\t\tcase '$reduce': return evalReduce(operand, doc);\n\t\tcase '$size': return evalSize(operand, doc);\n\t\tcase '$slice': return evalSlice(operand, doc);\n\t\tcase '$reverseArray': return evalReverseArray(operand, doc);\n\t\tcase '$zip': return evalZip(operand, doc);\n\t\t\n\t\t// Type operators\n\t\tcase '$type': return evalType(operand, doc);\n\t\tcase '$convert': return evalConvert(operand, doc);\n\t\tcase '$toBool': return evalToBool(operand, doc);\n\t\tcase '$toDecimal': return evalToDecimal(operand, doc);\n\t\tcase '$toDouble': return evalToDouble(operand, doc);\n\t\tcase '$toInt': return evalToInt(operand, doc);\n\t\tcase '$toLong': return evalToLong(operand, doc);\n\t\tcase '$toString': return evalToString(operand, doc);\n\t\t\n\t\t// Object operators\n\t\tcase '$objectToArray': return evalObjectToArray(operand, doc);\n\t\tcase '$arrayToObject': return evalArrayToObject(operand, doc);\n\t\tcase '$mergeObjects': return evalMergeObjects(operand, doc);\n\t\t\n\t\t// Literal operator\n\t\tcase '$literal': return operand;\n\t\t\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported aggregation operator: ${operator}`);\n\t}\n}\n\n// ============================================================================\n// ARITHMETIC OPERATORS\n// ============================================================================\n\nfunction evalAdd(operands, doc) {\n\tif (!Array.isArray(operands)) return null;\n\tlet sum = 0;\n\tfor (const operand of operands) {\n\t\tconst val = evaluateExpression(operand, doc);\n\t\tif (val instanceof Date) {\n\t\t\tsum += val.getTime();\n\t\t} else if (typeof val === 'number') {\n\t\t\tsum += val;\n\t\t}\n\t}\n\treturn sum;\n}\n\nfunction evalSubtract(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\t\n\tif (val1 instanceof Date && val2 instanceof Date) {\n\t\treturn val1.getTime() - val2.getTime();\n\t} else if (val1 instanceof Date && typeof val2 === 'number') {\n\t\treturn new Date(val1.getTime() - val2);\n\t} else if (typeof val1 === 'number' && typeof val2 === 'number') {\n\t\treturn val1 - val2;\n\t}\n\treturn null;\n}\n\nfunction evalMultiply(operands, doc) {\n\tif (!Array.isArray(operands)) return null;\n\tlet product = 1;\n\tfor (const operand of operands) {\n\t\tconst val = evaluateExpression(operand, doc);\n\t\tif (typeof val === 'number') {\n\t\t\tproduct *= val;\n\t\t}\n\t}\n\treturn product;\n}\n\nfunction evalDivide(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\tif (typeof val1 === 'number' && typeof val2 === 'number' && val2 !== 0) {\n\t\treturn val1 / val2;\n\t}\n\treturn null;\n}\n\nfunction evalMod(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\tif (typeof val1 === 'number' && typeof val2 === 'number' && val2 !== 0) {\n\t\treturn val1 % val2;\n\t}\n\treturn null;\n}\n\nfunction evalPow(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst base = evaluateExpression(operands[0], doc);\n\tconst exponent = evaluateExpression(operands[1], doc);\n\tif (typeof base === 'number' && typeof exponent === 'number') {\n\t\treturn Math.pow(base, exponent);\n\t}\n\treturn null;\n}\n\nfunction evalSqrt(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\tif (typeof val === 'number' && val >= 0) {\n\t\treturn Math.sqrt(val);\n\t}\n\treturn null;\n}\n\nfunction evalAbs(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\tif (typeof val === 'number') {\n\t\treturn Math.abs(val);\n\t}\n\treturn null;\n}\n\nfunction evalCeil(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\tif (typeof val === 'number') {\n\t\treturn Math.ceil(val);\n\t}\n\treturn null;\n}\n\nfunction evalFloor(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\tif (typeof val === 'number') {\n\t\treturn Math.floor(val);\n\t}\n\treturn null;\n}\n\nfunction evalTrunc(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\tif (typeof val === 'number') {\n\t\treturn Math.trunc(val);\n\t}\n\treturn null;\n}\n\nfunction evalRound(operands, doc) {\n\tconst val = evaluateExpression(Array.isArray(operands) ? operands[0] : operands, doc);\n\tconst place = Array.isArray(operands) && operands[1] !== undefined \n\t\t? evaluateExpression(operands[1], doc) \n\t\t: 0;\n\t\n\tif (typeof val === 'number' && typeof place === 'number') {\n\t\tconst multiplier = Math.pow(10, place);\n\t\treturn Math.round(val * multiplier) / multiplier;\n\t}\n\treturn null;\n}\n\n// ============================================================================\n// STRING OPERATORS\n// ============================================================================\n\nfunction evalConcat(operands, doc) {\n\tif (!Array.isArray(operands)) return null;\n\tlet result = '';\n\tfor (const operand of operands) {\n\t\tconst val = evaluateExpression(operand, doc);\n\t\tif (val !== null && val !== undefined) {\n\t\t\tresult += String(val);\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction evalSubstr(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length < 3) return null;\n\tconst str = String(evaluateExpression(operands[0], doc) || '');\n\tconst start = evaluateExpression(operands[1], doc);\n\tconst length = evaluateExpression(operands[2], doc);\n\tif (typeof start === 'number' && typeof length === 'number') {\n\t\treturn str.substr(start, length);\n\t}\n\treturn null;\n}\n\nfunction evalToLower(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn val !== null && val !== undefined ? String(val).toLowerCase() : '';\n}\n\nfunction evalToUpper(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn val !== null && val !== undefined ? String(val).toUpperCase() : '';\n}\n\nfunction evalTrim(operand, doc) {\n\tconst val = evaluateExpression(typeof operand === 'object' && operand.input ? operand.input : operand, doc);\n\tconst chars = operand.chars ? evaluateExpression(operand.chars, doc) : null;\n\t\n\tlet str = val !== null && val !== undefined ? String(val) : '';\n\t\n\tif (chars) {\n\t\tconst charsRegex = new RegExp(`^[${escapeRegex(chars)}]+|[${escapeRegex(chars)}]+$`, 'g');\n\t\treturn str.replace(charsRegex, '');\n\t}\n\treturn str.trim();\n}\n\nfunction evalLtrim(operand, doc) {\n\tconst val = evaluateExpression(typeof operand === 'object' && operand.input ? operand.input : operand, doc);\n\tconst chars = operand.chars ? evaluateExpression(operand.chars, doc) : null;\n\t\n\tlet str = val !== null && val !== undefined ? String(val) : '';\n\t\n\tif (chars) {\n\t\tconst charsRegex = new RegExp(`^[${escapeRegex(chars)}]+`, 'g');\n\t\treturn str.replace(charsRegex, '');\n\t}\n\treturn str.replace(/^\\s+/, '');\n}\n\nfunction evalRtrim(operand, doc) {\n\tconst val = evaluateExpression(typeof operand === 'object' && operand.input ? operand.input : operand, doc);\n\tconst chars = operand.chars ? evaluateExpression(operand.chars, doc) : null;\n\t\n\tlet str = val !== null && val !== undefined ? String(val) : '';\n\t\n\tif (chars) {\n\t\tconst charsRegex = new RegExp(`[${escapeRegex(chars)}]+$`, 'g');\n\t\treturn str.replace(charsRegex, '');\n\t}\n\treturn str.replace(/\\s+$/, '');\n}\n\nfunction evalSplit(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst str = String(evaluateExpression(operands[0], doc) || '');\n\tconst delimiter = String(evaluateExpression(operands[1], doc) || '');\n\treturn str.split(delimiter);\n}\n\nfunction evalStrLenCP(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn val !== null && val !== undefined ? String(val).length : 0;\n}\n\nfunction evalStrcasecmp(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst str1 = String(evaluateExpression(operands[0], doc) || '').toLowerCase();\n\tconst str2 = String(evaluateExpression(operands[1], doc) || '').toLowerCase();\n\t\n\tif (str1 < str2) return -1;\n\tif (str1 > str2) return 1;\n\treturn 0;\n}\n\nfunction evalIndexOfCP(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length < 2) return null;\n\tconst str = String(evaluateExpression(operands[0], doc) || '');\n\tconst substr = String(evaluateExpression(operands[1], doc) || '');\n\tconst start = operands[2] !== undefined ? evaluateExpression(operands[2], doc) : 0;\n\tconst end = operands[3] !== undefined ? evaluateExpression(operands[3], doc) : str.length;\n\t\n\tconst searchStr = str.substring(start, end);\n\tconst index = searchStr.indexOf(substr);\n\treturn index === -1 ? -1 : index + start;\n}\n\nfunction evalReplaceOne(operand, doc) {\n\tconst input = String(evaluateExpression(operand.input, doc) || '');\n\tconst find = String(evaluateExpression(operand.find, doc) || '');\n\tconst replacement = String(evaluateExpression(operand.replacement, doc) || '');\n\t\n\treturn input.replace(find, replacement);\n}\n\nfunction evalReplaceAll(operand, doc) {\n\tconst input = String(evaluateExpression(operand.input, doc) || '');\n\tconst find = String(evaluateExpression(operand.find, doc) || '');\n\tconst replacement = String(evaluateExpression(operand.replacement, doc) || '');\n\t\n\treturn input.split(find).join(replacement);\n}\n\nfunction escapeRegex(str) {\n\treturn str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n// ============================================================================\n// COMPARISON OPERATORS\n// ============================================================================\n\nfunction evalCmp(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\t\n\tif (val1 < val2) return -1;\n\tif (val1 > val2) return 1;\n\treturn 0;\n}\n\nfunction evalEq(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\treturn val1 === val2;\n}\n\nfunction evalNe(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\treturn val1 !== val2;\n}\n\nfunction evalGt(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\treturn val1 > val2;\n}\n\nfunction evalGte(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\treturn val1 >= val2;\n}\n\nfunction evalLt(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\treturn val1 < val2;\n}\n\nfunction evalLte(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst val1 = evaluateExpression(operands[0], doc);\n\tconst val2 = evaluateExpression(operands[1], doc);\n\treturn val1 <= val2;\n}\n\n// ============================================================================\n// LOGICAL OPERATORS\n// ============================================================================\n\nfunction evalAnd(operands, doc) {\n\tif (!Array.isArray(operands)) return null;\n\tfor (const operand of operands) {\n\t\tconst val = evaluateExpression(operand, doc);\n\t\tif (!val) return false;\n\t}\n\treturn true;\n}\n\nfunction evalOr(operands, doc) {\n\tif (!Array.isArray(operands)) return null;\n\tfor (const operand of operands) {\n\t\tconst val = evaluateExpression(operand, doc);\n\t\tif (val) return true;\n\t}\n\treturn false;\n}\n\nfunction evalNot(operand, doc) {\n\tconst val = evaluateExpression(Array.isArray(operand) ? operand[0] : operand, doc);\n\treturn !val;\n}\n\n// ============================================================================\n// CONDITIONAL OPERATORS\n// ============================================================================\n\nfunction evalCond(operand, doc) {\n\t// Supports both array form [if, then, else] and object form {if, then, else}\n\tlet ifExpr, thenExpr, elseExpr;\n\t\n\tif (Array.isArray(operand)) {\n\t\tif (operand.length !== 3) return null;\n\t\t[ifExpr, thenExpr, elseExpr] = operand;\n\t} else if (typeof operand === 'object') {\n\t\tifExpr = operand.if;\n\t\tthenExpr = operand.then;\n\t\telseExpr = operand.else;\n\t} else {\n\t\treturn null;\n\t}\n\t\n\tconst condition = evaluateExpression(ifExpr, doc);\n\treturn condition ? evaluateExpression(thenExpr, doc) : evaluateExpression(elseExpr, doc);\n}\n\nfunction evalIfNull(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length < 2) return null;\n\t\n\tfor (let i = 0; i < operands.length; i++) {\n\t\tconst val = evaluateExpression(operands[i], doc);\n\t\tif (val !== null && val !== undefined) {\n\t\t\treturn val;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction evalSwitch(operand, doc) {\n\tif (typeof operand !== 'object' || !Array.isArray(operand.branches)) {\n\t\treturn null;\n\t}\n\t\n\tfor (const branch of operand.branches) {\n\t\tconst caseResult = evaluateExpression(branch.case, doc);\n\t\tif (caseResult) {\n\t\t\treturn evaluateExpression(branch.then, doc);\n\t\t}\n\t}\n\t\n\treturn operand.default !== undefined ? evaluateExpression(operand.default, doc) : null;\n}\n\n// ============================================================================\n// DATE OPERATORS\n// ============================================================================\n\nfunction evalYear(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\treturn date.getUTCFullYear();\n\t}\n\treturn null;\n}\n\nfunction evalMonth(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\treturn date.getUTCMonth() + 1; // MongoDB returns 1-12\n\t}\n\treturn null;\n}\n\nfunction evalDayOfMonth(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\treturn date.getUTCDate();\n\t}\n\treturn null;\n}\n\nfunction evalDayOfWeek(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\treturn date.getUTCDay() + 1; // MongoDB returns 1-7 (Sunday is 1)\n\t}\n\treturn null;\n}\n\nfunction evalDayOfYear(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\tconst start = new Date(Date.UTC(date.getUTCFullYear(), 0, 0));\n\t\tconst diff = date - start;\n\t\tconst oneDay = 1000 * 60 * 60 * 24;\n\t\treturn Math.floor(diff / oneDay);\n\t}\n\treturn null;\n}\n\nfunction evalHour(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\treturn date.getUTCHours();\n\t}\n\treturn null;\n}\n\nfunction evalMinute(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\treturn date.getUTCMinutes();\n\t}\n\treturn null;\n}\n\nfunction evalSecond(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\treturn date.getUTCSeconds();\n\t}\n\treturn null;\n}\n\nfunction evalMillisecond(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\treturn date.getUTCMilliseconds();\n\t}\n\treturn null;\n}\n\nfunction evalWeek(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\tconst onejan = new Date(Date.UTC(date.getUTCFullYear(), 0, 1));\n\t\tconst week = Math.ceil((((date - onejan) / 86400000) + onejan.getUTCDay() + 1) / 7);\n\t\treturn week - 1; // MongoDB weeks are 0-indexed\n\t}\n\treturn null;\n}\n\nfunction evalIsoWeek(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\tconst target = new Date(date.valueOf());\n\t\tconst dayNr = (date.getUTCDay() + 6) % 7;\n\t\ttarget.setUTCDate(target.getUTCDate() - dayNr + 3);\n\t\tconst firstThursday = target.valueOf();\n\t\ttarget.setUTCMonth(0, 1);\n\t\tif (target.getUTCDay() !== 4) {\n\t\t\ttarget.setUTCMonth(0, 1 + ((4 - target.getUTCDay()) + 7) % 7);\n\t\t}\n\t\treturn 1 + Math.ceil((firstThursday - target) / 604800000);\n\t}\n\treturn null;\n}\n\nfunction evalIsoWeekYear(operand, doc) {\n\tconst date = evaluateExpression(operand, doc);\n\tif (date instanceof Date) {\n\t\tconst target = new Date(date.valueOf());\n\t\ttarget.setUTCDate(target.getUTCDate() - ((date.getUTCDay() + 6) % 7) + 3);\n\t\treturn target.getUTCFullYear();\n\t}\n\treturn null;\n}\n\nfunction evalDateToString(operand, doc) {\n\tconst format = operand.format ? evaluateExpression(operand.format, doc) : '%Y-%m-%dT%H:%M:%S.%LZ';\n\tconst date = evaluateExpression(operand.date, doc);\n\t\n\tif (!(date instanceof Date)) return null;\n\t\n\t// Simple format string implementation using UTC methods\n\treturn format\n\t\t.replace('%Y', date.getUTCFullYear())\n\t\t.replace('%m', String(date.getUTCMonth() + 1).padStart(2, '0'))\n\t\t.replace('%d', String(date.getUTCDate()).padStart(2, '0'))\n\t\t.replace('%H', String(date.getUTCHours()).padStart(2, '0'))\n\t\t.replace('%M', String(date.getUTCMinutes()).padStart(2, '0'))\n\t\t.replace('%S', String(date.getUTCSeconds()).padStart(2, '0'))\n\t\t.replace('%L', String(date.getUTCMilliseconds()).padStart(3, '0'));\n}\n\nfunction evalToDate(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\tif (val instanceof Date) return val;\n\tif (typeof val === 'string' || typeof val === 'number') {\n\t\tconst date = new Date(val);\n\t\treturn isNaN(date.getTime()) ? null : date;\n\t}\n\treturn null;\n}\n\n// ============================================================================\n// ARRAY OPERATORS\n// ============================================================================\n\nfunction evalArrayElemAt(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst arr = evaluateExpression(operands[0], doc);\n\tconst idx = evaluateExpression(operands[1], doc);\n\t\n\tif (!Array.isArray(arr) || typeof idx !== 'number') return null;\n\t\n\tconst index = idx < 0 ? arr.length + idx : idx;\n\treturn arr[index];\n}\n\nfunction evalConcatArrays(operands, doc) {\n\tif (!Array.isArray(operands)) return null;\n\tconst result = [];\n\tfor (const operand of operands) {\n\t\tconst arr = evaluateExpression(operand, doc);\n\t\tif (Array.isArray(arr)) {\n\t\t\tresult.push(...arr);\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction evalFilter(operand, doc) {\n\tconst input = evaluateExpression(operand.input, doc);\n\tconst asVar = operand.as || 'this';\n\tconst cond = operand.cond;\n\t\n\tif (!Array.isArray(input)) return null;\n\t\n\treturn input.filter(item => {\n\t\tconst itemDoc = { ...doc, [asVar]: item };\n\t\treturn evaluateExpression(cond, itemDoc);\n\t});\n}\n\nfunction evalIn(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length !== 2) return null;\n\tconst value = evaluateExpression(operands[0], doc);\n\tconst arr = evaluateExpression(operands[1], doc);\n\t\n\tif (!Array.isArray(arr)) return false;\n\treturn arr.includes(value);\n}\n\nfunction evalIndexOfArray(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length < 2) return null;\n\tconst arr = evaluateExpression(operands[0], doc);\n\tconst search = evaluateExpression(operands[1], doc);\n\tconst start = operands[2] !== undefined ? evaluateExpression(operands[2], doc) : 0;\n\tconst end = operands[3] !== undefined ? evaluateExpression(operands[3], doc) : arr.length;\n\t\n\tif (!Array.isArray(arr)) return null;\n\t\n\tfor (let i = start; i < end && i < arr.length; i++) {\n\t\tif (arr[i] === search) return i;\n\t}\n\treturn -1;\n}\n\nfunction evalIsArray(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn Array.isArray(val);\n}\n\nfunction evalMap(operand, doc) {\n\tconst input = evaluateExpression(operand.input, doc);\n\tconst asVar = operand.as || 'this';\n\tconst inExpr = operand.in;\n\t\n\tif (!Array.isArray(input)) return null;\n\t\n\treturn input.map(item => {\n\t\tconst itemDoc = { ...doc, [asVar]: item };\n\t\treturn evaluateExpression(inExpr, itemDoc);\n\t});\n}\n\nfunction evalReduce(operand, doc) {\n\tconst input = evaluateExpression(operand.input, doc);\n\tconst initialValue = evaluateExpression(operand.initialValue, doc);\n\tconst inExpr = operand.in;\n\t\n\tif (!Array.isArray(input)) return null;\n\t\n\tlet value = initialValue;\n\tfor (const item of input) {\n\t\tconst itemDoc = { ...doc, value, this: item };\n\t\tvalue = evaluateExpression(inExpr, itemDoc);\n\t}\n\treturn value;\n}\n\nfunction evalSize(operand, doc) {\n\tconst arr = evaluateExpression(operand, doc);\n\treturn Array.isArray(arr) ? arr.length : null;\n}\n\nfunction evalSlice(operands, doc) {\n\tif (!Array.isArray(operands) || operands.length < 2) return null;\n\tconst arr = evaluateExpression(operands[0], doc);\n\t\n\tif (!Array.isArray(arr)) return null;\n\t\n\tif (operands.length === 2) {\n\t\tconst n = evaluateExpression(operands[1], doc);\n\t\treturn n >= 0 ? arr.slice(0, n) : arr.slice(n);\n\t} else {\n\t\tconst position = evaluateExpression(operands[1], doc);\n\t\tconst n = evaluateExpression(operands[2], doc);\n\t\treturn arr.slice(position, position + n);\n\t}\n}\n\nfunction evalReverseArray(operand, doc) {\n\tconst arr = evaluateExpression(operand, doc);\n\treturn Array.isArray(arr) ? arr.slice().reverse() : null;\n}\n\nfunction evalZip(operand, doc) {\n\tconst inputs = operand.inputs ? evaluateExpression(operand.inputs, doc) : null;\n\tconst useLongestLength = operand.useLongestLength || false;\n\tconst defaults = operand.defaults;\n\t\n\tif (!Array.isArray(inputs)) return null;\n\t\n\tconst arrays = inputs.map(input => evaluateExpression(input, doc));\n\tif (!arrays.every(arr => Array.isArray(arr))) return null;\n\t\n\tconst maxLength = Math.max(...arrays.map(arr => arr.length));\n\tconst length = useLongestLength ? maxLength : Math.min(...arrays.map(arr => arr.length));\n\t\n\tconst result = [];\n\tfor (let i = 0; i < length; i++) {\n\t\tconst tuple = [];\n\t\tfor (let j = 0; j < arrays.length; j++) {\n\t\t\tif (i < arrays[j].length) {\n\t\t\t\ttuple.push(arrays[j][i]);\n\t\t\t} else if (defaults && j < defaults.length) {\n\t\t\t\ttuple.push(defaults[j]);\n\t\t\t} else {\n\t\t\t\ttuple.push(null);\n\t\t\t}\n\t\t}\n\t\tresult.push(tuple);\n\t}\n\treturn result;\n}\n\n// ============================================================================\n// TYPE OPERATORS\n// ============================================================================\n\nfunction evalType(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\t\n\tif (val === null) return 'null';\n\tif (val === undefined) return 'missing';\n\tif (typeof val === 'boolean') return 'bool';\n\tif (typeof val === 'number') return Number.isInteger(val) ? 'int' : 'double';\n\tif (typeof val === 'string') return 'string';\n\tif (val instanceof Date) return 'date';\n\tif (Array.isArray(val)) return 'array';\n\tif (typeof val === 'object') return 'object';\n\t\n\treturn 'unknown';\n}\n\nfunction evalConvert(operand, doc) {\n\tconst input = evaluateExpression(operand.input, doc);\n\tconst to = operand.to;\n\tconst onError = operand.onError;\n\tconst onNull = operand.onNull;\n\t\n\tif (input === null) {\n\t\treturn onNull !== undefined ? evaluateExpression(onNull, doc) : null;\n\t}\n\t\n\ttry {\n\t\tswitch (to) {\n\t\t\tcase 'double':\n\t\t\tcase 'decimal':\n\t\t\t\treturn parseFloat(input);\n\t\t\tcase 'int':\n\t\t\tcase 'long':\n\t\t\t\treturn parseInt(input);\n\t\t\tcase 'bool':\n\t\t\t\treturn Boolean(input);\n\t\t\tcase 'string':\n\t\t\t\treturn String(input);\n\t\t\tcase 'date':\n\t\t\t\treturn new Date(input);\n\t\t\tdefault:\n\t\t\t\treturn input;\n\t\t}\n\t} catch (e) {\n\t\treturn onError !== undefined ? evaluateExpression(onError, doc) : null;\n\t}\n}\n\nfunction evalToBool(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn Boolean(val);\n}\n\nfunction evalToDecimal(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn parseFloat(val);\n}\n\nfunction evalToDouble(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn parseFloat(val);\n}\n\nfunction evalToInt(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn parseInt(val);\n}\n\nfunction evalToLong(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\treturn parseInt(val);\n}\n\nfunction evalToString(operand, doc) {\n\tconst val = evaluateExpression(operand, doc);\n\tif (val === null || val === undefined) return null;\n\treturn String(val);\n}\n\n// ============================================================================\n// OBJECT OPERATORS\n// ============================================================================\n\nfunction evalObjectToArray(operand, doc) {\n\tconst obj = evaluateExpression(operand, doc);\n\tif (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {\n\t\treturn null;\n\t}\n\t\n\treturn Object.keys(obj).map(key => ({ k: key, v: obj[key] }));\n}\n\nfunction evalArrayToObject(operand, doc) {\n\tconst arr = evaluateExpression(operand, doc);\n\tif (!Array.isArray(arr)) return null;\n\t\n\tconst result = {};\n\tfor (const item of arr) {\n\t\tif (Array.isArray(item) && item.length === 2) {\n\t\t\tresult[item[0]] = item[1];\n\t\t} else if (typeof item === 'object' && item.k !== undefined && item.v !== undefined) {\n\t\t\tresult[item.k] = item.v;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction evalMergeObjects(operands, doc) {\n\tif (!Array.isArray(operands)) {\n\t\t// Single object\n\t\treturn evaluateExpression(operands, doc);\n\t}\n\t\n\tconst result = {};\n\tfor (const operand of operands) {\n\t\tconst obj = evaluateExpression(operand, doc);\n\t\tif (typeof obj === 'object' && obj !== null && !Array.isArray(obj)) {\n\t\t\tObject.assign(result, obj);\n\t\t}\n\t}\n\treturn result;\n}\n","import { getProp, getFieldValues, isArray, arrayMatches, objectMatches, toArray, isIn, bboxToGeojson } from '../utils.js';\nimport { stemmer, tokenize } from '@belteshazzar/binjson/textindex';\nimport { ObjectId } from '@belteshazzar/binjson';\nimport { evaluateExpression } from './aggregationExpressions.js';\n\n/**\n * BSON type mappings for $type operator\n */\nconst BSON_TYPES = {\n\t1: 'double',\n\t2: 'string',\n\t3: 'object',\n\t4: 'array',\n\t5: 'binData',\n\t6: 'undefined',\n\t7: 'objectId',\n\t8: 'bool',\n\t9: 'date',\n\t10: 'null',\n\t11: 'regex',\n\t13: 'javascript',\n\t15: 'javascriptWithScope',\n\t16: 'int',\n\t17: 'timestamp',\n\t18: 'long',\n\t19: 'decimal',\n\t127: 'maxKey',\n\t'-1': 'minKey'\n};\n\n// Reverse mapping from alias to code\nconst TYPE_ALIASES = Object.entries(BSON_TYPES).reduce((acc, [code, name]) => {\n\tacc[name] = parseInt(code);\n\treturn acc;\n}, {});\n\n/**\n * Check if a value matches a BSON type or type code\n */\nfunction matchesType(value, typeSpec) {\n\t// Handle array of types\n\tif (isArray(typeSpec)) {\n\t\tfor (let i = 0; i < typeSpec.length; i++) {\n\t\t\tif (matchesType(value, typeSpec[i])) return true;\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t// Get type code from spec (can be number or string alias)\n\tconst typeCode = typeof typeSpec === 'number' ? typeSpec : TYPE_ALIASES[typeSpec];\n\tconst typeName = BSON_TYPES[typeCode] || typeSpec;\n\t\n\t// Check value type\n\tif (value === null) return typeName === 'null' || typeCode === 10;\n\tif (value === undefined) return typeName === 'undefined' || typeCode === 6;\n\tif (typeof value === 'number') {\n\t\tif (Number.isInteger(value)) return typeName === 'int' || typeCode === 16;\n\t\treturn typeName === 'double' || typeCode === 1;\n\t}\n\tif (typeof value === 'string') return typeName === 'string' || typeCode === 2;\n\tif (typeof value === 'boolean') return typeName === 'bool' || typeCode === 8;\n\tif (value instanceof Date) return typeName === 'date' || typeCode === 9;\n\tif (value instanceof ObjectId) return typeName === 'objectId' || typeCode === 7;\n\tif (value instanceof RegExp) return typeName === 'regex' || typeCode === 11;\n\tif (isArray(value)) return typeName === 'array' || typeCode === 4;\n\tif (typeof value === 'object') return typeName === 'object' || typeCode === 3;\n\t\n\t// Fallback to simple type check\n\treturn typeof value === typeSpec;\n}\n\n/**\n * Bit query operator helpers\n */\nfunction toBitMask(positions) {\n\tif (isArray(positions)) {\n\t\t// Array of bit positions\n\t\tlet mask = 0;\n\t\tfor (let i = 0; i < positions.length; i++) {\n\t\t\tmask |= (1 << positions[i]);\n\t\t}\n\t\treturn mask;\n\t} else if (typeof positions === 'number') {\n\t\t// Bitmask directly\n\t\treturn positions;\n\t}\n\treturn 0;\n}\n\nfunction matchesBitsAllSet(value, positions) {\n\tif (typeof value !== 'number') return false;\n\tconst mask = toBitMask(positions);\n\treturn (value & mask) === mask;\n}\n\nfunction matchesBitsAllClear(value, positions) {\n\tif (typeof value !== 'number') return false;\n\tconst mask = toBitMask(positions);\n\treturn (value & mask) === 0;\n}\n\nfunction matchesBitsAnySet(value, positions) {\n\tif (typeof value !== 'number') return false;\n\tconst mask = toBitMask(positions);\n\treturn (value & mask) !== 0;\n}\n\nfunction matchesBitsAnyClear(value, positions) {\n\tif (typeof value !== 'number') return false;\n\tconst mask = toBitMask(positions);\n\treturn (value & mask) !== mask;\n}\n\n/**\n * JSON Schema validator (simplified)\n */\nfunction validateJsonSchema(doc, schema) {\n\t// Basic JSON Schema validation\n\tif (schema.type) {\n\t\tconst docType = isArray(doc) ? 'array' : (doc === null ? 'null' : typeof doc);\n\t\tif (schema.type !== docType) return false;\n\t}\n\t\n\tif (schema.required && isArray(schema.required)) {\n\t\tfor (let i = 0; i < schema.required.length; i++) {\n\t\t\tif (!(schema.required[i] in doc)) return false;\n\t\t}\n\t}\n\t\n\tif (schema.properties) {\n\t\tfor (const key in schema.properties) {\n\t\t\t// When using $jsonSchema as a query operator, properties must exist to match\n\t\t\t// (This is different from standard JSON Schema validation where properties are optional)\n\t\t\tif (!(key in doc)) return false;\n\t\t\t\n\t\t\tconst propSchema = schema.properties[key];\n\t\t\tif (!validateJsonSchema(doc[key], propSchema)) return false;\n\t\t}\n\t}\n\t\n\tif (schema.minimum !== undefined && typeof doc === 'number') {\n\t\tif (doc < schema.minimum) return false;\n\t}\n\t\n\tif (schema.maximum !== undefined && typeof doc === 'number') {\n\t\tif (doc > schema.maximum) return false;\n\t}\n\t\n\tif (schema.minLength !== undefined && typeof doc === 'string') {\n\t\tif (doc.length < schema.minLength) return false;\n\t}\n\t\n\tif (schema.maxLength !== undefined && typeof doc === 'string') {\n\t\tif (doc.length > schema.maxLength) return false;\n\t}\n\t\n\tif (schema.pattern && typeof doc === 'string') {\n\t\tconst regex = new RegExp(schema.pattern);\n\t\tif (!regex.test(doc)) return false;\n\t}\n\t\n\tif (schema.enum && isArray(schema.enum)) {\n\t\tif (!schema.enum.includes(doc)) return false;\n\t}\n\t\n\treturn true;\n}\n\n/**\n * Compare two values for equality, handling ObjectId instances\n */\nfunction valuesEqual(a, b) {\n\t// Handle ObjectId comparison\n\tif (a instanceof ObjectId && b instanceof ObjectId) {\n return a.equals(b);\n\t}\n\t\n\t// Regular equality\n\treturn a == b;\n}\n\n/**\n * Compare two values with a comparison operator, handling ObjectId instances\n */\nfunction compareValues(a, b, operator) {\n\t// Convert ObjectIds to comparable values (use timestamp for ordering)\n\tlet aVal = a;\n\tlet bVal = b;\n\t\n\tif (a instanceof ObjectId) {\n\t\taVal = a.toString();\n\t}\n\tif (b instanceof ObjectId) {\n\t\tbVal = b.toString();\n\t}\n\t\n\tswitch(operator) {\n\t\tcase '>': return aVal > bVal;\n\t\tcase '>=': return aVal >= bVal;\n\t\tcase '<': return aVal < bVal;\n\t\tcase '<=': return aVal <= bVal;\n\t\tdefault: return false;\n\t}\n}\n\n/**\n * Check if a field value (possibly from array traversal) matches a condition\n * Handles both single values and arrays of values (from array traversal)\n */\nfunction fieldValueMatches(fieldValue, checkFn) {\n\t// Use strict equality to allow null values through\n\tif (fieldValue === undefined) return false;\n\t\n\t// Check for null before isArray to avoid crash\n\tif (fieldValue === null) return checkFn(fieldValue);\n\t\n\t// If fieldValue is an array (from array traversal), check if ANY element matches\n\tif (isArray(fieldValue)) {\n\t\tfor (var i = 0; i < fieldValue.length; i++) {\n\t\t\tif (checkFn(fieldValue[i])) return true;\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t// Otherwise check the single value\n\treturn checkFn(fieldValue);\n}\n\n/**\n * Tokenize text for search\n */\nfunction tokenizeText(text) {\n\tif (typeof text !== 'string') return [];\n\n const words = tokenize(text);\n\treturn words.map(w => stemmer(w));\n}\n\n/**\n * Text search helper\n * Matches if the property contains tokens from the query\n */\nexport function text(prop, queryText) {\n\tif (typeof prop !== 'string') return false;\n\t\n\tconst propTokens = new Set(tokenizeText(prop));\n\tconst queryTokens = tokenizeText(queryText);\n\t\n\t// Match if any query term is in the document\n\treturn queryTokens.some(term => propTokens.has(term));\n}\n\n/**\n * Text search across all string fields in a document\n * Used for top-level $text operator\n */\nfunction textSearchDocument(doc, searchText) {\n\tif (!doc || typeof doc !== 'object') return false;\n\t\n\t// Recursively search all string fields\n\tfunction searchObject(obj) {\n\t\tif (typeof obj === 'string') {\n\t\t\treturn text(obj, searchText);\n\t\t}\n\t\t\n\t\tif (typeof obj !== 'object' || obj === null) {\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\t// Check arrays\n\t\tif (isArray(obj)) {\n\t\t\tfor (let i = 0; i < obj.length; i++) {\n\t\t\t\tif (searchObject(obj[i])) return true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t\n\t\t// Check object properties\n\t\tfor (const key in obj) {\n\t\t\tif (obj.hasOwnProperty(key)) {\n\t\t\t\tif (searchObject(obj[key])) return true;\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn false;\n\t}\n\t\n\treturn searchObject(doc);\n}\n\n/**\n * Geo within helper - using bounding box logic instead of de9im\n * This is a simpler implementation that doesn't require de9im dependency\n */\nexport function geoWithin(prop, query) {\n\ttry {\n\t\t// bbox format: [[minLon, maxLat], [maxLon, minLat]]\n\t\tif (!Array.isArray(query) || query.length !== 2) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst minLon = query[0][0];\n\t\tconst maxLat = query[0][1];\n\t\tconst maxLon = query[1][0];\n\t\tconst minLat = query[1][1];\n\n\t\t// Check if geometry is within bounding box\n\t\treturn isGeometryWithinBBox(prop, minLon, maxLon, minLat, maxLat);\n\t} catch (e) {\n\t\treturn false;\n\t}\n}\n\n/**\n * Check if a GeoJSON geometry is within a bounding box\n * For Points: checks if the point is within the bbox\n * For Polygons: checks if ALL vertices are within the bbox\n */\nfunction isGeometryWithinBBox(geoJson, minLon, maxLon, minLat, maxLat) {\n\tif (!geoJson) return false;\n\n\t// Handle GeoJSON FeatureCollection\n\tif (geoJson.type === 'FeatureCollection' && geoJson.features && geoJson.features.length > 0) {\n\t\t// All features must be within the bbox\n\t\tfor (const feature of geoJson.features) {\n\t\t\tif (feature.geometry) {\n\t\t\t\tif (!isGeometryWithinBBox(feature.geometry, minLon, maxLon, minLat, maxLat)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t// Handle GeoJSON Feature\n\tif (geoJson.type === 'Feature' && geoJson.geometry) {\n\t\treturn isGeometryWithinBBox(geoJson.geometry, minLon, maxLon, minLat, maxLat);\n\t}\n\n\t// Handle GeoJSON Point\n\tif (geoJson.type === 'Point' && geoJson.coordinates) {\n\t\tconst [lng, lat] = geoJson.coordinates;\n\t\tif (typeof lng === 'number' && typeof lat === 'number') {\n\t\t\treturn lng >= minLon && lng <= maxLon && lat >= minLat && lat <= maxLat;\n\t\t}\n\t}\n\n\t// Handle GeoJSON Polygon - ALL vertices must be within the bbox\n\tif (geoJson.type === 'Polygon' && geoJson.coordinates && geoJson.coordinates.length > 0) {\n\t\tfor (const ring of geoJson.coordinates) {\n\t\t\tfor (const coord of ring) {\n\t\t\t\tconst lng = coord[0];\n\t\t\t\tconst lat = coord[1];\n\t\t\t\tif (lng < minLon || lng > maxLon || lat < minLat || lat > maxLat) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Extract coordinates from a GeoJSON object for indexing purposes\n * This uses centroid for polygons to get a single point to index\n * @param {Object} geoJson - The GeoJSON object\n * @returns {Object|null} Object with lat and lng, or null if invalid\n */\nfunction extractCoordinatesFromGeoJSON(geoJson) {\n\tif (!geoJson) return null;\n\n\t// Handle GeoJSON FeatureCollection\n\tif (geoJson.type === 'FeatureCollection' && geoJson.features && geoJson.features.length > 0) {\n\t\tconst feature = geoJson.features[0];\n\t\tif (feature.geometry) {\n\t\t\treturn extractCoordinatesFromGeoJSON(feature.geometry);\n\t\t}\n\t}\n\n\t// Handle GeoJSON Feature\n\tif (geoJson.type === 'Feature' && geoJson.geometry) {\n\t\treturn extractCoordinatesFromGeoJSON(geoJson.geometry);\n\t}\n\n\t// Handle GeoJSON Point\n\tif (geoJson.type === 'Point' && geoJson.coordinates) {\n\t\tconst [lng, lat] = geoJson.coordinates;\n\t\tif (typeof lng === 'number' && typeof lat === 'number') {\n\t\t\treturn { lat, lng };\n\t\t}\n\t}\n\n\t// Handle GeoJSON Polygon - use centroid of first coordinate ring\n\tif (geoJson.type === 'Polygon' && geoJson.coordinates && geoJson.coordinates.length > 0) {\n\t\tconst ring = geoJson.coordinates[0];\n\t\tif (ring.length > 0) {\n\t\t\tlet sumLat = 0, sumLng = 0;\n\t\t\tfor (const coord of ring) {\n\t\t\t\tsumLng += coord[0];\n\t\t\t\tsumLat += coord[1];\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tlat: sumLat / ring.length,\n\t\t\t\tlng: sumLng / ring.length\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Calculate haversine distance between two points in kilometers\n */\nfunction haversineDistance(lat1, lng1, lat2, lng2) {\n\tconst R = 6371; // Earth's radius in kilometers\n\tconst dLat = (lat2 - lat1) * Math.PI / 180;\n\tconst dLng = (lng2 - lng1) * Math.PI / 180;\n\tconst a = \n\t\tMath.sin(dLat / 2) * Math.sin(dLat / 2) +\n\t\tMath.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *\n\t\tMath.sin(dLng / 2) * Math.sin(dLng / 2);\n\tconst c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\treturn R * c;\n}\n\n/**\n * Check if a point is within a certain distance (in meters) of a reference point\n */\nfunction isNear(geoJson, refLng, refLat, maxDistanceMeters) {\n\tconst coords = extractCoordinatesFromGeoJSON(geoJson);\n\tif (!coords) return false;\n\tconst distanceKm = haversineDistance(coords.lat, coords.lng, refLat, refLng);\n\tconst distanceM = distanceKm * 1000;\n\treturn distanceM <= maxDistanceMeters;\n}\n\n/**\n * Check if geometries intersect (simple implementation)\n */\nfunction geoIntersects(geoJson, queryGeo) {\n\tif (!geoJson || !queryGeo) return false;\n\t\n\t// Get coordinates from query geometry\n\tconst queryCoords = extractCoordinatesFromGeoJSON(queryGeo);\n\tif (!queryCoords) return false;\n\t\n\t// Get coordinates from document geometry\n\tconst docCoords = extractCoordinatesFromGeoJSON(geoJson);\n\tif (!docCoords) return false;\n\t\n\t// For now, simple point-in-polygon check for polygons\n\t// If query is a polygon, check if document point is inside\n\tif (queryGeo.type === 'Polygon' && geoJson.type === 'Point') {\n\t\treturn pointInPolygon(docCoords.lng, docCoords.lat, queryGeo.coordinates[0]);\n\t}\n\t\n\t// If document is a polygon and query is a point, check if point is inside\n\tif (geoJson.type === 'Polygon' && queryGeo.type === 'Point') {\n\t\tconst queryPt = queryGeo.coordinates;\n\t\treturn pointInPolygon(queryPt[0], queryPt[1], geoJson.coordinates[0]);\n\t}\n\t\n\t// For points, check if they're the same or very close\n\tif (geoJson.type === 'Point' && queryGeo.type === 'Point') {\n\t\tconst dist = haversineDistance(docCoords.lat, docCoords.lng, queryCoords.lat, queryCoords.lng);\n\t\treturn dist < 0.001; // Within about 1 meter\n\t}\n\t\n\treturn false;\n}\n\n/**\n * Point-in-polygon test using ray casting algorithm\n */\nfunction pointInPolygon(lng, lat, ring) {\n\tlet inside = false;\n\tfor (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n\t\tconst xi = ring[i][0], yi = ring[i][1];\n\t\tconst xj = ring[j][0], yj = ring[j][1];\n\t\tconst intersect = ((yi > lat) !== (yj > lat)) && (lng < (xj - xi) * (lat - yi) / (yj - yi) + xi);\n\t\tif (intersect) inside = !inside;\n\t}\n\treturn inside;\n}\n\n/**\n * $where operator implementation\n * SECURITY NOTE: This uses Function constructor which can execute arbitrary code.\n * This is acceptable for a local/in-memory database but should NOT be used\n * in environments where untrusted user input is processed.\n */\nexport function where(doc, value) {\n\tif (typeof value === 'function') {\n\t\ttry {\n\t\t\treturn value.call(doc);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t} else if (typeof value === 'string') {\n\t\t// Evaluate the string as a function\n\t\ttry {\n\t\t\tvar fn = new Function('return ' + value);\n\t\t\treturn fn.call(doc);\n\t\t} catch (e) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Top-level match function\n */\nexport function tlMatches(doc, query) {\n\tvar key = Object.keys(query)[0];\n\tvar value = query[key];\n\tif (key.charAt(0) == \"$\") {\n\t\tif (key == \"$and\") return and(doc, value);\n\t\telse if (key == \"$or\") return or(doc, value);\n\t\telse if (key == \"$not\") return not(doc, value);\n\t\telse if (key == \"$nor\") return nor(doc, value);\n\t\telse if (key == \"$where\") return where(doc, value);\n\t\telse if (key == \"$comment\") return true; // $comment is metadata, doesn't filter\n\t\telse if (key == \"$jsonSchema\") return validateJsonSchema(doc, value); // Top-level schema validation\n\t\telse if (key == \"$text\") {\n\t\t\t// Handle $text as top-level operator\n\t\t\t// Searches across all string fields in the document\n\t\t\tconst searchText = value.$search || value;\n\t\t\treturn textSearchDocument(doc, searchText);\n\t\t}\n\t\telse if (key == \"$expr\") {\n\t\t\t// Handle $expr at top level\n\t\t\ttry {\n\t\t\t\treturn evaluateExpression(value, doc);\n\t\t\t} catch (e) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse throw { $err: \"Can't canonicalize query: BadValue unknown top level operator: \" + key, code: 17287 };\n\t} else {\n\t\treturn opMatches(doc, key, value);\n\t}\n}\n\n/**\n * Operator match function\n */\nexport function opMatches(doc, key, value) {\n\t// Get field value using array-aware traversal\n\tvar fieldValue = getFieldValues(doc, key);\n\t\n\tif (typeof (value) == \"string\") return fieldValueMatches(fieldValue, function(v) { return valuesEqual(v, value); });\n\telse if (typeof (value) == \"number\") return fieldValueMatches(fieldValue, function(v) { return valuesEqual(v, value); });\n\telse if (typeof (value) == \"boolean\") return fieldValueMatches(fieldValue, function(v) { return valuesEqual(v, value); });\n\telse if (value instanceof ObjectId) return fieldValueMatches(fieldValue, function(v) { return valuesEqual(v, value); });\n\telse if (typeof (value) == \"object\") {\n\t\tif (value instanceof RegExp) return fieldValue != undefined && fieldValueMatches(fieldValue, function(v) { return v && v.match(value); });\n\t\telse if (isArray(value)) return fieldValue != undefined && fieldValueMatches(fieldValue, function(v) { return v && arrayMatches(v, value); });\n\t\telse {\n\t\t\tvar keys = Object.keys(value);\n\t\t\tif (keys[0].charAt(0) == \"$\") {\n\t\t\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\t\t\tvar operator = Object.keys(value)[i];\n\t\t\t\t\tvar operand = value[operator];\n\t\t\t\t\tif (operator == \"$eq\") {\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return valuesEqual(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$gt\") {\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return compareValues(v, operand, '>'); })) return false;\n\t\t\t\t\t} else if (operator == \"$gte\") {\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return compareValues(v, operand, '>='); })) return false;\n\t\t\t\t\t} else if (operator == \"$lt\") {\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return compareValues(v, operand, '<'); })) return false;\n\t\t\t\t\t} else if (operator == \"$lte\") {\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return compareValues(v, operand, '<='); })) return false;\n\t\t\t\t\t} else if (operator == \"$ne\") {\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return !valuesEqual(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$in\") {\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return isIn(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$nin\") {\n\t\t\t\t\t\tif (fieldValueMatches(fieldValue, function(v) { return isIn(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$exists\") {\n\t\t\t\t\t\t// For $exists, we need to use getProp which returns undefined if field doesn't exist\n\t\t\t\t\t\t// getFieldValues might return an array which would be truthy\n\t\t\t\t\tvar rawValue = getProp(doc, key);\n\t\t\t\t\tif (operand ? rawValue == undefined : rawValue != undefined) return false;\n\t\t\t\t} else if (operator == \"$type\") {\n\t\t\t\t\t// Support both BSON type codes and aliases\n\t\t\t\t\t// Note: $type checks the field value itself, not array elements\n\t\t\t\t\t// If field doesn't exist (undefined), it can only match type 'undefined' (6)\n\t\t\t\t\tif (fieldValue === undefined) {\n\t\t\t\t\t\tconst expectedTypeCode = typeof operand === 'number' ? operand : TYPE_ALIASES[operand];\n\t\t\t\t\t\tif (expectedTypeCode !== 6) return false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!matchesType(fieldValue, operand)) return false;\n\t\t\t\t\t}\n\t\t\t\t} else if (operator == \"$mod\") {\n\t\t\t\t\tif (operand.length != 2) throw { $err: \"Can't canonicalize query: BadValue malformed mod, not enough elements\", code: 17287 };\n\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return v != undefined && (v % operand[0] == operand[1]); })) return false;\n\t\t\t\t} else if (operator == \"$regex\") {\n\t\t\t\t\t// Support string pattern with optional $options\n\t\t\t\t\tvar pattern = operand;\n\t\t\t\t\tvar flags = value.$options || '';\n\t\t\t\t\tvar regex = (typeof pattern === 'string') ? new RegExp(pattern, flags) : pattern;\n\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return v != undefined && regex.test(v); })) return false;\n\t\t\t\t} else if (operator == \"$options\") {\n\t\t\t\t\t// $options is handled with $regex, skip here\n\t\t\t\t\tcontinue;\n\t\t\t\t} else if (operator == \"$text\") {\n\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return v != undefined && text(v, operand); })) return false;\n\t\t\t\t} else if (operator == \"$expr\") {\n\t\t\t\t\t// Evaluate aggregation expression against the document\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = evaluateExpression(operand, doc);\n\t\t\t\t\t\tif (!result) return false;\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t// If expression evaluation fails, don't match\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t} else if (operator == \"$geoWithin\") {\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return v != undefined && geoWithin(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$near\" || operator == \"$nearSphere\") {\n\t\t\t\t\t\t// Handle $near and $nearSphere with distance calculation\n\t\t\t\t\t\tlet coordinates;\n\t\t\t\t\t\tif (operand.$geometry) {\n\t\t\t\t\t\t\tcoordinates = operand.$geometry.coordinates;\n\t\t\t\t\t\t} else if (operand.coordinates) {\n\t\t\t\t\t\t\tcoordinates = operand.coordinates;\n\t\t\t\t\t\t} else if (Array.isArray(operand)) {\n\t\t\t\t\t\t\tcoordinates = operand;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (coordinates && coordinates.length >= 2) {\n\t\t\t\t\t\t\tconst [lng, lat] = coordinates;\n\t\t\t\t\t\t\tconst maxDistanceMeters = operand.$maxDistance || 1000000; // Default to 1000km\n\t\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return v != undefined && isNear(v, lng, lat, maxDistanceMeters); })) return false;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (operator == \"$geoIntersects\") {\n\t\t\t\t\t\t// Handle $geoIntersects\n\t\t\t\t\t\tconst geometry = operand.$geometry || operand;\n\t\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return v != undefined && geoIntersects(v, geometry); })) return false;\n\t\t\t\t\t} else if (operator == \"$not\") {\n\t\t\t\t\t\tif (opMatches(doc, key, operand)) return false;\n\t\t\t\t\t} else if (operator == \"$all\") {\n\t\t\t\t\t\t// $all requires the field to be an array, use getProp not getFieldValues\n\t\t\t\t\t\tvar arrayFieldValue = getProp(doc, key);\n\t\t\t\t\t\tif (arrayFieldValue == undefined || !isArray(arrayFieldValue)) return false;\n\t\t\t\t\t\tfor (var j = 0; j < operand.length; j++) {\n\t\t\t\t\t\t\tif (!isIn(operand[j], arrayFieldValue)) return false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (operator == \"$elemMatch\") {\n\t\t\t\t\t\t// $elemMatch requires the field to be an array, use getProp not getFieldValues\n\t\t\t\t\t\tvar arrayFieldValue = getProp(doc, key);\n\t\t\t\t\t\tif (arrayFieldValue == undefined || !isArray(arrayFieldValue)) return false;\n\t\t\t\t\t\tvar found = false;\n\t\t\t\t\t\tfor (var j = 0; j < arrayFieldValue.length; j++) {\n\t\t\t\t\t\t\tvar element = arrayFieldValue[j];\n\t\t\t\t\t\t\t// Check if element matches the query\n\t\t\t\t\t\t\tif (typeof element === 'object' && !isArray(element)) {\n\t\t\t\t\t\t\t\t// For objects, use matches\n\t\t\t\t\t\t\t\tif (matches(element, operand)) {\n\t\t\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// For primitive values, check operators directly\n\t\t\t\t\t\t\t\tvar matchesPrimitive = true;\n\t\t\t\t\t\t\t\tvar opKeys = Object.keys(operand);\n\t\t\t\t\t\t\t\tfor (var k = 0; k < opKeys.length; k++) {\n\t\t\t\t\t\t\t\t\tvar op = opKeys[k];\n\t\t\t\t\t\t\t\t\tvar opValue = operand[op];\n\t\t\t\t\t\t\t\t\tif (op == \"$gte\" && !(element >= opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$gt\" && !(element > opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$lte\" && !(element <= opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$lt\" && !(element < opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$eq\" && !(element == opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$ne\" && !(element != opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$in\" && !isIn(element, opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$nin\" && isIn(element, opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (matchesPrimitive) {\n\t\t\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!found) return false;\n\t\t\t\t} else if (operator == \"$size\") {\n\t\t\t\t\tvar sizeFieldValue = getProp(doc, key);\n\t\t\t\t\tif (sizeFieldValue == undefined || !isArray(sizeFieldValue)) return false;\n\t\t\t\t\tif (sizeFieldValue.length != operand) return false;\n\t\t\t\t} else if (operator == \"$bitsAllSet\") {\n\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return matchesBitsAllSet(v, operand); })) return false;\n\t\t\t\t} else if (operator == \"$bitsAllClear\") {\n\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return matchesBitsAllClear(v, operand); })) return false;\n\t\t\t\t} else if (operator == \"$bitsAnySet\") {\n\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return matchesBitsAnySet(v, operand); })) return false;\n\t\t\t\t} else if (operator == \"$bitsAnyClear\") {\n\t\t\t\t\tif (!fieldValueMatches(fieldValue, function(v) { return matchesBitsAnyClear(v, operand); })) return false;\n\t\t\t\t} else {\n\t\t\t\t\t\tthrow { $err: \"Can't canonicalize query: BadValue unknown operator: \" + operator, code: 17287 };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\treturn getProp(doc, key) && objectMatches(getProp(doc, key), value);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * $not operator\n */\nexport function not(doc, value) {\n\treturn !tlMatches(doc, value);\n}\n\n/**\n * $and operator\n */\nexport function and(doc, els) {\n\tfor (var i = 0; i < els.length; i++) {\n\t\tif (!tlMatches(doc, els[i])) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * $or operator\n */\nexport function or(doc, els) {\n\tfor (var i = 0; i < els.length; i++) {\n\t\tif (tlMatches(doc, els[i])) return true;\n\t}\n\treturn false;\n}\n\n/**\n * $nor operator\n */\nexport function nor(doc, els) {\n\tfor (var i = 0; i < els.length; i++) {\n\t\tif (tlMatches(doc, els[i])) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Main matches function - query structure: (top level operators ( \"age\" : (operators) ))\n * top, top level query, implicit $and\n */\nexport function matches(doc, query) {\n\treturn and(doc, toArray(query));\n}\n\n/**\n * Enhanced matching function that also tracks which array index matched for positional operator ($)\n * Returns an object with:\n * - matched: boolean indicating if the query matched\n * - arrayFilters: object mapping field paths to the first matched array index\n * \n * Example: if query is { \"grades\": { $gte: 85 } } and doc is { grades: [80, 90, 85] }\n * Returns: { matched: true, arrayFilters: { \"grades\": 1 } } (index 1 is 90, first to match)\n */\nexport function matchWithArrayIndices(doc, query) {\n\tconst arrayFilters = {};\n\tconst matched = andWithTracking(doc, toArray(query), arrayFilters);\n\treturn { matched, arrayFilters };\n}\n\n/**\n * Helper to track array indices during AND matching\n */\nfunction andWithTracking(doc, els, arrayFilters) {\n\tfor (var i = 0; i < els.length; i++) {\n\t\tif (!tlMatchesWithTracking(doc, els[i], arrayFilters)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Top level match with tracking\n */\nfunction tlMatchesWithTracking(doc, query, arrayFilters) {\n\tvar key = Object.keys(query)[0];\n\tvar value = query[key];\n\tif (key.charAt(0) == \"$\") {\n\t\tif (key == \"$and\") return andWithTracking(doc, value, arrayFilters);\n\t\telse if (key == \"$or\") return orWithTracking(doc, value, arrayFilters);\n\t\telse if (key == \"$not\") {\n\t\t\t// For $not, we don't track positions as it's a negation\n\t\t\treturn !tlMatches(doc, value);\n\t\t}\n\t\telse if (key == \"$nor\") return norWithTracking(doc, value, arrayFilters);\n\t\telse if (key == \"$where\") return where(doc, value);\n\t\telse if (key == \"$comment\") return true;\n\t\telse if (key == \"$jsonSchema\") return validateJsonSchema(doc, value);\n\t\telse if (key == \"$expr\") {\n\t\t\ttry {\n\t\t\t\treturn evaluateExpression(value, doc);\n\t\t\t} catch (e) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse throw { $err: \"Can't canonicalize query: BadValue unknown top level operator: \" + key, code: 17287 };\n\t} else {\n\t\treturn opMatchesWithTracking(doc, key, value, arrayFilters);\n\t}\n}\n\n/**\n * OR operator with tracking - track positions from the first matching clause\n */\nfunction orWithTracking(doc, els, arrayFilters) {\n\tfor (var i = 0; i < els.length; i++) {\n\t\tif (tlMatchesWithTracking(doc, els[i], arrayFilters)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * NOR operator with tracking\n */\nfunction norWithTracking(doc, els, arrayFilters) {\n\tfor (var i = 0; i < els.length; i++) {\n\t\tif (tlMatchesWithTracking(doc, els[i], arrayFilters)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/**\n * Operator match with array index tracking\n */\nfunction opMatchesWithTracking(doc, key, value, arrayFilters) {\n\t// Get the base field (before any dots)\n\tconst baseField = key.split('.')[0];\n\tconst fieldValue = getFieldValues(doc, key);\n\t\n\t// Helper to track which index matched\n\tconst trackMatchingIndex = (fieldValue, checkFn) => {\n\t\tif (fieldValue === undefined) return false;\n\t\tif (fieldValue === null) return checkFn(fieldValue);\n\t\t\n\t\t// If fieldValue is an array from array traversal\n\t\tif (isArray(fieldValue)) {\n\t\t\t// Check if the base field itself is an array in the document\n\t\t\tconst baseValue = getProp(doc, baseField);\n\t\t\tif (isArray(baseValue)) {\n\t\t\t\t// Find first matching index\n\t\t\t\tfor (var i = 0; i < fieldValue.length; i++) {\n\t\t\t\t\tif (checkFn(fieldValue[i])) {\n\t\t\t\t\t\t// Track this as the matched index for this field\n\t\t\t\t\t\tarrayFilters[key] = i;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Otherwise use regular matching\n\t\treturn fieldValueMatches(fieldValue, checkFn);\n\t};\n\t\n\t// Now perform the actual matching with tracking\n\tif (typeof (value) == \"string\") return trackMatchingIndex(fieldValue, function(v) { return valuesEqual(v, value); });\n\telse if (typeof (value) == \"number\") return trackMatchingIndex(fieldValue, function(v) { return valuesEqual(v, value); });\n\telse if (typeof (value) == \"boolean\") return trackMatchingIndex(fieldValue, function(v) { return valuesEqual(v, value); });\n\telse if (value instanceof ObjectId) return trackMatchingIndex(fieldValue, function(v) { return valuesEqual(v, value); });\n\telse if (typeof (value) == \"object\") {\n\t\tif (value instanceof RegExp) return fieldValue != undefined && trackMatchingIndex(fieldValue, function(v) { return v && v.match(value); });\n\t\telse if (isArray(value)) return fieldValue != undefined && trackMatchingIndex(fieldValue, function(v) { return v && arrayMatches(v, value); });\n\t\telse {\n\t\t\tvar keys = Object.keys(value);\n\t\t\tif (keys[0].charAt(0) == \"$\") {\n\t\t\t\t// Handle operators\n\t\t\t\tfor (var i = 0; i < keys.length; i++) {\n\t\t\t\t\tvar operator = keys[i];\n\t\t\t\t\tvar operand = value[operator];\n\t\t\t\t\tif (operator == \"$eq\") {\n\t\t\t\t\t\tif (!trackMatchingIndex(fieldValue, function(v) { return valuesEqual(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$gt\") {\n\t\t\t\t\t\tif (!trackMatchingIndex(fieldValue, function(v) { return compareValues(v, operand, '>'); })) return false;\n\t\t\t\t\t} else if (operator == \"$gte\") {\n\t\t\t\t\t\tif (!trackMatchingIndex(fieldValue, function(v) { return compareValues(v, operand, '>='); })) return false;\n\t\t\t\t\t} else if (operator == \"$lt\") {\n\t\t\t\t\t\tif (!trackMatchingIndex(fieldValue, function(v) { return compareValues(v, operand, '<'); })) return false;\n\t\t\t\t\t} else if (operator == \"$lte\") {\n\t\t\t\t\t\tif (!trackMatchingIndex(fieldValue, function(v) { return compareValues(v, operand, '<='); })) return false;\n\t\t\t\t\t} else if (operator == \"$ne\") {\n\t\t\t\t\t\tif (!trackMatchingIndex(fieldValue, function(v) { return !valuesEqual(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$in\") {\n\t\t\t\t\t\tif (!trackMatchingIndex(fieldValue, function(v) { return isIn(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$nin\") {\n\t\t\t\t\t\tif (trackMatchingIndex(fieldValue, function(v) { return isIn(v, operand); })) return false;\n\t\t\t\t\t} else if (operator == \"$elemMatch\") {\n\t\t\t\t\t\t// Special handling for $elemMatch\n\t\t\t\t\t\tvar arrayFieldValue = getProp(doc, key);\n\t\t\t\t\t\tif (arrayFieldValue == undefined || !isArray(arrayFieldValue)) return false;\n\t\t\t\t\t\tfor (var j = 0; j < arrayFieldValue.length; j++) {\n\t\t\t\t\t\t\tvar element = arrayFieldValue[j];\n\t\t\t\t\t\t\t// Check if element matches the query\n\t\t\t\t\t\t\tif (typeof element === 'object' && !isArray(element)) {\n\t\t\t\t\t\t\t\t// For objects, use matches\n\t\t\t\t\t\t\t\tif (matches(element, operand)) {\n\t\t\t\t\t\t\t\t\tarrayFilters[key] = j;\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// For primitive values, check operators directly\n\t\t\t\t\t\t\t\tvar matchesPrimitive = true;\n\t\t\t\t\t\t\t\tvar opKeys = Object.keys(operand);\n\t\t\t\t\t\t\t\tfor (var k = 0; k < opKeys.length; k++) {\n\t\t\t\t\t\t\t\t\tvar op = opKeys[k];\n\t\t\t\t\t\t\t\t\tvar opValue = operand[op];\n\t\t\t\t\t\t\t\t\tif (op == \"$gte\" && !(element >= opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$gt\" && !(element > opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$lte\" && !(element <= opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$lt\" && !(element < opValue)) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$eq\" && element != opValue) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t\telse if (op == \"$ne\" && element == opValue) matchesPrimitive = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (matchesPrimitive) {\n\t\t\t\t\t\t\t\t\tarrayFilters[key] = j;\n\t\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// For other operators, use standard matching\n\t\t\t\t\t\tif (!opMatches(doc, key, value)) return false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\t// Object equality\n\t\t\t\treturn fieldValue != undefined && trackMatchingIndex(fieldValue, function(v) { return objectMatches(v, value); });\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n","import { EventEmitter } from 'events';\nimport { matches } from './queryMatcher.js';\n\n/**\n * ChangeStream watches for changes in collections and emits change events\n * Compatible with MongoDB Change Streams API\n */\nexport class ChangeStream extends EventEmitter {\n\tconstructor(target, pipeline = [], options = {}) {\n\t\tsuper();\n\t\t\n\t\tthis.target = target; // MongoClient, DB, or Collection\n\t\tthis.pipeline = pipeline;\n\t\tthis.options = options;\n\t\tthis.closed = false;\n\t\tthis._listeners = new Map();\n\t\tthis._changeCounter = 0;\n\t\t\n\t\t// Start watching immediately (synchronously)\n\t\tthis._startWatching();\n\t}\n\n\t/**\n\t * Check if target is a DB instance (handles Proxies and minification)\n\t */\n\t_isDB(target) {\n\t\t// Check for DB-specific properties that won't trigger collection creation\n\t\t// Use hasOwnProperty or check the collections Map directly\n\t\treturn target && \n\t\t\ttypeof target.dbName === 'string' && \n\t\t\ttypeof target.getCollectionNames === 'function' &&\n\t\t\ttarget.collections instanceof Map;\n\t}\n\n\t/**\n\t * Check if target is a Server instance\n\t */\n\t_isServer(target) {\n\t\treturn target && \n\t\t\ttarget.databases instanceof Map &&\n\t\t\ttypeof target._getDB === 'function';\n\t}\n\n\t/**\n\t * Check if target is a MongoClient instance\n\t */\n\t_isMongoClient(target) {\n\t\treturn target && \n\t\t\ttypeof target.connect === 'function' &&\n\t\t\ttypeof target.db === 'function' &&\n\t\t\ttarget.constructor.name === 'MongoClient'; // MongoClient is not minified same way\n\t}\n\n\t/**\n\t * Start watching for changes\n\t * @private\n\t */\n\t_startWatching() {\n\t\tif (this.closed) return;\n\t\t\n\t\tconst collections = this._getCollectionsToWatch();\n\t\t\n\t\tfor (const collection of collections) {\n\t\t\tthis._watchCollection(collection);\n\t\t}\n\t\t\n\t\t// For Server watching, intercept _getDB calls\n\t\tif (this._isServer(this.target)) {\n\t\t\tthis._interceptServerDBCreation();\n\t\t}\n\t\t\n\t\t// For DB watching, we also need to intercept new collection creation\n\t\tif (this._isDB(this.target)) {\n\t\t\tthis._interceptDBCollectionCreation();\n\t\t}\n\t\t\n\t\t// For MongoClient watching, intercept db() calls\n\t\tif (this._isMongoClient(this.target)) {\n\t\t\tthis._interceptClientDBCreation();\n\t\t}\n\t}\n\n\t/**\n\t * Get collections to watch based on target type\n\t * @private\n\t */\n\t_getCollectionsToWatch() {\n\t\tconst collections = [];\n\t\t\n\t\t// Server - watch all collections in all databases\n\t\tif (this._isServer(this.target)) {\n\t\t\t// Watch all existing databases\n\t\t\tfor (const [dbName, db] of this.target.databases) {\n\t\t\t\tconst collectionNames = db.getCollectionNames();\n\t\t\t\tfor (const name of collectionNames) {\n\t\t\t\t\tconst collection = db[name];\n\t\t\t\t\tif (collection && collection.isCollection) {\n\t\t\t\t\t\tcollections.push(collection);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn collections;\n\t\t}\n\t\t\n\t\t// MongoClient - watch all collections in all databases\n\t\tif (this._isMongoClient(this.target)) {\n\t\t\t// Store reference to monitor for new databases/collections\n\t\t\tthis._monitorClient();\n\t\t\treturn collections;\n\t\t}\n\t\t\n\t\t// DB - watch all collections in the database\n\t\tif (this._isDB(this.target)) {\n\t\t\tconst collectionNames = this.target.getCollectionNames();\n\t\t\tfor (const name of collectionNames) {\n\t\t\t\tconst collection = this.target[name];\n\t\t\t\tif (collection && collection.isCollection) {\n\t\t\t\t\tcollections.push(collection);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Also monitor for new collections\n\t\t\tthis._monitorDB();\n\t\t}\n\t\t\n\t\t// Collection - watch specific collection\n\t\tif (this.target.isCollection) {\n\t\t\tcollections.push(this.target);\n\t\t}\n\t\t\n\t\treturn collections;\n\t}\n\n\t/**\n\t * Watch a specific collection for changes\n\t * @private\n\t */\n\t_watchCollection(collection) {\n\t\tif (this.closed) return;\n\t\tif (!collection) return; // Skip null/undefined\n\t\tif (typeof collection.on !== 'function') return; // Skip non-EventEmitters\n\t\tif (!collection.isCollection) return; // Skip non-collections\n\t\tif (this._listeners.has(collection)) return; // Already watching\n\t\t\n\t\tconst handlers = {\n\t\t\tinsert: (doc) => this._emitChange('insert', collection, doc),\n\t\t\tupdate: (doc, updateDescription) => this._emitChange('update', collection, doc, updateDescription),\n\t\t\treplace: (doc) => this._emitChange('replace', collection, doc),\n\t\t\tdelete: (doc) => this._emitChange('delete', collection, doc)\n\t\t};\n\t\t\n\t\t// Store handlers for cleanup\n\t\tthis._listeners.set(collection, handlers);\n\t\t\n\t\t// Listen to collection change events\n\t\tcollection.on('insert', handlers.insert);\n\t\tcollection.on('update', handlers.update);\n\t\tcollection.on('replace', handlers.replace);\n\t\tcollection.on('delete', handlers.delete);\n\t}\n\n\t/**\n\t * Emit a change event\n\t * @private\n\t */\n\t_emitChange(operationType, collection, doc, updateDescription = null) {\n\t\tif (this.closed) return;\n\t\t\n\t\tconst changeEvent = this._createChangeEvent(\n\t\t\toperationType,\n\t\t\tcollection,\n\t\t\tdoc,\n\t\t\tupdateDescription\n\t\t);\n\t\t\n\t\t// Apply pipeline filters if any\n\t\tif (!this._matchesPipeline(changeEvent)) {\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tthis.emit('change', changeEvent);\n\t}\n\n\t/**\n\t * Create a MongoDB-compatible change event document\n\t * @private\n\t */\n\t_createChangeEvent(operationType, collection, doc, updateDescription) {\n\t\tconst event = {\n\t\t\t_id: {\n\t\t\t\t_data: btoa(String(++this._changeCounter))\n\t\t\t},\n\t\t\toperationType,\n\t\t\tclusterTime: new Date(),\n\t\t\tns: {\n\t\t\t\tdb: collection.db.dbName,\n\t\t\t\tcoll: collection.name\n\t\t\t},\n\t\t\tdocumentKey: {\n\t\t\t\t_id: doc._id\n\t\t\t}\n\t\t};\n\t\t\n\t\tswitch (operationType) {\n\t\t\tcase 'insert':\n\t\t\t\tevent.fullDocument = doc;\n\t\t\t\tbreak;\n\t\t\t\t\n\t\t\tcase 'update':\n\t\t\t\tevent.updateDescription = updateDescription || {\n\t\t\t\t\tupdatedFields: {},\n\t\t\t\t\tremovedFields: [],\n\t\t\t\t\ttruncatedArrays: []\n\t\t\t\t};\n\t\t\t\t// Include full document if requested\n\t\t\t\tif (this.options.fullDocument === 'updateLookup') {\n\t\t\t\t\tevent.fullDocument = doc;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\t\n\t\t\tcase 'replace':\n\t\t\t\tevent.fullDocument = doc;\n\t\t\t\tbreak;\n\t\t\t\t\n\t\t\tcase 'delete':\n\t\t\t\t// For delete, doc contains the deleted document's _id\n\t\t\t\tbreak;\n\t\t}\n\t\t\n\t\treturn event;\n\t}\n\n\t/**\n\t * Check if change event matches pipeline filters\n\t * @private\n\t */\n\t_matchesPipeline(changeEvent) {\n\t\tif (!this.pipeline || this.pipeline.length === 0) {\n\t\t\treturn true;\n\t\t}\n\t\t\n\t\t// Process pipeline stages\n\t\tfor (const stage of this.pipeline) {\n\t\t\tif (stage.$match) {\n\t\t\t\t// Use the same query matcher as find()\n\t\t\t\t// Note: matches(document, query) - document first, query second\n\t\t\t\tif (!matches(changeEvent, stage.$match)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get nested value from object using dot notation\n\t * @private\n\t */\n\t_getNestedValue(obj, path) {\n\t\treturn path.split('.').reduce((current, part) => current?.[part], obj);\n\t}\n\n\t/**\n\t * Monitor client for new databases/collections (simplified)\n\t * @private\n\t */\n\t_monitorClient() {\n\t\t// Handled by _interceptClientDBCreation\n\t}\n\n\t/**\n\t * Intercept DB creation on a MongoClient\n\t * @private\n\t */\n\t_interceptClientDBCreation() {\n\t\tconst client = this.target;\n\t\tconst originalDb = client.db.bind(client);\n\t\tconst self = this;\n\t\t\n\t\t// Track databases we're watching\n\t\tthis._watchedDBs = new Map();\n\t\t\n\t\t// Override db() method to watch new databases\n\t\tclient.db = function(name, opts) {\n\t\t\tconst database = originalDb(name, opts);\n\t\t\tconst dbName = database.dbName;\n\t\t\t\n\t\t\t// Only set up watch once per database\n\t\t\tif (!self._watchedDBs.has(dbName)) {\n\t\t\t\tself._watchedDBs.set(dbName, database);\n\t\t\t\t\n\t\t\t\t// Watch existing collections in this database\n\t\t\t\tconst collectionNames = database.getCollectionNames();\n\t\t\t\tfor (const colName of collectionNames) {\n\t\t\t\t\tconst col = database[colName];\n\t\t\t\t\tif (col && col.isCollection && !self._listeners.has(col)) {\n\t\t\t\t\t\tself._watchCollection(col);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Intercept new collection creation on this database\n\t\t\t\tself._interceptDBCollectionCreationForClient(database);\n\t\t\t}\n\t\t\t\n\t\t\treturn database;\n\t\t};\n\t\t\n\t\t// Store original for cleanup\n\t\tthis._originalClientMethods = { db: originalDb };\n\t}\n\n\t/**\n\t * Intercept DB creation on a Server\n\t * @private\n\t */\n\t_interceptServerDBCreation() {\n\t\tconst server = this.target;\n\t\tconst originalGetDB = server._getDB.bind(server);\n\t\tconst self = this;\n\t\t\n\t\t// Track databases we're watching\n\t\tthis._watchedDBs = new Map();\n\t\t\n\t\t// Override _getDB() method to watch new databases\n\t\tserver._getDB = function(dbName) {\n\t\t\tconst db = originalGetDB(dbName);\n\t\t\t\n\t\t\t// Only set up watch once per database\n\t\t\tif (!self._watchedDBs.has(dbName)) {\n\t\t\t\tself._watchedDBs.set(dbName, db);\n\t\t\t\t\n\t\t\t\t// Watch existing collections in this database\n\t\t\t\tconst collectionNames = db.getCollectionNames();\n\t\t\t\tfor (const colName of collectionNames) {\n\t\t\t\t\tconst col = db[colName];\n\t\t\t\t\tif (col && col.isCollection && !self._listeners.has(col)) {\n\t\t\t\t\t\tself._watchCollection(col);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Intercept new collection creation on this database\n\t\t\t\tself._interceptDBCollectionCreationForServer(db);\n\t\t\t}\n\t\t\t\n\t\t\treturn db;\n\t\t};\n\t\t\n\t\t// Store original for cleanup\n\t\tthis._originalServerMethods = { _getDB: originalGetDB };\n\t}\n\n\t/**\n\t * Intercept collection creation for a database in server watch mode\n\t * @private\n\t */\n\t_interceptDBCollectionCreationForServer(db) {\n\t\tconst originalCollection = db.collection.bind(db);\n\t\tconst originalCreateCollection = db.createCollection.bind(db);\n\t\tconst self = this;\n\t\t\n\t\tdb.collection = function(name) {\n\t\t\tconst col = originalCollection(name);\n\t\t\tif (col && col.isCollection && !self._listeners.has(col)) {\n\t\t\t\tself._watchCollection(col);\n\t\t\t}\n\t\t\treturn col;\n\t\t};\n\t\t\n\t\tdb.createCollection = function(name) {\n\t\t\toriginalCreateCollection(name);\n\t\t\tconst col = db[name];\n\t\t\tif (col && col.isCollection && !self._listeners.has(col)) {\n\t\t\t\tself._watchCollection(col);\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Intercept collection creation for a database in client watch mode\n\t * @private\n\t */\n\t_interceptDBCollectionCreationForClient(db) {\n\t\tconst originalCollection = db.collection.bind(db);\n\t\tconst originalCreateCollection = db.createCollection.bind(db);\n\t\tconst self = this;\n\t\t\n\t\tdb.collection = function(name) {\n\t\t\tconst col = originalCollection(name);\n\t\t\tif (col && col.isCollection && !self._listeners.has(col)) {\n\t\t\t\tself._watchCollection(col);\n\t\t\t}\n\t\t\treturn col;\n\t\t};\n\t\t\n\t\tdb.createCollection = function(name) {\n\t\t\toriginalCreateCollection(name);\n\t\t\tconst col = db[name];\n\t\t\tif (col && col.isCollection && !self._listeners.has(col)) {\n\t\t\t\tself._watchCollection(col);\n\t\t\t}\n\t\t};\n\t}\n\n\t/**\n\t * Monitor database for new collections\n\t * @private\n\t */\n\t_monitorDB() {\n\t\t// Handled by _interceptDBCollectionCreation\n\t}\n\n\t/**\n\t * Intercept new collection creation on a DB\n\t * @private\n\t */\n\t_interceptDBCollectionCreation() {\n\t\t// Since DB is a Proxy, we need to override getCollection() on the target, not collection() on the proxy\n\t\t// The Proxy's get trap will always return methods from the target via Reflect.get\n\t\tconst db = this.target;\n\t\t\n\t\t// Get the actual DB instance (not the proxy) by accessing _proxy property or finding it\n\t\t// The DB constructor stores 'this' before returning the proxy, so we can access it\n\t\tlet actualDB = db;\n\t\t// If db has _proxy, it means db IS the proxy and we need to get through to the real target\n\t\t// But we can't easily do that. Instead, we need to override on the object itself.\n\t\t// The trick is to override getCollection, since that's what collection() calls\n\t\t\n\t\tconst originalGetCollection = db.getCollection.bind(db);\n\t\tconst originalCreateCollection = db.createCollection ? db.createCollection.bind(db) : null;\n\t\tconst self = this;\n\t\t\n\t\t// Override getCollection() method to watch new collections\n\t\tdb.getCollection = function(name) {\n\t\t\tconst col = originalGetCollection(name);\n\t\t\t// Watch this collection if we haven't already\n\t\t\tif (col && col.isCollection && !self._listeners.has(col)) {\n\t\t\t\tself._watchCollection(col);\n\t\t\t}\n\t\t\treturn col;\n\t\t};\n\t\t\n\t\t// Override createCollection() method if it exists\n\t\tif (originalCreateCollection) {\n\t\t\tdb.createCollection = function(name) {\n\t\t\t\toriginalCreateCollection(name);\n\t\t\t\tconst col = db[name];\n\t\t\t\tif (col && col.isCollection && !self._listeners.has(col)) {\n\t\t\t\t\tself._watchCollection(col);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\t\n\t\t// Store originals for cleanup\n\t\tthis._originalDBMethods = { \n\t\t\tgetCollection: originalGetCollection, \n\t\t\tcreateCollection: originalCreateCollection \n\t\t};\n\t}\n\n\t/**\n\t * Close the change stream\n\t */\n\tclose() {\n\t\tif (this.closed) return;\n\t\t\n\t\tthis.closed = true;\n\t\t\n\t\t// Remove all collection listeners\n\t\tfor (const [collection, handlers] of this._listeners) {\n\t\t\tcollection.off('insert', handlers.insert);\n\t\t\tcollection.off('update', handlers.update);\n\t\t\tcollection.off('replace', handlers.replace);\n\t\t\tcollection.off('delete', handlers.delete);\n\t\t}\n\t\t\n\t\tthis._listeners.clear();\n\t\t\n\t\t// Restore original Server methods if we intercepted them\n\t\tif (this._originalServerMethods && this.target.constructor.name === 'Server') {\n\t\t\tthis.target._getDB = this._originalServerMethods._getDB;\n\t\t}\n\t\t\n\t\t// Restore original DB methods if we intercepted them\n\t\tif (this._originalDBMethods && this.target.constructor.name === 'DB') {\n\t\t\tthis.target.collection = this._originalDBMethods.collection;\n\t\t\tthis.target.createCollection = this._originalDBMethods.createCollection;\n\t\t}\n\t\t\n\t\t// Restore original MongoClient methods if we intercepted them\n\t\tif (this._originalClientMethods && this.target.constructor.name === 'MongoClient') {\n\t\t\tthis.target.db = this._originalClientMethods.db;\n\t\t}\n\t\t\n\t\t// Emit close before removing all listeners\n\t\tthis.emit('close');\n\t\tthis.removeAllListeners();\n\t}\n\n\t/**\n\t * Check if the stream is closed\n\t */\n\tget isClosed() {\n\t\treturn this.closed;\n\t}\n\n\t/**\n\t * Async iterator support for for-await-of loops\n\t */\n\tasync *[Symbol.asyncIterator]() {\n\t\tconst queue = [];\n\t\tlet resolveNext = null;\n\t\tlet streamClosed = false;\n\t\t\n\t\tconst onChange = (change) => {\n\t\t\tif (resolveNext) {\n\t\t\t\tresolveNext({ value: change, done: false });\n\t\t\t\tresolveNext = null;\n\t\t\t} else {\n\t\t\t\tqueue.push(change);\n\t\t\t}\n\t\t};\n\t\t\n\t\tconst onClose = () => {\n\t\t\tstreamClosed = true;\n\t\t\tif (resolveNext) {\n\t\t\t\tresolveNext({ done: true });\n\t\t\t\tresolveNext = null;\n\t\t\t}\n\t\t};\n\t\t\n\t\tconst onError = (error) => {\n\t\t\tif (resolveNext) {\n\t\t\t\tresolveNext(Promise.reject(error));\n\t\t\t\tresolveNext = null;\n\t\t\t}\n\t\t};\n\t\t\n\t\tthis.on('change', onChange);\n\t\tthis.on('close', onClose);\n\t\tthis.on('error', onError);\n\t\t\n\t\ttry {\n\t\t\twhile (!streamClosed) {\n\t\t\t\tif (queue.length > 0) {\n\t\t\t\t\tyield queue.shift();\n\t\t\t\t} else {\n\t\t\t\t\tconst next = await new Promise((resolve) => {\n\t\t\t\t\t\tresolveNext = resolve;\n\t\t\t\t\t\t// Check if stream was closed while waiting\n\t\t\t\t\t\tif (streamClosed) {\n\t\t\t\t\t\t\tresolve({ done: true });\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t\t\tif (next.done) break;\n\t\t\t\t\tyield next.value;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.off('change', onChange);\n\t\t\tthis.off('close', onClose);\n\t\t\tthis.off('error', onError);\n\t\t}\n\t}\n\n\t/**\n\t * Get next change (for compatibility)\n\t */\n\tasync next() {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst onChange = (change) => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(change);\n\t\t\t};\n\t\t\t\n\t\t\tconst onClose = () => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(null);\n\t\t\t};\n\t\t\t\n\t\t\tconst onError = (error) => {\n\t\t\t\tcleanup();\n\t\t\t\treject(error);\n\t\t\t};\n\t\t\t\n\t\t\tconst cleanup = () => {\n\t\t\t\tthis.off('change', onChange);\n\t\t\t\tthis.off('close', onClose);\n\t\t\t\tthis.off('error', onError);\n\t\t\t};\n\t\t\t\n\t\t\tif (this.closed) {\n\t\t\t\tresolve(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\tthis.once('change', onChange);\n\t\t\tthis.once('close', onClose);\n\t\t\tthis.once('error', onError);\n\t\t});\n\t}\n}\n","/**\n * Performance timing utility for tracking operation durations\n */\nexport class PerformanceTimer {\n constructor(enabled = false) {\n this.enabled = enabled;\n this.timings = [];\n this.nestedLevel = 0;\n }\n\n /**\n * Enable or disable timing collection\n */\n setEnabled(enabled) {\n this.enabled = enabled;\n }\n\n /**\n * Start timing an operation\n */\n start(category, operation, details = {}) {\n if (!this.enabled) return null;\n\n return {\n category,\n operation,\n details,\n startTime: performance.now(),\n nestedLevel: this.nestedLevel++\n };\n }\n\n /**\n * End timing an operation\n */\n end(timer, additionalDetails = {}) {\n if (!this.enabled || !timer) return;\n\n // Decrement nested level regardless of whether we record timing\n // This ensures nesting doesn't get permanently corrupted even if end() is called without valid timer\n if (this.nestedLevel > 0) {\n this.nestedLevel--;\n }\n \n const endTime = performance.now();\n const duration = endTime - timer.startTime;\n\n this.timings.push({\n category: timer.category,\n operation: timer.operation,\n duration,\n details: { ...timer.details, ...additionalDetails },\n nestedLevel: timer.nestedLevel,\n timestamp: timer.startTime\n });\n }\n\n /**\n * Get all collected timings\n */\n getTimings() {\n return this.timings;\n }\n\n /**\n * Get timings grouped by category\n */\n getTimingsByCategory() {\n const grouped = {};\n for (const timing of this.timings) {\n if (!grouped[timing.category]) {\n grouped[timing.category] = [];\n }\n grouped[timing.category].push(timing);\n }\n return grouped;\n }\n\n /**\n * Get summary statistics\n */\n getSummary() {\n const summary = {};\n \n for (const timing of this.timings) {\n const key = `${timing.category}.${timing.operation}`;\n if (!summary[key]) {\n summary[key] = {\n category: timing.category,\n operation: timing.operation,\n count: 0,\n total: 0,\n min: Infinity,\n max: -Infinity,\n avg: 0\n };\n }\n \n const stats = summary[key];\n stats.count++;\n stats.total += timing.duration;\n stats.min = Math.min(stats.min, timing.duration);\n stats.max = Math.max(stats.max, timing.duration);\n stats.avg = stats.total / stats.count;\n }\n \n return Object.values(summary);\n }\n\n /**\n * Clear all timings\n */\n clear() {\n this.timings = [];\n this.nestedLevel = 0;\n }\n\n /**\n * Format timings as a human-readable string\n */\n formatTimings() {\n const summary = this.getSummary();\n \n if (summary.length === 0) {\n return 'No timing data collected';\n }\n\n let output = '\\n' + '='.repeat(80) + '\\n';\n output += 'PERFORMANCE TIMING REPORT\\n';\n output += '='.repeat(80) + '\\n\\n';\n\n // Group by category\n const byCategory = {};\n for (const stat of summary) {\n if (!byCategory[stat.category]) {\n byCategory[stat.category] = [];\n }\n byCategory[stat.category].push(stat);\n }\n\n for (const [category, stats] of Object.entries(byCategory)) {\n output += `${category.toUpperCase()}\\n`;\n output += '-'.repeat(80) + '\\n';\n output += 'Operation'.padEnd(30) + 'Count'.padStart(8) + 'Total(ms)'.padStart(12) + \n 'Avg(ms)'.padStart(12) + 'Min(ms)'.padStart(12) + 'Max(ms)'.padStart(12) + '\\n';\n output += '-'.repeat(80) + '\\n';\n\n for (const stat of stats) {\n output += stat.operation.padEnd(30) +\n stat.count.toString().padStart(8) +\n stat.total.toFixed(3).padStart(12) +\n stat.avg.toFixed(3).padStart(12) +\n stat.min.toFixed(3).padStart(12) +\n stat.max.toFixed(3).padStart(12) + '\\n';\n }\n output += '\\n';\n }\n\n output += '='.repeat(80) + '\\n';\n return output;\n }\n}\n\n// Global instance that can be accessed from anywhere\nexport const globalTimer = new PerformanceTimer(false);\n","import { EventEmitter } from 'events';\nimport { ObjectId } from '@belteshazzar/binjson';\nimport { globalTimer } from '../PerformanceTimer.js';\n\n/**\n * Serialize ObjectId and Date instances for worker communication\n */\nfunction serializePayload(obj) {\n if (obj === null || obj === undefined) return obj;\n if (typeof obj === 'function') {\n return { __function: obj.toString() };\n }\n \n // Check for ObjectId instances - try toString() first as it's the most reliable way\n if (obj && typeof obj === 'object' && typeof obj.toString === 'function') {\n try {\n const str = obj.toString();\n // bjson ObjectIds produce 24-character hex strings\n if (str && str.length === 24 && /^[0-9a-f]{24}$/i.test(str) && obj.constructor && obj.constructor.name === 'ObjectId') {\n return { __objectId: str };\n }\n } catch (e) {\n // toString() failed, continue to next check\n }\n }\n \n // Traditional instanceof check (may fail across worker boundaries in some cases)\n if (obj instanceof ObjectId) {\n return { __objectId: obj.toString() };\n }\n \n if (obj instanceof Date) {\n return { __date: obj.toISOString() };\n }\n if (Array.isArray(obj)) {\n return obj.map(serializePayload);\n }\n if (typeof obj === 'object') {\n const result = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = serializePayload(value);\n }\n return result;\n }\n return obj;\n}\n\n/**\n * Deserialize ObjectId and Date instances from worker communication\n */\nfunction deserializePayload(obj) {\n if (obj === null || obj === undefined) return obj;\n if (typeof obj === 'object' && obj.__function) {\n return typeof obj.__function === 'string' ? `(${obj.__function}).call(this)` : undefined;\n }\n if (typeof obj === 'object' && obj.__objectId) {\n return new ObjectId(obj.__objectId);\n }\n if (typeof obj === 'object' && obj.__date) {\n return new Date(obj.__date);\n }\n if (Array.isArray(obj)) {\n return obj.map(deserializePayload);\n }\n if (typeof obj === 'object') {\n const result = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = deserializePayload(value);\n }\n return result;\n }\n return obj;\n}\n\n/**\n * WorkerBridge provides a unified message-based transport between the main thread\n * and a worker (Web Worker in browsers, Worker Thread in Node.js).\n */\nexport class WorkerBridge extends EventEmitter {\n constructor(worker) {\n super();\n this.worker = worker;\n this._nextId = 1;\n this._pending = new Map();\n this._terminating = false;\n\n this._handleMessage = this._handleMessage.bind(this);\n this._handleError = this._handleError.bind(this);\n\n this._attach();\n }\n\n static async create(options = {}) {\n // Check if running in browser\n if (typeof window !== 'undefined' && typeof globalThis.Worker !== 'undefined') {\n return new BrowserWorkerBridge(options);\n }\n\n // Node.js environment - dynamically import to avoid browser compatibility issues\n const { Worker: NodeWorker } = await import('worker_threads');\n const { fileURLToPath } = await import('url');\n \n // Default to built worker artifact; use proper absolute path for Node worker\n let workerPath = options.workerPath;\n if (!workerPath) {\n const buildUrl = /* @vite-ignore */ new URL('../../dist/babymongo-server-worker.js', import.meta.url);\n workerPath = fileURLToPath(buildUrl);\n }\n const worker = new NodeWorker(workerPath, {\n workerData: options.workerData,\n });\n return new NodeWorkerBridge(worker);\n }\n\n /**\n * Send a request to the worker and await the response.\n * @param {Object} payload - Arbitrary payload for the worker.\n * @param {Object} [opts]\n * @param {number} [opts.timeout] - Optional timeout in ms.\n */\n sendRequest(payload, opts = {}) {\n const serializeTimer = globalTimer.start('ipc', 'serialize');\n const id = this._nextId++;\n const serializedPayload = serializePayload(payload);\n globalTimer.end(serializeTimer);\n \n const message = { type: 'request', id, payload: serializedPayload };\n\n return new Promise((resolve, reject) => {\n let timeoutHandle;\n if (opts.timeout) {\n timeoutHandle = setTimeout(() => {\n this._pending.delete(id);\n reject(new Error(`Worker request timed out after ${opts.timeout}ms`));\n }, opts.timeout);\n }\n\n const ipcTimer = globalTimer.start('ipc', 'roundtrip', { requestId: id });\n const originalResolve = resolve;\n const originalReject = reject;\n \n resolve = (result) => {\n globalTimer.end(ipcTimer);\n originalResolve(result);\n };\n \n reject = (error) => {\n globalTimer.end(ipcTimer);\n originalReject(error);\n };\n\n this._pending.set(id, { resolve, reject, timeoutHandle });\n this._post(message);\n });\n }\n\n /**\n * Gracefully close the worker without rejecting pending requests.\n * Any pending requests will simply be abandoned without error messages.\n */\n async terminate() {\n this._terminating = true;\n // Clear pending requests without rejecting them to avoid unhandled rejection warnings\n for (const [id, pending] of this._pending.entries()) {\n clearTimeout(pending.timeoutHandle);\n }\n this._pending.clear();\n await this._terminateImpl();\n }\n\n _handleMessage(event) {\n const data = event?.data ?? event; // Browser sends { data }, Node sends the raw object\n if (!data) return;\n\n if (data.type === 'response') {\n const pending = this._pending.get(data.id);\n if (!pending) return;\n this._pending.delete(data.id);\n clearTimeout(pending.timeoutHandle);\n if (data.success) {\n const deserializeTimer = globalTimer.start('ipc', 'deserialize');\n const deserializedResult = deserializePayload(data.result);\n globalTimer.end(deserializeTimer);\n pending.resolve(deserializedResult);\n } else {\n const error = new Error(data.error?.message || 'Worker error');\n if (data.error?.name) error.name = data.error.name;\n if (data.error?.stack) error.stack = data.error.stack;\n if (data.error?.code) error.code = data.error.code;\n if (data.error?.$err) error.$err = data.error.$err;\n pending.reject(error);\n }\n return;\n }\n\n // Forward events (e.g., change streams)\n if (data.type === 'event') {\n const deserializedPayload = deserializePayload(data.payload);\n this.emit('event', data.event, deserializedPayload);\n }\n }\n\n _handleError(error) {\n // Don't emit errors if we're intentionally terminating\n if (this._terminating) return;\n \n // Reject all pending requests on fatal worker error\n for (const [id, pending] of this._pending.entries()) {\n clearTimeout(pending.timeoutHandle);\n pending.reject(error);\n }\n this._pending.clear();\n this.emit('error', error);\n }\n\n // Abstract hooks per environment\n _attach() { throw new Error('Not implemented'); }\n _post() { throw new Error('Not implemented'); }\n _terminateImpl() { throw new Error('Not implemented'); }\n}\n\nclass BrowserWorkerBridge extends WorkerBridge {\n constructor(options = {}) {\n // Use globalThis.Worker to explicitly reference the Web Worker API\n const WebWorkerCtor = globalThis.Worker;\n if (!WebWorkerCtor) {\n throw new Error('Worker API is not available in this environment');\n }\n \n // Default to built worker artifact; allow override for custom hosting\n // Use absolute path from server root for consistent resolution in dev and prod\n const workerUrl = options.workerUrl || '/dist/babymongo-server-worker.js';\n const worker = new WebWorkerCtor(workerUrl, { type: 'module' });\n super(worker);\n }\n\n _attach() {\n this.worker.onmessage = this._handleMessage;\n this.worker.onerror = this._handleError;\n }\n\n _post(message) {\n this.worker.postMessage(message);\n }\n\n _terminateImpl() {\n this.worker.terminate();\n }\n}\n\nclass NodeWorkerBridge extends WorkerBridge {\n constructor(worker) {\n super(worker);\n }\n\n _attach() {\n this.worker.on('message', this._handleMessage);\n this.worker.on('error', this._handleError);\n this.worker.on('exit', (code) => {\n if (code !== 0 && !this._terminating) {\n this._handleError(new Error(`Worker stopped with exit code ${code}`));\n }\n });\n }\n\n _post(message) {\n this.worker.postMessage(message);\n }\n\n _terminateImpl() {\n return this.worker.terminate();\n }\n}\n"],"names":["ReflectOwnKeys","R","Reflect","ReflectApply","apply","target","receiver","args","Function","prototype","call","ownKeys","Object","getOwnPropertySymbols","getOwnPropertyNames","concat","NumberIsNaN","Number","isNaN","value","EventEmitter","init","this","eventsModule","exports","once","emitter","name","Promise","resolve","reject","errorListener","err","removeListener","resolver","slice","arguments","eventTargetAgnosticAddListener","handler","flags","on","addErrorHandlerIfEventEmitter","_events","_eventsCount","_maxListeners","defaultMaxListeners","checkListener","listener","TypeError","_getMaxListeners","that","_addListener","type","prepend","m","events","existing","warning","create","newListener","emit","unshift","push","length","warned","w","Error","String","count","console","warn","onceWrapper","fired","wrapFn","_onceWrap","state","wrapped","bind","_listeners","unwrap","evlistener","arr","ret","Array","i","unwrapListeners","arrayClone","listenerCount","n","copy","addEventListener","wrapListener","arg","removeEventListener","defineProperty","enumerable","get","set","RangeError","getPrototypeOf","setMaxListeners","getMaxListeners","doError","error","er","message","context","len","listeners","addListener","prependListener","prependOnceListener","list","position","originalListener","shift","index","pop","spliceOne","off","removeAllListeners","key","keys","rawListeners","eventNames","ErrorCodes","OK","INTERNAL_ERROR","BAD_VALUE","NO_SUCH_KEY","GRAPH_CONTAINS_CYCLE","HOST_UNREACHABLE","HOST_NOT_FOUND","UNKNOWN_ERROR","FAILED_TO_PARSE","CANNOT_MUTATE_OBJECT","USER_NOT_FOUND","UNSUPPORTED_FORMAT","UNAUTHORIZED","TYPE_MISMATCH","OVERFLOW","INVALID_LENGTH","PROTOCOL_ERROR","AUTHENTICATION_FAILED","ILLEGAL_OPERATION","NAMESPACE_NOT_FOUND","INDEX_NOT_FOUND","PATH_NOT_VIABLE","CANNOT_CREATE_INDEX","INDEX_ALREADY_EXISTS","INDEX_EXISTS","COMMAND_NOT_FOUND","NAMESPACE_EXISTS","INVALID_NAMESPACE","INDEX_OPTIONS_CONFLICT","INVALID_INDEX_SPECIFICATION_OPTION","WRITE_CONFLICT","DUPLICATE_KEY","DUPLICATE_KEY_UPDATE","DOCUMENT_VALIDATION_FAILURE","BAD_QUERY","CANNOT_INDEX_PARALLEL_ARRAYS","CURSOR_NOT_FOUND","COLLECTION_IS_EMPTY","CANNOT_DO_EXCLUSION_ON_FIELD_ID_IN_INCLUSION_PROJECTION","NOT_IMPLEMENTED","OPERATION_NOT_SUPPORTED","MongoError","constructor","options","super","code","codeName","_getCodeName","$err","collection","database","operation","query","document","field","captureStackTrace","toJSON","json","indexName","namespace","cursorId","feature","keyPattern","keyValue","writeErrors","MongoServerError","MongoDriverError","WriteError","DuplicateKeyError","keyStr","JSON","stringify","ValidationError","validationErrors","IndexError","IndexExistsError","IndexNotFoundError","CannotCreateIndexError","reason","QueryError","TypeMismatchError","expectedType","actualType","NamespaceError","NamespaceNotFoundError","InvalidNamespaceError","CursorError","CursorNotFoundError","NotImplementedError","OperationNotSupportedError","BadValueError","BulkWriteError","MongoNetworkError","ProxyChangeStream","bridge","streamId","pipeline","stream","method","sendRequest","then","resp","catch","closed","_pendingNext","_onEvent","eventName","payload","data","_cleanup","close","pending","next","onChange","change","_removePending","onError","onClose","indexOf","splice","Symbol","asyncIterator","ProxyCursor","batch","exhausted","batchSize","requestPromise","requestPayload","buffer","isArray","_batchSize","_requestPromise","_requestPayload","_initialized","_ensureInitialized","cursorOpts","_limit","limit","_skip","skip","_sort","sort","_min","min","_max","max","_hint","hint","_comment","comment","_maxTimeMS","maxTimeMS","_maxScan","maxScan","_returnKey","returnKey","_showRecordId","showRecordId","_collation","collation","res","hasNext","_closed","_getMore","toArray","results","spec","_closeRemote","isClosed","str","explain","verbosity","result","queryPlanner","plannerVersion","indexFilterSet","parsedQuery","winningPlan","stage","ok","executionStats","executionSuccess","nReturned","executionTimeMillis","itcount","size","_minIndexBounds","_maxIndexBounds","ms","noCursorTimeout","_noCursorTimeout","objsLeftInBatch","pretty","_pretty","readConcern","level","_readConcern","readPref","mode","tagSet","_readPref","bool","allowDiskUse","_allowDiskUse","forEach","fn","doc","map","_","ProxyCollection","dbName","db","_db","indexes","Proxy","prop","startsWith","_watch","_cursorMethod","_call","_validateProjection","cursor","onFulfilled","onRejected","projection","hasInclusion","hasExclusion","indexSpec","indexOptions","entries","k","v","join","find","idx","filter","getIndexes","ProxyDB","collections","Map","dbMethodNames","Set","_methodNames","has","collName","delete","clear","dbProxy","col","getCollectionNames","from","MongoClient","uri","freeze","_isConnected","_defaultDb","_parseDefaultDbName","_databases","workerBridge","_bridge","_ownsBridge","connect","client","opts","terminate","force","startSession","id","crypto","randomUUID","endSession","withTransaction","async","withSession","optionsOrExecutor","executor","session","writeConcern","readPreference","watch","match","_parseUriParams","params","queryIndex","pairs","substring","split","pair","decodeURIComponent","ObjectId","generate","isValid","toLowerCase","Uint8Array","b","toString","padStart","toHexString","getTimestamp","timestamp","parseInt","Date","equals","other","compare","localeCompare","inspect","toBytes","bytes","test","createFromTime","tsHex","Math","floor","ts","now","rand","getRandomValues","tail","random","padEnd","valuesEqual","a","getProp","obj","path","pathSegment","numericIndex","o","isIn","val","values","arrayMatches","x","y","objectMatches","p","hasOwnProperty","step2list","ational","tional","enci","anci","izer","bli","alli","entli","eli","ousli","ization","ation","ator","alism","iveness","fulness","ousness","aliti","iviti","biliti","logi","step3list","icate","ative","alize","iciti","ical","ful","ness","vowel","consonants","vowels","gt0","RegExp","eq1","gt1","vowelInStem","consonantLike","sfxLl","sfxE","sfxY","sfxIon","sfxEdOrIng","sfxAtOrBlOrIz","sfxEED","sfxS","sfxSsesOrIes","sfxMultiConsonantLike","step2","step3","step4","STOPWORDS","evaluateExpression","expr","charAt","item","operator","operand","operands","sum","getTime","evalAdd","val1","val2","evalSubtract","product","evalMultiply","evalDivide","evalMod","base","exponent","pow","evalPow","sqrt","evalSqrt","abs","evalAbs","ceil","evalCeil","evalFloor","trunc","evalTrunc","place","multiplier","round","evalRound","evalConcat","start","substr","evalSubstr","evalToLower","toUpperCase","evalToUpper","input","chars","charsRegex","escapeRegex","replace","trim","evalTrim","evalLtrim","evalRtrim","delimiter","evalSplit","evalStrLenCP","str1","str2","evalStrcasecmp","end","evalIndexOfCP","replacement","evalReplaceOne","evalReplaceAll","evalCmp","evalEq","evalNe","evalGt","evalGte","evalLt","evalLte","evalAnd","evalOr","evalNot","ifExpr","thenExpr","elseExpr","if","else","condition","evalCond","evalIfNull","branches","branch","case","default","evalSwitch","date","getUTCFullYear","evalYear","getUTCMonth","evalMonth","getUTCDate","evalDayOfMonth","getUTCDay","evalDayOfWeek","UTC","diff","oneDay","evalDayOfYear","getUTCHours","evalHour","getUTCMinutes","evalMinute","getUTCSeconds","evalSecond","getUTCMilliseconds","evalMillisecond","onejan","evalWeek","valueOf","dayNr","setUTCDate","firstThursday","setUTCMonth","evalIsoWeek","evalIsoWeekYear","format","evalDateToString","evalToDate","evalArrayElemAt","evalConcatArrays","asVar","as","cond","itemDoc","evalFilter","includes","evalIn","search","evalIndexOfArray","evalIsArray","inExpr","in","evalMap","initialValue","evalReduce","evalSize","evalSlice","reverse","evalReverseArray","inputs","useLongestLength","defaults","arrays","every","maxLength","tuple","j","evalZip","isInteger","evalType","to","onNull","parseFloat","Boolean","e","evalConvert","evalToBool","evalToDecimal","evalToDouble","evalToInt","evalToLong","evalToString","evalObjectToArray","evalArrayToObject","assign","evalMergeObjects","evaluateOperator","BSON_TYPES","TYPE_ALIASES","reduce","acc","matchesType","typeSpec","typeCode","typeName","toBitMask","positions","mask","matchesBitsAllSet","matchesBitsAllClear","matchesBitsAnySet","matchesBitsAnyClear","validateJsonSchema","schema","docType","required","properties","propSchema","minimum","maximum","minLength","pattern","enum","compareValues","aVal","bVal","fieldValueMatches","fieldValue","checkFn","tokenizeText","text","words","word","tokenize","firstCharacterWasLowerCaseY","codePointAt","exec","stemmer","queryText","propTokens","some","term","geoWithin","minLon","maxLat","maxLon","isGeometryWithinBBox","geoJson","minLat","features","geometry","coordinates","lng","lat","ring","coord","extractCoordinatesFromGeoJSON","sumLat","sumLng","haversineDistance","lat1","lng1","lat2","lng2","dLat","PI","dLng","sin","cos","atan2","isNear","refLng","refLat","maxDistanceMeters","coords","geoIntersects","queryGeo","queryCoords","docCoords","pointInPolygon","queryPt","inside","xi","yi","xj","yj","tlMatches","opMatches","and","els","or","not","nor","where","searchText","searchObject","textSearchDocument","$search","newResults","current","getFieldValues","rawValue","$options","regex","$geometry","$maxDistance","arrayFieldValue","found","element","matchesPrimitive","opKeys","op","opValue","matches","sizeFieldValue","el","ChangeStream","_changeCounter","_startWatching","_isDB","_isServer","databases","_getDB","_isMongoClient","_getCollectionsToWatch","_watchCollection","_interceptServerDBCreation","_interceptDBCollectionCreation","_interceptClientDBCreation","collectionNames","isCollection","_monitorClient","_monitorDB","handlers","insert","_emitChange","update","updateDescription","operationType","changeEvent","_createChangeEvent","_matchesPipeline","event","_id","_data","btoa","clusterTime","ns","coll","documentKey","fullDocument","updatedFields","removedFields","truncatedArrays","$match","_getNestedValue","part","originalDb","self","_watchedDBs","colName","_interceptDBCollectionCreationForClient","_originalClientMethods","server","originalGetDB","_interceptDBCollectionCreationForServer","_originalServerMethods","originalCollection","originalCreateCollection","createCollection","originalGetCollection","getCollection","_originalDBMethods","queue","resolveNext","streamClosed","done","cleanup","globalTimer","enabled","timings","nestedLevel","setEnabled","category","details","startTime","performance","timer","additionalDetails","duration","getTimings","getTimingsByCategory","grouped","timing","getSummary","summary","total","Infinity","avg","stats","formatTimings","output","repeat","byCategory","stat","toFixed","serializePayload","__function","__objectId","__date","toISOString","deserializePayload","WorkerBridge","worker","_nextId","_pending","_terminating","_handleMessage","_handleError","_attach","window","globalThis","Worker","BrowserWorkerBridge","NodeWorker","import","fileURLToPath","workerPath","URL","url","workerData","NodeWorkerBridge","serializeTimer","serializedPayload","timeoutHandle","timeout","setTimeout","ipcTimer","requestId","originalResolve","originalReject","_post","clearTimeout","_terminateImpl","success","deserializeTimer","deserializedResult","stack","deserializedPayload","WebWorkerCtor","workerUrl","onmessage","onerror","postMessage"],"mappings":"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","x_google_ignoreList":[0,7,9,10]}