@squidcloud/client 1.0.147 → 1.0.148

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/cjs/index.js CHANGED
@@ -36764,7 +36764,7 @@ function serialization_normalizeJsonAsString(json) {
36764
36764
  }
36765
36765
  function serialization_serializeObj(obj) {
36766
36766
  if (obj === undefined)
36767
- return null;
36767
+ return null; // TODO: change method signature.
36768
36768
  const objWithReplacedDates = lodash.cloneDeepWith(obj, value => {
36769
36769
  return lodash.isDate(value) ? { $date: value.toISOString() } : undefined;
36770
36770
  });
@@ -36813,9 +36813,6 @@ function decodeValueForMapping(encodedString) {
36813
36813
  }
36814
36814
  return deserializeObj(decodedValue);
36815
36815
  }
36816
- function recodeValue(value) {
36817
- return decodeValueForMapping(encodeValueForMapping(value));
36818
- }
36819
36816
 
36820
36817
  ;// CONCATENATED MODULE: ../common/src/query.types.ts
36821
36818
 
@@ -42178,24 +42175,37 @@ class DataManager {
42178
42175
  * change, it will not apply it in the document store but the query will still be notified.
42179
42176
  */
42180
42177
  let someDocumentsWereOutdated = false;
42181
- const squidIds = new Set();
42178
+ const updatedDocIds = new Set();
42179
+ const staleDocIds = new Set();
42182
42180
  for (const [squidDocId, incomingUpdateItem] of Object.entries(squidDocIdToNewData)) {
42183
42181
  const existingPendingIncomingUpdate = this.pendingIncomingUpdates.get(squidDocId);
42184
42182
  const timestampMetadata = this.docIdToServerTimestamp.get(squidDocId);
42185
42183
  if (existingPendingIncomingUpdate && existingPendingIncomingUpdate.timestamp > incomingUpdateItem.timestamp) {
42186
- /** There is a pending update with later timestamp fo the document - skip notifying this query. */
42184
+ /** There is a pending update with later timestamp for the document - skip notifying this query. */
42187
42185
  someDocumentsWereOutdated = true;
42186
+ continue;
42188
42187
  }
42189
- else if (!(timestampMetadata && timestampMetadata.timestamp > incomingUpdateItem.timestamp)) {
42190
- /** If the client knows of a later timestamp for this document, there is no need to apply the update. */
42188
+ if (!(timestampMetadata && timestampMetadata.timestamp > incomingUpdateItem.timestamp)) {
42189
+ /** If the client does not know of a later timestamp for this document, apply the update. */
42191
42190
  this.pendingIncomingUpdates.set(squidDocId, incomingUpdateItem);
42192
- squidIds.add(squidDocId);
42191
+ updatedDocIds.add(squidDocId);
42192
+ }
42193
+ else {
42194
+ /**
42195
+ * If the client knows of a later timestamp for this document, consider the incoming update as stale.
42196
+ * Since the ClientRequestId -> SquidDocId mapping may have been cleared before the updated, we still
42197
+ * need to refresh the map of ongoing queries to local documents.
42198
+ */
42199
+ staleDocIds.add(squidDocId);
42193
42200
  }
42194
42201
  }
42195
42202
  this.runInTransactionSync(() => {
42196
- for (const squidDocId of squidIds) {
42203
+ for (const squidDocId of updatedDocIds) {
42197
42204
  this.maybeApplyIncomingUpdate(squidDocId);
42198
42205
  }
42206
+ for (const squidDocId of staleDocIds) {
42207
+ this.refreshQueryMapping(squidDocId);
42208
+ }
42199
42209
  }, transactionId).then();
42200
42210
  return someDocumentsWereOutdated;
42201
42211
  }
@@ -42212,7 +42222,11 @@ class DataManager {
42212
42222
  this.docIdToLocalTimestamp.set(squidDocId, incomingUpdate.timestamp);
42213
42223
  /** The incomingUpdate was applied locally - remove it from pendingIncomingUpdates. */
42214
42224
  this.pendingIncomingUpdates.delete(squidDocId);
42215
- const allClientRequestIds = this.querySubscriptionManager.setClientRequestIdsForLocalDoc(squidDocId, incomingUpdate.properties);
42225
+ this.refreshQueryMapping(squidDocId);
42226
+ }
42227
+ refreshQueryMapping(squidDocId) {
42228
+ const doc = this.documentStore.getDocumentOrUndefined(squidDocId);
42229
+ const allClientRequestIds = this.querySubscriptionManager.setClientRequestIdsForLocalDoc(squidDocId, doc);
42216
42230
  allClientRequestIds.forEach(clientRequestId => {
42217
42231
  this.batchClientRequestIds.add(clientRequestId);
42218
42232
  });
@@ -42220,8 +42234,8 @@ class DataManager {
42220
42234
  * If the document was not deleted but there are no longer ongoing queries that will keep this document up-to-date,
42221
42235
  * we consider the document "forgotten" and mark the docIdToServerTimestamp with expireTimestamp.
42222
42236
  */
42223
- if (incomingUpdate.properties) {
42224
- if (!this.querySubscriptionManager.findQueriesForDocument(incomingUpdate.properties, squidDocId).length) {
42237
+ if (doc) {
42238
+ if (!this.querySubscriptionManager.findQueriesForDocument(doc, squidDocId).length) {
42225
42239
  this.forgetDocument(squidDocId);
42226
42240
  }
42227
42241
  }
@@ -56303,25 +56317,26 @@ class QuerySubscriptionManager {
56303
56317
  return (0,dist.truthy)(this.ongoingQueries.get(clientRequestId), 'UNKNOWN_QUERY').query;
56304
56318
  }
56305
56319
  /**
56306
- * A query receives updates from two different sources:
56320
+ * A query receives updates from three different sources:
56307
56321
  * 1 - An initial snapshot from the server or from a parent query
56308
56322
  * 2 - Incremental updates from the server (or from a parent query before the query is registered)
56323
+ * 3 - A new snapshot if the query is refreshed after connection has been lost.
56309
56324
  *
56310
56325
  * If an incremental update is received before the snapshot was received, we cannot process it for this query.
56311
56326
  * This boolean indicates whether the initial snapshot was received.
56312
56327
  */
56313
56328
  setGotInitialResult(clientRequestId) {
56314
56329
  const ongoingQuery = this.ongoingQueries.get(clientRequestId);
56315
- /** If this query already got initial result from the server, it means that the query is able to accept incremental
56316
- * updates. In this case we should clear the mapping we have for this clientRequestId
56317
- * since new updated mapping will be created.
56330
+ /**
56331
+ * If this query already got initial result from the server, it means that the query is able to accept incremental
56332
+ * updates. In this case we should clear the mapping we have for this clientRequestId since a new updated mapping
56333
+ * will be created when applying the update.
56318
56334
  */
56319
- if (!ongoingQuery || ongoingQuery.gotInitialResponse) {
56320
- this.removeClientRequestIdMapping(clientRequestId);
56321
- return;
56335
+ this.removeClientRequestIdMapping(clientRequestId);
56336
+ if (ongoingQuery) {
56337
+ ongoingQuery.gotInitialResponse = true;
56338
+ ongoingQuery.isInFlight = false;
56322
56339
  }
56323
- ongoingQuery.gotInitialResponse = true;
56324
- ongoingQuery.isInFlight = false;
56325
56340
  }
56326
56341
  /** Given a document, returns all the queries that should be notified with the new document properties. */
56327
56342
  findQueriesForDocument(doc, squidDocId) {
@@ -57258,7 +57273,7 @@ class RpcManager {
57258
57273
  }
57259
57274
  }
57260
57275
  catch (e) {
57261
- if (e instanceof external_axios_namespaceObject.AxiosError) {
57276
+ if (e === null || e === void 0 ? void 0 : e.isAxiosError) {
57262
57277
  const response = e.response;
57263
57278
  if (!response)
57264
57279
  throw e;
@@ -57890,6 +57905,21 @@ class Squid {
57890
57905
  constructor(options) {
57891
57906
  this.options = options;
57892
57907
  this.destructManager = new DestructManager();
57908
+ // Note: The following methods are bound using arrow functions to ensure that if a user accesses the methods via
57909
+ // destructuring (i.e. `{ setAuthProvider } = squid`) then `this` will still be bound to the Squid class.
57910
+ /**
57911
+ * Sets the authorization access token (OAuth2.0) provider that will be sent to the server and will be used for
57912
+ * providing the `auth` object to the security rules.
57913
+ *
57914
+ * @param authProvider The OAuth2.0 access token provider invoked for every backend request by Squid.
57915
+ * When the provider returns undefined, no authorization information is sent.
57916
+ * When a new provider is set, all future Squid backend requests will use the new token provider, and exising
57917
+ * in-flight requests won't be affected.
57918
+ * @returns void.
57919
+ */
57920
+ this.setAuthProvider = (authProvider) => {
57921
+ this.authManager.setAuthProvider(authProvider);
57922
+ };
57893
57923
  /**
57894
57924
  * Returns a reference to the collection in the provided integration.
57895
57925
  *
@@ -58127,21 +58157,6 @@ class Squid {
58127
58157
  static getInstances() {
58128
58158
  return Object.values(Squid.squidInstancesMap);
58129
58159
  }
58130
- // Note: The following methods are bound using arrow functions to ensure that if a user accesses the methods via
58131
- // destructuring (i.e. `{ setAuthProvider } = squid`) then `this` will still be bound to the Squid class.
58132
- /**
58133
- * Sets the authorization access token (OAuth2.0) provider that will be sent to the server and will be used for
58134
- * providing the `auth` object to the security rules.
58135
- *
58136
- * @param authProvider The OAuth2.0 access token provider invoked for every backend request by Squid.
58137
- * When the provider returns undefined, no authorization information is sent.
58138
- * When a new provider is set, all future Squid backend requests will use the new token provider, and exising
58139
- * in-flight requests won't be affected.
58140
- * @returns void
58141
- */
58142
- setAuthProvider(authProvider) {
58143
- this.authManager.setAuthProvider(authProvider);
58144
- }
58145
58160
  get secrets() {
58146
58161
  return (() => {
58147
58162
  return this.secretClient;
@@ -1,6 +1,5 @@
1
1
  export declare function normalizeJsonAsString(json: any): string;
2
- export declare function serializeObj(obj: any): string;
2
+ export declare function serializeObj(obj: unknown): string;
3
3
  export declare function deserializeObj<T = any>(str: string): T;
4
4
  export declare function encodeValueForMapping(value: any): string;
5
5
  export declare function decodeValueForMapping(encodedString: string): any;
6
- export declare function recodeValue(value: any): any;
@@ -5,5 +5,5 @@ export declare class BackendFunctionManager {
5
5
  private readonly clientIdService;
6
6
  private readonly rpcManager;
7
7
  constructor(clientIdService: ClientIdService, rpcManager: RpcManager);
8
- executeFunctionAndSubscribe<T>(functionName: string, ...params: any[]): Observable<T>;
8
+ executeFunctionAndSubscribe<T>(functionName: string, ...params: unknown[]): Observable<T>;
9
9
  }
@@ -1,10 +1,10 @@
1
1
  import { DocTimestamp, LockManager, Mutation, SquidDocId, SquidDocument } from '@squidcloud/common';
2
- import { QuerySender } from './query/query-sender';
3
2
  import { DestructManager } from './destruct.manager';
4
3
  import DocumentIdentityService from './document-identity.service';
5
4
  import { DocumentStore } from './document-store';
6
5
  import { MutationSender } from './mutation/mutation-sender';
7
6
  import { QueryBuilderFactory } from './query/query-builder.factory';
7
+ import { QuerySender } from './query/query-sender';
8
8
  import { QuerySubscriptionManager } from './query/query-subscription.manager';
9
9
  import { SocketManager } from './socket.manager';
10
10
  import { TransactionId } from './types';
@@ -117,6 +117,7 @@ export declare class DataManager {
117
117
  */
118
118
  private applyIncomingUpdates;
119
119
  private maybeApplyIncomingUpdate;
120
+ private refreshQueryMapping;
120
121
  private destruct;
121
122
  private stopDeleteExpiredTimestampsJob;
122
123
  /**
@@ -48,9 +48,10 @@ export declare class QuerySubscriptionManager {
48
48
  */
49
49
  getQuery(clientRequestId: ClientRequestId): Query;
50
50
  /**
51
- * A query receives updates from two different sources:
51
+ * A query receives updates from three different sources:
52
52
  * 1 - An initial snapshot from the server or from a parent query
53
53
  * 2 - Incremental updates from the server (or from a parent query before the query is registered)
54
+ * 3 - A new snapshot if the query is refreshed after connection has been lost.
54
55
  *
55
56
  * If an incremental update is received before the snapshot was received, we cannot process it for this query.
56
57
  * This boolean indicates whether the initial snapshot was received.
@@ -129,9 +129,9 @@ export declare class Squid {
129
129
  * When the provider returns undefined, no authorization information is sent.
130
130
  * When a new provider is set, all future Squid backend requests will use the new token provider, and exising
131
131
  * in-flight requests won't be affected.
132
- * @returns void
132
+ * @returns void.
133
133
  */
134
- setAuthProvider(authProvider: SquidAuthProvider): void;
134
+ setAuthProvider: (authProvider: SquidAuthProvider) => void;
135
135
  /**
136
136
  * Returns a reference to the collection in the provided integration.
137
137
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squidcloud/client",
3
- "version": "1.0.147",
3
+ "version": "1.0.148",
4
4
  "description": "A typescript implementation of the Squid client",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/typescript-client/src/index.d.ts",
@@ -13,6 +13,7 @@
13
13
  "build:dev": "webpack --mode=development",
14
14
  "build:prod": "webpack --mode=production",
15
15
  "watch": "webpack --watch",
16
+ "lint": "eslint . --ext .ts",
16
17
  "test": "jest --detectOpenHandles",
17
18
  "test:watch": "jest --watch",
18
19
  "test:cov": "jest --coverage",
@@ -32,7 +33,7 @@
32
33
  "license": "ISC",
33
34
  "dependencies": {
34
35
  "@apollo/client": "^3.7.4",
35
- "@squidcloud/common": "1.0.147",
36
+ "@squidcloud/common": "1.0.148",
36
37
  "@supercharge/promise-pool": "^2.3.2",
37
38
  "axios": "^1.6.2",
38
39
  "cross-fetch": "^3.1.5",