diff --git a/dist/cjs/rx-query-helper.js b/dist/cjs/rx-query-helper.js index ec81163c57a..3879d8f5602 100644 --- a/dist/cjs/rx-query-helper.js +++ b/dist/cjs/rx-query-helper.js @@ -7,6 +7,7 @@ exports.getQueryMatcher = getQueryMatcher; exports.getSortComparator = getSortComparator; exports.normalizeMangoQuery = normalizeMangoQuery; exports.runQueryUpdateFunction = runQueryUpdateFunction; +exports.selectorIncludesDeleted = selectorIncludesDeleted; var _queryPlanner = require("./query-planner.js"); var _rxSchemaHelper = require("./rx-schema-helper.js"); var _index = require("./plugins/utils/index.js"); @@ -211,4 +212,31 @@ async function runQueryUpdateFunction(rxQuery, fn) { return result; } } + +/** + * Checks if a given selector includes deleted documents. + * @param selector The MangoQuerySelector to check + * @returns True if the selector includes deleted documents, false otherwise + */ +function selectorIncludesDeleted(selector) { + if (!selector) { + return false; + } + var isTrue = value => value === true || typeof value === 'object' && value !== null && '$eq' in value && value.$eq === true; + var isNotFalse = value => value === true || typeof value === 'object' && value !== null && '$ne' in value && value.$ne === false; + var hasDeletedTrue = condition => '_deleted' in condition && (isTrue(condition._deleted) || isNotFalse(condition._deleted)); + if ('_deleted' in selector) { + return isTrue(selector._deleted) || isNotFalse(selector._deleted); + } + if ('$or' in selector && Array.isArray(selector.$or)) { + return selector.$or.some(hasDeletedTrue); + } + if ('$and' in selector && Array.isArray(selector.$and)) { + return selector.$and.some(hasDeletedTrue); + } + if ('$nor' in selector && Array.isArray(selector.$nor)) { + return !selector.$nor.every(condition => !hasDeletedTrue(condition)); + } + return false; +} //# sourceMappingURL=rx-query-helper.js.map \ No newline at end of file diff --git a/dist/cjs/rx-query-helper.js.map b/dist/cjs/rx-query-helper.js.map index ba9f842f3c1..4900a8d67de 100644 --- a/dist/cjs/rx-query-helper.js.map +++ b/dist/cjs/rx-query-helper.js.map @@ -1 +1 @@ -{"version":3,"file":"rx-query-helper.js","names":["_queryPlanner","require","_rxSchemaHelper","_index","_util","_rxError","_rxQueryMingo","normalizeMangoQuery","schema","mangoQuery","primaryKey","getPrimaryFieldOfPrimaryKey","flatClone","normalizedMangoQuery","clone","skip","selector","Object","entries","forEach","field","matcher","$eq","index","indexAr","toArray","includes","push","sort","map","indexes","fieldsWithLogicalOperator","Set","hasLogical","keys","find","operator","LOGICAL_OPERATORS","has","add","currentFieldsAmount","currentBestIndexForSort","useIndex","isMaybeReadonlyArray","firstWrongIndex","findIndex","indexField","isPrimaryInSort","p","firstPropertyNameOfObject","slice","getSortComparator","query","newRxError","sortParts","sortBlock","key","direction","values","getValueFn","objectPathMonad","fun","a","b","i","length","sortPart","valueA","valueB","ret","mingoSortComparator","getQueryMatcher","_schema","mingoQuery","getMingoQuery","doc","test","runQueryUpdateFunction","rxQuery","fn","docs","exec","Array","isArray","Promise","all","result"],"sources":["../../src/rx-query-helper.ts"],"sourcesContent":["import { LOGICAL_OPERATORS } from './query-planner.ts';\nimport { getPrimaryFieldOfPrimaryKey } from './rx-schema-helper.ts';\nimport type {\n DeepReadonly,\n DeterministicSortComparator,\n FilledMangoQuery,\n MangoQuery,\n MangoQuerySortDirection,\n QueryMatcher,\n RxDocument,\n RxDocumentData,\n RxJsonSchema,\n RxQuery\n} from './types/index.d.ts';\nimport {\n clone,\n firstPropertyNameOfObject,\n toArray,\n isMaybeReadonlyArray,\n flatClone,\n objectPathMonad,\n ObjectPathMonadFunction\n} from './plugins/utils/index.ts';\nimport {\n compare as mingoSortComparator\n} from 'mingo/util';\nimport { newRxError } from './rx-error.ts';\nimport { getMingoQuery } from './rx-query-mingo.ts';\n\n/**\n * Normalize the query to ensure we have all fields set\n * and queries that represent the same query logic are detected as equal by the caching.\n */\nexport function normalizeMangoQuery(\n schema: RxJsonSchema>,\n mangoQuery: MangoQuery\n): FilledMangoQuery {\n const primaryKey: string = getPrimaryFieldOfPrimaryKey(schema.primaryKey);\n mangoQuery = flatClone(mangoQuery);\n\n const normalizedMangoQuery: FilledMangoQuery = clone(mangoQuery) as any;\n if (typeof normalizedMangoQuery.skip !== 'number') {\n normalizedMangoQuery.skip = 0;\n }\n\n if (!normalizedMangoQuery.selector) {\n normalizedMangoQuery.selector = {};\n } else {\n normalizedMangoQuery.selector = normalizedMangoQuery.selector;\n /**\n * In mango query, it is possible to have an\n * equals comparison by directly assigning a value\n * to a property, without the '$eq' operator.\n * Like:\n * selector: {\n * foo: 'bar'\n * }\n * For normalization, we have to normalize this\n * so our checks can perform properly.\n *\n *\n * TODO this must work recursive with nested queries that\n * contain multiple selectors via $and or $or etc.\n */\n Object\n .entries(normalizedMangoQuery.selector)\n .forEach(([field, matcher]) => {\n if (typeof matcher !== 'object' || matcher === null) {\n (normalizedMangoQuery as any).selector[field] = {\n $eq: matcher\n };\n }\n });\n }\n\n /**\n * Ensure that if an index is specified,\n * the primaryKey is inside of it.\n */\n if (normalizedMangoQuery.index) {\n const indexAr = toArray(normalizedMangoQuery.index);\n if (!indexAr.includes(primaryKey)) {\n indexAr.push(primaryKey);\n }\n normalizedMangoQuery.index = indexAr;\n }\n\n /**\n * To ensure a deterministic sorting,\n * we have to ensure the primary key is always part\n * of the sort query.\n * Primary sorting is added as last sort parameter,\n * similar to how we add the primary key to indexes that do not have it.\n *\n */\n if (!normalizedMangoQuery.sort) {\n /**\n * If no sort is given at all,\n * we can assume that the user does not care about sort order at al.\n *\n * we cannot just use the primary key as sort parameter\n * because it would likely cause the query to run over the primary key index\n * which has a bad performance in most cases.\n */\n if (normalizedMangoQuery.index) {\n normalizedMangoQuery.sort = normalizedMangoQuery.index.map((field: string) => {\n return { [field as any]: 'asc' } as any;\n });\n } else {\n /**\n * Find the index that best matches the fields with the logical operators\n */\n if (schema.indexes) {\n const fieldsWithLogicalOperator: Set = new Set();\n Object.entries(normalizedMangoQuery.selector).forEach(([field, matcher]) => {\n let hasLogical = false;\n if (typeof matcher === 'object' && matcher !== null) {\n hasLogical = !!Object.keys(matcher).find(operator => LOGICAL_OPERATORS.has(operator));\n } else {\n hasLogical = true;\n }\n if (hasLogical) {\n fieldsWithLogicalOperator.add(field);\n }\n });\n\n\n let currentFieldsAmount = -1;\n let currentBestIndexForSort: string[] | readonly string[] | undefined;\n schema.indexes.forEach(index => {\n const useIndex = isMaybeReadonlyArray(index) ? index : [index];\n const firstWrongIndex = useIndex.findIndex(indexField => !fieldsWithLogicalOperator.has(indexField));\n if (\n firstWrongIndex > 0 &&\n firstWrongIndex > currentFieldsAmount\n ) {\n currentFieldsAmount = firstWrongIndex;\n currentBestIndexForSort = useIndex;\n }\n });\n if (currentBestIndexForSort) {\n normalizedMangoQuery.sort = currentBestIndexForSort.map((field: string) => {\n return { [field as any]: 'asc' } as any;\n });\n }\n\n }\n\n /**\n * Fall back to the primary key as sort order\n * if no better one has been found\n */\n if (!normalizedMangoQuery.sort) {\n normalizedMangoQuery.sort = [{ [primaryKey]: 'asc' }] as any;\n }\n }\n } else {\n const isPrimaryInSort = normalizedMangoQuery.sort\n .find(p => firstPropertyNameOfObject(p) === primaryKey);\n if (!isPrimaryInSort) {\n normalizedMangoQuery.sort = normalizedMangoQuery.sort.slice(0);\n normalizedMangoQuery.sort.push({ [primaryKey]: 'asc' } as any);\n }\n }\n\n return normalizedMangoQuery;\n}\n\n/**\n * Returns the sort-comparator,\n * which is able to sort documents in the same way\n * a query over the db would do.\n */\nexport function getSortComparator(\n schema: RxJsonSchema>,\n query: FilledMangoQuery\n): DeterministicSortComparator {\n if (!query.sort) {\n throw newRxError('SNH', { query });\n }\n const sortParts: {\n key: string;\n direction: MangoQuerySortDirection;\n getValueFn: ObjectPathMonadFunction;\n }[] = [];\n query.sort.forEach(sortBlock => {\n const key = Object.keys(sortBlock)[0];\n const direction = Object.values(sortBlock)[0];\n sortParts.push({\n key,\n direction,\n getValueFn: objectPathMonad(key)\n });\n });\n const fun: DeterministicSortComparator = (a: RxDocType, b: RxDocType) => {\n for (let i = 0; i < sortParts.length; ++i) {\n const sortPart = sortParts[i];\n const valueA = sortPart.getValueFn(a);\n const valueB = sortPart.getValueFn(b);\n if (valueA !== valueB) {\n const ret = sortPart.direction === 'asc' ? mingoSortComparator(valueA, valueB) : mingoSortComparator(valueB, valueA);\n return ret as any;\n }\n }\n };\n\n return fun;\n}\n\n\n/**\n * Returns a function\n * that can be used to check if a document\n * matches the query.\n */\nexport function getQueryMatcher(\n _schema: RxJsonSchema | RxJsonSchema>,\n query: FilledMangoQuery\n): QueryMatcher> {\n if (!query.sort) {\n throw newRxError('SNH', { query });\n }\n\n const mingoQuery = getMingoQuery(query.selector as any);\n const fun: QueryMatcher> = (doc: RxDocumentData | DeepReadonly>) => {\n return mingoQuery.test(doc);\n };\n return fun;\n}\n\n\nexport async function runQueryUpdateFunction(\n rxQuery: RxQuery,\n fn: (doc: RxDocument) => Promise>\n): Promise {\n const docs = await rxQuery.exec();\n if (!docs) {\n // only findOne() queries can return null\n return null as any;\n }\n if (Array.isArray(docs)) {\n return Promise.all(\n docs.map(doc => fn(doc))\n ) as any;\n } else {\n // via findOne()\n const result = await fn(docs as any);\n return result as any;\n }\n}\n"],"mappings":"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","ignoreList":[]} \ No newline at end of file +{"version":3,"file":"rx-query-helper.js","names":["_queryPlanner","require","_rxSchemaHelper","_index","_util","_rxError","_rxQueryMingo","normalizeMangoQuery","schema","mangoQuery","primaryKey","getPrimaryFieldOfPrimaryKey","flatClone","normalizedMangoQuery","clone","skip","selector","Object","entries","forEach","field","matcher","$eq","index","indexAr","toArray","includes","push","sort","map","indexes","fieldsWithLogicalOperator","Set","hasLogical","keys","find","operator","LOGICAL_OPERATORS","has","add","currentFieldsAmount","currentBestIndexForSort","useIndex","isMaybeReadonlyArray","firstWrongIndex","findIndex","indexField","isPrimaryInSort","p","firstPropertyNameOfObject","slice","getSortComparator","query","newRxError","sortParts","sortBlock","key","direction","values","getValueFn","objectPathMonad","fun","a","b","i","length","sortPart","valueA","valueB","ret","mingoSortComparator","getQueryMatcher","_schema","mingoQuery","getMingoQuery","doc","test","runQueryUpdateFunction","rxQuery","fn","docs","exec","Array","isArray","Promise","all","result","selectorIncludesDeleted","isTrue","value","isNotFalse","$ne","hasDeletedTrue","condition","_deleted","$or","some","$and","$nor","every"],"sources":["../../src/rx-query-helper.ts"],"sourcesContent":["import { LOGICAL_OPERATORS } from './query-planner.ts';\nimport { getPrimaryFieldOfPrimaryKey } from './rx-schema-helper.ts';\nimport type {\n DeepReadonly,\n DeterministicSortComparator,\n FilledMangoQuery,\n MangoQuery,\n MangoQueryOperators,\n MangoQuerySelector,\n MangoQuerySortDirection,\n PropertyType,\n QueryMatcher,\n RxDocument,\n RxDocumentData,\n RxJsonSchema,\n RxQuery\n} from './types/index.d.ts';\nimport {\n clone,\n firstPropertyNameOfObject,\n toArray,\n isMaybeReadonlyArray,\n flatClone,\n objectPathMonad,\n ObjectPathMonadFunction\n} from './plugins/utils/index.ts';\nimport {\n compare as mingoSortComparator\n} from 'mingo/util';\nimport { newRxError } from './rx-error.ts';\nimport { getMingoQuery } from './rx-query-mingo.ts';\n\n/**\n * Normalize the query to ensure we have all fields set\n * and queries that represent the same query logic are detected as equal by the caching.\n */\nexport function normalizeMangoQuery(\n schema: RxJsonSchema>,\n mangoQuery: MangoQuery\n): FilledMangoQuery {\n const primaryKey: string = getPrimaryFieldOfPrimaryKey(schema.primaryKey);\n mangoQuery = flatClone(mangoQuery);\n\n const normalizedMangoQuery: FilledMangoQuery = clone(mangoQuery) as any;\n if (typeof normalizedMangoQuery.skip !== 'number') {\n normalizedMangoQuery.skip = 0;\n }\n\n if (!normalizedMangoQuery.selector) {\n normalizedMangoQuery.selector = {};\n } else {\n normalizedMangoQuery.selector = normalizedMangoQuery.selector;\n /**\n * In mango query, it is possible to have an\n * equals comparison by directly assigning a value\n * to a property, without the '$eq' operator.\n * Like:\n * selector: {\n * foo: 'bar'\n * }\n * For normalization, we have to normalize this\n * so our checks can perform properly.\n *\n *\n * TODO this must work recursive with nested queries that\n * contain multiple selectors via $and or $or etc.\n */\n Object\n .entries(normalizedMangoQuery.selector)\n .forEach(([field, matcher]) => {\n if (typeof matcher !== 'object' || matcher === null) {\n (normalizedMangoQuery as any).selector[field] = {\n $eq: matcher\n };\n }\n });\n }\n\n /**\n * Ensure that if an index is specified,\n * the primaryKey is inside of it.\n */\n if (normalizedMangoQuery.index) {\n const indexAr = toArray(normalizedMangoQuery.index);\n if (!indexAr.includes(primaryKey)) {\n indexAr.push(primaryKey);\n }\n normalizedMangoQuery.index = indexAr;\n }\n\n /**\n * To ensure a deterministic sorting,\n * we have to ensure the primary key is always part\n * of the sort query.\n * Primary sorting is added as last sort parameter,\n * similar to how we add the primary key to indexes that do not have it.\n *\n */\n if (!normalizedMangoQuery.sort) {\n /**\n * If no sort is given at all,\n * we can assume that the user does not care about sort order at al.\n *\n * we cannot just use the primary key as sort parameter\n * because it would likely cause the query to run over the primary key index\n * which has a bad performance in most cases.\n */\n if (normalizedMangoQuery.index) {\n normalizedMangoQuery.sort = normalizedMangoQuery.index.map((field: string) => {\n return { [field as any]: 'asc' } as any;\n });\n } else {\n /**\n * Find the index that best matches the fields with the logical operators\n */\n if (schema.indexes) {\n const fieldsWithLogicalOperator: Set = new Set();\n Object.entries(normalizedMangoQuery.selector).forEach(([field, matcher]) => {\n let hasLogical = false;\n if (typeof matcher === 'object' && matcher !== null) {\n hasLogical = !!Object.keys(matcher).find(operator => LOGICAL_OPERATORS.has(operator));\n } else {\n hasLogical = true;\n }\n if (hasLogical) {\n fieldsWithLogicalOperator.add(field);\n }\n });\n\n\n let currentFieldsAmount = -1;\n let currentBestIndexForSort: string[] | readonly string[] | undefined;\n schema.indexes.forEach(index => {\n const useIndex = isMaybeReadonlyArray(index) ? index : [index];\n const firstWrongIndex = useIndex.findIndex(indexField => !fieldsWithLogicalOperator.has(indexField));\n if (\n firstWrongIndex > 0 &&\n firstWrongIndex > currentFieldsAmount\n ) {\n currentFieldsAmount = firstWrongIndex;\n currentBestIndexForSort = useIndex;\n }\n });\n if (currentBestIndexForSort) {\n normalizedMangoQuery.sort = currentBestIndexForSort.map((field: string) => {\n return { [field as any]: 'asc' } as any;\n });\n }\n\n }\n\n /**\n * Fall back to the primary key as sort order\n * if no better one has been found\n */\n if (!normalizedMangoQuery.sort) {\n normalizedMangoQuery.sort = [{ [primaryKey]: 'asc' }] as any;\n }\n }\n } else {\n const isPrimaryInSort = normalizedMangoQuery.sort\n .find(p => firstPropertyNameOfObject(p) === primaryKey);\n if (!isPrimaryInSort) {\n normalizedMangoQuery.sort = normalizedMangoQuery.sort.slice(0);\n normalizedMangoQuery.sort.push({ [primaryKey]: 'asc' } as any);\n }\n }\n\n return normalizedMangoQuery;\n}\n\n/**\n * Returns the sort-comparator,\n * which is able to sort documents in the same way\n * a query over the db would do.\n */\nexport function getSortComparator(\n schema: RxJsonSchema>,\n query: FilledMangoQuery\n): DeterministicSortComparator {\n if (!query.sort) {\n throw newRxError('SNH', { query });\n }\n const sortParts: {\n key: string;\n direction: MangoQuerySortDirection;\n getValueFn: ObjectPathMonadFunction;\n }[] = [];\n query.sort.forEach(sortBlock => {\n const key = Object.keys(sortBlock)[0];\n const direction = Object.values(sortBlock)[0];\n sortParts.push({\n key,\n direction,\n getValueFn: objectPathMonad(key)\n });\n });\n const fun: DeterministicSortComparator = (a: RxDocType, b: RxDocType) => {\n for (let i = 0; i < sortParts.length; ++i) {\n const sortPart = sortParts[i];\n const valueA = sortPart.getValueFn(a);\n const valueB = sortPart.getValueFn(b);\n if (valueA !== valueB) {\n const ret = sortPart.direction === 'asc' ? mingoSortComparator(valueA, valueB) : mingoSortComparator(valueB, valueA);\n return ret as any;\n }\n }\n };\n\n return fun;\n}\n\n\n/**\n * Returns a function\n * that can be used to check if a document\n * matches the query.\n */\nexport function getQueryMatcher(\n _schema: RxJsonSchema | RxJsonSchema>,\n query: FilledMangoQuery\n): QueryMatcher> {\n if (!query.sort) {\n throw newRxError('SNH', { query });\n }\n\n const mingoQuery = getMingoQuery(query.selector as any);\n const fun: QueryMatcher> = (doc: RxDocumentData | DeepReadonly>) => {\n return mingoQuery.test(doc);\n };\n return fun;\n}\n\n\nexport async function runQueryUpdateFunction(\n rxQuery: RxQuery,\n fn: (doc: RxDocument) => Promise>\n): Promise {\n const docs = await rxQuery.exec();\n if (!docs) {\n // only findOne() queries can return null\n return null as any;\n }\n if (Array.isArray(docs)) {\n return Promise.all(\n docs.map(doc => fn(doc))\n ) as any;\n } else {\n // via findOne()\n const result = await fn(docs as any);\n return result as any;\n }\n}\n\n/**\n * Checks if a given selector includes deleted documents.\n * @param selector The MangoQuerySelector to check\n * @returns True if the selector includes deleted documents, false otherwise\n */\nexport function selectorIncludesDeleted(\n selector: MangoQuerySelector | undefined\n): boolean {\n if (!selector) {\n return false;\n }\n\n const isTrue = (value: unknown): boolean =>\n value === true ||\n (typeof value === 'object' &&\n value !== null &&\n '$eq' in value &&\n (value as MangoQueryOperators).$eq === true);\n\n\n const isNotFalse = (value: unknown): boolean =>\n value === true ||\n (typeof value === 'object' &&\n value !== null &&\n '$ne' in value &&\n (value as MangoQueryOperators).$ne === false);\n\n const hasDeletedTrue = (\n condition: MangoQuerySelector\n ): boolean =>\n '_deleted' in condition &&\n (isTrue(condition._deleted as PropertyType) ||\n isNotFalse(\n condition._deleted as PropertyType\n ));\n\n if ('_deleted' in selector) {\n return (\n isTrue(selector._deleted as PropertyType) ||\n isNotFalse(selector._deleted as PropertyType)\n );\n }\n\n if ('$or' in selector && Array.isArray(selector.$or)) {\n return selector.$or.some(hasDeletedTrue);\n }\n\n if ('$and' in selector && Array.isArray(selector.$and)) {\n return selector.$and.some(hasDeletedTrue);\n }\n\n if ('$nor' in selector && Array.isArray(selector.$nor)) {\n return !selector.$nor.every((condition) => !hasDeletedTrue(condition));\n }\n\n return false;\n}\n"],"mappings":"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","ignoreList":[]} \ No newline at end of file diff --git a/dist/cjs/rx-query.js b/dist/cjs/rx-query.js index 1ec481f4c51..0037ea6501f 100644 --- a/dist/cjs/rx-query.js +++ b/dist/cjs/rx-query.js @@ -232,9 +232,16 @@ var RxQueryBase = exports.RxQueryBase = /*#__PURE__*/function () { // can be mutated by the hooks so we have to deep clone first. mangoQuery: (0, _rxQueryHelper.normalizeMangoQuery)(this.collection.schema.jsonSchema, this.mangoQuery) }; - hookInput.mangoQuery.selector._deleted = { - $eq: false - }; + + // Set _deleted to false if not explicitly set in selector + if (!this.includesDeleted) { + hookInput.mangoQuery.selector = { + ...hookInput.mangoQuery.selector, + _deleted: { + $eq: false + } + }; + } if (hookInput.mangoQuery.index) { hookInput.mangoQuery.index.unshift('_deleted'); } @@ -522,6 +529,11 @@ var RxQueryBase = exports.RxQueryBase = /*#__PURE__*/function () { var reactivity = this.collection.database.getReactivityFactory(); return reactivity.fromObservable(this.$, undefined, this.collection.database); } + }, { + key: "includesDeleted", + get: function () { + return (0, _rxQueryHelper.selectorIncludesDeleted)(this.mangoQuery.selector); + } // stores the changeEvent-number of the last handled change-event @@ -658,7 +670,12 @@ async function __ensureEqual(rxQuery) { if (await _loop(cE)) break; } } - if (rxQuery.op === 'count') { + if (rxQuery.includesDeleted) { + return rxQuery._execOverDatabase().then(newResultData => { + rxQuery._setResultData(newResultData); + return true; + }); + } else if (rxQuery.op === 'count') { // 'count' query var previousCount = (0, _eventReduceJs.ensureNotFalsy)(rxQuery._result).count; var newCount = previousCount; diff --git a/dist/cjs/rx-query.js.map b/dist/cjs/rx-query.js.map index 10965e35d3e..b3aeaf6ec8c 100644 --- a/dist/cjs/rx-query.js.map +++ b/dist/cjs/rx-query.js.map @@ -1 +1 @@ -{"version":3,"file":"rx-query.js","names":["_rxjs","require","_operators","_index","_rxError","_hooks","_eventReduce","_queryCache","_rxQueryHelper","_rxQuerySingleResult","_queryPlanner","_eventReduceJs","_rxStorageHelper","_queryCount","newQueryID","RESTORE_QUERY_UPDATE_DRIFT","RESTORE_QUERY_MAX_DOCS_CHANGED","RESTORE_QUERY_MAX_TIME_AGO","exports","RxQueryBase","op","mangoQuery","collection","other","id","_execOverDatabaseCount","_creationTime","now","_lastEnsureEqual","uncached","refCount$","BehaviorSubject","_result","_latestChangeEvent","_lastExecStart","_lastExecEnd","_limitBufferSize","_limitBufferResults","_persistentQueryCacheResult","undefined","_persistentQueryCacheResultLwt","_ensureEqualQueue","PROMISE_RESOLVE_FALSE","_getDefaultQuery","isFindOneByIdQuery","schema","primaryPath","_proto","prototype","_setResultData","newResultData","RxQuerySingleResult","Map","Array","from","values","docsDataMap","docsMap","docs","map","docData","_docCache","getCachedRxDocument","docsData","doc","set","primary","_data","length","_execOverDatabase","preparedQuery","getPreparedQuery","result","storageInstance","count","mode","database","allowSlowCount","newRxError","queryObj","ids","ensureNotFalsy","selector","$in","ret","mustBeQueried","forEach","getLatestDocumentDataIfExists","_deleted","push","findDocumentsById","docsPromise","queryCollection","then","exec","throwIfMissing","name","query","_ensureEqual","firstValueFrom","$","toString","stringObj","sortObject","value","JSON","stringify","persistentQueryId","String","hashFunction","hookInput","rxQuery","normalizeMangoQuery","jsonSchema","$eq","index","unshift","limit","runPluginHooks","prepareQuery","doesDocumentDataMatch","queryMatcher","remove","isArray","Promise","all","incrementalRemove","runQueryUpdateFunction","asRxQuery","update","_updateObj","pluginMissing","patch","incrementalPatch","modify","mutationFunction","incrementalModify","where","_queryObj","sort","_params","skip","_amount","enableLimitBuffer","bufferSize","console","error","enablePersistentQueryCache","backend","_persistentQueryCacheBackend","_persistentQueryCacheLoaded","_restoreQueryCacheFromPersistedState","getItem","log","persistedQueryCacheIds","Set","limitBufferIds","startsWith","add","replace","time","lwt","Number","documents","changedDocs","getChangedDocumentsSince","Math","floor","changedDocIds","d","docIdsWeNeedToFetch","filter","has","otherPotentialMatchingDocs","_queryCollectionByIds","concat","normalizedMangoQuery","sortComparator","getSortComparator","Infinity","lastValidIndex","findLastIndex","slice","unchangedItemsMayNowBeInResults","size","pastLimitItems","finalResults","_changeEventBuffer","counter","timeEnd","_createClass2","default","key","get","_$","results$","pipe","changeEvent","isLocal","startWith","mergeMap","shareReplay","RXJS_SHARE_REPLAY_DEFAULTS","distinctUntilChanged","prev","curr","useResult","merge","reactivity","getReactivityFactory","fromObservable","normalizedQuery","overwriteGetterForCaching","getQueryMatcher","tunnelQueryCache","getByQuery","createRxQuery","triggerCacheReplacement","_isResultsInSync","currentLatestEventNumber","getCounter","destroyed","__ensureEqual","mustReExec","missedChangeEvents","getFrom","runChangeEvents","reduceByLastOfDoc","_loop","cE","find","documentId","previousCount","newCount","didMatchBefore","previousDocumentData","doesMatchNow","documentData","eventReduceResult","calculateNewResults","runFullQueryAgain","changed","newResults","areRxDocumentArraysEqual","returnValue","updatePersistentQueryCache","docsKeys","idsToPersist","RX_META_LWT_MINIMUM","setItem","docResults","docIds","docId","Object","mutateableQuery","queryPlan","getQueryPlan","docsFromStorage","appendToArray","fromStorageList","queryResult","splice","keys","r","isRxQuery","obj"],"sources":["../../src/rx-query.ts"],"sourcesContent":["import {\n BehaviorSubject,\n firstValueFrom,\n Observable,\n merge\n} from 'rxjs';\nimport {\n mergeMap,\n filter,\n map,\n startWith,\n distinctUntilChanged,\n shareReplay\n} from 'rxjs/operators';\nimport {\n appendToArray,\n areRxDocumentArraysEqual,\n now,\n overwriteGetterForCaching,\n pluginMissing,\n PROMISE_RESOLVE_FALSE, RX_META_LWT_MINIMUM,\n RXJS_SHARE_REPLAY_DEFAULTS,\n sortObject\n} from './plugins/utils/index.ts';\nimport {\n newRxError\n} from './rx-error.ts';\nimport {\n runPluginHooks\n} from './hooks.ts';\nimport type {\n MangoQuery,\n PreparedQuery,\n QueryMatcher,\n RxChangeEvent,\n RxCollection,\n RxDocument,\n RxDocumentData,\n RxJsonSchema,\n FilledMangoQuery,\n ModifyFunction,\n RxDocumentWriteData,\n RxQuery,\n RxQueryOP, MangoQuerySelector, MangoQuerySortPart\n} from './types/index.d.ts';\nimport { calculateNewResults } from './event-reduce.ts';\nimport { triggerCacheReplacement } from './query-cache.ts';\nimport {\n getQueryMatcher,\n getSortComparator,\n normalizeMangoQuery,\n runQueryUpdateFunction\n\n} from './rx-query-helper.ts';\nimport { RxQuerySingleResult } from './rx-query-single-result.ts';\nimport { getQueryPlan } from './query-planner.ts';\nimport { ensureNotFalsy } from 'event-reduce-js';\nimport { getChangedDocumentsSince } from './rx-storage-helper.ts';\n\n\nexport interface QueryCacheBackend {\n getItem(key: string): Promise;\n setItem(key: string, value: T): Promise;\n}\n\nlet _queryCount = 0;\nconst newQueryID = function (): number {\n return ++_queryCount;\n};\n\n// allow changes to be 100ms older than the actual lwt value\nconst RESTORE_QUERY_UPDATE_DRIFT = 100;\n\n// 5000 seems like a sane number where re-executing the query will be easier than trying to restore\nconst RESTORE_QUERY_MAX_DOCS_CHANGED = 5000;\n\n// If a query was persisted more than a week ago, just re-execute it\nexport const RESTORE_QUERY_MAX_TIME_AGO = 7 * 24 * 60 * 60 * 1000;\n\nexport class RxQueryBase<\n RxDocType,\n RxQueryResult,\n OrmMethods = {},\n Reactivity = unknown,\n> {\n\n public id: number = newQueryID();\n\n /**\n * Some stats then are used for debugging and cache replacement policies\n */\n public _execOverDatabaseCount: number = 0;\n public _creationTime = now();\n\n // used in the query-cache to determine if the RxQuery can be cleaned up.\n public _lastEnsureEqual = 0;\n\n public uncached = false;\n\n // used to count the subscribers to the query\n public refCount$ = new BehaviorSubject(null);\n\n public isFindOneByIdQuery: false | string | string[];\n\n\n /**\n * Contains the current result state\n * or null if query has not run yet.\n */\n public _result: RxQuerySingleResult | null = null;\n\n\n constructor(\n public op: RxQueryOP,\n public mangoQuery: Readonly>,\n public collection: RxCollection,\n // used by some plugins\n public other: any = {}\n ) {\n if (!mangoQuery) {\n this.mangoQuery = _getDefaultQuery();\n }\n\n this.isFindOneByIdQuery = isFindOneByIdQuery(\n this.collection.schema.primaryPath as string,\n mangoQuery\n );\n }\n get $(): BehaviorSubject {\n if (!this._$) {\n\n const results$ = this.collection.$.pipe(\n /**\n * Performance shortcut.\n * Changes to local documents are not relevant for the query.\n */\n filter(changeEvent => !changeEvent.isLocal),\n /**\n * Start once to ensure the querying also starts\n * when there where no changes.\n */\n startWith(null),\n // ensure query results are up to date.\n mergeMap(() => _ensureEqual(this as any)),\n // use the current result set, written by _ensureEqual().\n map(() => this._result),\n // do not run stuff above for each new subscriber, only once.\n shareReplay(RXJS_SHARE_REPLAY_DEFAULTS),\n // do not proceed if result set has not changed.\n distinctUntilChanged((prev, curr) => {\n if (prev && prev.time === ensureNotFalsy(curr).time) {\n return true;\n } else {\n return false;\n }\n }),\n filter(result => !!result),\n /**\n * Map the result set to a single RxDocument or an array,\n * depending on query type\n */\n map((result) => {\n const useResult = ensureNotFalsy(result);\n if (this.op === 'count') {\n return useResult.count;\n } else if (this.op === 'findOne') {\n // findOne()-queries emit RxDocument or null\n return useResult.documents.length === 0 ? null : useResult.documents[0];\n } else if (this.op === 'findByIds') {\n return useResult.docsMap;\n } else {\n // find()-queries emit RxDocument[]\n // Flat copy the array so it won't matter if the user modifies it.\n return useResult.documents.slice(0);\n }\n })\n );\n\n this._$ = merge(\n results$,\n /**\n * Also add the refCount$ to the query observable\n * to allow us to count the amount of subscribers.\n */\n this.refCount$.pipe(\n filter(() => false)\n )\n );\n }\n return this._$ as any;\n }\n\n get $$(): Reactivity {\n const reactivity = this.collection.database.getReactivityFactory();\n return reactivity.fromObservable(\n this.$,\n undefined,\n this.collection.database\n ) as any;\n }\n\n // stores the changeEvent-number of the last handled change-event\n public _latestChangeEvent: -1 | number = -1;\n\n // time stamps on when the last full exec over the database has run\n // used to properly handle events that happen while the find-query is running\n public _lastExecStart: number = 0;\n public _lastExecEnd: number = 0;\n\n // Fields used for the Limit Buffer when enabled:\n public _limitBufferSize: number | null = null;\n public _limitBufferResults: RxDocumentData[] | null = null;\n\n // Fields used for the persistent query cache when enabled:\n public _persistentQueryCacheResult?: string[] | string = undefined;\n public _persistentQueryCacheResultLwt?: string = undefined; // lwt = latest write time\n public _persistentQueryCacheLoaded?: Promise;\n public _persistentQueryCacheBackend?: QueryCacheBackend;\n\n /**\n * ensures that the exec-runs\n * are not run in parallel\n */\n public _ensureEqualQueue: Promise = PROMISE_RESOLVE_FALSE;\n\n /**\n * Returns an observable that emits the results\n * This should behave like an rxjs-BehaviorSubject which means:\n * - Emit the current result-set on subscribe\n * - Emit the new result-set when an RxChangeEvent comes in\n * - Do not emit anything before the first result-set was created (no null)\n */\n public _$?: Observable;\n\n /**\n * set the new result-data as result-docs of the query\n * @param newResultData json-docs that were received from the storage\n */\n _setResultData(newResultData: RxDocumentData[] | number | Map>): void {\n if (typeof newResultData === 'number') {\n this._result = new RxQuerySingleResult(\n this.collection,\n [],\n newResultData\n );\n return;\n } else if (newResultData instanceof Map) {\n newResultData = Array.from((newResultData as Map>).values());\n }\n\n const docsDataMap = new Map();\n const docsMap = new Map();\n\n\n const docs = newResultData.map(docData => this.collection._docCache.getCachedRxDocument(docData));\n\n /**\n * Instead of using the newResultData in the result cache,\n * we directly use the objects that are stored in the RxDocument\n * to ensure we do not store the same data twice and fill up the memory.\n */\n const docsData = docs.map(doc => {\n docsDataMap.set(doc.primary, doc._data);\n docsMap.set(doc.primary, doc);\n return doc._data;\n });\n\n this._result = new RxQuerySingleResult(this.collection, docsData, docsData.length);\n }\n\n /**\n * executes the query on the database\n * @return results-array with document-data\n */\n async _execOverDatabase(): Promise[] | number> {\n this._execOverDatabaseCount = this._execOverDatabaseCount + 1;\n this._lastExecStart = now();\n\n\n if (this.op === 'count') {\n const preparedQuery = this.getPreparedQuery();\n const result = await this.collection.storageInstance.count(preparedQuery);\n if (result.mode === 'slow' && !this.collection.database.allowSlowCount) {\n throw newRxError('QU14', {\n collection: this.collection,\n queryObj: this.mangoQuery\n });\n } else {\n return result.count;\n }\n }\n\n if (this.op === 'findByIds') {\n const ids: string[] = ensureNotFalsy(this.mangoQuery.selector as any)[this.collection.schema.primaryPath].$in;\n const ret = new Map>();\n const mustBeQueried: string[] = [];\n // first try to fill from docCache\n ids.forEach(id => {\n const docData = this.collection._docCache.getLatestDocumentDataIfExists(id);\n if (docData) {\n if (!docData._deleted) {\n const doc = this.collection._docCache.getCachedRxDocument(docData);\n ret.set(id, doc);\n }\n } else {\n mustBeQueried.push(id);\n }\n });\n // everything which was not in docCache must be fetched from the storage\n if (mustBeQueried.length > 0) {\n const docs = await this.collection.storageInstance.findDocumentsById(mustBeQueried, false);\n docs.forEach(docData => {\n const doc = this.collection._docCache.getCachedRxDocument(docData);\n ret.set(doc.primary, doc);\n });\n }\n return ret as any;\n }\n\n\n const docsPromise = queryCollection(this as any);\n return docsPromise.then(docs => {\n this._lastExecEnd = now();\n return docs;\n });\n }\n\n /**\n * Execute the query\n * To have an easier implementations,\n * just subscribe and use the first result\n */\n public exec(throwIfMissing: true): Promise>;\n public exec(): Promise;\n public exec(throwIfMissing?: boolean): Promise {\n if (throwIfMissing && this.op !== 'findOne') {\n throw newRxError('QU9', {\n collection: this.collection.name,\n query: this.mangoQuery,\n op: this.op\n });\n }\n\n\n /**\n * run _ensureEqual() here,\n * this will make sure that errors in the query which throw inside of the RxStorage,\n * will be thrown at this execution context and not in the background.\n */\n return _ensureEqual(this as any)\n .then(() => firstValueFrom(this.$))\n .then(result => {\n if (!result && throwIfMissing) {\n throw newRxError('QU10', {\n collection: this.collection.name,\n query: this.mangoQuery,\n op: this.op\n });\n } else {\n return result;\n }\n });\n }\n\n\n\n /**\n * cached call to get the queryMatcher\n * @overwrites itself with the actual value\n */\n get queryMatcher(): QueryMatcher> {\n const schema = this.collection.schema.jsonSchema;\n const normalizedQuery = normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n );\n return overwriteGetterForCaching(\n this,\n 'queryMatcher',\n getQueryMatcher(\n schema,\n normalizedQuery\n ) as any\n );\n }\n\n /**\n * returns a string that is used for equal-comparisons\n * @overwrites itself with the actual value\n */\n toString(): string {\n const stringObj = sortObject({\n op: this.op,\n query: this.mangoQuery,\n other: this.other\n }, true);\n const value = JSON.stringify(stringObj);\n this.toString = () => value;\n return value;\n }\n\n persistentQueryId() {\n return String(this.collection.database.hashFunction(this.toString()));\n }\n\n /**\n * returns the prepared query\n * which can be send to the storage instance to query for documents.\n * @overwrites itself with the actual value.\n */\n getPreparedQuery(): PreparedQuery {\n const hookInput = {\n rxQuery: this,\n // can be mutated by the hooks so we have to deep clone first.\n mangoQuery: normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n )\n };\n\n (hookInput.mangoQuery.selector as any)._deleted = { $eq: false };\n if (hookInput.mangoQuery.index) {\n hookInput.mangoQuery.index.unshift('_deleted');\n }\n\n if (this._limitBufferSize !== null && hookInput.mangoQuery.limit) {\n hookInput.mangoQuery.limit = hookInput.mangoQuery.limit + this._limitBufferSize;\n }\n\n runPluginHooks('prePrepareQuery', hookInput);\n\n const value = prepareQuery(\n this.collection.schema.jsonSchema,\n hookInput.mangoQuery as any\n );\n\n this.getPreparedQuery = () => value;\n return value;\n }\n\n /**\n * returns true if the document matches the query,\n * does not use the 'skip' and 'limit'\n */\n doesDocumentDataMatch(docData: RxDocType | any): boolean {\n // if doc is deleted, it cannot match\n if (docData._deleted) {\n return false;\n }\n\n return this.queryMatcher(docData);\n }\n\n /**\n * deletes all found documents\n * @return promise with deleted documents\n */\n remove(): Promise {\n return this\n .exec()\n .then(docs => {\n if (Array.isArray(docs)) {\n // TODO use a bulk operation instead of running .remove() on each document\n return Promise.all(docs.map(doc => doc.remove()));\n } else {\n return (docs as any).remove();\n }\n });\n }\n incrementalRemove(): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalRemove(),\n );\n }\n\n\n /**\n * helper function to transform RxQueryBase to RxQuery type\n */\n get asRxQuery(): RxQuery {\n return this as any;\n }\n\n /**\n * updates all found documents\n * @overwritten by plugin (optional)\n */\n update(_updateObj: any): Promise {\n throw pluginMissing('update');\n }\n\n patch(patch: Partial): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.patch(patch),\n );\n }\n incrementalPatch(patch: Partial): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalPatch(patch),\n );\n }\n modify(mutationFunction: ModifyFunction): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.modify(mutationFunction),\n );\n }\n incrementalModify(mutationFunction: ModifyFunction): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalModify(mutationFunction),\n );\n }\n\n\n // we only set some methods of query-builder here\n // because the others depend on these ones\n where(_queryObj: MangoQuerySelector | keyof RxDocType | string): RxQuery {\n throw pluginMissing('query-builder');\n }\n sort(_params: string | MangoQuerySortPart): RxQuery {\n throw pluginMissing('query-builder');\n }\n skip(_amount: number | null): RxQuery {\n throw pluginMissing('query-builder');\n }\n limit(_amount: number | null): RxQuery {\n throw pluginMissing('query-builder');\n }\n\n enableLimitBuffer(bufferSize: number) {\n if (this._limitBufferSize !== null) {\n // Limit buffer has already been enabled, do nothing:\n return this;\n }\n if (this._lastExecStart !== 0) {\n console.error('Can\\'t use limit buffer if query has already executed');\n return this;\n }\n if (this.mangoQuery.skip || !this.mangoQuery.limit) {\n console.error('Right now, limit buffer only works on non-skip, limit queries.');\n return this;\n }\n this._limitBufferSize = bufferSize;\n return this;\n }\n\n enablePersistentQueryCache(backend: QueryCacheBackend) {\n if (this._persistentQueryCacheBackend) {\n // We've already tried to enable the query cache\n return this;\n }\n this._persistentQueryCacheBackend = backend;\n this._persistentQueryCacheLoaded = this._restoreQueryCacheFromPersistedState();\n return this;\n }\n\n private async _restoreQueryCacheFromPersistedState() {\n if (!this._persistentQueryCacheBackend) {\n // no cache backend provided, do nothing\n return;\n }\n if (this._persistentQueryCacheResult) {\n // we already restored the cache once, no need to run twice\n return;\n }\n if (this.mangoQuery.skip || this.op === 'count') {\n console.error('The persistent query cache only works on non-skip, non-count queries.');\n return;\n }\n\n // First, check if there are any query results persisted:\n const persistentQueryId = this.persistentQueryId();\n const value = await this._persistentQueryCacheBackend.getItem(`qc:${persistentQueryId}`);\n if (!value || !Array.isArray(value) || value.length === 0) {\n // eslint-disable-next-line no-console\n console.log(`no persistent query cache found in the backend, returning early ${this.toString()}`);\n return;\n }\n\n // If there are persisted ids, create our two Sets of ids from the cache:\n const persistedQueryCacheIds = new Set();\n const limitBufferIds = new Set();\n\n for (const id of value) {\n if (id.startsWith('lb-')) {\n limitBufferIds.add(id.replace('lb-', ''));\n } else {\n persistedQueryCacheIds.add(id);\n }\n }\n\n // eslint-disable-next-line no-console\n console.time(`Restoring persistent querycache ${this.toString()}`);\n\n // Next, pull the lwt from the cache:\n // TODO: if lwt is too old, should we just give up here? What if there are too many changedDocs?\n const lwt = (await this._persistentQueryCacheBackend.getItem(`qc:${persistentQueryId}:lwt`)) as string | null;\n if (!lwt) {\n return;\n }\n\n // If the query was persisted too long ago, just re-execute it.\n if (now() - Number(lwt) > RESTORE_QUERY_MAX_TIME_AGO) {\n return;\n }\n\n const primaryPath = this.collection.schema.primaryPath;\n\n const {documents: changedDocs} = await getChangedDocumentsSince(this.collection.storageInstance,\n RESTORE_QUERY_MAX_DOCS_CHANGED,\n // make sure we remove the monotonic clock (xxx.01, xxx.02) from the lwt timestamp to avoid issues with\n // lookups in indices (dexie)\n {id: '', lwt: Math.floor(Number(lwt)) - RESTORE_QUERY_UPDATE_DRIFT}\n );\n\n // If too many docs have changed, just give up and re-execute the query\n if (changedDocs.length === RESTORE_QUERY_MAX_DOCS_CHANGED) {\n return;\n }\n\n const changedDocIds = new Set(changedDocs.map((d) => d[primaryPath] as string));\n\n const docIdsWeNeedToFetch = [...persistedQueryCacheIds, ...limitBufferIds].filter((id) => !changedDocIds.has(id));\n\n // We use _queryCollectionByIds to fetch the remaining docs we need efficiently, pulling\n // from query cache if we can (and the storageInstance by ids if we can't):\n const otherPotentialMatchingDocs: RxDocumentData[] = [];\n await _queryCollectionByIds(this as any, otherPotentialMatchingDocs, docIdsWeNeedToFetch);\n\n // Now that we have all potential documents, we just filter (in-memory) the ones that still match our query:\n let docsData: RxDocumentData[] = [];\n for (const doc of changedDocs.concat(otherPotentialMatchingDocs)) {\n if (this.doesDocumentDataMatch(doc)) {\n docsData.push(doc);\n }\n }\n\n // Sort the documents by the query's sort field:\n const normalizedMangoQuery = normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n );\n const sortComparator = getSortComparator(this.collection.schema.jsonSchema, normalizedMangoQuery);\n const limit = normalizedMangoQuery.limit ? normalizedMangoQuery.limit : Infinity;\n docsData = docsData.sort(sortComparator);\n\n // We know for sure that all persisted and limit buffer ids (and changed docs before them) are in the correct\n // result set. And we can't be sure about any past that point. So cut it off there:\n const lastValidIndex = docsData.findLastIndex((d) => limitBufferIds.has(d[primaryPath] as string) || persistedQueryCacheIds.has(d[primaryPath] as string));\n docsData = docsData.slice(0, lastValidIndex + 1);\n\n // Now this is the trickiest part.\n // If we somehow have fewer docs than the limit of our query\n // (and this wasn't the case because before persistence)\n // then there is no way for us to know the correct results, and we re-exec:\n const unchangedItemsMayNowBeInResults = (\n this.mangoQuery.limit &&\n docsData.length < this.mangoQuery.limit &&\n persistedQueryCacheIds.size >= this.mangoQuery.limit\n );\n if (unchangedItemsMayNowBeInResults) {\n return;\n }\n\n // Our finalResults are the actual results of this query, and pastLimitItems are any remaining matching\n // documents we have left over (past the limit).\n const pastLimitItems = docsData.slice(limit);\n const finalResults = docsData.slice(0, limit);\n\n // If there are still items past the first LIMIT items, try to restore the limit buffer with them:\n if (limitBufferIds.size && pastLimitItems.length > 0) {\n this._limitBufferResults = pastLimitItems;\n } else {\n this._limitBufferResults = [];\n }\n\n // Finally, set the query's results to what we've pulled from disk:\n this._lastEnsureEqual = now();\n this._latestChangeEvent = this.collection._changeEventBuffer.counter;\n this._setResultData(finalResults);\n\n // eslint-disable-next-line no-console\n console.timeEnd(`Restoring persistent querycache ${this.toString()}`);\n }\n}\n\nexport function _getDefaultQuery(): MangoQuery {\n return {\n selector: {}\n };\n}\n\n/**\n * run this query through the QueryCache\n */\nexport function tunnelQueryCache(\n rxQuery: RxQueryBase\n): RxQuery {\n return rxQuery.collection._queryCache.getByQuery(rxQuery as any);\n}\n\nexport function createRxQuery(\n op: RxQueryOP,\n queryObj: MangoQuery,\n collection: RxCollection,\n other?: any\n) {\n runPluginHooks('preCreateRxQuery', {\n op,\n queryObj,\n collection,\n other\n });\n\n let ret = new RxQueryBase(op, queryObj, collection, other);\n\n // ensure when created with same params, only one is created\n ret = tunnelQueryCache(ret);\n // TODO: clear persistent query cache as well\n triggerCacheReplacement(collection);\n\n return ret;\n}\n\n/**\n * Check if the current results-state is in sync with the database\n * which means that no write event happened since the last run.\n * @return false if not which means it should re-execute\n */\nfunction _isResultsInSync(rxQuery: RxQueryBase): boolean {\n const currentLatestEventNumber = rxQuery.asRxQuery.collection._changeEventBuffer.getCounter();\n if (rxQuery._latestChangeEvent >= currentLatestEventNumber) {\n return true;\n } else {\n return false;\n }\n}\n\n\n/**\n * wraps __ensureEqual()\n * to ensure it does not run in parallel\n * @return true if has changed, false if not\n */\nfunction _ensureEqual(rxQuery: RxQueryBase): Promise {\n // Optimisation shortcut\n if (\n rxQuery.collection.database.destroyed ||\n _isResultsInSync(rxQuery)\n ) {\n return PROMISE_RESOLVE_FALSE;\n }\n\n rxQuery._ensureEqualQueue = rxQuery._ensureEqualQueue\n .then(() => __ensureEqual(rxQuery));\n return rxQuery._ensureEqualQueue;\n}\n\n\n/**\n * ensures that the results of this query is equal to the results which a query over the database would give\n * @return true if results have changed\n */\nasync function __ensureEqual(rxQuery: RxQueryBase): Promise {\n await rxQuery._persistentQueryCacheLoaded;\n\n rxQuery._lastEnsureEqual = now();\n\n /**\n * Optimisation shortcuts\n */\n if (\n // db is closed\n rxQuery.collection.database.destroyed ||\n // nothing happened since last run\n _isResultsInSync(rxQuery)\n ) {\n return PROMISE_RESOLVE_FALSE;\n }\n\n let ret = false;\n let mustReExec = false; // if this becomes true, a whole execution over the database is made\n if (rxQuery._latestChangeEvent === -1) {\n // have not executed yet -> must run\n mustReExec = true;\n }\n\n /**\n * try to use EventReduce to calculate the new results\n */\n if (!mustReExec) {\n const missedChangeEvents = rxQuery.asRxQuery.collection._changeEventBuffer.getFrom(rxQuery._latestChangeEvent + 1);\n if (missedChangeEvents === null) {\n // changeEventBuffer is of bounds -> we must re-execute over the database\n mustReExec = true;\n } else {\n rxQuery._latestChangeEvent = rxQuery.asRxQuery.collection._changeEventBuffer.getCounter();\n\n const runChangeEvents: RxChangeEvent[] = rxQuery.asRxQuery.collection\n ._changeEventBuffer\n .reduceByLastOfDoc(missedChangeEvents);\n\n if (rxQuery._limitBufferResults !== null) {\n // Check if any item in our limit buffer was modified by a change event\n for (const cE of runChangeEvents) {\n if (rxQuery._limitBufferResults.find((doc) => doc[rxQuery.collection.schema.primaryPath] === cE.documentId)) {\n // If so, the limit buffer is potential invalid -- let's just blow it up\n // TODO: could we instead update the documents in the limit buffer?\n rxQuery._limitBufferResults = null;\n break;\n }\n }\n }\n\n if (rxQuery.op === 'count') {\n // 'count' query\n const previousCount = ensureNotFalsy(rxQuery._result).count;\n let newCount = previousCount;\n runChangeEvents.forEach(cE => {\n const didMatchBefore = cE.previousDocumentData && rxQuery.doesDocumentDataMatch(cE.previousDocumentData);\n const doesMatchNow = rxQuery.doesDocumentDataMatch(cE.documentData);\n\n if (!didMatchBefore && doesMatchNow) {\n newCount++;\n }\n if (didMatchBefore && !doesMatchNow) {\n newCount--;\n }\n });\n if (newCount !== previousCount) {\n ret = true; // true because results changed\n rxQuery._setResultData(newCount as any);\n }\n } else {\n // 'find' or 'findOne' query\n const eventReduceResult = calculateNewResults(\n rxQuery as any,\n runChangeEvents\n );\n if (eventReduceResult.runFullQueryAgain) {\n // could not calculate the new results, execute must be done\n mustReExec = true;\n } else if (eventReduceResult.changed) {\n // we got the new results, we do not have to re-execute, mustReExec stays false\n ret = true; // true because results changed\n rxQuery._setResultData(eventReduceResult.newResults as any);\n }\n }\n }\n }\n\n // oh no we have to re-execute the whole query over the database\n if (mustReExec) {\n return rxQuery._execOverDatabase()\n .then(newResultData => {\n\n /**\n * The RxStorage is defined to always first emit events and then return\n * on bulkWrite() calls. So here we have to use the counter AFTER the execOverDatabase()\n * has been run, not the one from before.\n */\n rxQuery._latestChangeEvent = rxQuery.collection._changeEventBuffer.getCounter();\n\n // A count query needs a different has-changed check.\n if (typeof newResultData === 'number') {\n if (\n !rxQuery._result ||\n newResultData !== rxQuery._result.count\n ) {\n ret = true;\n rxQuery._setResultData(newResultData as any);\n }\n return ret;\n }\n if (\n !rxQuery._result ||\n !areRxDocumentArraysEqual(\n rxQuery.collection.schema.primaryPath,\n newResultData,\n rxQuery._result.docsData\n )\n ) {\n ret = true; // true because results changed\n rxQuery._setResultData(newResultData as any);\n }\n return ret;\n })\n .then(async (returnValue) => {\n await updatePersistentQueryCache(rxQuery);\n return returnValue;\n });\n }\n\n return ret; // true if results have changed\n}\n\n\nasync function updatePersistentQueryCache(rxQuery: RxQueryBase) {\n if (!rxQuery._persistentQueryCacheBackend) {\n return;\n }\n\n const backend = rxQuery._persistentQueryCacheBackend;\n\n const key = rxQuery.persistentQueryId();\n\n // update _persistedQueryCacheResult\n rxQuery._persistentQueryCacheResult = rxQuery._result?.docsKeys ?? [];\n\n const idsToPersist = [...rxQuery._persistentQueryCacheResult];\n if (rxQuery._limitBufferResults) {\n rxQuery._limitBufferResults.forEach((d) => {\n idsToPersist.push(`lb-${d[rxQuery.collection.schema.primaryPath]}`);\n });\n }\n // eslint-disable-next-line no-console\n console.time(`Query persistence: persisting results of ${JSON.stringify(rxQuery.mangoQuery)}`);\n // persist query cache\n const lwt = rxQuery._result?.time ?? RX_META_LWT_MINIMUM;\n\n await Promise.all([\n backend.setItem(`qc:${String(key)}`, idsToPersist),\n backend.setItem(`qc:${String(key)}:lwt`, lwt.toString()),\n ]);\n\n // eslint-disable-next-line no-console\n console.timeEnd(`Query persistence: persisting results of ${JSON.stringify(rxQuery.mangoQuery)}`);\n}\n\n\n// Refactored out of `queryCollection`: modifies the docResults array to fill it with data\nasync function _queryCollectionByIds(rxQuery: RxQuery | RxQueryBase, docResults: RxDocumentData[], docIds: string[]) {\n const collection = rxQuery.collection;\n docIds = docIds.filter(docId => {\n // first try to fill from docCache\n const docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (docData) {\n if (!docData._deleted) {\n docResults.push(docData);\n }\n return false;\n } else {\n return true;\n }\n });\n\n // otherwise get from storage\n if (docIds.length > 0) {\n const docsMap = await collection.storageInstance.findDocumentsById(docIds, false);\n Object.values(docsMap).forEach(docData => {\n docResults.push(docData);\n });\n }\n}\n\n/**\n * @returns a format of the query that can be used with the storage\n * when calling RxStorageInstance().query()\n */\nexport function prepareQuery(\n schema: RxJsonSchema>,\n mutateableQuery: FilledMangoQuery\n): PreparedQuery {\n if (!mutateableQuery.sort) {\n throw newRxError('SNH', {\n query: mutateableQuery\n });\n }\n\n /**\n * Store the query plan together with the\n * prepared query to save performance.\n */\n const queryPlan = getQueryPlan(\n schema,\n mutateableQuery\n );\n\n return {\n query: mutateableQuery,\n queryPlan\n };\n}\n\n/**\n * Runs the query over the storage instance\n * of the collection.\n * Does some optimizations to ensure findById is used\n * when specific queries are used.\n */\nexport async function queryCollection(\n rxQuery: RxQuery | RxQueryBase\n): Promise[]> {\n await rxQuery._persistentQueryCacheLoaded;\n\n let docs: RxDocumentData[] = [];\n const collection = rxQuery.collection;\n\n /**\n * Optimizations shortcut.\n * If query is find-one-document-by-id,\n * then we do not have to use the slow query() method\n * but instead can use findDocumentsById()\n */\n if (rxQuery.isFindOneByIdQuery) {\n if (Array.isArray(rxQuery.isFindOneByIdQuery)) {\n let docIds = rxQuery.isFindOneByIdQuery;\n docIds = docIds.filter(docId => {\n // first try to fill from docCache\n const docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (docData) {\n if (!docData._deleted) {\n docs.push(docData);\n }\n return false;\n } else {\n return true;\n }\n });\n // otherwise get from storage\n if (docIds.length > 0) {\n const docsFromStorage = await collection.storageInstance.findDocumentsById(docIds, false);\n appendToArray(docs, docsFromStorage);\n }\n await _queryCollectionByIds(rxQuery, docs, rxQuery.isFindOneByIdQuery);\n } else {\n const docId = rxQuery.isFindOneByIdQuery;\n\n // first try to fill from docCache\n let docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (!docData) {\n // otherwise get from storage\n const fromStorageList = await collection.storageInstance.findDocumentsById([docId], false);\n if (fromStorageList[0]) {\n docData = fromStorageList[0];\n }\n }\n if (docData && !docData._deleted) {\n docs.push(docData);\n }\n }\n } else {\n const preparedQuery = rxQuery.getPreparedQuery();\n const queryResult = await collection.storageInstance.query(preparedQuery);\n if (rxQuery._limitBufferSize !== null && rxQuery.mangoQuery.limit && queryResult.documents.length > rxQuery.mangoQuery.limit) {\n // If there are more than query.limit results, we pull out our buffer items from the\n // last rxQuery._limitBufferSize items of the results.\n rxQuery._limitBufferResults = queryResult.documents.splice(rxQuery.mangoQuery.limit);\n }\n docs = queryResult.documents;\n }\n return docs;\n}\n\n/**\n * Returns true if the given query\n * selects exactly one document by its id.\n * Used to optimize performance because these kind of\n * queries do not have to run over an index and can use get-by-id instead.\n * Returns false if no query of that kind.\n * Returns the document id otherwise.\n */\nexport function isFindOneByIdQuery(\n primaryPath: string,\n query: MangoQuery\n): false | string | string[] {\n // must have exactly one operator which must be $eq || $in\n if (\n !query.skip &&\n query.selector &&\n Object.keys(query.selector).length === 1 &&\n query.selector[primaryPath]\n ) {\n const value: any = query.selector[primaryPath];\n if (typeof value === 'string') {\n return value;\n } else if (\n Object.keys(value).length === 1 &&\n typeof value.$eq === 'string'\n ) {\n return value.$eq;\n }\n\n // same with $in string arrays\n if (\n Object.keys(value).length === 1 &&\n Array.isArray(value.$eq) &&\n // must only contain strings\n !(value.$eq as any[]).find(r => typeof r !== 'string')\n ) {\n return value.$eq;\n }\n }\n return false;\n}\n\n\nexport function isRxQuery(obj: any): boolean {\n return obj instanceof RxQueryBase;\n}\n"],"mappings":"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","ignoreList":[]} \ No newline at end of file +{"version":3,"file":"rx-query.js","names":["_rxjs","require","_operators","_index","_rxError","_hooks","_eventReduce","_queryCache","_rxQueryHelper","_rxQuerySingleResult","_queryPlanner","_eventReduceJs","_rxStorageHelper","_queryCount","newQueryID","RESTORE_QUERY_UPDATE_DRIFT","RESTORE_QUERY_MAX_DOCS_CHANGED","RESTORE_QUERY_MAX_TIME_AGO","exports","RxQueryBase","op","mangoQuery","collection","other","id","_execOverDatabaseCount","_creationTime","now","_lastEnsureEqual","uncached","refCount$","BehaviorSubject","_result","_latestChangeEvent","_lastExecStart","_lastExecEnd","_limitBufferSize","_limitBufferResults","_persistentQueryCacheResult","undefined","_persistentQueryCacheResultLwt","_ensureEqualQueue","PROMISE_RESOLVE_FALSE","_getDefaultQuery","isFindOneByIdQuery","schema","primaryPath","_proto","prototype","_setResultData","newResultData","RxQuerySingleResult","Map","Array","from","values","docsDataMap","docsMap","docs","map","docData","_docCache","getCachedRxDocument","docsData","doc","set","primary","_data","length","_execOverDatabase","preparedQuery","getPreparedQuery","result","storageInstance","count","mode","database","allowSlowCount","newRxError","queryObj","ids","ensureNotFalsy","selector","$in","ret","mustBeQueried","forEach","getLatestDocumentDataIfExists","_deleted","push","findDocumentsById","docsPromise","queryCollection","then","exec","throwIfMissing","name","query","_ensureEqual","firstValueFrom","$","toString","stringObj","sortObject","value","JSON","stringify","persistentQueryId","String","hashFunction","hookInput","rxQuery","normalizeMangoQuery","jsonSchema","includesDeleted","$eq","index","unshift","limit","runPluginHooks","prepareQuery","doesDocumentDataMatch","queryMatcher","remove","isArray","Promise","all","incrementalRemove","runQueryUpdateFunction","asRxQuery","update","_updateObj","pluginMissing","patch","incrementalPatch","modify","mutationFunction","incrementalModify","where","_queryObj","sort","_params","skip","_amount","enableLimitBuffer","bufferSize","console","error","enablePersistentQueryCache","backend","_persistentQueryCacheBackend","_persistentQueryCacheLoaded","_restoreQueryCacheFromPersistedState","getItem","log","persistedQueryCacheIds","Set","limitBufferIds","startsWith","add","replace","time","lwt","Number","documents","changedDocs","getChangedDocumentsSince","Math","floor","changedDocIds","d","docIdsWeNeedToFetch","filter","has","otherPotentialMatchingDocs","_queryCollectionByIds","concat","normalizedMangoQuery","sortComparator","getSortComparator","Infinity","lastValidIndex","findLastIndex","slice","unchangedItemsMayNowBeInResults","size","pastLimitItems","finalResults","_changeEventBuffer","counter","timeEnd","_createClass2","default","key","get","_$","results$","pipe","changeEvent","isLocal","startWith","mergeMap","shareReplay","RXJS_SHARE_REPLAY_DEFAULTS","distinctUntilChanged","prev","curr","useResult","merge","reactivity","getReactivityFactory","fromObservable","selectorIncludesDeleted","normalizedQuery","overwriteGetterForCaching","getQueryMatcher","tunnelQueryCache","getByQuery","createRxQuery","triggerCacheReplacement","_isResultsInSync","currentLatestEventNumber","getCounter","destroyed","__ensureEqual","mustReExec","missedChangeEvents","getFrom","runChangeEvents","reduceByLastOfDoc","_loop","cE","find","documentId","previousCount","newCount","didMatchBefore","previousDocumentData","doesMatchNow","documentData","eventReduceResult","calculateNewResults","runFullQueryAgain","changed","newResults","areRxDocumentArraysEqual","returnValue","updatePersistentQueryCache","docsKeys","idsToPersist","RX_META_LWT_MINIMUM","setItem","docResults","docIds","docId","Object","mutateableQuery","queryPlan","getQueryPlan","docsFromStorage","appendToArray","fromStorageList","queryResult","splice","keys","r","isRxQuery","obj"],"sources":["../../src/rx-query.ts"],"sourcesContent":["import {\n BehaviorSubject,\n firstValueFrom,\n Observable,\n merge\n} from 'rxjs';\nimport {\n mergeMap,\n filter,\n map,\n startWith,\n distinctUntilChanged,\n shareReplay\n} from 'rxjs/operators';\nimport {\n appendToArray,\n areRxDocumentArraysEqual,\n now,\n overwriteGetterForCaching,\n pluginMissing,\n PROMISE_RESOLVE_FALSE, RX_META_LWT_MINIMUM,\n RXJS_SHARE_REPLAY_DEFAULTS,\n sortObject\n} from './plugins/utils/index.ts';\nimport {\n newRxError\n} from './rx-error.ts';\nimport {\n runPluginHooks\n} from './hooks.ts';\nimport type {\n MangoQuery,\n PreparedQuery,\n QueryMatcher,\n RxChangeEvent,\n RxCollection,\n RxDocument,\n RxDocumentData,\n RxJsonSchema,\n FilledMangoQuery,\n ModifyFunction,\n RxDocumentWriteData,\n RxQuery,\n RxQueryOP, MangoQuerySelector, MangoQuerySortPart\n} from './types/index.d.ts';\nimport { calculateNewResults } from './event-reduce.ts';\nimport { triggerCacheReplacement } from './query-cache.ts';\nimport {\n getQueryMatcher,\n getSortComparator,\n normalizeMangoQuery,\n runQueryUpdateFunction,\n selectorIncludesDeleted\n\n} from './rx-query-helper.ts';\nimport { RxQuerySingleResult } from './rx-query-single-result.ts';\nimport { getQueryPlan } from './query-planner.ts';\nimport { ensureNotFalsy } from 'event-reduce-js';\nimport { getChangedDocumentsSince } from './rx-storage-helper.ts';\n\n\nexport interface QueryCacheBackend {\n getItem(key: string): Promise;\n setItem(key: string, value: T): Promise;\n}\n\nlet _queryCount = 0;\nconst newQueryID = function (): number {\n return ++_queryCount;\n};\n\n// allow changes to be 100ms older than the actual lwt value\nconst RESTORE_QUERY_UPDATE_DRIFT = 100;\n\n// 5000 seems like a sane number where re-executing the query will be easier than trying to restore\nconst RESTORE_QUERY_MAX_DOCS_CHANGED = 5000;\n\n// If a query was persisted more than a week ago, just re-execute it\nexport const RESTORE_QUERY_MAX_TIME_AGO = 7 * 24 * 60 * 60 * 1000;\n\nexport class RxQueryBase<\n RxDocType,\n RxQueryResult,\n OrmMethods = {},\n Reactivity = unknown,\n> {\n\n public id: number = newQueryID();\n\n /**\n * Some stats then are used for debugging and cache replacement policies\n */\n public _execOverDatabaseCount: number = 0;\n public _creationTime = now();\n\n // used in the query-cache to determine if the RxQuery can be cleaned up.\n public _lastEnsureEqual = 0;\n\n public uncached = false;\n\n // used to count the subscribers to the query\n public refCount$ = new BehaviorSubject(null);\n\n public isFindOneByIdQuery: false | string | string[];\n\n\n /**\n * Contains the current result state\n * or null if query has not run yet.\n */\n public _result: RxQuerySingleResult | null = null;\n\n\n constructor(\n public op: RxQueryOP,\n public mangoQuery: Readonly>,\n public collection: RxCollection,\n // used by some plugins\n public other: any = {}\n ) {\n if (!mangoQuery) {\n this.mangoQuery = _getDefaultQuery();\n }\n\n this.isFindOneByIdQuery = isFindOneByIdQuery(\n this.collection.schema.primaryPath as string,\n mangoQuery\n );\n }\n get $(): BehaviorSubject {\n if (!this._$) {\n\n const results$ = this.collection.$.pipe(\n /**\n * Performance shortcut.\n * Changes to local documents are not relevant for the query.\n */\n filter(changeEvent => !changeEvent.isLocal),\n /**\n * Start once to ensure the querying also starts\n * when there where no changes.\n */\n startWith(null),\n // ensure query results are up to date.\n mergeMap(() => _ensureEqual(this as any)),\n // use the current result set, written by _ensureEqual().\n map(() => this._result),\n // do not run stuff above for each new subscriber, only once.\n shareReplay(RXJS_SHARE_REPLAY_DEFAULTS),\n // do not proceed if result set has not changed.\n distinctUntilChanged((prev, curr) => {\n if (prev && prev.time === ensureNotFalsy(curr).time) {\n return true;\n } else {\n return false;\n }\n }),\n filter(result => !!result),\n /**\n * Map the result set to a single RxDocument or an array,\n * depending on query type\n */\n map((result) => {\n const useResult = ensureNotFalsy(result);\n if (this.op === 'count') {\n return useResult.count;\n } else if (this.op === 'findOne') {\n // findOne()-queries emit RxDocument or null\n return useResult.documents.length === 0 ? null : useResult.documents[0];\n } else if (this.op === 'findByIds') {\n return useResult.docsMap;\n } else {\n // find()-queries emit RxDocument[]\n // Flat copy the array so it won't matter if the user modifies it.\n return useResult.documents.slice(0);\n }\n })\n );\n\n this._$ = merge(\n results$,\n /**\n * Also add the refCount$ to the query observable\n * to allow us to count the amount of subscribers.\n */\n this.refCount$.pipe(\n filter(() => false)\n )\n );\n }\n return this._$ as any;\n }\n\n get $$(): Reactivity {\n const reactivity = this.collection.database.getReactivityFactory();\n return reactivity.fromObservable(\n this.$,\n undefined,\n this.collection.database\n ) as any;\n }\n\n get includesDeleted(): boolean {\n return selectorIncludesDeleted(this.mangoQuery.selector);\n }\n\n // stores the changeEvent-number of the last handled change-event\n public _latestChangeEvent: -1 | number = -1;\n\n // time stamps on when the last full exec over the database has run\n // used to properly handle events that happen while the find-query is running\n public _lastExecStart: number = 0;\n public _lastExecEnd: number = 0;\n\n // Fields used for the Limit Buffer when enabled:\n public _limitBufferSize: number | null = null;\n public _limitBufferResults: RxDocumentData[] | null = null;\n\n // Fields used for the persistent query cache when enabled:\n public _persistentQueryCacheResult?: string[] | string = undefined;\n public _persistentQueryCacheResultLwt?: string = undefined; // lwt = latest write time\n public _persistentQueryCacheLoaded?: Promise;\n public _persistentQueryCacheBackend?: QueryCacheBackend;\n\n /**\n * ensures that the exec-runs\n * are not run in parallel\n */\n public _ensureEqualQueue: Promise = PROMISE_RESOLVE_FALSE;\n\n /**\n * Returns an observable that emits the results\n * This should behave like an rxjs-BehaviorSubject which means:\n * - Emit the current result-set on subscribe\n * - Emit the new result-set when an RxChangeEvent comes in\n * - Do not emit anything before the first result-set was created (no null)\n */\n public _$?: Observable;\n\n /**\n * set the new result-data as result-docs of the query\n * @param newResultData json-docs that were received from the storage\n */\n _setResultData(newResultData: RxDocumentData[] | number | Map>): void {\n if (typeof newResultData === 'number') {\n this._result = new RxQuerySingleResult(\n this.collection,\n [],\n newResultData\n );\n return;\n } else if (newResultData instanceof Map) {\n newResultData = Array.from((newResultData as Map>).values());\n }\n\n const docsDataMap = new Map();\n const docsMap = new Map();\n\n\n const docs = newResultData.map(docData => this.collection._docCache.getCachedRxDocument(docData));\n\n /**\n * Instead of using the newResultData in the result cache,\n * we directly use the objects that are stored in the RxDocument\n * to ensure we do not store the same data twice and fill up the memory.\n */\n const docsData = docs.map(doc => {\n docsDataMap.set(doc.primary, doc._data);\n docsMap.set(doc.primary, doc);\n return doc._data;\n });\n\n this._result = new RxQuerySingleResult(this.collection, docsData, docsData.length);\n }\n\n /**\n * executes the query on the database\n * @return results-array with document-data\n */\n async _execOverDatabase(): Promise[] | number> {\n this._execOverDatabaseCount = this._execOverDatabaseCount + 1;\n this._lastExecStart = now();\n\n\n if (this.op === 'count') {\n const preparedQuery = this.getPreparedQuery();\n const result = await this.collection.storageInstance.count(preparedQuery);\n if (result.mode === 'slow' && !this.collection.database.allowSlowCount) {\n throw newRxError('QU14', {\n collection: this.collection,\n queryObj: this.mangoQuery\n });\n } else {\n return result.count;\n }\n }\n\n if (this.op === 'findByIds') {\n const ids: string[] = ensureNotFalsy(this.mangoQuery.selector as any)[this.collection.schema.primaryPath].$in;\n const ret = new Map>();\n const mustBeQueried: string[] = [];\n // first try to fill from docCache\n ids.forEach(id => {\n const docData = this.collection._docCache.getLatestDocumentDataIfExists(id);\n if (docData) {\n if (!docData._deleted) {\n const doc = this.collection._docCache.getCachedRxDocument(docData);\n ret.set(id, doc);\n }\n } else {\n mustBeQueried.push(id);\n }\n });\n // everything which was not in docCache must be fetched from the storage\n if (mustBeQueried.length > 0) {\n const docs = await this.collection.storageInstance.findDocumentsById(mustBeQueried, false);\n docs.forEach(docData => {\n const doc = this.collection._docCache.getCachedRxDocument(docData);\n ret.set(doc.primary, doc);\n });\n }\n return ret as any;\n }\n\n\n const docsPromise = queryCollection(this as any);\n return docsPromise.then(docs => {\n this._lastExecEnd = now();\n return docs;\n });\n }\n\n /**\n * Execute the query\n * To have an easier implementations,\n * just subscribe and use the first result\n */\n public exec(throwIfMissing: true): Promise>;\n public exec(): Promise;\n public exec(throwIfMissing?: boolean): Promise {\n if (throwIfMissing && this.op !== 'findOne') {\n throw newRxError('QU9', {\n collection: this.collection.name,\n query: this.mangoQuery,\n op: this.op\n });\n }\n\n\n /**\n * run _ensureEqual() here,\n * this will make sure that errors in the query which throw inside of the RxStorage,\n * will be thrown at this execution context and not in the background.\n */\n return _ensureEqual(this as any)\n .then(() => firstValueFrom(this.$))\n .then(result => {\n if (!result && throwIfMissing) {\n throw newRxError('QU10', {\n collection: this.collection.name,\n query: this.mangoQuery,\n op: this.op\n });\n } else {\n return result;\n }\n });\n }\n\n\n\n /**\n * cached call to get the queryMatcher\n * @overwrites itself with the actual value\n */\n get queryMatcher(): QueryMatcher> {\n const schema = this.collection.schema.jsonSchema;\n const normalizedQuery = normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n );\n return overwriteGetterForCaching(\n this,\n 'queryMatcher',\n getQueryMatcher(\n schema,\n normalizedQuery\n ) as any\n );\n }\n\n /**\n * returns a string that is used for equal-comparisons\n * @overwrites itself with the actual value\n */\n toString(): string {\n const stringObj = sortObject({\n op: this.op,\n query: this.mangoQuery,\n other: this.other\n }, true);\n const value = JSON.stringify(stringObj);\n this.toString = () => value;\n return value;\n }\n\n persistentQueryId() {\n return String(this.collection.database.hashFunction(this.toString()));\n }\n\n /**\n * returns the prepared query\n * which can be send to the storage instance to query for documents.\n * @overwrites itself with the actual value.\n */\n getPreparedQuery(): PreparedQuery {\n const hookInput = {\n rxQuery: this,\n // can be mutated by the hooks so we have to deep clone first.\n mangoQuery: normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n )\n };\n\n // Set _deleted to false if not explicitly set in selector\n if (!this.includesDeleted) {\n hookInput.mangoQuery.selector = {\n ...hookInput.mangoQuery.selector,\n _deleted: { $eq: false },\n };\n }\n\n if (hookInput.mangoQuery.index) {\n hookInput.mangoQuery.index.unshift('_deleted');\n }\n\n if (this._limitBufferSize !== null && hookInput.mangoQuery.limit) {\n hookInput.mangoQuery.limit = hookInput.mangoQuery.limit + this._limitBufferSize;\n }\n\n runPluginHooks('prePrepareQuery', hookInput);\n\n const value = prepareQuery(\n this.collection.schema.jsonSchema,\n hookInput.mangoQuery as any\n );\n\n this.getPreparedQuery = () => value;\n return value;\n }\n\n /**\n * returns true if the document matches the query,\n * does not use the 'skip' and 'limit'\n */\n doesDocumentDataMatch(docData: RxDocType | any): boolean {\n // if doc is deleted, it cannot match\n if (docData._deleted) {\n return false;\n }\n\n return this.queryMatcher(docData);\n }\n\n /**\n * deletes all found documents\n * @return promise with deleted documents\n */\n remove(): Promise {\n return this\n .exec()\n .then(docs => {\n if (Array.isArray(docs)) {\n // TODO use a bulk operation instead of running .remove() on each document\n return Promise.all(docs.map(doc => doc.remove()));\n } else {\n return (docs as any).remove();\n }\n });\n }\n incrementalRemove(): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalRemove(),\n );\n }\n\n\n /**\n * helper function to transform RxQueryBase to RxQuery type\n */\n get asRxQuery(): RxQuery {\n return this as any;\n }\n\n /**\n * updates all found documents\n * @overwritten by plugin (optional)\n */\n update(_updateObj: any): Promise {\n throw pluginMissing('update');\n }\n\n patch(patch: Partial): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.patch(patch),\n );\n }\n incrementalPatch(patch: Partial): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalPatch(patch),\n );\n }\n modify(mutationFunction: ModifyFunction): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.modify(mutationFunction),\n );\n }\n incrementalModify(mutationFunction: ModifyFunction): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalModify(mutationFunction),\n );\n }\n\n\n // we only set some methods of query-builder here\n // because the others depend on these ones\n where(_queryObj: MangoQuerySelector | keyof RxDocType | string): RxQuery {\n throw pluginMissing('query-builder');\n }\n sort(_params: string | MangoQuerySortPart): RxQuery {\n throw pluginMissing('query-builder');\n }\n skip(_amount: number | null): RxQuery {\n throw pluginMissing('query-builder');\n }\n limit(_amount: number | null): RxQuery {\n throw pluginMissing('query-builder');\n }\n\n enableLimitBuffer(bufferSize: number) {\n if (this._limitBufferSize !== null) {\n // Limit buffer has already been enabled, do nothing:\n return this;\n }\n if (this._lastExecStart !== 0) {\n console.error('Can\\'t use limit buffer if query has already executed');\n return this;\n }\n if (this.mangoQuery.skip || !this.mangoQuery.limit) {\n console.error('Right now, limit buffer only works on non-skip, limit queries.');\n return this;\n }\n this._limitBufferSize = bufferSize;\n return this;\n }\n\n enablePersistentQueryCache(backend: QueryCacheBackend) {\n if (this._persistentQueryCacheBackend) {\n // We've already tried to enable the query cache\n return this;\n }\n this._persistentQueryCacheBackend = backend;\n this._persistentQueryCacheLoaded = this._restoreQueryCacheFromPersistedState();\n return this;\n }\n\n private async _restoreQueryCacheFromPersistedState() {\n if (!this._persistentQueryCacheBackend) {\n // no cache backend provided, do nothing\n return;\n }\n if (this._persistentQueryCacheResult) {\n // we already restored the cache once, no need to run twice\n return;\n }\n if (this.mangoQuery.skip || this.op === 'count') {\n console.error('The persistent query cache only works on non-skip, non-count queries.');\n return;\n }\n\n // First, check if there are any query results persisted:\n const persistentQueryId = this.persistentQueryId();\n const value = await this._persistentQueryCacheBackend.getItem(`qc:${persistentQueryId}`);\n if (!value || !Array.isArray(value) || value.length === 0) {\n // eslint-disable-next-line no-console\n console.log(`no persistent query cache found in the backend, returning early ${this.toString()}`);\n return;\n }\n\n // If there are persisted ids, create our two Sets of ids from the cache:\n const persistedQueryCacheIds = new Set();\n const limitBufferIds = new Set();\n\n for (const id of value) {\n if (id.startsWith('lb-')) {\n limitBufferIds.add(id.replace('lb-', ''));\n } else {\n persistedQueryCacheIds.add(id);\n }\n }\n\n // eslint-disable-next-line no-console\n console.time(`Restoring persistent querycache ${this.toString()}`);\n\n // Next, pull the lwt from the cache:\n // TODO: if lwt is too old, should we just give up here? What if there are too many changedDocs?\n const lwt = (await this._persistentQueryCacheBackend.getItem(`qc:${persistentQueryId}:lwt`)) as string | null;\n if (!lwt) {\n return;\n }\n\n // If the query was persisted too long ago, just re-execute it.\n if (now() - Number(lwt) > RESTORE_QUERY_MAX_TIME_AGO) {\n return;\n }\n\n const primaryPath = this.collection.schema.primaryPath;\n\n const {documents: changedDocs} = await getChangedDocumentsSince(this.collection.storageInstance,\n RESTORE_QUERY_MAX_DOCS_CHANGED,\n // make sure we remove the monotonic clock (xxx.01, xxx.02) from the lwt timestamp to avoid issues with\n // lookups in indices (dexie)\n {id: '', lwt: Math.floor(Number(lwt)) - RESTORE_QUERY_UPDATE_DRIFT}\n );\n\n // If too many docs have changed, just give up and re-execute the query\n if (changedDocs.length === RESTORE_QUERY_MAX_DOCS_CHANGED) {\n return;\n }\n\n const changedDocIds = new Set(changedDocs.map((d) => d[primaryPath] as string));\n\n const docIdsWeNeedToFetch = [...persistedQueryCacheIds, ...limitBufferIds].filter((id) => !changedDocIds.has(id));\n\n // We use _queryCollectionByIds to fetch the remaining docs we need efficiently, pulling\n // from query cache if we can (and the storageInstance by ids if we can't):\n const otherPotentialMatchingDocs: RxDocumentData[] = [];\n await _queryCollectionByIds(this as any, otherPotentialMatchingDocs, docIdsWeNeedToFetch);\n\n // Now that we have all potential documents, we just filter (in-memory) the ones that still match our query:\n let docsData: RxDocumentData[] = [];\n for (const doc of changedDocs.concat(otherPotentialMatchingDocs)) {\n if (this.doesDocumentDataMatch(doc)) {\n docsData.push(doc);\n }\n }\n\n // Sort the documents by the query's sort field:\n const normalizedMangoQuery = normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n );\n const sortComparator = getSortComparator(this.collection.schema.jsonSchema, normalizedMangoQuery);\n const limit = normalizedMangoQuery.limit ? normalizedMangoQuery.limit : Infinity;\n docsData = docsData.sort(sortComparator);\n\n // We know for sure that all persisted and limit buffer ids (and changed docs before them) are in the correct\n // result set. And we can't be sure about any past that point. So cut it off there:\n const lastValidIndex = docsData.findLastIndex((d) => limitBufferIds.has(d[primaryPath] as string) || persistedQueryCacheIds.has(d[primaryPath] as string));\n docsData = docsData.slice(0, lastValidIndex + 1);\n\n // Now this is the trickiest part.\n // If we somehow have fewer docs than the limit of our query\n // (and this wasn't the case because before persistence)\n // then there is no way for us to know the correct results, and we re-exec:\n const unchangedItemsMayNowBeInResults = (\n this.mangoQuery.limit &&\n docsData.length < this.mangoQuery.limit &&\n persistedQueryCacheIds.size >= this.mangoQuery.limit\n );\n if (unchangedItemsMayNowBeInResults) {\n return;\n }\n\n // Our finalResults are the actual results of this query, and pastLimitItems are any remaining matching\n // documents we have left over (past the limit).\n const pastLimitItems = docsData.slice(limit);\n const finalResults = docsData.slice(0, limit);\n\n // If there are still items past the first LIMIT items, try to restore the limit buffer with them:\n if (limitBufferIds.size && pastLimitItems.length > 0) {\n this._limitBufferResults = pastLimitItems;\n } else {\n this._limitBufferResults = [];\n }\n\n // Finally, set the query's results to what we've pulled from disk:\n this._lastEnsureEqual = now();\n this._latestChangeEvent = this.collection._changeEventBuffer.counter;\n this._setResultData(finalResults);\n\n // eslint-disable-next-line no-console\n console.timeEnd(`Restoring persistent querycache ${this.toString()}`);\n }\n}\n\nexport function _getDefaultQuery(): MangoQuery {\n return {\n selector: {}\n };\n}\n\n/**\n * run this query through the QueryCache\n */\nexport function tunnelQueryCache(\n rxQuery: RxQueryBase\n): RxQuery {\n return rxQuery.collection._queryCache.getByQuery(rxQuery as any);\n}\n\nexport function createRxQuery(\n op: RxQueryOP,\n queryObj: MangoQuery,\n collection: RxCollection,\n other?: any\n) {\n runPluginHooks('preCreateRxQuery', {\n op,\n queryObj,\n collection,\n other\n });\n\n let ret = new RxQueryBase(op, queryObj, collection, other);\n\n // ensure when created with same params, only one is created\n ret = tunnelQueryCache(ret);\n // TODO: clear persistent query cache as well\n triggerCacheReplacement(collection);\n\n return ret;\n}\n\n/**\n * Check if the current results-state is in sync with the database\n * which means that no write event happened since the last run.\n * @return false if not which means it should re-execute\n */\nfunction _isResultsInSync(rxQuery: RxQueryBase): boolean {\n const currentLatestEventNumber = rxQuery.asRxQuery.collection._changeEventBuffer.getCounter();\n if (rxQuery._latestChangeEvent >= currentLatestEventNumber) {\n return true;\n } else {\n return false;\n }\n}\n\n\n/**\n * wraps __ensureEqual()\n * to ensure it does not run in parallel\n * @return true if has changed, false if not\n */\nfunction _ensureEqual(rxQuery: RxQueryBase): Promise {\n // Optimisation shortcut\n if (\n rxQuery.collection.database.destroyed ||\n _isResultsInSync(rxQuery)\n ) {\n return PROMISE_RESOLVE_FALSE;\n }\n\n rxQuery._ensureEqualQueue = rxQuery._ensureEqualQueue\n .then(() => __ensureEqual(rxQuery));\n return rxQuery._ensureEqualQueue;\n}\n\n\n/**\n * ensures that the results of this query is equal to the results which a query over the database would give\n * @return true if results have changed\n */\nasync function __ensureEqual(rxQuery: RxQueryBase): Promise {\n await rxQuery._persistentQueryCacheLoaded;\n\n rxQuery._lastEnsureEqual = now();\n\n /**\n * Optimisation shortcuts\n */\n if (\n // db is closed\n rxQuery.collection.database.destroyed ||\n // nothing happened since last run\n _isResultsInSync(rxQuery)\n ) {\n return PROMISE_RESOLVE_FALSE;\n }\n\n let ret = false;\n let mustReExec = false; // if this becomes true, a whole execution over the database is made\n if (rxQuery._latestChangeEvent === -1) {\n // have not executed yet -> must run\n mustReExec = true;\n }\n\n /**\n * try to use EventReduce to calculate the new results\n */\n if (!mustReExec) {\n const missedChangeEvents = rxQuery.asRxQuery.collection._changeEventBuffer.getFrom(rxQuery._latestChangeEvent + 1);\n if (missedChangeEvents === null) {\n // changeEventBuffer is of bounds -> we must re-execute over the database\n mustReExec = true;\n } else {\n rxQuery._latestChangeEvent = rxQuery.asRxQuery.collection._changeEventBuffer.getCounter();\n\n const runChangeEvents: RxChangeEvent[] = rxQuery.asRxQuery.collection\n ._changeEventBuffer\n .reduceByLastOfDoc(missedChangeEvents);\n\n if (rxQuery._limitBufferResults !== null) {\n // Check if any item in our limit buffer was modified by a change event\n for (const cE of runChangeEvents) {\n if (rxQuery._limitBufferResults.find((doc) => doc[rxQuery.collection.schema.primaryPath] === cE.documentId)) {\n // If so, the limit buffer is potential invalid -- let's just blow it up\n // TODO: could we instead update the documents in the limit buffer?\n rxQuery._limitBufferResults = null;\n break;\n }\n }\n }\n\n if (rxQuery.includesDeleted) {\n return rxQuery._execOverDatabase().then((newResultData) => {\n rxQuery._setResultData(newResultData);\n return true;\n });\n } else if (rxQuery.op === 'count') {\n // 'count' query\n const previousCount = ensureNotFalsy(rxQuery._result).count;\n let newCount = previousCount;\n runChangeEvents.forEach(cE => {\n const didMatchBefore = cE.previousDocumentData && rxQuery.doesDocumentDataMatch(cE.previousDocumentData);\n const doesMatchNow = rxQuery.doesDocumentDataMatch(cE.documentData);\n\n if (!didMatchBefore && doesMatchNow) {\n newCount++;\n }\n if (didMatchBefore && !doesMatchNow) {\n newCount--;\n }\n });\n if (newCount !== previousCount) {\n ret = true; // true because results changed\n rxQuery._setResultData(newCount as any);\n }\n } else {\n // 'find' or 'findOne' query\n const eventReduceResult = calculateNewResults(\n rxQuery as any,\n runChangeEvents\n );\n if (eventReduceResult.runFullQueryAgain) {\n // could not calculate the new results, execute must be done\n mustReExec = true;\n } else if (eventReduceResult.changed) {\n // we got the new results, we do not have to re-execute, mustReExec stays false\n ret = true; // true because results changed\n rxQuery._setResultData(eventReduceResult.newResults as any);\n }\n }\n }\n }\n\n // oh no we have to re-execute the whole query over the database\n if (mustReExec) {\n return rxQuery._execOverDatabase()\n .then(newResultData => {\n\n /**\n * The RxStorage is defined to always first emit events and then return\n * on bulkWrite() calls. So here we have to use the counter AFTER the execOverDatabase()\n * has been run, not the one from before.\n */\n rxQuery._latestChangeEvent = rxQuery.collection._changeEventBuffer.getCounter();\n\n // A count query needs a different has-changed check.\n if (typeof newResultData === 'number') {\n if (\n !rxQuery._result ||\n newResultData !== rxQuery._result.count\n ) {\n ret = true;\n rxQuery._setResultData(newResultData as any);\n }\n return ret;\n }\n if (\n !rxQuery._result ||\n !areRxDocumentArraysEqual(\n rxQuery.collection.schema.primaryPath,\n newResultData,\n rxQuery._result.docsData\n )\n ) {\n ret = true; // true because results changed\n rxQuery._setResultData(newResultData as any);\n }\n return ret;\n })\n .then(async (returnValue) => {\n await updatePersistentQueryCache(rxQuery);\n return returnValue;\n });\n }\n\n return ret; // true if results have changed\n}\n\n\nasync function updatePersistentQueryCache(rxQuery: RxQueryBase) {\n if (!rxQuery._persistentQueryCacheBackend) {\n return;\n }\n\n const backend = rxQuery._persistentQueryCacheBackend;\n\n const key = rxQuery.persistentQueryId();\n\n // update _persistedQueryCacheResult\n rxQuery._persistentQueryCacheResult = rxQuery._result?.docsKeys ?? [];\n\n const idsToPersist = [...rxQuery._persistentQueryCacheResult];\n if (rxQuery._limitBufferResults) {\n rxQuery._limitBufferResults.forEach((d) => {\n idsToPersist.push(`lb-${d[rxQuery.collection.schema.primaryPath]}`);\n });\n }\n // eslint-disable-next-line no-console\n console.time(`Query persistence: persisting results of ${JSON.stringify(rxQuery.mangoQuery)}`);\n // persist query cache\n const lwt = rxQuery._result?.time ?? RX_META_LWT_MINIMUM;\n\n await Promise.all([\n backend.setItem(`qc:${String(key)}`, idsToPersist),\n backend.setItem(`qc:${String(key)}:lwt`, lwt.toString()),\n ]);\n\n // eslint-disable-next-line no-console\n console.timeEnd(`Query persistence: persisting results of ${JSON.stringify(rxQuery.mangoQuery)}`);\n}\n\n\n// Refactored out of `queryCollection`: modifies the docResults array to fill it with data\nasync function _queryCollectionByIds(rxQuery: RxQuery | RxQueryBase, docResults: RxDocumentData[], docIds: string[]) {\n const collection = rxQuery.collection;\n docIds = docIds.filter(docId => {\n // first try to fill from docCache\n const docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (docData) {\n if (!docData._deleted) {\n docResults.push(docData);\n }\n return false;\n } else {\n return true;\n }\n });\n\n // otherwise get from storage\n if (docIds.length > 0) {\n const docsMap = await collection.storageInstance.findDocumentsById(docIds, false);\n Object.values(docsMap).forEach(docData => {\n docResults.push(docData);\n });\n }\n}\n\n/**\n * @returns a format of the query that can be used with the storage\n * when calling RxStorageInstance().query()\n */\nexport function prepareQuery(\n schema: RxJsonSchema>,\n mutateableQuery: FilledMangoQuery\n): PreparedQuery {\n if (!mutateableQuery.sort) {\n throw newRxError('SNH', {\n query: mutateableQuery\n });\n }\n\n /**\n * Store the query plan together with the\n * prepared query to save performance.\n */\n const queryPlan = getQueryPlan(\n schema,\n mutateableQuery\n );\n\n return {\n query: mutateableQuery,\n queryPlan\n };\n}\n\n/**\n * Runs the query over the storage instance\n * of the collection.\n * Does some optimizations to ensure findById is used\n * when specific queries are used.\n */\nexport async function queryCollection(\n rxQuery: RxQuery | RxQueryBase\n): Promise[]> {\n await rxQuery._persistentQueryCacheLoaded;\n\n let docs: RxDocumentData[] = [];\n const collection = rxQuery.collection;\n\n /**\n * Optimizations shortcut.\n * If query is find-one-document-by-id,\n * then we do not have to use the slow query() method\n * but instead can use findDocumentsById()\n */\n if (rxQuery.isFindOneByIdQuery) {\n if (Array.isArray(rxQuery.isFindOneByIdQuery)) {\n let docIds = rxQuery.isFindOneByIdQuery;\n docIds = docIds.filter(docId => {\n // first try to fill from docCache\n const docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (docData) {\n if (!docData._deleted) {\n docs.push(docData);\n }\n return false;\n } else {\n return true;\n }\n });\n // otherwise get from storage\n if (docIds.length > 0) {\n const docsFromStorage = await collection.storageInstance.findDocumentsById(docIds, false);\n appendToArray(docs, docsFromStorage);\n }\n await _queryCollectionByIds(rxQuery, docs, rxQuery.isFindOneByIdQuery);\n } else {\n const docId = rxQuery.isFindOneByIdQuery;\n\n // first try to fill from docCache\n let docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (!docData) {\n // otherwise get from storage\n const fromStorageList = await collection.storageInstance.findDocumentsById([docId], false);\n if (fromStorageList[0]) {\n docData = fromStorageList[0];\n }\n }\n if (docData && !docData._deleted) {\n docs.push(docData);\n }\n }\n } else {\n const preparedQuery = rxQuery.getPreparedQuery();\n const queryResult = await collection.storageInstance.query(preparedQuery);\n if (rxQuery._limitBufferSize !== null && rxQuery.mangoQuery.limit && queryResult.documents.length > rxQuery.mangoQuery.limit) {\n // If there are more than query.limit results, we pull out our buffer items from the\n // last rxQuery._limitBufferSize items of the results.\n rxQuery._limitBufferResults = queryResult.documents.splice(rxQuery.mangoQuery.limit);\n }\n docs = queryResult.documents;\n }\n return docs;\n}\n\n/**\n * Returns true if the given query\n * selects exactly one document by its id.\n * Used to optimize performance because these kind of\n * queries do not have to run over an index and can use get-by-id instead.\n * Returns false if no query of that kind.\n * Returns the document id otherwise.\n */\nexport function isFindOneByIdQuery(\n primaryPath: string,\n query: MangoQuery\n): false | string | string[] {\n // must have exactly one operator which must be $eq || $in\n if (\n !query.skip &&\n query.selector &&\n Object.keys(query.selector).length === 1 &&\n query.selector[primaryPath]\n ) {\n const value: any = query.selector[primaryPath];\n if (typeof value === 'string') {\n return value;\n } else if (\n Object.keys(value).length === 1 &&\n typeof value.$eq === 'string'\n ) {\n return value.$eq;\n }\n\n // same with $in string arrays\n if (\n Object.keys(value).length === 1 &&\n Array.isArray(value.$eq) &&\n // must only contain strings\n !(value.$eq as any[]).find(r => typeof r !== 'string')\n ) {\n return value.$eq;\n }\n }\n return false;\n}\n\n\nexport function isRxQuery(obj: any): boolean {\n return obj instanceof RxQueryBase;\n}\n"],"mappings":"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","ignoreList":[]} \ No newline at end of file diff --git a/dist/esm/rx-query-helper.js b/dist/esm/rx-query-helper.js index 9eeb6694c7d..f425a65759b 100644 --- a/dist/esm/rx-query-helper.js +++ b/dist/esm/rx-query-helper.js @@ -203,4 +203,31 @@ export async function runQueryUpdateFunction(rxQuery, fn) { return result; } } + +/** + * Checks if a given selector includes deleted documents. + * @param selector The MangoQuerySelector to check + * @returns True if the selector includes deleted documents, false otherwise + */ +export function selectorIncludesDeleted(selector) { + if (!selector) { + return false; + } + var isTrue = value => value === true || typeof value === 'object' && value !== null && '$eq' in value && value.$eq === true; + var isNotFalse = value => value === true || typeof value === 'object' && value !== null && '$ne' in value && value.$ne === false; + var hasDeletedTrue = condition => '_deleted' in condition && (isTrue(condition._deleted) || isNotFalse(condition._deleted)); + if ('_deleted' in selector) { + return isTrue(selector._deleted) || isNotFalse(selector._deleted); + } + if ('$or' in selector && Array.isArray(selector.$or)) { + return selector.$or.some(hasDeletedTrue); + } + if ('$and' in selector && Array.isArray(selector.$and)) { + return selector.$and.some(hasDeletedTrue); + } + if ('$nor' in selector && Array.isArray(selector.$nor)) { + return !selector.$nor.every(condition => !hasDeletedTrue(condition)); + } + return false; +} //# sourceMappingURL=rx-query-helper.js.map \ No newline at end of file diff --git a/dist/esm/rx-query-helper.js.map b/dist/esm/rx-query-helper.js.map index 0f8ad98b22d..2ecc15e6756 100644 --- a/dist/esm/rx-query-helper.js.map +++ b/dist/esm/rx-query-helper.js.map @@ -1 +1 @@ -{"version":3,"file":"rx-query-helper.js","names":["LOGICAL_OPERATORS","getPrimaryFieldOfPrimaryKey","clone","firstPropertyNameOfObject","toArray","isMaybeReadonlyArray","flatClone","objectPathMonad","compare","mingoSortComparator","newRxError","getMingoQuery","normalizeMangoQuery","schema","mangoQuery","primaryKey","normalizedMangoQuery","skip","selector","Object","entries","forEach","field","matcher","$eq","index","indexAr","includes","push","sort","map","indexes","fieldsWithLogicalOperator","Set","hasLogical","keys","find","operator","has","add","currentFieldsAmount","currentBestIndexForSort","useIndex","firstWrongIndex","findIndex","indexField","isPrimaryInSort","p","slice","getSortComparator","query","sortParts","sortBlock","key","direction","values","getValueFn","fun","a","b","i","length","sortPart","valueA","valueB","ret","getQueryMatcher","_schema","mingoQuery","doc","test","runQueryUpdateFunction","rxQuery","fn","docs","exec","Array","isArray","Promise","all","result"],"sources":["../../src/rx-query-helper.ts"],"sourcesContent":["import { LOGICAL_OPERATORS } from './query-planner.ts';\nimport { getPrimaryFieldOfPrimaryKey } from './rx-schema-helper.ts';\nimport type {\n DeepReadonly,\n DeterministicSortComparator,\n FilledMangoQuery,\n MangoQuery,\n MangoQuerySortDirection,\n QueryMatcher,\n RxDocument,\n RxDocumentData,\n RxJsonSchema,\n RxQuery\n} from './types/index.d.ts';\nimport {\n clone,\n firstPropertyNameOfObject,\n toArray,\n isMaybeReadonlyArray,\n flatClone,\n objectPathMonad,\n ObjectPathMonadFunction\n} from './plugins/utils/index.ts';\nimport {\n compare as mingoSortComparator\n} from 'mingo/util';\nimport { newRxError } from './rx-error.ts';\nimport { getMingoQuery } from './rx-query-mingo.ts';\n\n/**\n * Normalize the query to ensure we have all fields set\n * and queries that represent the same query logic are detected as equal by the caching.\n */\nexport function normalizeMangoQuery(\n schema: RxJsonSchema>,\n mangoQuery: MangoQuery\n): FilledMangoQuery {\n const primaryKey: string = getPrimaryFieldOfPrimaryKey(schema.primaryKey);\n mangoQuery = flatClone(mangoQuery);\n\n const normalizedMangoQuery: FilledMangoQuery = clone(mangoQuery) as any;\n if (typeof normalizedMangoQuery.skip !== 'number') {\n normalizedMangoQuery.skip = 0;\n }\n\n if (!normalizedMangoQuery.selector) {\n normalizedMangoQuery.selector = {};\n } else {\n normalizedMangoQuery.selector = normalizedMangoQuery.selector;\n /**\n * In mango query, it is possible to have an\n * equals comparison by directly assigning a value\n * to a property, without the '$eq' operator.\n * Like:\n * selector: {\n * foo: 'bar'\n * }\n * For normalization, we have to normalize this\n * so our checks can perform properly.\n *\n *\n * TODO this must work recursive with nested queries that\n * contain multiple selectors via $and or $or etc.\n */\n Object\n .entries(normalizedMangoQuery.selector)\n .forEach(([field, matcher]) => {\n if (typeof matcher !== 'object' || matcher === null) {\n (normalizedMangoQuery as any).selector[field] = {\n $eq: matcher\n };\n }\n });\n }\n\n /**\n * Ensure that if an index is specified,\n * the primaryKey is inside of it.\n */\n if (normalizedMangoQuery.index) {\n const indexAr = toArray(normalizedMangoQuery.index);\n if (!indexAr.includes(primaryKey)) {\n indexAr.push(primaryKey);\n }\n normalizedMangoQuery.index = indexAr;\n }\n\n /**\n * To ensure a deterministic sorting,\n * we have to ensure the primary key is always part\n * of the sort query.\n * Primary sorting is added as last sort parameter,\n * similar to how we add the primary key to indexes that do not have it.\n *\n */\n if (!normalizedMangoQuery.sort) {\n /**\n * If no sort is given at all,\n * we can assume that the user does not care about sort order at al.\n *\n * we cannot just use the primary key as sort parameter\n * because it would likely cause the query to run over the primary key index\n * which has a bad performance in most cases.\n */\n if (normalizedMangoQuery.index) {\n normalizedMangoQuery.sort = normalizedMangoQuery.index.map((field: string) => {\n return { [field as any]: 'asc' } as any;\n });\n } else {\n /**\n * Find the index that best matches the fields with the logical operators\n */\n if (schema.indexes) {\n const fieldsWithLogicalOperator: Set = new Set();\n Object.entries(normalizedMangoQuery.selector).forEach(([field, matcher]) => {\n let hasLogical = false;\n if (typeof matcher === 'object' && matcher !== null) {\n hasLogical = !!Object.keys(matcher).find(operator => LOGICAL_OPERATORS.has(operator));\n } else {\n hasLogical = true;\n }\n if (hasLogical) {\n fieldsWithLogicalOperator.add(field);\n }\n });\n\n\n let currentFieldsAmount = -1;\n let currentBestIndexForSort: string[] | readonly string[] | undefined;\n schema.indexes.forEach(index => {\n const useIndex = isMaybeReadonlyArray(index) ? index : [index];\n const firstWrongIndex = useIndex.findIndex(indexField => !fieldsWithLogicalOperator.has(indexField));\n if (\n firstWrongIndex > 0 &&\n firstWrongIndex > currentFieldsAmount\n ) {\n currentFieldsAmount = firstWrongIndex;\n currentBestIndexForSort = useIndex;\n }\n });\n if (currentBestIndexForSort) {\n normalizedMangoQuery.sort = currentBestIndexForSort.map((field: string) => {\n return { [field as any]: 'asc' } as any;\n });\n }\n\n }\n\n /**\n * Fall back to the primary key as sort order\n * if no better one has been found\n */\n if (!normalizedMangoQuery.sort) {\n normalizedMangoQuery.sort = [{ [primaryKey]: 'asc' }] as any;\n }\n }\n } else {\n const isPrimaryInSort = normalizedMangoQuery.sort\n .find(p => firstPropertyNameOfObject(p) === primaryKey);\n if (!isPrimaryInSort) {\n normalizedMangoQuery.sort = normalizedMangoQuery.sort.slice(0);\n normalizedMangoQuery.sort.push({ [primaryKey]: 'asc' } as any);\n }\n }\n\n return normalizedMangoQuery;\n}\n\n/**\n * Returns the sort-comparator,\n * which is able to sort documents in the same way\n * a query over the db would do.\n */\nexport function getSortComparator(\n schema: RxJsonSchema>,\n query: FilledMangoQuery\n): DeterministicSortComparator {\n if (!query.sort) {\n throw newRxError('SNH', { query });\n }\n const sortParts: {\n key: string;\n direction: MangoQuerySortDirection;\n getValueFn: ObjectPathMonadFunction;\n }[] = [];\n query.sort.forEach(sortBlock => {\n const key = Object.keys(sortBlock)[0];\n const direction = Object.values(sortBlock)[0];\n sortParts.push({\n key,\n direction,\n getValueFn: objectPathMonad(key)\n });\n });\n const fun: DeterministicSortComparator = (a: RxDocType, b: RxDocType) => {\n for (let i = 0; i < sortParts.length; ++i) {\n const sortPart = sortParts[i];\n const valueA = sortPart.getValueFn(a);\n const valueB = sortPart.getValueFn(b);\n if (valueA !== valueB) {\n const ret = sortPart.direction === 'asc' ? mingoSortComparator(valueA, valueB) : mingoSortComparator(valueB, valueA);\n return ret as any;\n }\n }\n };\n\n return fun;\n}\n\n\n/**\n * Returns a function\n * that can be used to check if a document\n * matches the query.\n */\nexport function getQueryMatcher(\n _schema: RxJsonSchema | RxJsonSchema>,\n query: FilledMangoQuery\n): QueryMatcher> {\n if (!query.sort) {\n throw newRxError('SNH', { query });\n }\n\n const mingoQuery = getMingoQuery(query.selector as any);\n const fun: QueryMatcher> = (doc: RxDocumentData | DeepReadonly>) => {\n return mingoQuery.test(doc);\n };\n return fun;\n}\n\n\nexport async function runQueryUpdateFunction(\n rxQuery: RxQuery,\n fn: (doc: RxDocument) => Promise>\n): Promise {\n const docs = await rxQuery.exec();\n if (!docs) {\n // only findOne() queries can return null\n return null as any;\n }\n if (Array.isArray(docs)) {\n return Promise.all(\n docs.map(doc => fn(doc))\n ) as any;\n } else {\n // via findOne()\n const result = await fn(docs as any);\n return result as any;\n }\n}\n"],"mappings":"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","ignoreList":[]} \ No newline at end of file +{"version":3,"file":"rx-query-helper.js","names":["LOGICAL_OPERATORS","getPrimaryFieldOfPrimaryKey","clone","firstPropertyNameOfObject","toArray","isMaybeReadonlyArray","flatClone","objectPathMonad","compare","mingoSortComparator","newRxError","getMingoQuery","normalizeMangoQuery","schema","mangoQuery","primaryKey","normalizedMangoQuery","skip","selector","Object","entries","forEach","field","matcher","$eq","index","indexAr","includes","push","sort","map","indexes","fieldsWithLogicalOperator","Set","hasLogical","keys","find","operator","has","add","currentFieldsAmount","currentBestIndexForSort","useIndex","firstWrongIndex","findIndex","indexField","isPrimaryInSort","p","slice","getSortComparator","query","sortParts","sortBlock","key","direction","values","getValueFn","fun","a","b","i","length","sortPart","valueA","valueB","ret","getQueryMatcher","_schema","mingoQuery","doc","test","runQueryUpdateFunction","rxQuery","fn","docs","exec","Array","isArray","Promise","all","result","selectorIncludesDeleted","isTrue","value","isNotFalse","$ne","hasDeletedTrue","condition","_deleted","$or","some","$and","$nor","every"],"sources":["../../src/rx-query-helper.ts"],"sourcesContent":["import { LOGICAL_OPERATORS } from './query-planner.ts';\nimport { getPrimaryFieldOfPrimaryKey } from './rx-schema-helper.ts';\nimport type {\n DeepReadonly,\n DeterministicSortComparator,\n FilledMangoQuery,\n MangoQuery,\n MangoQueryOperators,\n MangoQuerySelector,\n MangoQuerySortDirection,\n PropertyType,\n QueryMatcher,\n RxDocument,\n RxDocumentData,\n RxJsonSchema,\n RxQuery\n} from './types/index.d.ts';\nimport {\n clone,\n firstPropertyNameOfObject,\n toArray,\n isMaybeReadonlyArray,\n flatClone,\n objectPathMonad,\n ObjectPathMonadFunction\n} from './plugins/utils/index.ts';\nimport {\n compare as mingoSortComparator\n} from 'mingo/util';\nimport { newRxError } from './rx-error.ts';\nimport { getMingoQuery } from './rx-query-mingo.ts';\n\n/**\n * Normalize the query to ensure we have all fields set\n * and queries that represent the same query logic are detected as equal by the caching.\n */\nexport function normalizeMangoQuery(\n schema: RxJsonSchema>,\n mangoQuery: MangoQuery\n): FilledMangoQuery {\n const primaryKey: string = getPrimaryFieldOfPrimaryKey(schema.primaryKey);\n mangoQuery = flatClone(mangoQuery);\n\n const normalizedMangoQuery: FilledMangoQuery = clone(mangoQuery) as any;\n if (typeof normalizedMangoQuery.skip !== 'number') {\n normalizedMangoQuery.skip = 0;\n }\n\n if (!normalizedMangoQuery.selector) {\n normalizedMangoQuery.selector = {};\n } else {\n normalizedMangoQuery.selector = normalizedMangoQuery.selector;\n /**\n * In mango query, it is possible to have an\n * equals comparison by directly assigning a value\n * to a property, without the '$eq' operator.\n * Like:\n * selector: {\n * foo: 'bar'\n * }\n * For normalization, we have to normalize this\n * so our checks can perform properly.\n *\n *\n * TODO this must work recursive with nested queries that\n * contain multiple selectors via $and or $or etc.\n */\n Object\n .entries(normalizedMangoQuery.selector)\n .forEach(([field, matcher]) => {\n if (typeof matcher !== 'object' || matcher === null) {\n (normalizedMangoQuery as any).selector[field] = {\n $eq: matcher\n };\n }\n });\n }\n\n /**\n * Ensure that if an index is specified,\n * the primaryKey is inside of it.\n */\n if (normalizedMangoQuery.index) {\n const indexAr = toArray(normalizedMangoQuery.index);\n if (!indexAr.includes(primaryKey)) {\n indexAr.push(primaryKey);\n }\n normalizedMangoQuery.index = indexAr;\n }\n\n /**\n * To ensure a deterministic sorting,\n * we have to ensure the primary key is always part\n * of the sort query.\n * Primary sorting is added as last sort parameter,\n * similar to how we add the primary key to indexes that do not have it.\n *\n */\n if (!normalizedMangoQuery.sort) {\n /**\n * If no sort is given at all,\n * we can assume that the user does not care about sort order at al.\n *\n * we cannot just use the primary key as sort parameter\n * because it would likely cause the query to run over the primary key index\n * which has a bad performance in most cases.\n */\n if (normalizedMangoQuery.index) {\n normalizedMangoQuery.sort = normalizedMangoQuery.index.map((field: string) => {\n return { [field as any]: 'asc' } as any;\n });\n } else {\n /**\n * Find the index that best matches the fields with the logical operators\n */\n if (schema.indexes) {\n const fieldsWithLogicalOperator: Set = new Set();\n Object.entries(normalizedMangoQuery.selector).forEach(([field, matcher]) => {\n let hasLogical = false;\n if (typeof matcher === 'object' && matcher !== null) {\n hasLogical = !!Object.keys(matcher).find(operator => LOGICAL_OPERATORS.has(operator));\n } else {\n hasLogical = true;\n }\n if (hasLogical) {\n fieldsWithLogicalOperator.add(field);\n }\n });\n\n\n let currentFieldsAmount = -1;\n let currentBestIndexForSort: string[] | readonly string[] | undefined;\n schema.indexes.forEach(index => {\n const useIndex = isMaybeReadonlyArray(index) ? index : [index];\n const firstWrongIndex = useIndex.findIndex(indexField => !fieldsWithLogicalOperator.has(indexField));\n if (\n firstWrongIndex > 0 &&\n firstWrongIndex > currentFieldsAmount\n ) {\n currentFieldsAmount = firstWrongIndex;\n currentBestIndexForSort = useIndex;\n }\n });\n if (currentBestIndexForSort) {\n normalizedMangoQuery.sort = currentBestIndexForSort.map((field: string) => {\n return { [field as any]: 'asc' } as any;\n });\n }\n\n }\n\n /**\n * Fall back to the primary key as sort order\n * if no better one has been found\n */\n if (!normalizedMangoQuery.sort) {\n normalizedMangoQuery.sort = [{ [primaryKey]: 'asc' }] as any;\n }\n }\n } else {\n const isPrimaryInSort = normalizedMangoQuery.sort\n .find(p => firstPropertyNameOfObject(p) === primaryKey);\n if (!isPrimaryInSort) {\n normalizedMangoQuery.sort = normalizedMangoQuery.sort.slice(0);\n normalizedMangoQuery.sort.push({ [primaryKey]: 'asc' } as any);\n }\n }\n\n return normalizedMangoQuery;\n}\n\n/**\n * Returns the sort-comparator,\n * which is able to sort documents in the same way\n * a query over the db would do.\n */\nexport function getSortComparator(\n schema: RxJsonSchema>,\n query: FilledMangoQuery\n): DeterministicSortComparator {\n if (!query.sort) {\n throw newRxError('SNH', { query });\n }\n const sortParts: {\n key: string;\n direction: MangoQuerySortDirection;\n getValueFn: ObjectPathMonadFunction;\n }[] = [];\n query.sort.forEach(sortBlock => {\n const key = Object.keys(sortBlock)[0];\n const direction = Object.values(sortBlock)[0];\n sortParts.push({\n key,\n direction,\n getValueFn: objectPathMonad(key)\n });\n });\n const fun: DeterministicSortComparator = (a: RxDocType, b: RxDocType) => {\n for (let i = 0; i < sortParts.length; ++i) {\n const sortPart = sortParts[i];\n const valueA = sortPart.getValueFn(a);\n const valueB = sortPart.getValueFn(b);\n if (valueA !== valueB) {\n const ret = sortPart.direction === 'asc' ? mingoSortComparator(valueA, valueB) : mingoSortComparator(valueB, valueA);\n return ret as any;\n }\n }\n };\n\n return fun;\n}\n\n\n/**\n * Returns a function\n * that can be used to check if a document\n * matches the query.\n */\nexport function getQueryMatcher(\n _schema: RxJsonSchema | RxJsonSchema>,\n query: FilledMangoQuery\n): QueryMatcher> {\n if (!query.sort) {\n throw newRxError('SNH', { query });\n }\n\n const mingoQuery = getMingoQuery(query.selector as any);\n const fun: QueryMatcher> = (doc: RxDocumentData | DeepReadonly>) => {\n return mingoQuery.test(doc);\n };\n return fun;\n}\n\n\nexport async function runQueryUpdateFunction(\n rxQuery: RxQuery,\n fn: (doc: RxDocument) => Promise>\n): Promise {\n const docs = await rxQuery.exec();\n if (!docs) {\n // only findOne() queries can return null\n return null as any;\n }\n if (Array.isArray(docs)) {\n return Promise.all(\n docs.map(doc => fn(doc))\n ) as any;\n } else {\n // via findOne()\n const result = await fn(docs as any);\n return result as any;\n }\n}\n\n/**\n * Checks if a given selector includes deleted documents.\n * @param selector The MangoQuerySelector to check\n * @returns True if the selector includes deleted documents, false otherwise\n */\nexport function selectorIncludesDeleted(\n selector: MangoQuerySelector | undefined\n): boolean {\n if (!selector) {\n return false;\n }\n\n const isTrue = (value: unknown): boolean =>\n value === true ||\n (typeof value === 'object' &&\n value !== null &&\n '$eq' in value &&\n (value as MangoQueryOperators).$eq === true);\n\n\n const isNotFalse = (value: unknown): boolean =>\n value === true ||\n (typeof value === 'object' &&\n value !== null &&\n '$ne' in value &&\n (value as MangoQueryOperators).$ne === false);\n\n const hasDeletedTrue = (\n condition: MangoQuerySelector\n ): boolean =>\n '_deleted' in condition &&\n (isTrue(condition._deleted as PropertyType) ||\n isNotFalse(\n condition._deleted as PropertyType\n ));\n\n if ('_deleted' in selector) {\n return (\n isTrue(selector._deleted as PropertyType) ||\n isNotFalse(selector._deleted as PropertyType)\n );\n }\n\n if ('$or' in selector && Array.isArray(selector.$or)) {\n return selector.$or.some(hasDeletedTrue);\n }\n\n if ('$and' in selector && Array.isArray(selector.$and)) {\n return selector.$and.some(hasDeletedTrue);\n }\n\n if ('$nor' in selector && Array.isArray(selector.$nor)) {\n return !selector.$nor.every((condition) => !hasDeletedTrue(condition));\n }\n\n return false;\n}\n"],"mappings":"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","ignoreList":[]} \ No newline at end of file diff --git a/dist/esm/rx-query.js b/dist/esm/rx-query.js index e5c988d056a..eb00fa96ef9 100644 --- a/dist/esm/rx-query.js +++ b/dist/esm/rx-query.js @@ -6,7 +6,7 @@ import { newRxError } from "./rx-error.js"; import { runPluginHooks } from "./hooks.js"; import { calculateNewResults } from "./event-reduce.js"; import { triggerCacheReplacement } from "./query-cache.js"; -import { getQueryMatcher, getSortComparator, normalizeMangoQuery, runQueryUpdateFunction } from "./rx-query-helper.js"; +import { getQueryMatcher, getSortComparator, normalizeMangoQuery, runQueryUpdateFunction, selectorIncludesDeleted } from "./rx-query-helper.js"; import { RxQuerySingleResult } from "./rx-query-single-result.js"; import { getQueryPlan } from "./query-planner.js"; import { ensureNotFalsy } from 'event-reduce-js'; @@ -218,9 +218,16 @@ export var RxQueryBase = /*#__PURE__*/function () { // can be mutated by the hooks so we have to deep clone first. mangoQuery: normalizeMangoQuery(this.collection.schema.jsonSchema, this.mangoQuery) }; - hookInput.mangoQuery.selector._deleted = { - $eq: false - }; + + // Set _deleted to false if not explicitly set in selector + if (!this.includesDeleted) { + hookInput.mangoQuery.selector = { + ...hookInput.mangoQuery.selector, + _deleted: { + $eq: false + } + }; + } if (hookInput.mangoQuery.index) { hookInput.mangoQuery.index.unshift('_deleted'); } @@ -508,6 +515,11 @@ export var RxQueryBase = /*#__PURE__*/function () { var reactivity = this.collection.database.getReactivityFactory(); return reactivity.fromObservable(this.$, undefined, this.collection.database); } + }, { + key: "includesDeleted", + get: function () { + return selectorIncludesDeleted(this.mangoQuery.selector); + } // stores the changeEvent-number of the last handled change-event @@ -644,7 +656,12 @@ async function __ensureEqual(rxQuery) { if (await _loop(cE)) break; } } - if (rxQuery.op === 'count') { + if (rxQuery.includesDeleted) { + return rxQuery._execOverDatabase().then(newResultData => { + rxQuery._setResultData(newResultData); + return true; + }); + } else if (rxQuery.op === 'count') { // 'count' query var previousCount = ensureNotFalsy(rxQuery._result).count; var newCount = previousCount; diff --git a/dist/esm/rx-query.js.map b/dist/esm/rx-query.js.map index db4f510dafe..d7191439d67 100644 --- a/dist/esm/rx-query.js.map +++ b/dist/esm/rx-query.js.map @@ -1 +1 @@ -{"version":3,"file":"rx-query.js","names":["BehaviorSubject","firstValueFrom","merge","mergeMap","filter","map","startWith","distinctUntilChanged","shareReplay","appendToArray","areRxDocumentArraysEqual","now","overwriteGetterForCaching","pluginMissing","PROMISE_RESOLVE_FALSE","RX_META_LWT_MINIMUM","RXJS_SHARE_REPLAY_DEFAULTS","sortObject","newRxError","runPluginHooks","calculateNewResults","triggerCacheReplacement","getQueryMatcher","getSortComparator","normalizeMangoQuery","runQueryUpdateFunction","RxQuerySingleResult","getQueryPlan","ensureNotFalsy","getChangedDocumentsSince","_queryCount","newQueryID","RESTORE_QUERY_UPDATE_DRIFT","RESTORE_QUERY_MAX_DOCS_CHANGED","RESTORE_QUERY_MAX_TIME_AGO","RxQueryBase","op","mangoQuery","collection","other","id","_execOverDatabaseCount","_creationTime","_lastEnsureEqual","uncached","refCount$","_result","_latestChangeEvent","_lastExecStart","_lastExecEnd","_limitBufferSize","_limitBufferResults","_persistentQueryCacheResult","undefined","_persistentQueryCacheResultLwt","_ensureEqualQueue","_getDefaultQuery","isFindOneByIdQuery","schema","primaryPath","_proto","prototype","_setResultData","newResultData","Map","Array","from","values","docsDataMap","docsMap","docs","docData","_docCache","getCachedRxDocument","docsData","doc","set","primary","_data","length","_execOverDatabase","preparedQuery","getPreparedQuery","result","storageInstance","count","mode","database","allowSlowCount","queryObj","ids","selector","$in","ret","mustBeQueried","forEach","getLatestDocumentDataIfExists","_deleted","push","findDocumentsById","docsPromise","queryCollection","then","exec","throwIfMissing","name","query","_ensureEqual","$","toString","stringObj","value","JSON","stringify","persistentQueryId","String","hashFunction","hookInput","rxQuery","jsonSchema","$eq","index","unshift","limit","prepareQuery","doesDocumentDataMatch","queryMatcher","remove","isArray","Promise","all","incrementalRemove","asRxQuery","update","_updateObj","patch","incrementalPatch","modify","mutationFunction","incrementalModify","where","_queryObj","sort","_params","skip","_amount","enableLimitBuffer","bufferSize","console","error","enablePersistentQueryCache","backend","_persistentQueryCacheBackend","_persistentQueryCacheLoaded","_restoreQueryCacheFromPersistedState","getItem","log","persistedQueryCacheIds","Set","limitBufferIds","startsWith","add","replace","time","lwt","Number","documents","changedDocs","Math","floor","changedDocIds","d","docIdsWeNeedToFetch","has","otherPotentialMatchingDocs","_queryCollectionByIds","concat","normalizedMangoQuery","sortComparator","Infinity","lastValidIndex","findLastIndex","slice","unchangedItemsMayNowBeInResults","size","pastLimitItems","finalResults","_changeEventBuffer","counter","timeEnd","_createClass","key","get","_$","results$","pipe","changeEvent","isLocal","prev","curr","useResult","reactivity","getReactivityFactory","fromObservable","normalizedQuery","tunnelQueryCache","_queryCache","getByQuery","createRxQuery","_isResultsInSync","currentLatestEventNumber","getCounter","destroyed","__ensureEqual","mustReExec","missedChangeEvents","getFrom","runChangeEvents","reduceByLastOfDoc","_loop","cE","find","documentId","previousCount","newCount","didMatchBefore","previousDocumentData","doesMatchNow","documentData","eventReduceResult","runFullQueryAgain","changed","newResults","returnValue","updatePersistentQueryCache","docsKeys","idsToPersist","setItem","docResults","docIds","docId","Object","mutateableQuery","queryPlan","docsFromStorage","fromStorageList","queryResult","splice","keys","r","isRxQuery","obj"],"sources":["../../src/rx-query.ts"],"sourcesContent":["import {\n BehaviorSubject,\n firstValueFrom,\n Observable,\n merge\n} from 'rxjs';\nimport {\n mergeMap,\n filter,\n map,\n startWith,\n distinctUntilChanged,\n shareReplay\n} from 'rxjs/operators';\nimport {\n appendToArray,\n areRxDocumentArraysEqual,\n now,\n overwriteGetterForCaching,\n pluginMissing,\n PROMISE_RESOLVE_FALSE, RX_META_LWT_MINIMUM,\n RXJS_SHARE_REPLAY_DEFAULTS,\n sortObject\n} from './plugins/utils/index.ts';\nimport {\n newRxError\n} from './rx-error.ts';\nimport {\n runPluginHooks\n} from './hooks.ts';\nimport type {\n MangoQuery,\n PreparedQuery,\n QueryMatcher,\n RxChangeEvent,\n RxCollection,\n RxDocument,\n RxDocumentData,\n RxJsonSchema,\n FilledMangoQuery,\n ModifyFunction,\n RxDocumentWriteData,\n RxQuery,\n RxQueryOP, MangoQuerySelector, MangoQuerySortPart\n} from './types/index.d.ts';\nimport { calculateNewResults } from './event-reduce.ts';\nimport { triggerCacheReplacement } from './query-cache.ts';\nimport {\n getQueryMatcher,\n getSortComparator,\n normalizeMangoQuery,\n runQueryUpdateFunction\n\n} from './rx-query-helper.ts';\nimport { RxQuerySingleResult } from './rx-query-single-result.ts';\nimport { getQueryPlan } from './query-planner.ts';\nimport { ensureNotFalsy } from 'event-reduce-js';\nimport { getChangedDocumentsSince } from './rx-storage-helper.ts';\n\n\nexport interface QueryCacheBackend {\n getItem(key: string): Promise;\n setItem(key: string, value: T): Promise;\n}\n\nlet _queryCount = 0;\nconst newQueryID = function (): number {\n return ++_queryCount;\n};\n\n// allow changes to be 100ms older than the actual lwt value\nconst RESTORE_QUERY_UPDATE_DRIFT = 100;\n\n// 5000 seems like a sane number where re-executing the query will be easier than trying to restore\nconst RESTORE_QUERY_MAX_DOCS_CHANGED = 5000;\n\n// If a query was persisted more than a week ago, just re-execute it\nexport const RESTORE_QUERY_MAX_TIME_AGO = 7 * 24 * 60 * 60 * 1000;\n\nexport class RxQueryBase<\n RxDocType,\n RxQueryResult,\n OrmMethods = {},\n Reactivity = unknown,\n> {\n\n public id: number = newQueryID();\n\n /**\n * Some stats then are used for debugging and cache replacement policies\n */\n public _execOverDatabaseCount: number = 0;\n public _creationTime = now();\n\n // used in the query-cache to determine if the RxQuery can be cleaned up.\n public _lastEnsureEqual = 0;\n\n public uncached = false;\n\n // used to count the subscribers to the query\n public refCount$ = new BehaviorSubject(null);\n\n public isFindOneByIdQuery: false | string | string[];\n\n\n /**\n * Contains the current result state\n * or null if query has not run yet.\n */\n public _result: RxQuerySingleResult | null = null;\n\n\n constructor(\n public op: RxQueryOP,\n public mangoQuery: Readonly>,\n public collection: RxCollection,\n // used by some plugins\n public other: any = {}\n ) {\n if (!mangoQuery) {\n this.mangoQuery = _getDefaultQuery();\n }\n\n this.isFindOneByIdQuery = isFindOneByIdQuery(\n this.collection.schema.primaryPath as string,\n mangoQuery\n );\n }\n get $(): BehaviorSubject {\n if (!this._$) {\n\n const results$ = this.collection.$.pipe(\n /**\n * Performance shortcut.\n * Changes to local documents are not relevant for the query.\n */\n filter(changeEvent => !changeEvent.isLocal),\n /**\n * Start once to ensure the querying also starts\n * when there where no changes.\n */\n startWith(null),\n // ensure query results are up to date.\n mergeMap(() => _ensureEqual(this as any)),\n // use the current result set, written by _ensureEqual().\n map(() => this._result),\n // do not run stuff above for each new subscriber, only once.\n shareReplay(RXJS_SHARE_REPLAY_DEFAULTS),\n // do not proceed if result set has not changed.\n distinctUntilChanged((prev, curr) => {\n if (prev && prev.time === ensureNotFalsy(curr).time) {\n return true;\n } else {\n return false;\n }\n }),\n filter(result => !!result),\n /**\n * Map the result set to a single RxDocument or an array,\n * depending on query type\n */\n map((result) => {\n const useResult = ensureNotFalsy(result);\n if (this.op === 'count') {\n return useResult.count;\n } else if (this.op === 'findOne') {\n // findOne()-queries emit RxDocument or null\n return useResult.documents.length === 0 ? null : useResult.documents[0];\n } else if (this.op === 'findByIds') {\n return useResult.docsMap;\n } else {\n // find()-queries emit RxDocument[]\n // Flat copy the array so it won't matter if the user modifies it.\n return useResult.documents.slice(0);\n }\n })\n );\n\n this._$ = merge(\n results$,\n /**\n * Also add the refCount$ to the query observable\n * to allow us to count the amount of subscribers.\n */\n this.refCount$.pipe(\n filter(() => false)\n )\n );\n }\n return this._$ as any;\n }\n\n get $$(): Reactivity {\n const reactivity = this.collection.database.getReactivityFactory();\n return reactivity.fromObservable(\n this.$,\n undefined,\n this.collection.database\n ) as any;\n }\n\n // stores the changeEvent-number of the last handled change-event\n public _latestChangeEvent: -1 | number = -1;\n\n // time stamps on when the last full exec over the database has run\n // used to properly handle events that happen while the find-query is running\n public _lastExecStart: number = 0;\n public _lastExecEnd: number = 0;\n\n // Fields used for the Limit Buffer when enabled:\n public _limitBufferSize: number | null = null;\n public _limitBufferResults: RxDocumentData[] | null = null;\n\n // Fields used for the persistent query cache when enabled:\n public _persistentQueryCacheResult?: string[] | string = undefined;\n public _persistentQueryCacheResultLwt?: string = undefined; // lwt = latest write time\n public _persistentQueryCacheLoaded?: Promise;\n public _persistentQueryCacheBackend?: QueryCacheBackend;\n\n /**\n * ensures that the exec-runs\n * are not run in parallel\n */\n public _ensureEqualQueue: Promise = PROMISE_RESOLVE_FALSE;\n\n /**\n * Returns an observable that emits the results\n * This should behave like an rxjs-BehaviorSubject which means:\n * - Emit the current result-set on subscribe\n * - Emit the new result-set when an RxChangeEvent comes in\n * - Do not emit anything before the first result-set was created (no null)\n */\n public _$?: Observable;\n\n /**\n * set the new result-data as result-docs of the query\n * @param newResultData json-docs that were received from the storage\n */\n _setResultData(newResultData: RxDocumentData[] | number | Map>): void {\n if (typeof newResultData === 'number') {\n this._result = new RxQuerySingleResult(\n this.collection,\n [],\n newResultData\n );\n return;\n } else if (newResultData instanceof Map) {\n newResultData = Array.from((newResultData as Map>).values());\n }\n\n const docsDataMap = new Map();\n const docsMap = new Map();\n\n\n const docs = newResultData.map(docData => this.collection._docCache.getCachedRxDocument(docData));\n\n /**\n * Instead of using the newResultData in the result cache,\n * we directly use the objects that are stored in the RxDocument\n * to ensure we do not store the same data twice and fill up the memory.\n */\n const docsData = docs.map(doc => {\n docsDataMap.set(doc.primary, doc._data);\n docsMap.set(doc.primary, doc);\n return doc._data;\n });\n\n this._result = new RxQuerySingleResult(this.collection, docsData, docsData.length);\n }\n\n /**\n * executes the query on the database\n * @return results-array with document-data\n */\n async _execOverDatabase(): Promise[] | number> {\n this._execOverDatabaseCount = this._execOverDatabaseCount + 1;\n this._lastExecStart = now();\n\n\n if (this.op === 'count') {\n const preparedQuery = this.getPreparedQuery();\n const result = await this.collection.storageInstance.count(preparedQuery);\n if (result.mode === 'slow' && !this.collection.database.allowSlowCount) {\n throw newRxError('QU14', {\n collection: this.collection,\n queryObj: this.mangoQuery\n });\n } else {\n return result.count;\n }\n }\n\n if (this.op === 'findByIds') {\n const ids: string[] = ensureNotFalsy(this.mangoQuery.selector as any)[this.collection.schema.primaryPath].$in;\n const ret = new Map>();\n const mustBeQueried: string[] = [];\n // first try to fill from docCache\n ids.forEach(id => {\n const docData = this.collection._docCache.getLatestDocumentDataIfExists(id);\n if (docData) {\n if (!docData._deleted) {\n const doc = this.collection._docCache.getCachedRxDocument(docData);\n ret.set(id, doc);\n }\n } else {\n mustBeQueried.push(id);\n }\n });\n // everything which was not in docCache must be fetched from the storage\n if (mustBeQueried.length > 0) {\n const docs = await this.collection.storageInstance.findDocumentsById(mustBeQueried, false);\n docs.forEach(docData => {\n const doc = this.collection._docCache.getCachedRxDocument(docData);\n ret.set(doc.primary, doc);\n });\n }\n return ret as any;\n }\n\n\n const docsPromise = queryCollection(this as any);\n return docsPromise.then(docs => {\n this._lastExecEnd = now();\n return docs;\n });\n }\n\n /**\n * Execute the query\n * To have an easier implementations,\n * just subscribe and use the first result\n */\n public exec(throwIfMissing: true): Promise>;\n public exec(): Promise;\n public exec(throwIfMissing?: boolean): Promise {\n if (throwIfMissing && this.op !== 'findOne') {\n throw newRxError('QU9', {\n collection: this.collection.name,\n query: this.mangoQuery,\n op: this.op\n });\n }\n\n\n /**\n * run _ensureEqual() here,\n * this will make sure that errors in the query which throw inside of the RxStorage,\n * will be thrown at this execution context and not in the background.\n */\n return _ensureEqual(this as any)\n .then(() => firstValueFrom(this.$))\n .then(result => {\n if (!result && throwIfMissing) {\n throw newRxError('QU10', {\n collection: this.collection.name,\n query: this.mangoQuery,\n op: this.op\n });\n } else {\n return result;\n }\n });\n }\n\n\n\n /**\n * cached call to get the queryMatcher\n * @overwrites itself with the actual value\n */\n get queryMatcher(): QueryMatcher> {\n const schema = this.collection.schema.jsonSchema;\n const normalizedQuery = normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n );\n return overwriteGetterForCaching(\n this,\n 'queryMatcher',\n getQueryMatcher(\n schema,\n normalizedQuery\n ) as any\n );\n }\n\n /**\n * returns a string that is used for equal-comparisons\n * @overwrites itself with the actual value\n */\n toString(): string {\n const stringObj = sortObject({\n op: this.op,\n query: this.mangoQuery,\n other: this.other\n }, true);\n const value = JSON.stringify(stringObj);\n this.toString = () => value;\n return value;\n }\n\n persistentQueryId() {\n return String(this.collection.database.hashFunction(this.toString()));\n }\n\n /**\n * returns the prepared query\n * which can be send to the storage instance to query for documents.\n * @overwrites itself with the actual value.\n */\n getPreparedQuery(): PreparedQuery {\n const hookInput = {\n rxQuery: this,\n // can be mutated by the hooks so we have to deep clone first.\n mangoQuery: normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n )\n };\n\n (hookInput.mangoQuery.selector as any)._deleted = { $eq: false };\n if (hookInput.mangoQuery.index) {\n hookInput.mangoQuery.index.unshift('_deleted');\n }\n\n if (this._limitBufferSize !== null && hookInput.mangoQuery.limit) {\n hookInput.mangoQuery.limit = hookInput.mangoQuery.limit + this._limitBufferSize;\n }\n\n runPluginHooks('prePrepareQuery', hookInput);\n\n const value = prepareQuery(\n this.collection.schema.jsonSchema,\n hookInput.mangoQuery as any\n );\n\n this.getPreparedQuery = () => value;\n return value;\n }\n\n /**\n * returns true if the document matches the query,\n * does not use the 'skip' and 'limit'\n */\n doesDocumentDataMatch(docData: RxDocType | any): boolean {\n // if doc is deleted, it cannot match\n if (docData._deleted) {\n return false;\n }\n\n return this.queryMatcher(docData);\n }\n\n /**\n * deletes all found documents\n * @return promise with deleted documents\n */\n remove(): Promise {\n return this\n .exec()\n .then(docs => {\n if (Array.isArray(docs)) {\n // TODO use a bulk operation instead of running .remove() on each document\n return Promise.all(docs.map(doc => doc.remove()));\n } else {\n return (docs as any).remove();\n }\n });\n }\n incrementalRemove(): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalRemove(),\n );\n }\n\n\n /**\n * helper function to transform RxQueryBase to RxQuery type\n */\n get asRxQuery(): RxQuery {\n return this as any;\n }\n\n /**\n * updates all found documents\n * @overwritten by plugin (optional)\n */\n update(_updateObj: any): Promise {\n throw pluginMissing('update');\n }\n\n patch(patch: Partial): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.patch(patch),\n );\n }\n incrementalPatch(patch: Partial): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalPatch(patch),\n );\n }\n modify(mutationFunction: ModifyFunction): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.modify(mutationFunction),\n );\n }\n incrementalModify(mutationFunction: ModifyFunction): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalModify(mutationFunction),\n );\n }\n\n\n // we only set some methods of query-builder here\n // because the others depend on these ones\n where(_queryObj: MangoQuerySelector | keyof RxDocType | string): RxQuery {\n throw pluginMissing('query-builder');\n }\n sort(_params: string | MangoQuerySortPart): RxQuery {\n throw pluginMissing('query-builder');\n }\n skip(_amount: number | null): RxQuery {\n throw pluginMissing('query-builder');\n }\n limit(_amount: number | null): RxQuery {\n throw pluginMissing('query-builder');\n }\n\n enableLimitBuffer(bufferSize: number) {\n if (this._limitBufferSize !== null) {\n // Limit buffer has already been enabled, do nothing:\n return this;\n }\n if (this._lastExecStart !== 0) {\n console.error('Can\\'t use limit buffer if query has already executed');\n return this;\n }\n if (this.mangoQuery.skip || !this.mangoQuery.limit) {\n console.error('Right now, limit buffer only works on non-skip, limit queries.');\n return this;\n }\n this._limitBufferSize = bufferSize;\n return this;\n }\n\n enablePersistentQueryCache(backend: QueryCacheBackend) {\n if (this._persistentQueryCacheBackend) {\n // We've already tried to enable the query cache\n return this;\n }\n this._persistentQueryCacheBackend = backend;\n this._persistentQueryCacheLoaded = this._restoreQueryCacheFromPersistedState();\n return this;\n }\n\n private async _restoreQueryCacheFromPersistedState() {\n if (!this._persistentQueryCacheBackend) {\n // no cache backend provided, do nothing\n return;\n }\n if (this._persistentQueryCacheResult) {\n // we already restored the cache once, no need to run twice\n return;\n }\n if (this.mangoQuery.skip || this.op === 'count') {\n console.error('The persistent query cache only works on non-skip, non-count queries.');\n return;\n }\n\n // First, check if there are any query results persisted:\n const persistentQueryId = this.persistentQueryId();\n const value = await this._persistentQueryCacheBackend.getItem(`qc:${persistentQueryId}`);\n if (!value || !Array.isArray(value) || value.length === 0) {\n // eslint-disable-next-line no-console\n console.log(`no persistent query cache found in the backend, returning early ${this.toString()}`);\n return;\n }\n\n // If there are persisted ids, create our two Sets of ids from the cache:\n const persistedQueryCacheIds = new Set();\n const limitBufferIds = new Set();\n\n for (const id of value) {\n if (id.startsWith('lb-')) {\n limitBufferIds.add(id.replace('lb-', ''));\n } else {\n persistedQueryCacheIds.add(id);\n }\n }\n\n // eslint-disable-next-line no-console\n console.time(`Restoring persistent querycache ${this.toString()}`);\n\n // Next, pull the lwt from the cache:\n // TODO: if lwt is too old, should we just give up here? What if there are too many changedDocs?\n const lwt = (await this._persistentQueryCacheBackend.getItem(`qc:${persistentQueryId}:lwt`)) as string | null;\n if (!lwt) {\n return;\n }\n\n // If the query was persisted too long ago, just re-execute it.\n if (now() - Number(lwt) > RESTORE_QUERY_MAX_TIME_AGO) {\n return;\n }\n\n const primaryPath = this.collection.schema.primaryPath;\n\n const {documents: changedDocs} = await getChangedDocumentsSince(this.collection.storageInstance,\n RESTORE_QUERY_MAX_DOCS_CHANGED,\n // make sure we remove the monotonic clock (xxx.01, xxx.02) from the lwt timestamp to avoid issues with\n // lookups in indices (dexie)\n {id: '', lwt: Math.floor(Number(lwt)) - RESTORE_QUERY_UPDATE_DRIFT}\n );\n\n // If too many docs have changed, just give up and re-execute the query\n if (changedDocs.length === RESTORE_QUERY_MAX_DOCS_CHANGED) {\n return;\n }\n\n const changedDocIds = new Set(changedDocs.map((d) => d[primaryPath] as string));\n\n const docIdsWeNeedToFetch = [...persistedQueryCacheIds, ...limitBufferIds].filter((id) => !changedDocIds.has(id));\n\n // We use _queryCollectionByIds to fetch the remaining docs we need efficiently, pulling\n // from query cache if we can (and the storageInstance by ids if we can't):\n const otherPotentialMatchingDocs: RxDocumentData[] = [];\n await _queryCollectionByIds(this as any, otherPotentialMatchingDocs, docIdsWeNeedToFetch);\n\n // Now that we have all potential documents, we just filter (in-memory) the ones that still match our query:\n let docsData: RxDocumentData[] = [];\n for (const doc of changedDocs.concat(otherPotentialMatchingDocs)) {\n if (this.doesDocumentDataMatch(doc)) {\n docsData.push(doc);\n }\n }\n\n // Sort the documents by the query's sort field:\n const normalizedMangoQuery = normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n );\n const sortComparator = getSortComparator(this.collection.schema.jsonSchema, normalizedMangoQuery);\n const limit = normalizedMangoQuery.limit ? normalizedMangoQuery.limit : Infinity;\n docsData = docsData.sort(sortComparator);\n\n // We know for sure that all persisted and limit buffer ids (and changed docs before them) are in the correct\n // result set. And we can't be sure about any past that point. So cut it off there:\n const lastValidIndex = docsData.findLastIndex((d) => limitBufferIds.has(d[primaryPath] as string) || persistedQueryCacheIds.has(d[primaryPath] as string));\n docsData = docsData.slice(0, lastValidIndex + 1);\n\n // Now this is the trickiest part.\n // If we somehow have fewer docs than the limit of our query\n // (and this wasn't the case because before persistence)\n // then there is no way for us to know the correct results, and we re-exec:\n const unchangedItemsMayNowBeInResults = (\n this.mangoQuery.limit &&\n docsData.length < this.mangoQuery.limit &&\n persistedQueryCacheIds.size >= this.mangoQuery.limit\n );\n if (unchangedItemsMayNowBeInResults) {\n return;\n }\n\n // Our finalResults are the actual results of this query, and pastLimitItems are any remaining matching\n // documents we have left over (past the limit).\n const pastLimitItems = docsData.slice(limit);\n const finalResults = docsData.slice(0, limit);\n\n // If there are still items past the first LIMIT items, try to restore the limit buffer with them:\n if (limitBufferIds.size && pastLimitItems.length > 0) {\n this._limitBufferResults = pastLimitItems;\n } else {\n this._limitBufferResults = [];\n }\n\n // Finally, set the query's results to what we've pulled from disk:\n this._lastEnsureEqual = now();\n this._latestChangeEvent = this.collection._changeEventBuffer.counter;\n this._setResultData(finalResults);\n\n // eslint-disable-next-line no-console\n console.timeEnd(`Restoring persistent querycache ${this.toString()}`);\n }\n}\n\nexport function _getDefaultQuery(): MangoQuery {\n return {\n selector: {}\n };\n}\n\n/**\n * run this query through the QueryCache\n */\nexport function tunnelQueryCache(\n rxQuery: RxQueryBase\n): RxQuery {\n return rxQuery.collection._queryCache.getByQuery(rxQuery as any);\n}\n\nexport function createRxQuery(\n op: RxQueryOP,\n queryObj: MangoQuery,\n collection: RxCollection,\n other?: any\n) {\n runPluginHooks('preCreateRxQuery', {\n op,\n queryObj,\n collection,\n other\n });\n\n let ret = new RxQueryBase(op, queryObj, collection, other);\n\n // ensure when created with same params, only one is created\n ret = tunnelQueryCache(ret);\n // TODO: clear persistent query cache as well\n triggerCacheReplacement(collection);\n\n return ret;\n}\n\n/**\n * Check if the current results-state is in sync with the database\n * which means that no write event happened since the last run.\n * @return false if not which means it should re-execute\n */\nfunction _isResultsInSync(rxQuery: RxQueryBase): boolean {\n const currentLatestEventNumber = rxQuery.asRxQuery.collection._changeEventBuffer.getCounter();\n if (rxQuery._latestChangeEvent >= currentLatestEventNumber) {\n return true;\n } else {\n return false;\n }\n}\n\n\n/**\n * wraps __ensureEqual()\n * to ensure it does not run in parallel\n * @return true if has changed, false if not\n */\nfunction _ensureEqual(rxQuery: RxQueryBase): Promise {\n // Optimisation shortcut\n if (\n rxQuery.collection.database.destroyed ||\n _isResultsInSync(rxQuery)\n ) {\n return PROMISE_RESOLVE_FALSE;\n }\n\n rxQuery._ensureEqualQueue = rxQuery._ensureEqualQueue\n .then(() => __ensureEqual(rxQuery));\n return rxQuery._ensureEqualQueue;\n}\n\n\n/**\n * ensures that the results of this query is equal to the results which a query over the database would give\n * @return true if results have changed\n */\nasync function __ensureEqual(rxQuery: RxQueryBase): Promise {\n await rxQuery._persistentQueryCacheLoaded;\n\n rxQuery._lastEnsureEqual = now();\n\n /**\n * Optimisation shortcuts\n */\n if (\n // db is closed\n rxQuery.collection.database.destroyed ||\n // nothing happened since last run\n _isResultsInSync(rxQuery)\n ) {\n return PROMISE_RESOLVE_FALSE;\n }\n\n let ret = false;\n let mustReExec = false; // if this becomes true, a whole execution over the database is made\n if (rxQuery._latestChangeEvent === -1) {\n // have not executed yet -> must run\n mustReExec = true;\n }\n\n /**\n * try to use EventReduce to calculate the new results\n */\n if (!mustReExec) {\n const missedChangeEvents = rxQuery.asRxQuery.collection._changeEventBuffer.getFrom(rxQuery._latestChangeEvent + 1);\n if (missedChangeEvents === null) {\n // changeEventBuffer is of bounds -> we must re-execute over the database\n mustReExec = true;\n } else {\n rxQuery._latestChangeEvent = rxQuery.asRxQuery.collection._changeEventBuffer.getCounter();\n\n const runChangeEvents: RxChangeEvent[] = rxQuery.asRxQuery.collection\n ._changeEventBuffer\n .reduceByLastOfDoc(missedChangeEvents);\n\n if (rxQuery._limitBufferResults !== null) {\n // Check if any item in our limit buffer was modified by a change event\n for (const cE of runChangeEvents) {\n if (rxQuery._limitBufferResults.find((doc) => doc[rxQuery.collection.schema.primaryPath] === cE.documentId)) {\n // If so, the limit buffer is potential invalid -- let's just blow it up\n // TODO: could we instead update the documents in the limit buffer?\n rxQuery._limitBufferResults = null;\n break;\n }\n }\n }\n\n if (rxQuery.op === 'count') {\n // 'count' query\n const previousCount = ensureNotFalsy(rxQuery._result).count;\n let newCount = previousCount;\n runChangeEvents.forEach(cE => {\n const didMatchBefore = cE.previousDocumentData && rxQuery.doesDocumentDataMatch(cE.previousDocumentData);\n const doesMatchNow = rxQuery.doesDocumentDataMatch(cE.documentData);\n\n if (!didMatchBefore && doesMatchNow) {\n newCount++;\n }\n if (didMatchBefore && !doesMatchNow) {\n newCount--;\n }\n });\n if (newCount !== previousCount) {\n ret = true; // true because results changed\n rxQuery._setResultData(newCount as any);\n }\n } else {\n // 'find' or 'findOne' query\n const eventReduceResult = calculateNewResults(\n rxQuery as any,\n runChangeEvents\n );\n if (eventReduceResult.runFullQueryAgain) {\n // could not calculate the new results, execute must be done\n mustReExec = true;\n } else if (eventReduceResult.changed) {\n // we got the new results, we do not have to re-execute, mustReExec stays false\n ret = true; // true because results changed\n rxQuery._setResultData(eventReduceResult.newResults as any);\n }\n }\n }\n }\n\n // oh no we have to re-execute the whole query over the database\n if (mustReExec) {\n return rxQuery._execOverDatabase()\n .then(newResultData => {\n\n /**\n * The RxStorage is defined to always first emit events and then return\n * on bulkWrite() calls. So here we have to use the counter AFTER the execOverDatabase()\n * has been run, not the one from before.\n */\n rxQuery._latestChangeEvent = rxQuery.collection._changeEventBuffer.getCounter();\n\n // A count query needs a different has-changed check.\n if (typeof newResultData === 'number') {\n if (\n !rxQuery._result ||\n newResultData !== rxQuery._result.count\n ) {\n ret = true;\n rxQuery._setResultData(newResultData as any);\n }\n return ret;\n }\n if (\n !rxQuery._result ||\n !areRxDocumentArraysEqual(\n rxQuery.collection.schema.primaryPath,\n newResultData,\n rxQuery._result.docsData\n )\n ) {\n ret = true; // true because results changed\n rxQuery._setResultData(newResultData as any);\n }\n return ret;\n })\n .then(async (returnValue) => {\n await updatePersistentQueryCache(rxQuery);\n return returnValue;\n });\n }\n\n return ret; // true if results have changed\n}\n\n\nasync function updatePersistentQueryCache(rxQuery: RxQueryBase) {\n if (!rxQuery._persistentQueryCacheBackend) {\n return;\n }\n\n const backend = rxQuery._persistentQueryCacheBackend;\n\n const key = rxQuery.persistentQueryId();\n\n // update _persistedQueryCacheResult\n rxQuery._persistentQueryCacheResult = rxQuery._result?.docsKeys ?? [];\n\n const idsToPersist = [...rxQuery._persistentQueryCacheResult];\n if (rxQuery._limitBufferResults) {\n rxQuery._limitBufferResults.forEach((d) => {\n idsToPersist.push(`lb-${d[rxQuery.collection.schema.primaryPath]}`);\n });\n }\n // eslint-disable-next-line no-console\n console.time(`Query persistence: persisting results of ${JSON.stringify(rxQuery.mangoQuery)}`);\n // persist query cache\n const lwt = rxQuery._result?.time ?? RX_META_LWT_MINIMUM;\n\n await Promise.all([\n backend.setItem(`qc:${String(key)}`, idsToPersist),\n backend.setItem(`qc:${String(key)}:lwt`, lwt.toString()),\n ]);\n\n // eslint-disable-next-line no-console\n console.timeEnd(`Query persistence: persisting results of ${JSON.stringify(rxQuery.mangoQuery)}`);\n}\n\n\n// Refactored out of `queryCollection`: modifies the docResults array to fill it with data\nasync function _queryCollectionByIds(rxQuery: RxQuery | RxQueryBase, docResults: RxDocumentData[], docIds: string[]) {\n const collection = rxQuery.collection;\n docIds = docIds.filter(docId => {\n // first try to fill from docCache\n const docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (docData) {\n if (!docData._deleted) {\n docResults.push(docData);\n }\n return false;\n } else {\n return true;\n }\n });\n\n // otherwise get from storage\n if (docIds.length > 0) {\n const docsMap = await collection.storageInstance.findDocumentsById(docIds, false);\n Object.values(docsMap).forEach(docData => {\n docResults.push(docData);\n });\n }\n}\n\n/**\n * @returns a format of the query that can be used with the storage\n * when calling RxStorageInstance().query()\n */\nexport function prepareQuery(\n schema: RxJsonSchema>,\n mutateableQuery: FilledMangoQuery\n): PreparedQuery {\n if (!mutateableQuery.sort) {\n throw newRxError('SNH', {\n query: mutateableQuery\n });\n }\n\n /**\n * Store the query plan together with the\n * prepared query to save performance.\n */\n const queryPlan = getQueryPlan(\n schema,\n mutateableQuery\n );\n\n return {\n query: mutateableQuery,\n queryPlan\n };\n}\n\n/**\n * Runs the query over the storage instance\n * of the collection.\n * Does some optimizations to ensure findById is used\n * when specific queries are used.\n */\nexport async function queryCollection(\n rxQuery: RxQuery | RxQueryBase\n): Promise[]> {\n await rxQuery._persistentQueryCacheLoaded;\n\n let docs: RxDocumentData[] = [];\n const collection = rxQuery.collection;\n\n /**\n * Optimizations shortcut.\n * If query is find-one-document-by-id,\n * then we do not have to use the slow query() method\n * but instead can use findDocumentsById()\n */\n if (rxQuery.isFindOneByIdQuery) {\n if (Array.isArray(rxQuery.isFindOneByIdQuery)) {\n let docIds = rxQuery.isFindOneByIdQuery;\n docIds = docIds.filter(docId => {\n // first try to fill from docCache\n const docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (docData) {\n if (!docData._deleted) {\n docs.push(docData);\n }\n return false;\n } else {\n return true;\n }\n });\n // otherwise get from storage\n if (docIds.length > 0) {\n const docsFromStorage = await collection.storageInstance.findDocumentsById(docIds, false);\n appendToArray(docs, docsFromStorage);\n }\n await _queryCollectionByIds(rxQuery, docs, rxQuery.isFindOneByIdQuery);\n } else {\n const docId = rxQuery.isFindOneByIdQuery;\n\n // first try to fill from docCache\n let docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (!docData) {\n // otherwise get from storage\n const fromStorageList = await collection.storageInstance.findDocumentsById([docId], false);\n if (fromStorageList[0]) {\n docData = fromStorageList[0];\n }\n }\n if (docData && !docData._deleted) {\n docs.push(docData);\n }\n }\n } else {\n const preparedQuery = rxQuery.getPreparedQuery();\n const queryResult = await collection.storageInstance.query(preparedQuery);\n if (rxQuery._limitBufferSize !== null && rxQuery.mangoQuery.limit && queryResult.documents.length > rxQuery.mangoQuery.limit) {\n // If there are more than query.limit results, we pull out our buffer items from the\n // last rxQuery._limitBufferSize items of the results.\n rxQuery._limitBufferResults = queryResult.documents.splice(rxQuery.mangoQuery.limit);\n }\n docs = queryResult.documents;\n }\n return docs;\n}\n\n/**\n * Returns true if the given query\n * selects exactly one document by its id.\n * Used to optimize performance because these kind of\n * queries do not have to run over an index and can use get-by-id instead.\n * Returns false if no query of that kind.\n * Returns the document id otherwise.\n */\nexport function isFindOneByIdQuery(\n primaryPath: string,\n query: MangoQuery\n): false | string | string[] {\n // must have exactly one operator which must be $eq || $in\n if (\n !query.skip &&\n query.selector &&\n Object.keys(query.selector).length === 1 &&\n query.selector[primaryPath]\n ) {\n const value: any = query.selector[primaryPath];\n if (typeof value === 'string') {\n return value;\n } else if (\n Object.keys(value).length === 1 &&\n typeof value.$eq === 'string'\n ) {\n return value.$eq;\n }\n\n // same with $in string arrays\n if (\n Object.keys(value).length === 1 &&\n Array.isArray(value.$eq) &&\n // must only contain strings\n !(value.$eq as any[]).find(r => typeof r !== 'string')\n ) {\n return value.$eq;\n }\n }\n return false;\n}\n\n\nexport function isRxQuery(obj: any): boolean {\n return obj instanceof RxQueryBase;\n}\n"],"mappings":"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","ignoreList":[]} \ No newline at end of file +{"version":3,"file":"rx-query.js","names":["BehaviorSubject","firstValueFrom","merge","mergeMap","filter","map","startWith","distinctUntilChanged","shareReplay","appendToArray","areRxDocumentArraysEqual","now","overwriteGetterForCaching","pluginMissing","PROMISE_RESOLVE_FALSE","RX_META_LWT_MINIMUM","RXJS_SHARE_REPLAY_DEFAULTS","sortObject","newRxError","runPluginHooks","calculateNewResults","triggerCacheReplacement","getQueryMatcher","getSortComparator","normalizeMangoQuery","runQueryUpdateFunction","selectorIncludesDeleted","RxQuerySingleResult","getQueryPlan","ensureNotFalsy","getChangedDocumentsSince","_queryCount","newQueryID","RESTORE_QUERY_UPDATE_DRIFT","RESTORE_QUERY_MAX_DOCS_CHANGED","RESTORE_QUERY_MAX_TIME_AGO","RxQueryBase","op","mangoQuery","collection","other","id","_execOverDatabaseCount","_creationTime","_lastEnsureEqual","uncached","refCount$","_result","_latestChangeEvent","_lastExecStart","_lastExecEnd","_limitBufferSize","_limitBufferResults","_persistentQueryCacheResult","undefined","_persistentQueryCacheResultLwt","_ensureEqualQueue","_getDefaultQuery","isFindOneByIdQuery","schema","primaryPath","_proto","prototype","_setResultData","newResultData","Map","Array","from","values","docsDataMap","docsMap","docs","docData","_docCache","getCachedRxDocument","docsData","doc","set","primary","_data","length","_execOverDatabase","preparedQuery","getPreparedQuery","result","storageInstance","count","mode","database","allowSlowCount","queryObj","ids","selector","$in","ret","mustBeQueried","forEach","getLatestDocumentDataIfExists","_deleted","push","findDocumentsById","docsPromise","queryCollection","then","exec","throwIfMissing","name","query","_ensureEqual","$","toString","stringObj","value","JSON","stringify","persistentQueryId","String","hashFunction","hookInput","rxQuery","jsonSchema","includesDeleted","$eq","index","unshift","limit","prepareQuery","doesDocumentDataMatch","queryMatcher","remove","isArray","Promise","all","incrementalRemove","asRxQuery","update","_updateObj","patch","incrementalPatch","modify","mutationFunction","incrementalModify","where","_queryObj","sort","_params","skip","_amount","enableLimitBuffer","bufferSize","console","error","enablePersistentQueryCache","backend","_persistentQueryCacheBackend","_persistentQueryCacheLoaded","_restoreQueryCacheFromPersistedState","getItem","log","persistedQueryCacheIds","Set","limitBufferIds","startsWith","add","replace","time","lwt","Number","documents","changedDocs","Math","floor","changedDocIds","d","docIdsWeNeedToFetch","has","otherPotentialMatchingDocs","_queryCollectionByIds","concat","normalizedMangoQuery","sortComparator","Infinity","lastValidIndex","findLastIndex","slice","unchangedItemsMayNowBeInResults","size","pastLimitItems","finalResults","_changeEventBuffer","counter","timeEnd","_createClass","key","get","_$","results$","pipe","changeEvent","isLocal","prev","curr","useResult","reactivity","getReactivityFactory","fromObservable","normalizedQuery","tunnelQueryCache","_queryCache","getByQuery","createRxQuery","_isResultsInSync","currentLatestEventNumber","getCounter","destroyed","__ensureEqual","mustReExec","missedChangeEvents","getFrom","runChangeEvents","reduceByLastOfDoc","_loop","cE","find","documentId","previousCount","newCount","didMatchBefore","previousDocumentData","doesMatchNow","documentData","eventReduceResult","runFullQueryAgain","changed","newResults","returnValue","updatePersistentQueryCache","docsKeys","idsToPersist","setItem","docResults","docIds","docId","Object","mutateableQuery","queryPlan","docsFromStorage","fromStorageList","queryResult","splice","keys","r","isRxQuery","obj"],"sources":["../../src/rx-query.ts"],"sourcesContent":["import {\n BehaviorSubject,\n firstValueFrom,\n Observable,\n merge\n} from 'rxjs';\nimport {\n mergeMap,\n filter,\n map,\n startWith,\n distinctUntilChanged,\n shareReplay\n} from 'rxjs/operators';\nimport {\n appendToArray,\n areRxDocumentArraysEqual,\n now,\n overwriteGetterForCaching,\n pluginMissing,\n PROMISE_RESOLVE_FALSE, RX_META_LWT_MINIMUM,\n RXJS_SHARE_REPLAY_DEFAULTS,\n sortObject\n} from './plugins/utils/index.ts';\nimport {\n newRxError\n} from './rx-error.ts';\nimport {\n runPluginHooks\n} from './hooks.ts';\nimport type {\n MangoQuery,\n PreparedQuery,\n QueryMatcher,\n RxChangeEvent,\n RxCollection,\n RxDocument,\n RxDocumentData,\n RxJsonSchema,\n FilledMangoQuery,\n ModifyFunction,\n RxDocumentWriteData,\n RxQuery,\n RxQueryOP, MangoQuerySelector, MangoQuerySortPart\n} from './types/index.d.ts';\nimport { calculateNewResults } from './event-reduce.ts';\nimport { triggerCacheReplacement } from './query-cache.ts';\nimport {\n getQueryMatcher,\n getSortComparator,\n normalizeMangoQuery,\n runQueryUpdateFunction,\n selectorIncludesDeleted\n\n} from './rx-query-helper.ts';\nimport { RxQuerySingleResult } from './rx-query-single-result.ts';\nimport { getQueryPlan } from './query-planner.ts';\nimport { ensureNotFalsy } from 'event-reduce-js';\nimport { getChangedDocumentsSince } from './rx-storage-helper.ts';\n\n\nexport interface QueryCacheBackend {\n getItem(key: string): Promise;\n setItem(key: string, value: T): Promise;\n}\n\nlet _queryCount = 0;\nconst newQueryID = function (): number {\n return ++_queryCount;\n};\n\n// allow changes to be 100ms older than the actual lwt value\nconst RESTORE_QUERY_UPDATE_DRIFT = 100;\n\n// 5000 seems like a sane number where re-executing the query will be easier than trying to restore\nconst RESTORE_QUERY_MAX_DOCS_CHANGED = 5000;\n\n// If a query was persisted more than a week ago, just re-execute it\nexport const RESTORE_QUERY_MAX_TIME_AGO = 7 * 24 * 60 * 60 * 1000;\n\nexport class RxQueryBase<\n RxDocType,\n RxQueryResult,\n OrmMethods = {},\n Reactivity = unknown,\n> {\n\n public id: number = newQueryID();\n\n /**\n * Some stats then are used for debugging and cache replacement policies\n */\n public _execOverDatabaseCount: number = 0;\n public _creationTime = now();\n\n // used in the query-cache to determine if the RxQuery can be cleaned up.\n public _lastEnsureEqual = 0;\n\n public uncached = false;\n\n // used to count the subscribers to the query\n public refCount$ = new BehaviorSubject(null);\n\n public isFindOneByIdQuery: false | string | string[];\n\n\n /**\n * Contains the current result state\n * or null if query has not run yet.\n */\n public _result: RxQuerySingleResult | null = null;\n\n\n constructor(\n public op: RxQueryOP,\n public mangoQuery: Readonly>,\n public collection: RxCollection,\n // used by some plugins\n public other: any = {}\n ) {\n if (!mangoQuery) {\n this.mangoQuery = _getDefaultQuery();\n }\n\n this.isFindOneByIdQuery = isFindOneByIdQuery(\n this.collection.schema.primaryPath as string,\n mangoQuery\n );\n }\n get $(): BehaviorSubject {\n if (!this._$) {\n\n const results$ = this.collection.$.pipe(\n /**\n * Performance shortcut.\n * Changes to local documents are not relevant for the query.\n */\n filter(changeEvent => !changeEvent.isLocal),\n /**\n * Start once to ensure the querying also starts\n * when there where no changes.\n */\n startWith(null),\n // ensure query results are up to date.\n mergeMap(() => _ensureEqual(this as any)),\n // use the current result set, written by _ensureEqual().\n map(() => this._result),\n // do not run stuff above for each new subscriber, only once.\n shareReplay(RXJS_SHARE_REPLAY_DEFAULTS),\n // do not proceed if result set has not changed.\n distinctUntilChanged((prev, curr) => {\n if (prev && prev.time === ensureNotFalsy(curr).time) {\n return true;\n } else {\n return false;\n }\n }),\n filter(result => !!result),\n /**\n * Map the result set to a single RxDocument or an array,\n * depending on query type\n */\n map((result) => {\n const useResult = ensureNotFalsy(result);\n if (this.op === 'count') {\n return useResult.count;\n } else if (this.op === 'findOne') {\n // findOne()-queries emit RxDocument or null\n return useResult.documents.length === 0 ? null : useResult.documents[0];\n } else if (this.op === 'findByIds') {\n return useResult.docsMap;\n } else {\n // find()-queries emit RxDocument[]\n // Flat copy the array so it won't matter if the user modifies it.\n return useResult.documents.slice(0);\n }\n })\n );\n\n this._$ = merge(\n results$,\n /**\n * Also add the refCount$ to the query observable\n * to allow us to count the amount of subscribers.\n */\n this.refCount$.pipe(\n filter(() => false)\n )\n );\n }\n return this._$ as any;\n }\n\n get $$(): Reactivity {\n const reactivity = this.collection.database.getReactivityFactory();\n return reactivity.fromObservable(\n this.$,\n undefined,\n this.collection.database\n ) as any;\n }\n\n get includesDeleted(): boolean {\n return selectorIncludesDeleted(this.mangoQuery.selector);\n }\n\n // stores the changeEvent-number of the last handled change-event\n public _latestChangeEvent: -1 | number = -1;\n\n // time stamps on when the last full exec over the database has run\n // used to properly handle events that happen while the find-query is running\n public _lastExecStart: number = 0;\n public _lastExecEnd: number = 0;\n\n // Fields used for the Limit Buffer when enabled:\n public _limitBufferSize: number | null = null;\n public _limitBufferResults: RxDocumentData[] | null = null;\n\n // Fields used for the persistent query cache when enabled:\n public _persistentQueryCacheResult?: string[] | string = undefined;\n public _persistentQueryCacheResultLwt?: string = undefined; // lwt = latest write time\n public _persistentQueryCacheLoaded?: Promise;\n public _persistentQueryCacheBackend?: QueryCacheBackend;\n\n /**\n * ensures that the exec-runs\n * are not run in parallel\n */\n public _ensureEqualQueue: Promise = PROMISE_RESOLVE_FALSE;\n\n /**\n * Returns an observable that emits the results\n * This should behave like an rxjs-BehaviorSubject which means:\n * - Emit the current result-set on subscribe\n * - Emit the new result-set when an RxChangeEvent comes in\n * - Do not emit anything before the first result-set was created (no null)\n */\n public _$?: Observable;\n\n /**\n * set the new result-data as result-docs of the query\n * @param newResultData json-docs that were received from the storage\n */\n _setResultData(newResultData: RxDocumentData[] | number | Map>): void {\n if (typeof newResultData === 'number') {\n this._result = new RxQuerySingleResult(\n this.collection,\n [],\n newResultData\n );\n return;\n } else if (newResultData instanceof Map) {\n newResultData = Array.from((newResultData as Map>).values());\n }\n\n const docsDataMap = new Map();\n const docsMap = new Map();\n\n\n const docs = newResultData.map(docData => this.collection._docCache.getCachedRxDocument(docData));\n\n /**\n * Instead of using the newResultData in the result cache,\n * we directly use the objects that are stored in the RxDocument\n * to ensure we do not store the same data twice and fill up the memory.\n */\n const docsData = docs.map(doc => {\n docsDataMap.set(doc.primary, doc._data);\n docsMap.set(doc.primary, doc);\n return doc._data;\n });\n\n this._result = new RxQuerySingleResult(this.collection, docsData, docsData.length);\n }\n\n /**\n * executes the query on the database\n * @return results-array with document-data\n */\n async _execOverDatabase(): Promise[] | number> {\n this._execOverDatabaseCount = this._execOverDatabaseCount + 1;\n this._lastExecStart = now();\n\n\n if (this.op === 'count') {\n const preparedQuery = this.getPreparedQuery();\n const result = await this.collection.storageInstance.count(preparedQuery);\n if (result.mode === 'slow' && !this.collection.database.allowSlowCount) {\n throw newRxError('QU14', {\n collection: this.collection,\n queryObj: this.mangoQuery\n });\n } else {\n return result.count;\n }\n }\n\n if (this.op === 'findByIds') {\n const ids: string[] = ensureNotFalsy(this.mangoQuery.selector as any)[this.collection.schema.primaryPath].$in;\n const ret = new Map>();\n const mustBeQueried: string[] = [];\n // first try to fill from docCache\n ids.forEach(id => {\n const docData = this.collection._docCache.getLatestDocumentDataIfExists(id);\n if (docData) {\n if (!docData._deleted) {\n const doc = this.collection._docCache.getCachedRxDocument(docData);\n ret.set(id, doc);\n }\n } else {\n mustBeQueried.push(id);\n }\n });\n // everything which was not in docCache must be fetched from the storage\n if (mustBeQueried.length > 0) {\n const docs = await this.collection.storageInstance.findDocumentsById(mustBeQueried, false);\n docs.forEach(docData => {\n const doc = this.collection._docCache.getCachedRxDocument(docData);\n ret.set(doc.primary, doc);\n });\n }\n return ret as any;\n }\n\n\n const docsPromise = queryCollection(this as any);\n return docsPromise.then(docs => {\n this._lastExecEnd = now();\n return docs;\n });\n }\n\n /**\n * Execute the query\n * To have an easier implementations,\n * just subscribe and use the first result\n */\n public exec(throwIfMissing: true): Promise>;\n public exec(): Promise;\n public exec(throwIfMissing?: boolean): Promise {\n if (throwIfMissing && this.op !== 'findOne') {\n throw newRxError('QU9', {\n collection: this.collection.name,\n query: this.mangoQuery,\n op: this.op\n });\n }\n\n\n /**\n * run _ensureEqual() here,\n * this will make sure that errors in the query which throw inside of the RxStorage,\n * will be thrown at this execution context and not in the background.\n */\n return _ensureEqual(this as any)\n .then(() => firstValueFrom(this.$))\n .then(result => {\n if (!result && throwIfMissing) {\n throw newRxError('QU10', {\n collection: this.collection.name,\n query: this.mangoQuery,\n op: this.op\n });\n } else {\n return result;\n }\n });\n }\n\n\n\n /**\n * cached call to get the queryMatcher\n * @overwrites itself with the actual value\n */\n get queryMatcher(): QueryMatcher> {\n const schema = this.collection.schema.jsonSchema;\n const normalizedQuery = normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n );\n return overwriteGetterForCaching(\n this,\n 'queryMatcher',\n getQueryMatcher(\n schema,\n normalizedQuery\n ) as any\n );\n }\n\n /**\n * returns a string that is used for equal-comparisons\n * @overwrites itself with the actual value\n */\n toString(): string {\n const stringObj = sortObject({\n op: this.op,\n query: this.mangoQuery,\n other: this.other\n }, true);\n const value = JSON.stringify(stringObj);\n this.toString = () => value;\n return value;\n }\n\n persistentQueryId() {\n return String(this.collection.database.hashFunction(this.toString()));\n }\n\n /**\n * returns the prepared query\n * which can be send to the storage instance to query for documents.\n * @overwrites itself with the actual value.\n */\n getPreparedQuery(): PreparedQuery {\n const hookInput = {\n rxQuery: this,\n // can be mutated by the hooks so we have to deep clone first.\n mangoQuery: normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n )\n };\n\n // Set _deleted to false if not explicitly set in selector\n if (!this.includesDeleted) {\n hookInput.mangoQuery.selector = {\n ...hookInput.mangoQuery.selector,\n _deleted: { $eq: false },\n };\n }\n\n if (hookInput.mangoQuery.index) {\n hookInput.mangoQuery.index.unshift('_deleted');\n }\n\n if (this._limitBufferSize !== null && hookInput.mangoQuery.limit) {\n hookInput.mangoQuery.limit = hookInput.mangoQuery.limit + this._limitBufferSize;\n }\n\n runPluginHooks('prePrepareQuery', hookInput);\n\n const value = prepareQuery(\n this.collection.schema.jsonSchema,\n hookInput.mangoQuery as any\n );\n\n this.getPreparedQuery = () => value;\n return value;\n }\n\n /**\n * returns true if the document matches the query,\n * does not use the 'skip' and 'limit'\n */\n doesDocumentDataMatch(docData: RxDocType | any): boolean {\n // if doc is deleted, it cannot match\n if (docData._deleted) {\n return false;\n }\n\n return this.queryMatcher(docData);\n }\n\n /**\n * deletes all found documents\n * @return promise with deleted documents\n */\n remove(): Promise {\n return this\n .exec()\n .then(docs => {\n if (Array.isArray(docs)) {\n // TODO use a bulk operation instead of running .remove() on each document\n return Promise.all(docs.map(doc => doc.remove()));\n } else {\n return (docs as any).remove();\n }\n });\n }\n incrementalRemove(): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalRemove(),\n );\n }\n\n\n /**\n * helper function to transform RxQueryBase to RxQuery type\n */\n get asRxQuery(): RxQuery {\n return this as any;\n }\n\n /**\n * updates all found documents\n * @overwritten by plugin (optional)\n */\n update(_updateObj: any): Promise {\n throw pluginMissing('update');\n }\n\n patch(patch: Partial): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.patch(patch),\n );\n }\n incrementalPatch(patch: Partial): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalPatch(patch),\n );\n }\n modify(mutationFunction: ModifyFunction): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.modify(mutationFunction),\n );\n }\n incrementalModify(mutationFunction: ModifyFunction): Promise {\n return runQueryUpdateFunction(\n this.asRxQuery,\n (doc) => doc.incrementalModify(mutationFunction),\n );\n }\n\n\n // we only set some methods of query-builder here\n // because the others depend on these ones\n where(_queryObj: MangoQuerySelector | keyof RxDocType | string): RxQuery {\n throw pluginMissing('query-builder');\n }\n sort(_params: string | MangoQuerySortPart): RxQuery {\n throw pluginMissing('query-builder');\n }\n skip(_amount: number | null): RxQuery {\n throw pluginMissing('query-builder');\n }\n limit(_amount: number | null): RxQuery {\n throw pluginMissing('query-builder');\n }\n\n enableLimitBuffer(bufferSize: number) {\n if (this._limitBufferSize !== null) {\n // Limit buffer has already been enabled, do nothing:\n return this;\n }\n if (this._lastExecStart !== 0) {\n console.error('Can\\'t use limit buffer if query has already executed');\n return this;\n }\n if (this.mangoQuery.skip || !this.mangoQuery.limit) {\n console.error('Right now, limit buffer only works on non-skip, limit queries.');\n return this;\n }\n this._limitBufferSize = bufferSize;\n return this;\n }\n\n enablePersistentQueryCache(backend: QueryCacheBackend) {\n if (this._persistentQueryCacheBackend) {\n // We've already tried to enable the query cache\n return this;\n }\n this._persistentQueryCacheBackend = backend;\n this._persistentQueryCacheLoaded = this._restoreQueryCacheFromPersistedState();\n return this;\n }\n\n private async _restoreQueryCacheFromPersistedState() {\n if (!this._persistentQueryCacheBackend) {\n // no cache backend provided, do nothing\n return;\n }\n if (this._persistentQueryCacheResult) {\n // we already restored the cache once, no need to run twice\n return;\n }\n if (this.mangoQuery.skip || this.op === 'count') {\n console.error('The persistent query cache only works on non-skip, non-count queries.');\n return;\n }\n\n // First, check if there are any query results persisted:\n const persistentQueryId = this.persistentQueryId();\n const value = await this._persistentQueryCacheBackend.getItem(`qc:${persistentQueryId}`);\n if (!value || !Array.isArray(value) || value.length === 0) {\n // eslint-disable-next-line no-console\n console.log(`no persistent query cache found in the backend, returning early ${this.toString()}`);\n return;\n }\n\n // If there are persisted ids, create our two Sets of ids from the cache:\n const persistedQueryCacheIds = new Set();\n const limitBufferIds = new Set();\n\n for (const id of value) {\n if (id.startsWith('lb-')) {\n limitBufferIds.add(id.replace('lb-', ''));\n } else {\n persistedQueryCacheIds.add(id);\n }\n }\n\n // eslint-disable-next-line no-console\n console.time(`Restoring persistent querycache ${this.toString()}`);\n\n // Next, pull the lwt from the cache:\n // TODO: if lwt is too old, should we just give up here? What if there are too many changedDocs?\n const lwt = (await this._persistentQueryCacheBackend.getItem(`qc:${persistentQueryId}:lwt`)) as string | null;\n if (!lwt) {\n return;\n }\n\n // If the query was persisted too long ago, just re-execute it.\n if (now() - Number(lwt) > RESTORE_QUERY_MAX_TIME_AGO) {\n return;\n }\n\n const primaryPath = this.collection.schema.primaryPath;\n\n const {documents: changedDocs} = await getChangedDocumentsSince(this.collection.storageInstance,\n RESTORE_QUERY_MAX_DOCS_CHANGED,\n // make sure we remove the monotonic clock (xxx.01, xxx.02) from the lwt timestamp to avoid issues with\n // lookups in indices (dexie)\n {id: '', lwt: Math.floor(Number(lwt)) - RESTORE_QUERY_UPDATE_DRIFT}\n );\n\n // If too many docs have changed, just give up and re-execute the query\n if (changedDocs.length === RESTORE_QUERY_MAX_DOCS_CHANGED) {\n return;\n }\n\n const changedDocIds = new Set(changedDocs.map((d) => d[primaryPath] as string));\n\n const docIdsWeNeedToFetch = [...persistedQueryCacheIds, ...limitBufferIds].filter((id) => !changedDocIds.has(id));\n\n // We use _queryCollectionByIds to fetch the remaining docs we need efficiently, pulling\n // from query cache if we can (and the storageInstance by ids if we can't):\n const otherPotentialMatchingDocs: RxDocumentData[] = [];\n await _queryCollectionByIds(this as any, otherPotentialMatchingDocs, docIdsWeNeedToFetch);\n\n // Now that we have all potential documents, we just filter (in-memory) the ones that still match our query:\n let docsData: RxDocumentData[] = [];\n for (const doc of changedDocs.concat(otherPotentialMatchingDocs)) {\n if (this.doesDocumentDataMatch(doc)) {\n docsData.push(doc);\n }\n }\n\n // Sort the documents by the query's sort field:\n const normalizedMangoQuery = normalizeMangoQuery(\n this.collection.schema.jsonSchema,\n this.mangoQuery\n );\n const sortComparator = getSortComparator(this.collection.schema.jsonSchema, normalizedMangoQuery);\n const limit = normalizedMangoQuery.limit ? normalizedMangoQuery.limit : Infinity;\n docsData = docsData.sort(sortComparator);\n\n // We know for sure that all persisted and limit buffer ids (and changed docs before them) are in the correct\n // result set. And we can't be sure about any past that point. So cut it off there:\n const lastValidIndex = docsData.findLastIndex((d) => limitBufferIds.has(d[primaryPath] as string) || persistedQueryCacheIds.has(d[primaryPath] as string));\n docsData = docsData.slice(0, lastValidIndex + 1);\n\n // Now this is the trickiest part.\n // If we somehow have fewer docs than the limit of our query\n // (and this wasn't the case because before persistence)\n // then there is no way for us to know the correct results, and we re-exec:\n const unchangedItemsMayNowBeInResults = (\n this.mangoQuery.limit &&\n docsData.length < this.mangoQuery.limit &&\n persistedQueryCacheIds.size >= this.mangoQuery.limit\n );\n if (unchangedItemsMayNowBeInResults) {\n return;\n }\n\n // Our finalResults are the actual results of this query, and pastLimitItems are any remaining matching\n // documents we have left over (past the limit).\n const pastLimitItems = docsData.slice(limit);\n const finalResults = docsData.slice(0, limit);\n\n // If there are still items past the first LIMIT items, try to restore the limit buffer with them:\n if (limitBufferIds.size && pastLimitItems.length > 0) {\n this._limitBufferResults = pastLimitItems;\n } else {\n this._limitBufferResults = [];\n }\n\n // Finally, set the query's results to what we've pulled from disk:\n this._lastEnsureEqual = now();\n this._latestChangeEvent = this.collection._changeEventBuffer.counter;\n this._setResultData(finalResults);\n\n // eslint-disable-next-line no-console\n console.timeEnd(`Restoring persistent querycache ${this.toString()}`);\n }\n}\n\nexport function _getDefaultQuery(): MangoQuery {\n return {\n selector: {}\n };\n}\n\n/**\n * run this query through the QueryCache\n */\nexport function tunnelQueryCache(\n rxQuery: RxQueryBase\n): RxQuery {\n return rxQuery.collection._queryCache.getByQuery(rxQuery as any);\n}\n\nexport function createRxQuery(\n op: RxQueryOP,\n queryObj: MangoQuery,\n collection: RxCollection,\n other?: any\n) {\n runPluginHooks('preCreateRxQuery', {\n op,\n queryObj,\n collection,\n other\n });\n\n let ret = new RxQueryBase(op, queryObj, collection, other);\n\n // ensure when created with same params, only one is created\n ret = tunnelQueryCache(ret);\n // TODO: clear persistent query cache as well\n triggerCacheReplacement(collection);\n\n return ret;\n}\n\n/**\n * Check if the current results-state is in sync with the database\n * which means that no write event happened since the last run.\n * @return false if not which means it should re-execute\n */\nfunction _isResultsInSync(rxQuery: RxQueryBase): boolean {\n const currentLatestEventNumber = rxQuery.asRxQuery.collection._changeEventBuffer.getCounter();\n if (rxQuery._latestChangeEvent >= currentLatestEventNumber) {\n return true;\n } else {\n return false;\n }\n}\n\n\n/**\n * wraps __ensureEqual()\n * to ensure it does not run in parallel\n * @return true if has changed, false if not\n */\nfunction _ensureEqual(rxQuery: RxQueryBase): Promise {\n // Optimisation shortcut\n if (\n rxQuery.collection.database.destroyed ||\n _isResultsInSync(rxQuery)\n ) {\n return PROMISE_RESOLVE_FALSE;\n }\n\n rxQuery._ensureEqualQueue = rxQuery._ensureEqualQueue\n .then(() => __ensureEqual(rxQuery));\n return rxQuery._ensureEqualQueue;\n}\n\n\n/**\n * ensures that the results of this query is equal to the results which a query over the database would give\n * @return true if results have changed\n */\nasync function __ensureEqual(rxQuery: RxQueryBase): Promise {\n await rxQuery._persistentQueryCacheLoaded;\n\n rxQuery._lastEnsureEqual = now();\n\n /**\n * Optimisation shortcuts\n */\n if (\n // db is closed\n rxQuery.collection.database.destroyed ||\n // nothing happened since last run\n _isResultsInSync(rxQuery)\n ) {\n return PROMISE_RESOLVE_FALSE;\n }\n\n let ret = false;\n let mustReExec = false; // if this becomes true, a whole execution over the database is made\n if (rxQuery._latestChangeEvent === -1) {\n // have not executed yet -> must run\n mustReExec = true;\n }\n\n /**\n * try to use EventReduce to calculate the new results\n */\n if (!mustReExec) {\n const missedChangeEvents = rxQuery.asRxQuery.collection._changeEventBuffer.getFrom(rxQuery._latestChangeEvent + 1);\n if (missedChangeEvents === null) {\n // changeEventBuffer is of bounds -> we must re-execute over the database\n mustReExec = true;\n } else {\n rxQuery._latestChangeEvent = rxQuery.asRxQuery.collection._changeEventBuffer.getCounter();\n\n const runChangeEvents: RxChangeEvent[] = rxQuery.asRxQuery.collection\n ._changeEventBuffer\n .reduceByLastOfDoc(missedChangeEvents);\n\n if (rxQuery._limitBufferResults !== null) {\n // Check if any item in our limit buffer was modified by a change event\n for (const cE of runChangeEvents) {\n if (rxQuery._limitBufferResults.find((doc) => doc[rxQuery.collection.schema.primaryPath] === cE.documentId)) {\n // If so, the limit buffer is potential invalid -- let's just blow it up\n // TODO: could we instead update the documents in the limit buffer?\n rxQuery._limitBufferResults = null;\n break;\n }\n }\n }\n\n if (rxQuery.includesDeleted) {\n return rxQuery._execOverDatabase().then((newResultData) => {\n rxQuery._setResultData(newResultData);\n return true;\n });\n } else if (rxQuery.op === 'count') {\n // 'count' query\n const previousCount = ensureNotFalsy(rxQuery._result).count;\n let newCount = previousCount;\n runChangeEvents.forEach(cE => {\n const didMatchBefore = cE.previousDocumentData && rxQuery.doesDocumentDataMatch(cE.previousDocumentData);\n const doesMatchNow = rxQuery.doesDocumentDataMatch(cE.documentData);\n\n if (!didMatchBefore && doesMatchNow) {\n newCount++;\n }\n if (didMatchBefore && !doesMatchNow) {\n newCount--;\n }\n });\n if (newCount !== previousCount) {\n ret = true; // true because results changed\n rxQuery._setResultData(newCount as any);\n }\n } else {\n // 'find' or 'findOne' query\n const eventReduceResult = calculateNewResults(\n rxQuery as any,\n runChangeEvents\n );\n if (eventReduceResult.runFullQueryAgain) {\n // could not calculate the new results, execute must be done\n mustReExec = true;\n } else if (eventReduceResult.changed) {\n // we got the new results, we do not have to re-execute, mustReExec stays false\n ret = true; // true because results changed\n rxQuery._setResultData(eventReduceResult.newResults as any);\n }\n }\n }\n }\n\n // oh no we have to re-execute the whole query over the database\n if (mustReExec) {\n return rxQuery._execOverDatabase()\n .then(newResultData => {\n\n /**\n * The RxStorage is defined to always first emit events and then return\n * on bulkWrite() calls. So here we have to use the counter AFTER the execOverDatabase()\n * has been run, not the one from before.\n */\n rxQuery._latestChangeEvent = rxQuery.collection._changeEventBuffer.getCounter();\n\n // A count query needs a different has-changed check.\n if (typeof newResultData === 'number') {\n if (\n !rxQuery._result ||\n newResultData !== rxQuery._result.count\n ) {\n ret = true;\n rxQuery._setResultData(newResultData as any);\n }\n return ret;\n }\n if (\n !rxQuery._result ||\n !areRxDocumentArraysEqual(\n rxQuery.collection.schema.primaryPath,\n newResultData,\n rxQuery._result.docsData\n )\n ) {\n ret = true; // true because results changed\n rxQuery._setResultData(newResultData as any);\n }\n return ret;\n })\n .then(async (returnValue) => {\n await updatePersistentQueryCache(rxQuery);\n return returnValue;\n });\n }\n\n return ret; // true if results have changed\n}\n\n\nasync function updatePersistentQueryCache(rxQuery: RxQueryBase) {\n if (!rxQuery._persistentQueryCacheBackend) {\n return;\n }\n\n const backend = rxQuery._persistentQueryCacheBackend;\n\n const key = rxQuery.persistentQueryId();\n\n // update _persistedQueryCacheResult\n rxQuery._persistentQueryCacheResult = rxQuery._result?.docsKeys ?? [];\n\n const idsToPersist = [...rxQuery._persistentQueryCacheResult];\n if (rxQuery._limitBufferResults) {\n rxQuery._limitBufferResults.forEach((d) => {\n idsToPersist.push(`lb-${d[rxQuery.collection.schema.primaryPath]}`);\n });\n }\n // eslint-disable-next-line no-console\n console.time(`Query persistence: persisting results of ${JSON.stringify(rxQuery.mangoQuery)}`);\n // persist query cache\n const lwt = rxQuery._result?.time ?? RX_META_LWT_MINIMUM;\n\n await Promise.all([\n backend.setItem(`qc:${String(key)}`, idsToPersist),\n backend.setItem(`qc:${String(key)}:lwt`, lwt.toString()),\n ]);\n\n // eslint-disable-next-line no-console\n console.timeEnd(`Query persistence: persisting results of ${JSON.stringify(rxQuery.mangoQuery)}`);\n}\n\n\n// Refactored out of `queryCollection`: modifies the docResults array to fill it with data\nasync function _queryCollectionByIds(rxQuery: RxQuery | RxQueryBase, docResults: RxDocumentData[], docIds: string[]) {\n const collection = rxQuery.collection;\n docIds = docIds.filter(docId => {\n // first try to fill from docCache\n const docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (docData) {\n if (!docData._deleted) {\n docResults.push(docData);\n }\n return false;\n } else {\n return true;\n }\n });\n\n // otherwise get from storage\n if (docIds.length > 0) {\n const docsMap = await collection.storageInstance.findDocumentsById(docIds, false);\n Object.values(docsMap).forEach(docData => {\n docResults.push(docData);\n });\n }\n}\n\n/**\n * @returns a format of the query that can be used with the storage\n * when calling RxStorageInstance().query()\n */\nexport function prepareQuery(\n schema: RxJsonSchema>,\n mutateableQuery: FilledMangoQuery\n): PreparedQuery {\n if (!mutateableQuery.sort) {\n throw newRxError('SNH', {\n query: mutateableQuery\n });\n }\n\n /**\n * Store the query plan together with the\n * prepared query to save performance.\n */\n const queryPlan = getQueryPlan(\n schema,\n mutateableQuery\n );\n\n return {\n query: mutateableQuery,\n queryPlan\n };\n}\n\n/**\n * Runs the query over the storage instance\n * of the collection.\n * Does some optimizations to ensure findById is used\n * when specific queries are used.\n */\nexport async function queryCollection(\n rxQuery: RxQuery | RxQueryBase\n): Promise[]> {\n await rxQuery._persistentQueryCacheLoaded;\n\n let docs: RxDocumentData[] = [];\n const collection = rxQuery.collection;\n\n /**\n * Optimizations shortcut.\n * If query is find-one-document-by-id,\n * then we do not have to use the slow query() method\n * but instead can use findDocumentsById()\n */\n if (rxQuery.isFindOneByIdQuery) {\n if (Array.isArray(rxQuery.isFindOneByIdQuery)) {\n let docIds = rxQuery.isFindOneByIdQuery;\n docIds = docIds.filter(docId => {\n // first try to fill from docCache\n const docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (docData) {\n if (!docData._deleted) {\n docs.push(docData);\n }\n return false;\n } else {\n return true;\n }\n });\n // otherwise get from storage\n if (docIds.length > 0) {\n const docsFromStorage = await collection.storageInstance.findDocumentsById(docIds, false);\n appendToArray(docs, docsFromStorage);\n }\n await _queryCollectionByIds(rxQuery, docs, rxQuery.isFindOneByIdQuery);\n } else {\n const docId = rxQuery.isFindOneByIdQuery;\n\n // first try to fill from docCache\n let docData = rxQuery.collection._docCache.getLatestDocumentDataIfExists(docId);\n if (!docData) {\n // otherwise get from storage\n const fromStorageList = await collection.storageInstance.findDocumentsById([docId], false);\n if (fromStorageList[0]) {\n docData = fromStorageList[0];\n }\n }\n if (docData && !docData._deleted) {\n docs.push(docData);\n }\n }\n } else {\n const preparedQuery = rxQuery.getPreparedQuery();\n const queryResult = await collection.storageInstance.query(preparedQuery);\n if (rxQuery._limitBufferSize !== null && rxQuery.mangoQuery.limit && queryResult.documents.length > rxQuery.mangoQuery.limit) {\n // If there are more than query.limit results, we pull out our buffer items from the\n // last rxQuery._limitBufferSize items of the results.\n rxQuery._limitBufferResults = queryResult.documents.splice(rxQuery.mangoQuery.limit);\n }\n docs = queryResult.documents;\n }\n return docs;\n}\n\n/**\n * Returns true if the given query\n * selects exactly one document by its id.\n * Used to optimize performance because these kind of\n * queries do not have to run over an index and can use get-by-id instead.\n * Returns false if no query of that kind.\n * Returns the document id otherwise.\n */\nexport function isFindOneByIdQuery(\n primaryPath: string,\n query: MangoQuery\n): false | string | string[] {\n // must have exactly one operator which must be $eq || $in\n if (\n !query.skip &&\n query.selector &&\n Object.keys(query.selector).length === 1 &&\n query.selector[primaryPath]\n ) {\n const value: any = query.selector[primaryPath];\n if (typeof value === 'string') {\n return value;\n } else if (\n Object.keys(value).length === 1 &&\n typeof value.$eq === 'string'\n ) {\n return value.$eq;\n }\n\n // same with $in string arrays\n if (\n Object.keys(value).length === 1 &&\n Array.isArray(value.$eq) &&\n // must only contain strings\n !(value.$eq as any[]).find(r => typeof r !== 'string')\n ) {\n return value.$eq;\n }\n }\n return false;\n}\n\n\nexport function isRxQuery(obj: any): boolean {\n return obj instanceof RxQueryBase;\n}\n"],"mappings":"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","ignoreList":[]} \ No newline at end of file diff --git a/dist/types/rx-query-helper.d.ts b/dist/types/rx-query-helper.d.ts index b15d69b6743..79876a8c3e8 100644 --- a/dist/types/rx-query-helper.d.ts +++ b/dist/types/rx-query-helper.d.ts @@ -1,4 +1,4 @@ -import type { DeterministicSortComparator, FilledMangoQuery, MangoQuery, QueryMatcher, RxDocument, RxDocumentData, RxJsonSchema, RxQuery } from './types/index.d.ts'; +import type { DeterministicSortComparator, FilledMangoQuery, MangoQuery, MangoQuerySelector, QueryMatcher, RxDocument, RxDocumentData, RxJsonSchema, RxQuery } from './types/index.d.ts'; /** * Normalize the query to ensure we have all fields set * and queries that represent the same query logic are detected as equal by the caching. @@ -17,3 +17,9 @@ export declare function getSortComparator(schema: RxJsonSchema(_schema: RxJsonSchema | RxJsonSchema>, query: FilledMangoQuery): QueryMatcher>; export declare function runQueryUpdateFunction(rxQuery: RxQuery, fn: (doc: RxDocument) => Promise>): Promise; +/** + * Checks if a given selector includes deleted documents. + * @param selector The MangoQuerySelector to check + * @returns True if the selector includes deleted documents, false otherwise + */ +export declare function selectorIncludesDeleted(selector: MangoQuerySelector | undefined): boolean; diff --git a/dist/types/rx-query.d.ts b/dist/types/rx-query.d.ts index 7c6b0fdc70d..401b489ff87 100644 --- a/dist/types/rx-query.d.ts +++ b/dist/types/rx-query.d.ts @@ -29,6 +29,7 @@ export declare class RxQueryBase>, collection: RxCollection, other?: any); get $(): BehaviorSubject; get $$(): Reactivity; + get includesDeleted(): boolean; _latestChangeEvent: -1 | number; _lastExecStart: number; _lastExecEnd: number; diff --git a/examples/vite-vanilla-ts/package.json b/examples/vite-vanilla-ts/package.json index ecbe06f65a8..2b2134a0f0a 100644 --- a/examples/vite-vanilla-ts/package.json +++ b/examples/vite-vanilla-ts/package.json @@ -14,6 +14,7 @@ "test:e2e": "testcafe chrome -e test/ --hostname localhost --selector-timeout 8000 --retry-test-pages" }, "devDependencies": { + "@swc/core": "1.6.0", "async-test-util": "2.5.0", "concurrently": "8.2.2", "copyfiles": "2.4.1", diff --git a/src/rx-query-helper.ts b/src/rx-query-helper.ts index 5a9b5490198..1862b475afc 100644 --- a/src/rx-query-helper.ts +++ b/src/rx-query-helper.ts @@ -5,7 +5,10 @@ import type { DeterministicSortComparator, FilledMangoQuery, MangoQuery, + MangoQueryOperators, + MangoQuerySelector, MangoQuerySortDirection, + PropertyType, QueryMatcher, RxDocument, RxDocumentData, @@ -248,3 +251,61 @@ export async function runQueryUpdateFunction( return result as any; } } + +/** + * Checks if a given selector includes deleted documents. + * @param selector The MangoQuerySelector to check + * @returns True if the selector includes deleted documents, false otherwise + */ +export function selectorIncludesDeleted( + selector: MangoQuerySelector | undefined +): boolean { + if (!selector) { + return false; + } + + const isTrue = (value: unknown): boolean => + value === true || + (typeof value === 'object' && + value !== null && + '$eq' in value && + (value as MangoQueryOperators).$eq === true); + + + const isNotFalse = (value: unknown): boolean => + value === true || + (typeof value === 'object' && + value !== null && + '$ne' in value && + (value as MangoQueryOperators).$ne === false); + + const hasDeletedTrue = ( + condition: MangoQuerySelector + ): boolean => + '_deleted' in condition && + (isTrue(condition._deleted as PropertyType) || + isNotFalse( + condition._deleted as PropertyType + )); + + if ('_deleted' in selector) { + return ( + isTrue(selector._deleted as PropertyType) || + isNotFalse(selector._deleted as PropertyType) + ); + } + + if ('$or' in selector && Array.isArray(selector.$or)) { + return selector.$or.some(hasDeletedTrue); + } + + if ('$and' in selector && Array.isArray(selector.$and)) { + return selector.$and.some(hasDeletedTrue); + } + + if ('$nor' in selector && Array.isArray(selector.$nor)) { + return !selector.$nor.every((condition) => !hasDeletedTrue(condition)); + } + + return false; +} diff --git a/src/rx-query.ts b/src/rx-query.ts index 83e74bdb7c0..8ac89dd2f56 100644 --- a/src/rx-query.ts +++ b/src/rx-query.ts @@ -49,7 +49,8 @@ import { getQueryMatcher, getSortComparator, normalizeMangoQuery, - runQueryUpdateFunction + runQueryUpdateFunction, + selectorIncludesDeleted } from './rx-query-helper.ts'; import { RxQuerySingleResult } from './rx-query-single-result.ts'; @@ -199,6 +200,10 @@ export class RxQueryBase< ) as any; } + get includesDeleted(): boolean { + return selectorIncludesDeleted(this.mangoQuery.selector); + } + // stores the changeEvent-number of the last handled change-event public _latestChangeEvent: -1 | number = -1; @@ -418,7 +423,14 @@ export class RxQueryBase< ) }; - (hookInput.mangoQuery.selector as any)._deleted = { $eq: false }; + // Set _deleted to false if not explicitly set in selector + if (!this.includesDeleted) { + hookInput.mangoQuery.selector = { + ...hookInput.mangoQuery.selector, + _deleted: { $eq: false }, + }; + } + if (hookInput.mangoQuery.index) { hookInput.mangoQuery.index.unshift('_deleted'); } @@ -816,7 +828,12 @@ async function __ensureEqual(rxQuery: RxQueryBase): P } } - if (rxQuery.op === 'count') { + if (rxQuery.includesDeleted) { + return rxQuery._execOverDatabase().then((newResultData) => { + rxQuery._setResultData(newResultData); + return true; + }); + } else if (rxQuery.op === 'count') { // 'count' query const previousCount = ensureNotFalsy(rxQuery._result).count; let newCount = previousCount;