@squidcloud/local-backend 1.0.450 → 1.0.452
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend/src/actions.js +264 -0
- package/dist/backend/src/actions.js.map +1 -0
- package/dist/backend/src/index.js +24 -0
- package/dist/backend/src/index.js.map +1 -0
- package/dist/backend/src/llm-service.js +8 -0
- package/dist/backend/src/llm-service.js.map +1 -0
- package/dist/backend/src/metadata.js +336 -0
- package/dist/backend/src/metadata.js.map +1 -0
- package/dist/backend/src/project.js +31 -0
- package/dist/backend/src/project.js.map +1 -0
- package/dist/backend/src/public-types.js +32 -0
- package/dist/backend/src/public-types.js.map +1 -0
- package/dist/backend/src/squid.service.js +194 -0
- package/dist/backend/src/squid.service.js.map +1 -0
- package/dist/backend/src/utils.js +13 -0
- package/dist/backend/src/utils.js.map +1 -0
- package/dist/internal-common/src/ai/ai-model.registry.js +564 -0
- package/dist/internal-common/src/ai/ai-model.registry.js.map +1 -0
- package/dist/internal-common/src/public-types/ai-agent.public-types.js.map +1 -1
- package/dist/internal-common/src/public-types/ai-common.public-types.js +1 -1
- package/dist/internal-common/src/public-types/ai-common.public-types.js.map +1 -1
- package/dist/internal-common/src/public-types/ai-matchmaking.public-types.js +3 -0
- package/dist/internal-common/src/public-types/ai-matchmaking.public-types.js.map +1 -0
- package/dist/internal-common/src/public-types/external-auth/external-auth.public-types.js +3 -0
- package/dist/internal-common/src/public-types/external-auth/external-auth.public-types.js.map +1 -0
- package/dist/internal-common/src/public-types/http-status.public-types.js +64 -0
- package/dist/internal-common/src/public-types/http-status.public-types.js.map +1 -0
- package/dist/internal-common/src/public-types/regions.public-types.js +5 -0
- package/dist/internal-common/src/public-types/regions.public-types.js.map +1 -0
- package/dist/internal-common/src/public-types/serialized-query.public-types.js +3 -0
- package/dist/internal-common/src/public-types/serialized-query.public-types.js.map +1 -0
- package/dist/internal-common/src/public-types/web.public-types.js +3 -0
- package/dist/internal-common/src/public-types/web.public-types.js.map +1 -0
- package/dist/internal-common/src/public-types-backend/bundle-data.public-types.js +2 -1
- package/dist/internal-common/src/public-types-backend/bundle-data.public-types.js.map +1 -1
- package/dist/internal-common/src/public-types-backend/llm.public-types.js +3 -0
- package/dist/internal-common/src/public-types-backend/llm.public-types.js.map +1 -0
- package/dist/internal-common/src/public-utils/context-utils.js +12 -0
- package/dist/internal-common/src/public-utils/context-utils.js.map +1 -0
- package/dist/internal-common/src/public-utils/id-utils.js +60 -0
- package/dist/internal-common/src/public-utils/id-utils.js.map +1 -0
- package/dist/internal-common/src/types/ai-knowledge-base.types.js +3 -0
- package/dist/internal-common/src/types/ai-knowledge-base.types.js.map +1 -0
- package/dist/internal-common/src/types/ai-matchmaking.types.js +3 -0
- package/dist/internal-common/src/types/ai-matchmaking.types.js.map +1 -0
- package/dist/internal-common/src/types/application.types.js +4 -0
- package/dist/internal-common/src/types/application.types.js.map +1 -1
- package/dist/internal-common/src/types/backend-function.types.js +3 -0
- package/dist/internal-common/src/types/backend-function.types.js.map +1 -0
- package/dist/internal-common/src/types/backend-run.types.js.map +1 -1
- package/dist/internal-common/src/types/bundle-data.types.js.map +1 -1
- package/dist/internal-common/src/types/headers.types.js +13 -0
- package/dist/internal-common/src/types/headers.types.js.map +1 -0
- package/dist/internal-common/src/types/integrration-lifecycle.types.js +3 -0
- package/dist/internal-common/src/types/integrration-lifecycle.types.js.map +1 -0
- package/dist/internal-common/src/types/management-api-key.types.js +5 -0
- package/dist/internal-common/src/types/management-api-key.types.js.map +1 -0
- package/dist/internal-common/src/types/mutation.types.js +187 -0
- package/dist/internal-common/src/types/mutation.types.js.map +1 -0
- package/dist/internal-common/src/types/notification.types.js +3 -0
- package/dist/internal-common/src/types/notification.types.js.map +1 -0
- package/dist/internal-common/src/types/quota.types.js +52 -0
- package/dist/internal-common/src/types/quota.types.js.map +1 -0
- package/dist/internal-common/src/types/socket.types.js +6 -0
- package/dist/internal-common/src/types/socket.types.js.map +1 -0
- package/dist/internal-common/src/types/url-shortener.types.js +3 -0
- package/dist/internal-common/src/types/url-shortener.types.js.map +1 -0
- package/dist/internal-common/src/utils/array.js +75 -0
- package/dist/internal-common/src/utils/array.js.map +1 -0
- package/dist/internal-common/src/utils/backend-transforms.js +11 -4
- package/dist/internal-common/src/utils/backend-transforms.js.map +1 -1
- package/dist/internal-common/src/utils/e2e-test-utils.js +7 -0
- package/dist/internal-common/src/utils/e2e-test-utils.js.map +1 -0
- package/dist/internal-common/src/utils/file-utils.js +18 -0
- package/dist/internal-common/src/utils/file-utils.js.map +1 -0
- package/dist/internal-common/src/utils/http.js +0 -2
- package/dist/internal-common/src/utils/http.js.map +1 -1
- package/dist/internal-common/src/utils/lock.manager.js +40 -0
- package/dist/internal-common/src/utils/lock.manager.js.map +1 -0
- package/dist/internal-common/src/utils/metric-utils.js +105 -0
- package/dist/internal-common/src/utils/metric-utils.js.map +1 -0
- package/dist/internal-common/src/utils/python-ipc.js +218 -0
- package/dist/internal-common/src/utils/python-ipc.js.map +1 -0
- package/dist/internal-common/src/utils/squid-service.utils.js +33 -5
- package/dist/internal-common/src/utils/squid-service.utils.js.map +1 -1
- package/dist/internal-common/src/utils/trace-id-generator.js +8 -0
- package/dist/internal-common/src/utils/trace-id-generator.js.map +1 -0
- package/dist/internal-common/src/utils/tsoa-utils.js +26 -24
- package/dist/internal-common/src/utils/tsoa-utils.js.map +1 -1
- package/dist/internal-common/src/utils/validation.js +46 -0
- package/dist/internal-common/src/utils/validation.js.map +1 -0
- package/dist/internal-common/src/utils.js +7 -0
- package/dist/internal-common/src/utils.js.map +1 -1
- package/dist/local-backend/src/local-backend-socket.service.js +20 -3
- package/dist/local-backend/src/local-backend-socket.service.js.map +1 -1
- package/dist/local-backend/src/local-backend.app.js +43 -0
- package/dist/local-backend/src/local-backend.app.js.map +1 -1
- package/dist/local-backend/src/local-backend.module.js +9 -4
- package/dist/local-backend/src/local-backend.module.js.map +1 -1
- package/dist/local-backend/src/local-backend.service.js +73 -10
- package/dist/local-backend/src/local-backend.service.js.map +1 -1
- package/dist/local-backend/src/local-backend.types.js +3 -2
- package/dist/local-backend/src/local-backend.types.js.map +1 -1
- package/dist/local-backend/src/main.js +143 -11
- package/dist/local-backend/src/main.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/typescript-client/src/admin-client.js +23 -0
- package/dist/typescript-client/src/admin-client.js.map +1 -0
- package/dist/typescript-client/src/agent/ai-agent-client-reference.js +392 -0
- package/dist/typescript-client/src/agent/ai-agent-client-reference.js.map +1 -0
- package/dist/typescript-client/src/agent/ai-agent-client.js +60 -0
- package/dist/typescript-client/src/agent/ai-agent-client.js.map +1 -0
- package/dist/typescript-client/src/agent/ai-agent-client.types.js +5 -0
- package/dist/typescript-client/src/agent/ai-agent-client.types.js.map +1 -0
- package/dist/typescript-client/src/ai-audio-client.js +20 -0
- package/dist/typescript-client/src/ai-audio-client.js.map +1 -0
- package/dist/typescript-client/src/ai-client.js +110 -0
- package/dist/typescript-client/src/ai-client.js.map +1 -0
- package/dist/typescript-client/src/ai-files-client.js +27 -0
- package/dist/typescript-client/src/ai-files-client.js.map +1 -0
- package/dist/typescript-client/src/ai-image-client.js +20 -0
- package/dist/typescript-client/src/ai-image-client.js.map +1 -0
- package/dist/typescript-client/src/ai-knowledge-base/ai-knowledge-base-client-reference.js +111 -0
- package/dist/typescript-client/src/ai-knowledge-base/ai-knowledge-base-client-reference.js.map +1 -0
- package/dist/typescript-client/src/ai-knowledge-base/ai-knowledge-base-client.js +24 -0
- package/dist/typescript-client/src/ai-knowledge-base/ai-knowledge-base-client.js.map +1 -0
- package/dist/typescript-client/src/ai-matchmaking-client.js +93 -0
- package/dist/typescript-client/src/ai-matchmaking-client.js.map +1 -0
- package/dist/typescript-client/src/api-client.js +55 -0
- package/dist/typescript-client/src/api-client.js.map +1 -0
- package/dist/typescript-client/src/auth.manager.js +36 -0
- package/dist/typescript-client/src/auth.manager.js.map +1 -0
- package/dist/typescript-client/src/backend-function.manager.js +60 -0
- package/dist/typescript-client/src/backend-function.manager.js.map +1 -0
- package/dist/typescript-client/src/client-customization.utils.js +11 -0
- package/dist/typescript-client/src/client-customization.utils.js.map +1 -0
- package/dist/typescript-client/src/client-id.service.js +60 -0
- package/dist/typescript-client/src/client-id.service.js.map +1 -0
- package/dist/typescript-client/src/collection-reference.factory.js +28 -0
- package/dist/typescript-client/src/collection-reference.factory.js.map +1 -0
- package/dist/typescript-client/src/collection-reference.js +181 -0
- package/dist/typescript-client/src/collection-reference.js.map +1 -0
- package/dist/typescript-client/src/connection-details.js +25 -0
- package/dist/typescript-client/src/connection-details.js.map +1 -0
- package/dist/typescript-client/src/console-utils.js +25 -0
- package/dist/typescript-client/src/console-utils.js.map +1 -0
- package/dist/typescript-client/src/data.manager.js +608 -0
- package/dist/typescript-client/src/data.manager.js.map +1 -0
- package/dist/typescript-client/src/destruct.manager.js +46 -0
- package/dist/typescript-client/src/destruct.manager.js.map +1 -0
- package/dist/typescript-client/src/distributed-lock.manager.js +108 -0
- package/dist/typescript-client/src/distributed-lock.manager.js.map +1 -0
- package/dist/typescript-client/src/document-identity.service.js +24 -0
- package/dist/typescript-client/src/document-identity.service.js.map +1 -0
- package/dist/typescript-client/src/document-reference.factory.js +52 -0
- package/dist/typescript-client/src/document-reference.factory.js.map +1 -0
- package/dist/typescript-client/src/document-reference.js +207 -0
- package/dist/typescript-client/src/document-reference.js.map +1 -0
- package/dist/typescript-client/src/document-store.js +184 -0
- package/dist/typescript-client/src/document-store.js.map +1 -0
- package/dist/typescript-client/src/execute-function-options.js +47 -0
- package/dist/typescript-client/src/execute-function-options.js.map +1 -0
- package/dist/typescript-client/src/external-auth-client.js +32 -0
- package/dist/typescript-client/src/external-auth-client.js.map +1 -0
- package/dist/typescript-client/src/extraction-client.js +27 -0
- package/dist/typescript-client/src/extraction-client.js.map +1 -0
- package/dist/typescript-client/src/file-args-transformer.js +44 -0
- package/dist/typescript-client/src/file-args-transformer.js.map +1 -0
- package/dist/typescript-client/src/index.js +80 -0
- package/dist/typescript-client/src/index.js.map +1 -0
- package/dist/typescript-client/src/integration-client.js +62 -0
- package/dist/typescript-client/src/integration-client.js.map +1 -0
- package/dist/typescript-client/src/job-client.js +67 -0
- package/dist/typescript-client/src/job-client.js.map +1 -0
- package/dist/typescript-client/src/management-client.js +66 -0
- package/dist/typescript-client/src/management-client.js.map +1 -0
- package/dist/typescript-client/src/mutation/mutation-sender.js +38 -0
- package/dist/typescript-client/src/mutation/mutation-sender.js.map +1 -0
- package/dist/typescript-client/src/native-query-manager.js +13 -0
- package/dist/typescript-client/src/native-query-manager.js.map +1 -0
- package/dist/typescript-client/src/notification-client.js +32 -0
- package/dist/typescript-client/src/notification-client.js.map +1 -0
- package/dist/typescript-client/src/observability-client.js +56 -0
- package/dist/typescript-client/src/observability-client.js.map +1 -0
- package/dist/typescript-client/src/public-types.js +47 -0
- package/dist/typescript-client/src/public-types.js.map +1 -0
- package/dist/typescript-client/src/public-utils.js +18 -0
- package/dist/typescript-client/src/public-utils.js.map +1 -0
- package/dist/typescript-client/src/query/deserializer.js +78 -0
- package/dist/typescript-client/src/query/deserializer.js.map +1 -0
- package/dist/typescript-client/src/query/join-query-builder.factory.js +335 -0
- package/dist/typescript-client/src/query/join-query-builder.factory.js.map +1 -0
- package/dist/typescript-client/src/query/local-query-manager.js +29 -0
- package/dist/typescript-client/src/query/local-query-manager.js.map +1 -0
- package/dist/typescript-client/src/query/pagination.js +205 -0
- package/dist/typescript-client/src/query/pagination.js.map +1 -0
- package/dist/typescript-client/src/query/query-builder.factory.js +423 -0
- package/dist/typescript-client/src/query/query-builder.factory.js.map +1 -0
- package/dist/typescript-client/src/query/query-sender.js +81 -0
- package/dist/typescript-client/src/query/query-sender.js.map +1 -0
- package/dist/typescript-client/src/query/query-subscription.manager.js +820 -0
- package/dist/typescript-client/src/query/query-subscription.manager.js.map +1 -0
- package/dist/typescript-client/src/query/query.types.js +11 -0
- package/dist/typescript-client/src/query/query.types.js.map +1 -0
- package/dist/typescript-client/src/query/snapshot-emitter.js +3 -0
- package/dist/typescript-client/src/query/snapshot-emitter.js.map +1 -0
- package/dist/typescript-client/src/query-utils.js +21 -0
- package/dist/typescript-client/src/query-utils.js.map +1 -0
- package/dist/typescript-client/src/queue.manager.js +123 -0
- package/dist/typescript-client/src/queue.manager.js.map +1 -0
- package/dist/typescript-client/src/rate-limiter.js +35 -0
- package/dist/typescript-client/src/rate-limiter.js.map +1 -0
- package/dist/typescript-client/src/rpc.manager.js +214 -0
- package/dist/typescript-client/src/rpc.manager.js.map +1 -0
- package/dist/typescript-client/src/runtime-options.js +9 -0
- package/dist/typescript-client/src/runtime-options.js.map +1 -0
- package/dist/typescript-client/src/scheduler-client.js +29 -0
- package/dist/typescript-client/src/scheduler-client.js.map +1 -0
- package/dist/typescript-client/src/secret.client.js +62 -0
- package/dist/typescript-client/src/secret.client.js.map +1 -0
- package/dist/typescript-client/src/socket.manager.js +249 -0
- package/dist/typescript-client/src/socket.manager.js.map +1 -0
- package/dist/typescript-client/src/squid-http-client.js +135 -0
- package/dist/typescript-client/src/squid-http-client.js.map +1 -0
- package/dist/typescript-client/src/squid.js +259 -0
- package/dist/typescript-client/src/squid.js.map +1 -0
- package/dist/typescript-client/src/storage-client.js +51 -0
- package/dist/typescript-client/src/storage-client.js.map +1 -0
- package/dist/typescript-client/src/types.js +18 -0
- package/dist/typescript-client/src/types.js.map +1 -0
- package/dist/typescript-client/src/version.js +5 -0
- package/dist/typescript-client/src/version.js.map +1 -0
- package/dist/typescript-client/src/web-client.js +92 -0
- package/dist/typescript-client/src/web-client.js.map +1 -0
- package/dist/typescript-client/src/webhook.manager.js +85 -0
- package/dist/typescript-client/src/webhook.manager.js.map +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QuerySubscriptionManager = exports.FETCH_BEYOND_LIMIT = void 0;
|
|
4
|
+
const assertic_1 = require("assertic");
|
|
5
|
+
const otrie_1 = require("otrie");
|
|
6
|
+
const rxjs_1 = require("rxjs");
|
|
7
|
+
const operators_1 = require("rxjs/operators");
|
|
8
|
+
const query_public_context_1 = require("../../../internal-common/src/public-types-backend/query.public-context");
|
|
9
|
+
const document_types_1 = require("../../../internal-common/src/types/document.types");
|
|
10
|
+
const query_types_1 = require("../../../internal-common/src/types/query.types");
|
|
11
|
+
const array_1 = require("../../../internal-common/src/utils/array");
|
|
12
|
+
const global_utils_1 = require("../../../internal-common/src/utils/global.utils");
|
|
13
|
+
const object_1 = require("../../../internal-common/src/utils/object");
|
|
14
|
+
const serialization_1 = require("../../../internal-common/src/utils/serialization");
|
|
15
|
+
const query_types_2 = require("./query.types");
|
|
16
|
+
exports.FETCH_BEYOND_LIMIT = 100;
|
|
17
|
+
const LIMIT_UNDERFLOW_TRIGGER = 20;
|
|
18
|
+
class QuerySubscriptionManager {
|
|
19
|
+
constructor(rpcManager, clientIdService, documentStore, destructManager, documentIdentityService, querySender, socketManager, lockManager) {
|
|
20
|
+
this.rpcManager = rpcManager;
|
|
21
|
+
this.clientIdService = clientIdService;
|
|
22
|
+
this.documentStore = documentStore;
|
|
23
|
+
this.destructManager = destructManager;
|
|
24
|
+
this.documentIdentityService = documentIdentityService;
|
|
25
|
+
this.querySender = querySender;
|
|
26
|
+
this.socketManager = socketManager;
|
|
27
|
+
this.lockManager = lockManager;
|
|
28
|
+
this.onOrphanDocuments = new rxjs_1.Subject();
|
|
29
|
+
this.ongoingQueries = new Map();
|
|
30
|
+
this.clientRequestIdToLocalDocuments = new Map();
|
|
31
|
+
this.localDocumentToClientRequestIds = new Map();
|
|
32
|
+
this.queryMappingManager = new ClientQueryMappingManager();
|
|
33
|
+
this.queryResultsSubject = new rxjs_1.Subject();
|
|
34
|
+
this.documentIdentityService.observeChanges().subscribe(this.migrateDocIds.bind(this));
|
|
35
|
+
this.clientIdService.observeClientReadyToBeRegenerated().subscribe(() => {
|
|
36
|
+
this.refreshOngoingQueries();
|
|
37
|
+
});
|
|
38
|
+
this.destructManager.onPreDestruct(() => {
|
|
39
|
+
this.preDestruct();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
dumpSubscriptionInfo() {
|
|
43
|
+
console.log('Ongoing queries:', this.ongoingQueries);
|
|
44
|
+
console.log('ClientRequestId to local documents:', this.clientRequestIdToLocalDocuments);
|
|
45
|
+
console.log('Local documents to clientRequestId:', this.localDocumentToClientRequestIds);
|
|
46
|
+
}
|
|
47
|
+
observeQueryResults() {
|
|
48
|
+
return this.queryResultsSubject.asObservable();
|
|
49
|
+
}
|
|
50
|
+
hasOngoingQuery(clientRequestId) {
|
|
51
|
+
return this.ongoingQueries.has(clientRequestId);
|
|
52
|
+
}
|
|
53
|
+
getQuery(clientRequestId) {
|
|
54
|
+
return (0, assertic_1.truthy)(this.ongoingQueries.get(clientRequestId), 'UNKNOWN_QUERY').query;
|
|
55
|
+
}
|
|
56
|
+
setGotInitialResult(clientRequestId) {
|
|
57
|
+
const ongoingQuery = this.ongoingQueries.get(clientRequestId);
|
|
58
|
+
if (ongoingQuery?.gotInitialResponse) {
|
|
59
|
+
this.removeClientRequestIdMapping(clientRequestId);
|
|
60
|
+
}
|
|
61
|
+
if (ongoingQuery) {
|
|
62
|
+
ongoingQuery.gotInitialResponse = true;
|
|
63
|
+
ongoingQuery.isInFlight = false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
findQueriesForDocument(doc, squidDocId) {
|
|
67
|
+
const { collectionName, integrationId } = (0, document_types_1.parseSquidDocId)(squidDocId);
|
|
68
|
+
const mapping = this.queryMappingManager.getMapping(collectionName, integrationId);
|
|
69
|
+
if (!mapping)
|
|
70
|
+
return [];
|
|
71
|
+
return findQueriesForDocumentSync(mapping, doc);
|
|
72
|
+
}
|
|
73
|
+
setClientRequestIdsForLocalDoc(squidDocId, properties) {
|
|
74
|
+
const clientRequestIdsBefore = this.localDocumentToClientRequestIds.get(squidDocId) || new Set();
|
|
75
|
+
const clientRequestIdsAfter = new Set(properties
|
|
76
|
+
? this.findQueriesForDocument(properties, squidDocId).map(querySubscriptionId => (0, query_types_1.parseQuerySubscriptionId)(querySubscriptionId).clientRequestId)
|
|
77
|
+
: []);
|
|
78
|
+
const allClientRequestIds = new Set([...clientRequestIdsBefore, ...clientRequestIdsAfter]);
|
|
79
|
+
for (const clientRequestIdBefore of [...clientRequestIdsBefore]) {
|
|
80
|
+
if (clientRequestIdsAfter.has(clientRequestIdBefore))
|
|
81
|
+
continue;
|
|
82
|
+
clientRequestIdsBefore.delete(clientRequestIdBefore);
|
|
83
|
+
const localDocsBefore = this.clientRequestIdToLocalDocuments.get(clientRequestIdBefore);
|
|
84
|
+
if (localDocsBefore) {
|
|
85
|
+
localDocsBefore.delete(squidDocId);
|
|
86
|
+
if (!localDocsBefore.size) {
|
|
87
|
+
this.clientRequestIdToLocalDocuments.delete(clientRequestIdBefore);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!clientRequestIdsBefore.size) {
|
|
91
|
+
this.localDocumentToClientRequestIds.delete(squidDocId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const clientRequestIdAfter of clientRequestIdsAfter) {
|
|
95
|
+
let clientRequestIds = this.localDocumentToClientRequestIds.get(squidDocId);
|
|
96
|
+
if (!clientRequestIds) {
|
|
97
|
+
clientRequestIds = new Set();
|
|
98
|
+
this.localDocumentToClientRequestIds.set(squidDocId, clientRequestIds);
|
|
99
|
+
}
|
|
100
|
+
clientRequestIds.add(clientRequestIdAfter);
|
|
101
|
+
let localDocuments = this.clientRequestIdToLocalDocuments.get(clientRequestIdAfter);
|
|
102
|
+
if (!localDocuments) {
|
|
103
|
+
localDocuments = new Set();
|
|
104
|
+
this.clientRequestIdToLocalDocuments.set(clientRequestIdAfter, localDocuments);
|
|
105
|
+
}
|
|
106
|
+
localDocuments.add(squidDocId);
|
|
107
|
+
}
|
|
108
|
+
return [...allClientRequestIds];
|
|
109
|
+
}
|
|
110
|
+
addDocToQuery(squidDocId, clientRequestId) {
|
|
111
|
+
let clientRequestIds = this.localDocumentToClientRequestIds.get(squidDocId);
|
|
112
|
+
if (!clientRequestIds) {
|
|
113
|
+
clientRequestIds = new Set();
|
|
114
|
+
this.localDocumentToClientRequestIds.set(squidDocId, clientRequestIds);
|
|
115
|
+
}
|
|
116
|
+
clientRequestIds.add(clientRequestId);
|
|
117
|
+
let localDocuments = this.clientRequestIdToLocalDocuments.get(clientRequestId);
|
|
118
|
+
if (!localDocuments) {
|
|
119
|
+
localDocuments = new Set();
|
|
120
|
+
this.clientRequestIdToLocalDocuments.set(clientRequestId, localDocuments);
|
|
121
|
+
}
|
|
122
|
+
localDocuments.add(squidDocId);
|
|
123
|
+
}
|
|
124
|
+
removeDocFromQuery(squidDocId, clientRequestId) {
|
|
125
|
+
const clientRequestIds = this.localDocumentToClientRequestIds.get(squidDocId);
|
|
126
|
+
let noQueriesNeedDoc = !clientRequestIds;
|
|
127
|
+
if (clientRequestIds) {
|
|
128
|
+
clientRequestIds.delete(clientRequestId);
|
|
129
|
+
if (!clientRequestIds.size) {
|
|
130
|
+
this.localDocumentToClientRequestIds.delete(squidDocId);
|
|
131
|
+
noQueriesNeedDoc = true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const localDocuments = this.clientRequestIdToLocalDocuments.get(clientRequestId);
|
|
135
|
+
if (localDocuments) {
|
|
136
|
+
localDocuments.delete(squidDocId);
|
|
137
|
+
if (!localDocuments.size) {
|
|
138
|
+
this.clientRequestIdToLocalDocuments.delete(clientRequestId);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (noQueriesNeedDoc) {
|
|
142
|
+
this.documentStore.deleteDocument(squidDocId);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
errorOutAllQueries(squidDocId, err) {
|
|
146
|
+
const clientRequestIds = this.localDocumentToClientRequestIds.get(squidDocId) || new Set();
|
|
147
|
+
for (const clientRequestId of clientRequestIds) {
|
|
148
|
+
const ongoingQuery = this.ongoingQueries.get(clientRequestId);
|
|
149
|
+
if (!ongoingQuery)
|
|
150
|
+
continue;
|
|
151
|
+
if (!this.destructManager.isDestructing) {
|
|
152
|
+
ongoingQuery.dataSubject.error(err);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
ongoingQuery.dataSubject.complete();
|
|
156
|
+
}
|
|
157
|
+
ongoingQuery.done = true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
notifyAllSubscriptions(clientRequestIds) {
|
|
161
|
+
const rootOngoingQueries = new Set();
|
|
162
|
+
for (const clientRequestId of clientRequestIds) {
|
|
163
|
+
const ongoingQuery = this.ongoingQueries.get(clientRequestId);
|
|
164
|
+
if (!ongoingQuery)
|
|
165
|
+
continue;
|
|
166
|
+
if (!ongoingQuery.gotInitialResponse || !ongoingQuery.activated || ongoingQuery.isInFlight)
|
|
167
|
+
continue;
|
|
168
|
+
const docIdSet = this.clientRequestIdToLocalDocuments.get(clientRequestId) || new Set();
|
|
169
|
+
const result = this.documentStore.sortAndLimitDocs(docIdSet, ongoingQuery.query);
|
|
170
|
+
const observablesUpdated = ongoingQuery.supportedQueries
|
|
171
|
+
.map(supportedOngoingQuery => this.updateOngoingQueryWithNewDataFromSupportingQuery(result, supportedOngoingQuery))
|
|
172
|
+
.some(Boolean);
|
|
173
|
+
let rootOngoingQuery = ongoingQuery;
|
|
174
|
+
while (!rootOngoingQuery.allObservables) {
|
|
175
|
+
rootOngoingQuery = (0, assertic_1.truthy)(rootOngoingQuery?.supportingOngoingQuery);
|
|
176
|
+
}
|
|
177
|
+
if (observablesUpdated) {
|
|
178
|
+
rootOngoingQueries.add(rootOngoingQuery);
|
|
179
|
+
}
|
|
180
|
+
if (ongoingQuery.query.limit > 0) {
|
|
181
|
+
switch (ongoingQuery.limitUnderflowState) {
|
|
182
|
+
case query_types_2.LimitUnderflowState.UNKNOWN:
|
|
183
|
+
ongoingQuery.limitUnderflowState =
|
|
184
|
+
docIdSet.size === ongoingQuery.query.limit + exports.FETCH_BEYOND_LIMIT
|
|
185
|
+
? query_types_2.LimitUnderflowState.ENABLED
|
|
186
|
+
: query_types_2.LimitUnderflowState.DISABLED;
|
|
187
|
+
break;
|
|
188
|
+
case query_types_2.LimitUnderflowState.DISABLED:
|
|
189
|
+
break;
|
|
190
|
+
case query_types_2.LimitUnderflowState.ENABLED:
|
|
191
|
+
if (docIdSet.size < ongoingQuery.query.limit + LIMIT_UNDERFLOW_TRIGGER) {
|
|
192
|
+
ongoingQuery.limitUnderflowState = query_types_2.LimitUnderflowState.UNKNOWN;
|
|
193
|
+
this.sendQueryToServerOrUseParentQuery(ongoingQuery);
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
ongoingQuery.dataSubject.next(result);
|
|
199
|
+
}
|
|
200
|
+
for (const rootOngoingQuery of rootOngoingQueries) {
|
|
201
|
+
const allObservables = this.collectAllObservables(rootOngoingQuery);
|
|
202
|
+
(0, assertic_1.truthy)(rootOngoingQuery.allObservables).next(allObservables);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
findValidParentOfQuery(query) {
|
|
206
|
+
const qc = new query_public_context_1.QueryContext(query);
|
|
207
|
+
for (const candidateParentQuery of this.ongoingQueries.values()) {
|
|
208
|
+
if (!this.isValidParent(candidateParentQuery)) {
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (qc.isSubqueryOfQuery(candidateParentQuery.query)) {
|
|
212
|
+
return candidateParentQuery;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
processQuery(query, rootAlias, joins, joinConditions, subscribe, forceFetchFromServer, clientRequestId) {
|
|
218
|
+
if (subscribe) {
|
|
219
|
+
this.socketManager.notifyWebSocketIsNeeded();
|
|
220
|
+
}
|
|
221
|
+
return (0, rxjs_1.defer)(() => {
|
|
222
|
+
const rootOngoingQuery = this.createOngoingQueryGraph(query, rootAlias, joins, joinConditions, subscribe, true, {}, clientRequestId);
|
|
223
|
+
if (forceFetchFromServer) {
|
|
224
|
+
rootOngoingQuery.forceFetchFromServer = true;
|
|
225
|
+
}
|
|
226
|
+
if (!this.lockManager.canGetLock(query_types_2.RUN_IN_TRANSACTION_MUTEX)) {
|
|
227
|
+
console.warn('WARNING: Executing a query inside a transaction is not supported and will cause a transaction deadlock. If you are executing a query while an active transaction is running but outside of its callback, you can disregard this message.');
|
|
228
|
+
}
|
|
229
|
+
this.sendQueryToServerOrUseParentQuery(rootOngoingQuery);
|
|
230
|
+
rootOngoingQuery.allObservables = new rxjs_1.ReplaySubject(1);
|
|
231
|
+
const result = rootOngoingQuery.allObservables.pipe((0, rxjs_1.switchMap)(allObservables => (0, rxjs_1.combineLatest)(allObservables).pipe((0, operators_1.map)(allResults => this.joinResults(allResults, joinConditions, rootOngoingQuery)))), (0, operators_1.filter)(() => this.allOngoingQueriesGotInitialResult(rootOngoingQuery)), (0, rxjs_1.startWith)(undefined), (0, rxjs_1.pairwise)(), (0, operators_1.filter)(([before, after]) => !(0, object_1.isEqual)(before, after)), (0, operators_1.map)(([, after]) => after), subscribe ? (0, rxjs_1.tap)() : (0, rxjs_1.take)(1), (0, rxjs_1.finalize)(() => {
|
|
232
|
+
rootOngoingQuery.dataSubject.complete();
|
|
233
|
+
rootOngoingQuery.done = true;
|
|
234
|
+
void this.completeAllSupportedQueries(rootOngoingQuery);
|
|
235
|
+
rootOngoingQuery.allObservables?.complete();
|
|
236
|
+
}));
|
|
237
|
+
const allObservables = this.collectAllObservables(rootOngoingQuery);
|
|
238
|
+
rootOngoingQuery.allObservables.next(allObservables);
|
|
239
|
+
return result;
|
|
240
|
+
}).pipe((0, rxjs_1.share)());
|
|
241
|
+
}
|
|
242
|
+
hasOngoingQueryForDocId(squidDocId) {
|
|
243
|
+
const clientRequestIds = this.localDocumentToClientRequestIds.get(squidDocId);
|
|
244
|
+
return !!clientRequestIds && !!clientRequestIds.size;
|
|
245
|
+
}
|
|
246
|
+
unsubscribe() {
|
|
247
|
+
const ongoingQueries = [...this.ongoingQueries.values()];
|
|
248
|
+
for (const ongoingQuery of ongoingQueries) {
|
|
249
|
+
ongoingQuery.dataSubject.complete();
|
|
250
|
+
ongoingQuery.allObservables?.complete();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
hasSubscription(clientRequestId) {
|
|
254
|
+
return !!this.ongoingQueries.get(clientRequestId)?.subscribe;
|
|
255
|
+
}
|
|
256
|
+
isValidParent(candidateParentQuery) {
|
|
257
|
+
if (!candidateParentQuery.activated ||
|
|
258
|
+
candidateParentQuery.isInFlight ||
|
|
259
|
+
candidateParentQuery.isEmptyForJoin ||
|
|
260
|
+
candidateParentQuery.done ||
|
|
261
|
+
!candidateParentQuery.subscribe ||
|
|
262
|
+
!candidateParentQuery.gotInitialResponse ||
|
|
263
|
+
!candidateParentQuery.dataSubject.value) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
const limit = candidateParentQuery.query.limit === -1 ? 1000 : candidateParentQuery.query.limit;
|
|
267
|
+
return candidateParentQuery.dataSubject.value.length < limit;
|
|
268
|
+
}
|
|
269
|
+
findValidParentOfOngoingQuery(ongoingQuery) {
|
|
270
|
+
if (ongoingQuery.forceFetchFromServer)
|
|
271
|
+
return undefined;
|
|
272
|
+
const qc = new query_public_context_1.QueryContext(ongoingQuery.query);
|
|
273
|
+
for (const candidateParentQuery of this.ongoingQueries.values()) {
|
|
274
|
+
if (ongoingQuery === candidateParentQuery) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
else if (!this.isValidParent(candidateParentQuery)) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
else if (qc.isSubqueryOfQuery(candidateParentQuery.query)) {
|
|
281
|
+
return candidateParentQuery;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return undefined;
|
|
285
|
+
}
|
|
286
|
+
removeClientRequestIdMapping(clientRequestId) {
|
|
287
|
+
const docs = this.clientRequestIdToLocalDocuments.get(clientRequestId);
|
|
288
|
+
if (!docs)
|
|
289
|
+
return;
|
|
290
|
+
this.clientRequestIdToLocalDocuments.delete(clientRequestId);
|
|
291
|
+
const orphanDocument = [];
|
|
292
|
+
for (const doc of docs) {
|
|
293
|
+
const clientRequestIds = (0, assertic_1.truthy)(this.localDocumentToClientRequestIds.get(doc));
|
|
294
|
+
clientRequestIds.delete(clientRequestId);
|
|
295
|
+
if (!clientRequestIds.size) {
|
|
296
|
+
this.localDocumentToClientRequestIds.delete(doc);
|
|
297
|
+
orphanDocument.push(doc);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (orphanDocument.length) {
|
|
301
|
+
this.onOrphanDocuments.next(orphanDocument);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
registerQueryFinalizer(ongoingQuery) {
|
|
305
|
+
const clientRequestId = ongoingQuery.clientRequestId;
|
|
306
|
+
const querySubscriptionId = (0, query_types_1.getQuerySubscriptionId)(this.clientIdService.getClientId(), clientRequestId);
|
|
307
|
+
ongoingQuery.dataSubject
|
|
308
|
+
.pipe((0, rxjs_1.finalize)(async () => {
|
|
309
|
+
if (ongoingQuery.unsubscribeBlockerCount.value > 0) {
|
|
310
|
+
await (0, rxjs_1.firstValueFrom)((0, rxjs_1.race)(this.destructManager.observeIsDestructing(), ongoingQuery.unsubscribeBlockerCount.pipe((0, operators_1.filter)(count => count === 0))));
|
|
311
|
+
}
|
|
312
|
+
void this.queryMappingManager.removeQuery(querySubscriptionId);
|
|
313
|
+
this.ongoingQueries.delete(clientRequestId);
|
|
314
|
+
if (ongoingQuery.subscribe) {
|
|
315
|
+
if (!ongoingQuery.isEmptyForJoin && ongoingQuery.activated) {
|
|
316
|
+
const unsubscribeRequest = {
|
|
317
|
+
clientRequestId,
|
|
318
|
+
};
|
|
319
|
+
this.rpcManager.post('query/unsubscribe', unsubscribeRequest).catch(e => {
|
|
320
|
+
if (this.destructManager.isDestructing)
|
|
321
|
+
return;
|
|
322
|
+
console.error('Got error while unsubscribing from query', ongoingQuery.query, e);
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
this.removeClientRequestIdMapping(clientRequestId);
|
|
327
|
+
}), (0, operators_1.filter)(Boolean))
|
|
328
|
+
.subscribe({
|
|
329
|
+
error: () => {
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
createOngoingQueryGraph(query, alias, joins, joinConditionsMap, subscribe, isRoot, createdOngoingQueries = {}, providedClientRequestId) {
|
|
334
|
+
if (createdOngoingQueries[alias])
|
|
335
|
+
return createdOngoingQueries[alias];
|
|
336
|
+
const clientRequestId = isRoot && providedClientRequestId ? providedClientRequestId : this.clientIdService.generateClientRequestId();
|
|
337
|
+
const supportedQueries = [];
|
|
338
|
+
const result = {
|
|
339
|
+
clientRequestId,
|
|
340
|
+
activated: isRoot,
|
|
341
|
+
alias,
|
|
342
|
+
query,
|
|
343
|
+
subscribe,
|
|
344
|
+
dataSubject: new rxjs_1.BehaviorSubject(null),
|
|
345
|
+
supportedQueries,
|
|
346
|
+
supportingOngoingQuery: undefined,
|
|
347
|
+
joinCondition: undefined,
|
|
348
|
+
gotInitialResponse: false,
|
|
349
|
+
isEmptyForJoin: false,
|
|
350
|
+
canExpandForJoin: true,
|
|
351
|
+
unsubscribeBlockerCount: new rxjs_1.BehaviorSubject(0),
|
|
352
|
+
queryRegistered: new rxjs_1.BehaviorSubject(false),
|
|
353
|
+
done: false,
|
|
354
|
+
isInFlight: false,
|
|
355
|
+
forceFetchFromServer: false,
|
|
356
|
+
limitUnderflowState: subscribe ? query_types_2.LimitUnderflowState.UNKNOWN : query_types_2.LimitUnderflowState.DISABLED,
|
|
357
|
+
};
|
|
358
|
+
this.registerQueryFinalizer(result);
|
|
359
|
+
this.ongoingQueries.set(clientRequestId, result);
|
|
360
|
+
createdOngoingQueries[alias] = result;
|
|
361
|
+
for (const [rightAlias, joinCondition] of Object.entries(joinConditionsMap)) {
|
|
362
|
+
const leftAlias = joinCondition.leftAlias;
|
|
363
|
+
if (leftAlias !== alias && rightAlias !== alias)
|
|
364
|
+
continue;
|
|
365
|
+
const chosenAlias = leftAlias === alias ? rightAlias : leftAlias;
|
|
366
|
+
if (leftAlias === alias) {
|
|
367
|
+
const supportedQuery = this.createOngoingQueryGraph(joins[chosenAlias], chosenAlias, joins, joinConditionsMap, subscribe, false, createdOngoingQueries);
|
|
368
|
+
supportedQuery.joinCondition = joinCondition;
|
|
369
|
+
supportedQueries.push(supportedQuery);
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
result.supportingOngoingQuery = this.createOngoingQueryGraph(joins[chosenAlias], chosenAlias, joins, joinConditionsMap, subscribe, false, createdOngoingQueries);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
collectAllObservables(ongoingQuery, result = []) {
|
|
378
|
+
if (ongoingQuery.isEmptyForJoin) {
|
|
379
|
+
return result;
|
|
380
|
+
}
|
|
381
|
+
const alias = ongoingQuery.alias;
|
|
382
|
+
result.push(ongoingQuery.dataSubject.pipe((0, operators_1.filter)(Boolean), (0, operators_1.map)(docs => {
|
|
383
|
+
return { docs, alias };
|
|
384
|
+
})));
|
|
385
|
+
for (const supportedQuery of ongoingQuery.supportedQueries) {
|
|
386
|
+
this.collectAllObservables(supportedQuery, result);
|
|
387
|
+
}
|
|
388
|
+
return result;
|
|
389
|
+
}
|
|
390
|
+
joinResults(allResults, joinConditions, rootOngoingQuery) {
|
|
391
|
+
const aliasToDocs = allResults.reduce((accum, docsAndAlias) => {
|
|
392
|
+
if (accum[docsAndAlias.alias]) {
|
|
393
|
+
accum[docsAndAlias.alias].push(...docsAndAlias.docs);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
accum[docsAndAlias.alias] = [...docsAndAlias.docs];
|
|
397
|
+
}
|
|
398
|
+
return accum;
|
|
399
|
+
}, {});
|
|
400
|
+
let result = aliasToDocs[rootOngoingQuery.alias].map(doc => ({
|
|
401
|
+
[rootOngoingQuery.alias]: doc,
|
|
402
|
+
}));
|
|
403
|
+
const ongoingQueriesInOrder = this.getOngoingQueriesBfs(rootOngoingQuery);
|
|
404
|
+
const visitedAliases = new Set();
|
|
405
|
+
for (let i = 1; i < ongoingQueriesInOrder.length; i++) {
|
|
406
|
+
const ongoingQuery = ongoingQueriesInOrder[i];
|
|
407
|
+
const rightAlias = ongoingQuery.alias;
|
|
408
|
+
if (visitedAliases.has(rightAlias))
|
|
409
|
+
continue;
|
|
410
|
+
visitedAliases.add(rightAlias);
|
|
411
|
+
result = this.join(result, rightAlias, aliasToDocs[rightAlias], joinConditions[rightAlias]);
|
|
412
|
+
}
|
|
413
|
+
return result;
|
|
414
|
+
}
|
|
415
|
+
join(left, rightAlias, rightDocs, joinCondition) {
|
|
416
|
+
if (!left.length)
|
|
417
|
+
return left;
|
|
418
|
+
const availableLeftAliases = Object.keys(left[0]);
|
|
419
|
+
if (!(joinCondition && availableLeftAliases.includes(joinCondition.leftAlias))) {
|
|
420
|
+
throw new Error('No join condition found for alias ' + rightAlias);
|
|
421
|
+
}
|
|
422
|
+
const rightAsMap = new Map();
|
|
423
|
+
(rightDocs || []).forEach(doc => {
|
|
424
|
+
const val = this.transformKey(doc[joinCondition.right]);
|
|
425
|
+
if (!rightAsMap.has(val))
|
|
426
|
+
rightAsMap.set(val, []);
|
|
427
|
+
(0, assertic_1.truthy)(rightAsMap.get(val)).push(doc);
|
|
428
|
+
});
|
|
429
|
+
return left.flatMap(leftElement => {
|
|
430
|
+
const rightDocsWithSameValue = rightAsMap.get(this.transformKey(leftElement[joinCondition.leftAlias]?.[joinCondition.left])) || [];
|
|
431
|
+
if (rightDocsWithSameValue.length) {
|
|
432
|
+
return rightDocsWithSameValue.map(rightDoc => ({ ...leftElement, [rightAlias]: rightDoc }));
|
|
433
|
+
}
|
|
434
|
+
else if (joinCondition.isInner) {
|
|
435
|
+
return [];
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
return [{ ...leftElement, [rightAlias]: undefined }];
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
getOngoingQueriesBfs(rootOngoingQuery) {
|
|
443
|
+
const result = [];
|
|
444
|
+
const queue = [rootOngoingQuery];
|
|
445
|
+
while (queue.length) {
|
|
446
|
+
const current = (0, assertic_1.truthy)(queue.shift());
|
|
447
|
+
if (current.isEmptyForJoin)
|
|
448
|
+
continue;
|
|
449
|
+
result.push(current);
|
|
450
|
+
queue.push(...current.supportedQueries);
|
|
451
|
+
}
|
|
452
|
+
return result;
|
|
453
|
+
}
|
|
454
|
+
updateOngoingQueryWithNewDataFromSupportingQuery(supportingQueryResult, supportedOngoingQuery) {
|
|
455
|
+
const joinCondition = (0, assertic_1.truthy)(supportedOngoingQuery.joinCondition);
|
|
456
|
+
const query = supportedOngoingQuery.query;
|
|
457
|
+
if (!supportedOngoingQuery.activated) {
|
|
458
|
+
supportedOngoingQuery.activated = true;
|
|
459
|
+
const existingCondValues = query.conditions
|
|
460
|
+
.filter(query_types_1.isSimpleCondition)
|
|
461
|
+
.filter(cond => {
|
|
462
|
+
return cond.fieldName === joinCondition.right && cond.operator === '==';
|
|
463
|
+
})
|
|
464
|
+
.map(cond => cond.value);
|
|
465
|
+
if (existingCondValues.length) {
|
|
466
|
+
this.sendQueryToServerOrUseParentQuery(supportedOngoingQuery);
|
|
467
|
+
supportedOngoingQuery.canExpandForJoin = false;
|
|
468
|
+
return true;
|
|
469
|
+
}
|
|
470
|
+
const newConditions = supportingQueryResult
|
|
471
|
+
.map(supportingDoc => supportingDoc[joinCondition.left] ?? null)
|
|
472
|
+
.map(value => {
|
|
473
|
+
return {
|
|
474
|
+
fieldName: joinCondition.right,
|
|
475
|
+
operator: '==',
|
|
476
|
+
value,
|
|
477
|
+
};
|
|
478
|
+
});
|
|
479
|
+
if (newConditions.length) {
|
|
480
|
+
query.conditions.push(...newConditions);
|
|
481
|
+
this.sendQueryToServerOrUseParentQuery(supportedOngoingQuery);
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
supportedOngoingQuery.isEmptyForJoin = true;
|
|
485
|
+
}
|
|
486
|
+
return true;
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
if (!supportedOngoingQuery.canExpandForJoin) {
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
const supportedQueriesWithSameAlias = (0, assertic_1.truthy)(supportedOngoingQuery.supportingOngoingQuery?.supportedQueries).filter(q => q.alias === supportedOngoingQuery.alias);
|
|
493
|
+
const allNeededValues = new Set(supportingQueryResult.map(resultDoc => resultDoc[joinCondition.left] ?? null));
|
|
494
|
+
for (const supportedQuery of supportedQueriesWithSameAlias) {
|
|
495
|
+
supportedQuery.query.conditions
|
|
496
|
+
.filter(query_types_1.isSimpleCondition)
|
|
497
|
+
.filter(cond => cond.fieldName === joinCondition.right)
|
|
498
|
+
.forEach(cond => {
|
|
499
|
+
allNeededValues.delete(cond.value);
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
if (allNeededValues.size === 0) {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
const newQuery = (0, object_1.cloneDeep)(query);
|
|
506
|
+
newQuery.conditions = newQuery.conditions.filter(cond => !(0, query_types_1.isSimpleCondition)(cond) || cond.fieldName !== joinCondition.right);
|
|
507
|
+
[...allNeededValues].forEach(value => {
|
|
508
|
+
newQuery.conditions.push({
|
|
509
|
+
fieldName: joinCondition.right,
|
|
510
|
+
operator: '==',
|
|
511
|
+
value,
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
const ongoingQuery = {
|
|
515
|
+
...supportedOngoingQuery,
|
|
516
|
+
query: newQuery,
|
|
517
|
+
activated: true,
|
|
518
|
+
gotInitialResponse: false,
|
|
519
|
+
dataSubject: new rxjs_1.BehaviorSubject(null),
|
|
520
|
+
clientRequestId: this.clientIdService.generateClientRequestId(),
|
|
521
|
+
isEmptyForJoin: false,
|
|
522
|
+
};
|
|
523
|
+
this.registerQueryFinalizer(ongoingQuery);
|
|
524
|
+
this.ongoingQueries.set(ongoingQuery.clientRequestId, ongoingQuery);
|
|
525
|
+
(0, assertic_1.truthy)(supportedOngoingQuery.supportingOngoingQuery).supportedQueries.push(ongoingQuery);
|
|
526
|
+
this.sendQueryToServerOrUseParentQuery(ongoingQuery);
|
|
527
|
+
return true;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
allOngoingQueriesGotInitialResult(rootOngoingQuery) {
|
|
531
|
+
if (rootOngoingQuery.isEmptyForJoin)
|
|
532
|
+
return true;
|
|
533
|
+
if (!rootOngoingQuery.gotInitialResponse)
|
|
534
|
+
return false;
|
|
535
|
+
if (!rootOngoingQuery.supportedQueries.length)
|
|
536
|
+
return true;
|
|
537
|
+
return rootOngoingQuery.supportedQueries.every(ongoingQuery => this.allOngoingQueriesGotInitialResult(ongoingQuery));
|
|
538
|
+
}
|
|
539
|
+
async completeAllSupportedQueries(rootOngoingQuery) {
|
|
540
|
+
const supportedQueries = [...(rootOngoingQuery.supportedQueries || [])];
|
|
541
|
+
while (supportedQueries.length) {
|
|
542
|
+
const supportedQuery = (0, assertic_1.truthy)(supportedQueries.shift());
|
|
543
|
+
supportedQueries.push(...(supportedQuery.supportedQueries || []));
|
|
544
|
+
await (0, rxjs_1.firstValueFrom)(supportedQuery.unsubscribeBlockerCount.pipe((0, operators_1.filter)(count => count === 0)));
|
|
545
|
+
supportedQuery.dataSubject.complete();
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
transformKey(key) {
|
|
549
|
+
if (key instanceof Date) {
|
|
550
|
+
return `DATE AS string KEY: ${key.toISOString()}`;
|
|
551
|
+
}
|
|
552
|
+
return key;
|
|
553
|
+
}
|
|
554
|
+
preDestruct() {
|
|
555
|
+
this.unsubscribe();
|
|
556
|
+
}
|
|
557
|
+
sendQueryToServerOrUseParentQuery(ongoingQuery, forceSendToServer = false) {
|
|
558
|
+
if (this.destructManager.isDestructing)
|
|
559
|
+
return;
|
|
560
|
+
const query = ongoingQuery.query;
|
|
561
|
+
const clientRequestId = ongoingQuery.clientRequestId;
|
|
562
|
+
const querySubscriptionId = (0, query_types_1.getQuerySubscriptionId)(this.clientIdService.getClientId(), clientRequestId);
|
|
563
|
+
this.queryMappingManager.addQuery(query, querySubscriptionId);
|
|
564
|
+
this.ongoingQueries.set(clientRequestId, ongoingQuery);
|
|
565
|
+
const parentOngoingQuery = forceSendToServer ? undefined : this.findValidParentOfOngoingQuery(ongoingQuery);
|
|
566
|
+
if (parentOngoingQuery) {
|
|
567
|
+
void this.useParentOngoingQuery(ongoingQuery, parentOngoingQuery);
|
|
568
|
+
}
|
|
569
|
+
else {
|
|
570
|
+
this.sendQueryToServer(ongoingQuery);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
async useParentOngoingQuery(ongoingQuery, parentOngoingQuery) {
|
|
574
|
+
const queryRegisterRequest = {
|
|
575
|
+
clientRequestId: ongoingQuery.clientRequestId,
|
|
576
|
+
query: ongoingQuery.query,
|
|
577
|
+
parentClientRequestId: parentOngoingQuery.clientRequestId,
|
|
578
|
+
};
|
|
579
|
+
const queryContext = new query_public_context_1.QueryContext(ongoingQuery.query);
|
|
580
|
+
parentOngoingQuery.unsubscribeBlockerCount.next(parentOngoingQuery.unsubscribeBlockerCount.value + 1);
|
|
581
|
+
try {
|
|
582
|
+
await (0, rxjs_1.firstValueFrom)(parentOngoingQuery.queryRegistered.pipe((0, operators_1.filter)(Boolean)));
|
|
583
|
+
}
|
|
584
|
+
catch (e) {
|
|
585
|
+
if (!this.destructManager.isDestructing) {
|
|
586
|
+
ongoingQuery.dataSubject.error(e);
|
|
587
|
+
ongoingQuery.queryRegistered.error(e);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
ongoingQuery.dataSubject.complete();
|
|
591
|
+
ongoingQuery.queryRegistered.complete();
|
|
592
|
+
}
|
|
593
|
+
ongoingQuery.done = true;
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
if (this.destructManager.isDestructing)
|
|
597
|
+
return;
|
|
598
|
+
if (ongoingQuery.done) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
this.rpcManager
|
|
602
|
+
.post('query/register', queryRegisterRequest)
|
|
603
|
+
.then(() => {
|
|
604
|
+
ongoingQuery.isInFlight = false;
|
|
605
|
+
ongoingQuery.queryRegistered.next(true);
|
|
606
|
+
})
|
|
607
|
+
.catch(e => {
|
|
608
|
+
ongoingQuery.isInFlight = false;
|
|
609
|
+
if (!this.destructManager.isDestructing) {
|
|
610
|
+
console.error('Query error', ongoingQuery.query, parentOngoingQuery.query, e);
|
|
611
|
+
ongoingQuery.dataSubject.error(e);
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
ongoingQuery.dataSubject.complete();
|
|
615
|
+
}
|
|
616
|
+
ongoingQuery.done = true;
|
|
617
|
+
})
|
|
618
|
+
.finally(() => {
|
|
619
|
+
parentOngoingQuery.unsubscribeBlockerCount.next(parentOngoingQuery.unsubscribeBlockerCount.value - 1);
|
|
620
|
+
});
|
|
621
|
+
const takeUntilNotifier = (0, rxjs_1.race)(ongoingQuery.queryRegistered.pipe((0, operators_1.filter)(Boolean), (0, rxjs_1.delay)(2000), (0, rxjs_1.take)(1)), this.destructManager.observeIsDestructing().pipe((0, rxjs_1.take)(1)));
|
|
622
|
+
parentOngoingQuery.dataSubject
|
|
623
|
+
.pipe((0, rxjs_1.takeWhile)(() => {
|
|
624
|
+
return !ongoingQuery.done;
|
|
625
|
+
}), (0, rxjs_1.takeUntil)(takeUntilNotifier), (0, operators_1.filter)(Boolean), (0, rxjs_1.tap)(() => {
|
|
626
|
+
if (ongoingQuery.gotInitialResponse)
|
|
627
|
+
return;
|
|
628
|
+
this.setGotInitialResult(ongoingQuery.clientRequestId);
|
|
629
|
+
}), (0, operators_1.map)(documents => documents.filter(doc => queryContext.documentMatchesQuery(doc))))
|
|
630
|
+
.subscribe({
|
|
631
|
+
next: results => {
|
|
632
|
+
for (const result of results) {
|
|
633
|
+
this.setClientRequestIdsForLocalDoc((0, document_types_1.getSquidDocId)(result.__docId__, ongoingQuery.query.collectionName, ongoingQuery.query.integrationId), result);
|
|
634
|
+
}
|
|
635
|
+
this.notifyAllSubscriptions([ongoingQuery.clientRequestId]);
|
|
636
|
+
},
|
|
637
|
+
error: e => {
|
|
638
|
+
if (!this.destructManager.isDestructing) {
|
|
639
|
+
ongoingQuery.dataSubject.error(e);
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
ongoingQuery.dataSubject.complete();
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
sendQueryToServer(ongoingQuery) {
|
|
648
|
+
const oldLimit = ongoingQuery.query.limit;
|
|
649
|
+
const newLimit = oldLimit > 0 && ongoingQuery.subscribe ? oldLimit + exports.FETCH_BEYOND_LIMIT : oldLimit;
|
|
650
|
+
const queryRequest = {
|
|
651
|
+
query: { ...ongoingQuery.query, limit: newLimit },
|
|
652
|
+
clientRequestId: ongoingQuery.clientRequestId,
|
|
653
|
+
subscribe: ongoingQuery.subscribe,
|
|
654
|
+
};
|
|
655
|
+
ongoingQuery.isInFlight = true;
|
|
656
|
+
this.querySender
|
|
657
|
+
.sendQuery(queryRequest)
|
|
658
|
+
.then(queryResult => {
|
|
659
|
+
ongoingQuery.isInFlight = false;
|
|
660
|
+
ongoingQuery.queryRegistered.next(true);
|
|
661
|
+
this.queryResultsSubject.next(queryResult);
|
|
662
|
+
})
|
|
663
|
+
.catch(e => {
|
|
664
|
+
ongoingQuery.isInFlight = false;
|
|
665
|
+
if (!this.destructManager.isDestructing) {
|
|
666
|
+
global_utils_1.DebugLogger.debug('Query error', ongoingQuery.query, e);
|
|
667
|
+
ongoingQuery.dataSubject.error(e);
|
|
668
|
+
ongoingQuery.queryRegistered.error('query failed');
|
|
669
|
+
}
|
|
670
|
+
else {
|
|
671
|
+
ongoingQuery.dataSubject.complete();
|
|
672
|
+
ongoingQuery.queryRegistered.complete();
|
|
673
|
+
}
|
|
674
|
+
ongoingQuery.done = true;
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
refreshOngoingQueries() {
|
|
678
|
+
for (const query of this.ongoingQueries.values()) {
|
|
679
|
+
this.sendQueryToServerOrUseParentQuery(query, true);
|
|
680
|
+
}
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
migrateDocIds(idResolutionMap) {
|
|
684
|
+
const squidDocIds = Object.keys(idResolutionMap);
|
|
685
|
+
for (const set of this.clientRequestIdToLocalDocuments.values()) {
|
|
686
|
+
squidDocIds.forEach(key => {
|
|
687
|
+
if (set.has(key)) {
|
|
688
|
+
set.delete(key);
|
|
689
|
+
set.add(idResolutionMap[key]);
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
squidDocIds.forEach(key => {
|
|
694
|
+
(0, object_1.replaceKeyInMap)(this.localDocumentToClientRequestIds, key, idResolutionMap[key]);
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
exports.QuerySubscriptionManager = QuerySubscriptionManager;
|
|
699
|
+
function matchesCompositeCondition(condition, doc) {
|
|
700
|
+
for (const subCondition of condition.fields) {
|
|
701
|
+
const valueInDocument = (0, object_1.getInPath)(doc, subCondition.fieldName) ?? null;
|
|
702
|
+
if ((0, query_types_1.compareOperator)(subCondition.value, valueInDocument, subCondition.operator)) {
|
|
703
|
+
return true;
|
|
704
|
+
}
|
|
705
|
+
if ((0, query_types_1.compareOperator)(subCondition.value, valueInDocument, '!=')) {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
function findQueriesForDocumentSync(mapping, doc) {
|
|
712
|
+
const result = [...(mapping.unconditional || [])];
|
|
713
|
+
const mappedIdFoundMap = new Map();
|
|
714
|
+
for (const [encodedCondition, queryIds] of Object.entries(mapping.conditional || {})) {
|
|
715
|
+
const condition = (0, serialization_1.deserializeObj)(encodedCondition);
|
|
716
|
+
let matchesCondition;
|
|
717
|
+
if ((0, query_types_1.isSimpleCondition)(condition)) {
|
|
718
|
+
const valueInDocument = (0, object_1.getInPath)(doc, condition.fieldName) ?? null;
|
|
719
|
+
matchesCondition = (0, query_types_1.compareOperator)(condition.value, valueInDocument, condition.operator);
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
matchesCondition = matchesCompositeCondition(condition, doc);
|
|
723
|
+
}
|
|
724
|
+
if (matchesCondition) {
|
|
725
|
+
for (const mappedId of queryIds) {
|
|
726
|
+
mappedIdFoundMap.set(mappedId, (mappedIdFoundMap.get(mappedId) || 0) + 1);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
for (const [mappedId, matchCount] of mappedIdFoundMap.entries()) {
|
|
731
|
+
if (matchCount >= mapping.queriesMetadata[mappedId].condCount) {
|
|
732
|
+
result.push(mappedId);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
return result;
|
|
736
|
+
}
|
|
737
|
+
class ClientQueryMappingManager {
|
|
738
|
+
constructor() {
|
|
739
|
+
this.stateService = new otrie_1.TrieStore({});
|
|
740
|
+
this.querySubscriptionIdToQuery = {};
|
|
741
|
+
}
|
|
742
|
+
addQuery(query, querySubscriptionId) {
|
|
743
|
+
this.stateService.runInBatch(() => {
|
|
744
|
+
let condCount = 0;
|
|
745
|
+
const visitedEqualityFields = new Set();
|
|
746
|
+
for (const condition of query.conditions) {
|
|
747
|
+
if ((0, query_types_1.isSimpleCondition)(condition) && ['=='].includes(condition.operator)) {
|
|
748
|
+
const fieldName = (0, serialization_1.encodeValueForMapping)(condition.fieldName);
|
|
749
|
+
if (!visitedEqualityFields.has(fieldName)) {
|
|
750
|
+
condCount++;
|
|
751
|
+
visitedEqualityFields.add(fieldName);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
condCount++;
|
|
756
|
+
}
|
|
757
|
+
const conditionPath = this.getConditionStatePath(query, condition);
|
|
758
|
+
const clientRequestIdsForCondition = [...(this.stateService.get(conditionPath) || [])];
|
|
759
|
+
(0, array_1.insertSorted)(clientRequestIdsForCondition, querySubscriptionId);
|
|
760
|
+
this.stateService.set(conditionPath, clientRequestIdsForCondition);
|
|
761
|
+
}
|
|
762
|
+
if (!query.conditions.length) {
|
|
763
|
+
const path = ['queryMapping', query.collectionName, query.integrationId, 'mapping', 'unconditional'];
|
|
764
|
+
const currentArray = [...(this.stateService.get(path) || [])];
|
|
765
|
+
(0, array_1.insertSorted)(currentArray, querySubscriptionId);
|
|
766
|
+
this.stateService.set(path, currentArray);
|
|
767
|
+
}
|
|
768
|
+
this.stateService.set([...this.getQueryMetadataStatePath(query, querySubscriptionId), 'condCount'], condCount);
|
|
769
|
+
});
|
|
770
|
+
this.querySubscriptionIdToQuery[querySubscriptionId] = query;
|
|
771
|
+
}
|
|
772
|
+
async removeQuery(querySubscriptionId) {
|
|
773
|
+
const query = this.querySubscriptionIdToQuery[querySubscriptionId];
|
|
774
|
+
if (!query)
|
|
775
|
+
return;
|
|
776
|
+
this.stateService.runInBatch(() => {
|
|
777
|
+
for (const cond of query.conditions) {
|
|
778
|
+
const path = this.getConditionStatePath(query, cond);
|
|
779
|
+
const currentArray = [...(this.stateService.get(path) || [])];
|
|
780
|
+
(0, array_1.removeSorted)(currentArray, querySubscriptionId);
|
|
781
|
+
if (currentArray.length) {
|
|
782
|
+
this.stateService.set(path, currentArray);
|
|
783
|
+
}
|
|
784
|
+
else {
|
|
785
|
+
this.stateService.delete(path);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
if (!query.conditions.length) {
|
|
789
|
+
const path = ['queryMapping', query.collectionName, query.integrationId, 'mapping', 'unconditional'];
|
|
790
|
+
const currentArray = [...(this.stateService.get(path) || [])];
|
|
791
|
+
(0, array_1.removeSorted)(currentArray, querySubscriptionId);
|
|
792
|
+
this.stateService.set(path, currentArray);
|
|
793
|
+
}
|
|
794
|
+
this.stateService.delete(this.getQueryMetadataStatePath(query, querySubscriptionId));
|
|
795
|
+
});
|
|
796
|
+
return query;
|
|
797
|
+
}
|
|
798
|
+
getMapping(collectionName, integrationId) {
|
|
799
|
+
return this.stateService.get([
|
|
800
|
+
'queryMapping',
|
|
801
|
+
collectionName,
|
|
802
|
+
integrationId,
|
|
803
|
+
'mapping',
|
|
804
|
+
]);
|
|
805
|
+
}
|
|
806
|
+
getQueryMetadataStatePath(query, clientRequestId) {
|
|
807
|
+
return [
|
|
808
|
+
'queryMapping',
|
|
809
|
+
query.collectionName,
|
|
810
|
+
query.integrationId,
|
|
811
|
+
'mapping',
|
|
812
|
+
'queriesMetadata',
|
|
813
|
+
`${clientRequestId}`,
|
|
814
|
+
];
|
|
815
|
+
}
|
|
816
|
+
getConditionStatePath(query, cond) {
|
|
817
|
+
return ['queryMapping', query.collectionName, query.integrationId, 'mapping', 'conditional', (0, query_types_1.encodeCondition)(cond)];
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
//# sourceMappingURL=query-subscription.manager.js.map
|