@rocicorp/zero 1.2.0-canary.12 → 1.2.0-canary.14
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/out/shared/src/sorted-entries.d.ts +2 -0
- package/out/shared/src/sorted-entries.d.ts.map +1 -0
- package/out/shared/src/sorted-entries.js +9 -0
- package/out/shared/src/sorted-entries.js.map +1 -0
- package/out/zero/package.js +1 -1
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/auth/auth.d.ts +8 -26
- package/out/zero-cache/src/auth/auth.d.ts.map +1 -1
- package/out/zero-cache/src/auth/auth.js +57 -82
- package/out/zero-cache/src/auth/auth.js.map +1 -1
- package/out/zero-cache/src/auth/jwt.d.ts +3 -3
- package/out/zero-cache/src/auth/jwt.d.ts.map +1 -1
- package/out/zero-cache/src/auth/jwt.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +22 -2
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +21 -0
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts +2 -9
- package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
- package/out/zero-cache/src/custom/fetch.js +9 -4
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts +20 -9
- package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js +71 -37
- package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.js +3 -0
- package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +4 -1
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +2 -2
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +4 -4
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
- package/out/zero-cache/src/server/reaper.js +4 -1
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +34 -11
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +2 -2
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +4 -3
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +2 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +7 -5
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +3 -3
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +20 -20
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +91 -104
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts +168 -0
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js +385 -0
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +2 -3
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +3 -3
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +20 -26
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +203 -114
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/pg-versions.d.ts +3 -0
- package/out/zero-cache/src/types/pg-versions.d.ts.map +1 -0
- package/out/zero-cache/src/types/pg-versions.js +7 -0
- package/out/zero-cache/src/types/pg-versions.js.map +1 -0
- package/out/zero-cache/src/workers/connect-params.d.ts +1 -1
- package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connect-params.js +1 -1
- package/out/zero-cache/src/workers/connect-params.js.map +1 -1
- package/out/zero-cache/src/workers/connection.js +4 -4
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts +2 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +46 -36
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts +2 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +53 -26
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +4 -4
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +34 -5
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts +4 -3
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +33 -11
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-protocol/src/change-desired-queries.d.ts +4 -0
- package/out/zero-protocol/src/change-desired-queries.d.ts.map +1 -1
- package/out/zero-protocol/src/change-desired-queries.js +4 -1
- package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
- package/out/zero-protocol/src/connect.d.ts +4 -0
- package/out/zero-protocol/src/connect.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.js +2 -1
- package/out/zero-protocol/src/connect.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +4 -0
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js +2 -1
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero-protocol/src/up.d.ts +3 -0
- package/out/zero-protocol/src/up.d.ts.map +1 -1
- package/out/zero-react/src/zero-provider.d.ts.map +1 -1
- package/out/zero-react/src/zero-provider.js +11 -5
- package/out/zero-react/src/zero-provider.js.map +1 -1
- package/out/zero-solid/src/use-zero.d.ts.map +1 -1
- package/out/zero-solid/src/use-zero.js +8 -9
- package/out/zero-solid/src/use-zero.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-syncer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/view-syncer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAcjD,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,yDAAyD,CAAC;AACzG,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,iDAAiD,CAAC;AAC1F,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"view-syncer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/view-syncer.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@ import { assert, unreachable } from "../../../../shared/src/asserts.js";
|
|
|
2
2
|
import { must } from "../../../../shared/src/must.js";
|
|
3
3
|
import { InvalidConnectionRequest, InvalidConnectionRequestBaseCookie, Rehome } from "../../../../zero-protocol/src/error-kind-enum.js";
|
|
4
4
|
import { ZeroCache } from "../../../../zero-protocol/src/error-origin-enum.js";
|
|
5
|
-
import "../../../../zero-protocol/src/error-reason-enum.js";
|
|
6
5
|
import { ProtocolError, isProtocolError } from "../../../../zero-protocol/src/error.js";
|
|
7
6
|
import { MAX_TTL_MS, clampTTL } from "../../../../zql/src/query/ttl.js";
|
|
8
7
|
import { stringify } from "../../../../shared/src/bigint-json.js";
|
|
@@ -19,7 +18,8 @@ import { Subscription } from "../../types/subscription.js";
|
|
|
19
18
|
import { CustomKeyMap } from "../../../../shared/src/custom-key-map.js";
|
|
20
19
|
import { ttlClockAsNumber, ttlClockFromNumber } from "./ttl-clock.js";
|
|
21
20
|
import { EMPTY_CVR_VERSION, cmpVersions, versionFromString, versionString, versionToCookie } from "./schema/types.js";
|
|
22
|
-
import { ProtocolErrorWithLevel, getLogLevel } from "../../types/error-with-level.js";
|
|
21
|
+
import { ProtocolErrorWithLevel, getLogLevel, wrapWithProtocolError } from "../../types/error-with-level.js";
|
|
22
|
+
import { isAuthErrorBody } from "../../auth/auth.js";
|
|
23
23
|
import { ClientHandler, startPoke } from "./client-handler.js";
|
|
24
24
|
import { tracer } from "./tracer.js";
|
|
25
25
|
import { CVRStore, ClientNotFoundError } from "./cvr-store.js";
|
|
@@ -41,6 +41,7 @@ function randomID() {
|
|
|
41
41
|
var TTL_CLOCK_INTERVAL = 6e4;
|
|
42
42
|
var ViewSyncerService = class {
|
|
43
43
|
id;
|
|
44
|
+
contextManager;
|
|
44
45
|
#shard;
|
|
45
46
|
#lc;
|
|
46
47
|
#pipelines;
|
|
@@ -48,10 +49,6 @@ var ViewSyncerService = class {
|
|
|
48
49
|
#drainCoordinator;
|
|
49
50
|
#keepaliveMs;
|
|
50
51
|
#slowHydrateThreshold;
|
|
51
|
-
#queryConfig;
|
|
52
|
-
#authSession;
|
|
53
|
-
userQueryURL;
|
|
54
|
-
userQueryHeaders;
|
|
55
52
|
#lastConnectTime = Date.now();
|
|
56
53
|
/**
|
|
57
54
|
* The TTL clock is used to determine the time at which queries are considered
|
|
@@ -82,10 +79,8 @@ var ViewSyncerService = class {
|
|
|
82
79
|
#initialized = resolver();
|
|
83
80
|
#cvr;
|
|
84
81
|
#pipelinesSynced = false;
|
|
85
|
-
#httpCookie;
|
|
86
|
-
#origin;
|
|
87
|
-
#lastAuthRevision = 0;
|
|
88
82
|
#expiredQueriesTimer = 0;
|
|
83
|
+
#authMaintenanceTimer = 0;
|
|
89
84
|
#setTimeout;
|
|
90
85
|
#customQueryTransformer;
|
|
91
86
|
#queryReplacements = /* @__PURE__ */ new Map();
|
|
@@ -109,12 +104,11 @@ var ViewSyncerService = class {
|
|
|
109
104
|
#inspectorDelegate;
|
|
110
105
|
#config;
|
|
111
106
|
#runPriorityOp;
|
|
112
|
-
constructor(config, lc, shard, taskID, clientGroupID, cvrDb, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, inspectorDelegate, customQueryTransformer, runPriorityOp,
|
|
113
|
-
const queryConfig = config.query?.url ? config.query : config.getQueries;
|
|
107
|
+
constructor(config, lc, shard, taskID, clientGroupID, cvrDb, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, inspectorDelegate, contextManager, customQueryTransformer, runPriorityOp, keepaliveMs = DEFAULT_KEEPALIVE_MS, setTimeoutFn = setTimeout.bind(globalThis)) {
|
|
114
108
|
this.#config = config;
|
|
115
109
|
this.id = clientGroupID;
|
|
110
|
+
this.contextManager = contextManager;
|
|
116
111
|
this.#shard = shard;
|
|
117
|
-
this.#queryConfig = queryConfig;
|
|
118
112
|
this.#lc = lc;
|
|
119
113
|
this.#pipelines = pipelineDriver;
|
|
120
114
|
this.#stateChanges = versionChanges;
|
|
@@ -123,32 +117,11 @@ var ViewSyncerService = class {
|
|
|
123
117
|
this.#slowHydrateThreshold = slowHydrateThreshold;
|
|
124
118
|
this.#inspectorDelegate = inspectorDelegate;
|
|
125
119
|
this.#customQueryTransformer = customQueryTransformer;
|
|
126
|
-
this.#authSession = authSession;
|
|
127
120
|
this.#cvrStore = new CVRStore(lc, cvrDb, shard, taskID, clientGroupID, () => this.#stateChanges.cancel());
|
|
128
121
|
this.#setTimeout = setTimeoutFn;
|
|
129
122
|
this.#runPriorityOp = runPriorityOp;
|
|
130
123
|
this.keepalive();
|
|
131
124
|
}
|
|
132
|
-
get auth() {
|
|
133
|
-
return this.#authSession.auth;
|
|
134
|
-
}
|
|
135
|
-
clearAuth() {
|
|
136
|
-
this.#authSession.clear();
|
|
137
|
-
this.#lastAuthRevision = 0;
|
|
138
|
-
}
|
|
139
|
-
initAuthSession(userID, wireAuth) {
|
|
140
|
-
return this.#authSession.update(userID, wireAuth);
|
|
141
|
-
}
|
|
142
|
-
#getHeaderOptions(forwardCookie) {
|
|
143
|
-
return {
|
|
144
|
-
apiKey: this.#queryConfig.apiKey,
|
|
145
|
-
customHeaders: this.userQueryHeaders,
|
|
146
|
-
allowedClientHeaders: this.#queryConfig.allowedClientHeaders,
|
|
147
|
-
token: this.#authSession.auth?.raw,
|
|
148
|
-
cookie: forwardCookie ? this.#httpCookie : void 0,
|
|
149
|
-
origin: this.#origin
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
125
|
#runInLockWithCVR(fn) {
|
|
153
126
|
const rid = randomID();
|
|
154
127
|
this.#lc.debug?.("about to acquire lock for cvr ", rid);
|
|
@@ -186,6 +159,8 @@ var ViewSyncerService = class {
|
|
|
186
159
|
} catch (e) {
|
|
187
160
|
this.#cvr = void 0;
|
|
188
161
|
throw e;
|
|
162
|
+
} finally {
|
|
163
|
+
this.#scheduleAuthMaintenance(lc);
|
|
189
164
|
}
|
|
190
165
|
});
|
|
191
166
|
}
|
|
@@ -227,7 +202,7 @@ var ViewSyncerService = class {
|
|
|
227
202
|
}
|
|
228
203
|
lc.info?.(`init pipelines@${version} (cvr@${cvrVer})`);
|
|
229
204
|
await this.#hydrateUnchangedQueries(lc, cvr);
|
|
230
|
-
await this.#syncQueryPipelineSet(lc, cvr, "missing");
|
|
205
|
+
await this.#syncQueryPipelineSet(lc, cvr, "missing", void 0);
|
|
231
206
|
this.#pipelinesSynced = true;
|
|
232
207
|
});
|
|
233
208
|
}
|
|
@@ -246,7 +221,7 @@ var ViewSyncerService = class {
|
|
|
246
221
|
if (hasExpiredQueries(cvr)) {
|
|
247
222
|
lc = lc.withContext("method", "#removeExpiredQueries");
|
|
248
223
|
lc.debug?.("Queries have expired");
|
|
249
|
-
if (this.#pipelinesSynced) await this.#syncQueryPipelineSet(lc, cvr, "missing");
|
|
224
|
+
if (this.#pipelinesSynced) await this.#syncQueryPipelineSet(lc, cvr, "missing", void 0);
|
|
250
225
|
}
|
|
251
226
|
this.#scheduleExpireEviction(lc, cvr);
|
|
252
227
|
};
|
|
@@ -285,6 +260,10 @@ var ViewSyncerService = class {
|
|
|
285
260
|
return this.#clients.size === 0;
|
|
286
261
|
}
|
|
287
262
|
#deleteClientDueToDisconnect(clientID, client) {
|
|
263
|
+
this.contextManager.closeConnection({
|
|
264
|
+
clientID,
|
|
265
|
+
wsID: client.wsID
|
|
266
|
+
});
|
|
288
267
|
if (this.#clients.get(clientID) === client) {
|
|
289
268
|
this.#clients.delete(clientID);
|
|
290
269
|
if (this.#clients.size === 0) {
|
|
@@ -299,73 +278,110 @@ var ViewSyncerService = class {
|
|
|
299
278
|
clearTimeout(this.#expiredQueriesTimer);
|
|
300
279
|
this.#expiredQueriesTimer = 0;
|
|
301
280
|
}
|
|
302
|
-
|
|
281
|
+
#stopAuthMaintenanceTimer() {
|
|
282
|
+
if (this.#authMaintenanceTimer !== 0) this.#lc.debug?.("Stopping auth maintenance timer");
|
|
283
|
+
clearTimeout(this.#authMaintenanceTimer);
|
|
284
|
+
this.#authMaintenanceTimer = 0;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Schedules the auth maintenance wakeup from coordinator-derived
|
|
288
|
+
* deadlines. The timer plumbing is intentionally separate from the actual
|
|
289
|
+
* revalidation/retransform work so future policy changes only need to update
|
|
290
|
+
* the maintenance workers, not the wakeup logic.
|
|
291
|
+
*
|
|
292
|
+
* This is intentionally cheap & idempotent, so it can be called frequently
|
|
293
|
+
* when upstream state might have changed.
|
|
294
|
+
*/
|
|
295
|
+
#scheduleAuthMaintenance(lc) {
|
|
296
|
+
this.#stopAuthMaintenanceTimer();
|
|
297
|
+
const plan = this.contextManager.planMaintenance();
|
|
298
|
+
if (plan.earliestDeadlineAt === void 0) {
|
|
299
|
+
lc.debug?.("No auth maintenance wakeup scheduled");
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const delay = Math.max(0, plan.earliestDeadlineAt - Date.now());
|
|
303
|
+
lc.debug?.(`Scheduling auth maintenance timer at ${new Date(plan.earliestDeadlineAt).toISOString()}`, {
|
|
304
|
+
delay,
|
|
305
|
+
earliestDeadlineAt: plan.earliestDeadlineAt
|
|
306
|
+
});
|
|
307
|
+
this.#authMaintenanceTimer = this.#setTimeout(() => {
|
|
308
|
+
this.#authMaintenanceTimer = 0;
|
|
309
|
+
this.#runInLockWithCVR((lc, cvr) => this.#runAuthMaintenance(lc, cvr)).catch((e) => this.#stateChanges.fail(e));
|
|
310
|
+
}, delay);
|
|
311
|
+
}
|
|
312
|
+
async #runAuthMaintenance(lc, _cvr) {
|
|
313
|
+
const plan = this.contextManager.planMaintenance();
|
|
314
|
+
if (plan.dueRevalidations.length === 0 && !plan.dueRetransform) {
|
|
315
|
+
lc.debug?.("Auth maintenance woke up with no due work");
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
lc.debug?.("Auth maintenance woke up with pending work", {
|
|
319
|
+
dueRevalidations: plan.dueRevalidations.length,
|
|
320
|
+
dueRetransform: plan.dueRetransform
|
|
321
|
+
});
|
|
322
|
+
for (const connection of plan.dueRevalidations) try {
|
|
323
|
+
await this.#validateConnection(connection);
|
|
324
|
+
} catch (e) {
|
|
325
|
+
if (isProtocolError(e) && isTransformFailedError(e)) {
|
|
326
|
+
lc.warn?.("Scheduled auth revalidation failed; deferring auth maintenance", {
|
|
327
|
+
clientID: connection.clientID,
|
|
328
|
+
wsID: connection.wsID,
|
|
329
|
+
message: e.message
|
|
330
|
+
});
|
|
331
|
+
this.contextManager.deferMaintenance("revalidate");
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
throw e;
|
|
335
|
+
}
|
|
336
|
+
if (this.contextManager.planMaintenance().dueRetransform) await this.#runBackgroundRetransform(lc);
|
|
337
|
+
}
|
|
338
|
+
initConnection(selector, initConnectionMessage) {
|
|
303
339
|
this.#lc.debug?.("viewSyncer.initConnection");
|
|
304
340
|
return startSpan(tracer, "vs.initConnection", () => {
|
|
305
|
-
const
|
|
306
|
-
this.#
|
|
307
|
-
this.#origin = origin;
|
|
308
|
-
const [, { userQueryURL, userQueryHeaders }] = initConnectionMessage;
|
|
309
|
-
if (this.userQueryURL === void 0) {
|
|
310
|
-
this.userQueryURL = userQueryURL;
|
|
311
|
-
this.userQueryHeaders = userQueryHeaders;
|
|
312
|
-
} else if (this.userQueryURL !== userQueryURL) this.#lc.warn?.("Client provided different query parameters than client group", {
|
|
313
|
-
clientID,
|
|
314
|
-
clientURL: userQueryURL,
|
|
315
|
-
clientGroupURL: this.userQueryURL
|
|
316
|
-
});
|
|
317
|
-
const lc = this.#lc.withContext("clientID", clientID).withContext("wsID", wsID);
|
|
341
|
+
const ctx = this.contextManager.mustGetConnectionContext(selector);
|
|
342
|
+
const lc = this.#lc.withContext("clientID", ctx.clientID).withContext("wsID", ctx.wsID);
|
|
318
343
|
const downstream = Subscription.create({ cleanup: (_, err) => {
|
|
319
344
|
err ? lc[getLogLevel(err)]?.(`client closed with error`, err) : lc.info?.("client closed");
|
|
320
|
-
this.#deleteClientDueToDisconnect(clientID, newClient);
|
|
321
|
-
this.#activeClients.add(-1, { [PROTOCOL_VERSION_ATTR]: protocolVersion });
|
|
345
|
+
this.#deleteClientDueToDisconnect(ctx.clientID, newClient);
|
|
346
|
+
this.#activeClients.add(-1, { [PROTOCOL_VERSION_ATTR]: ctx.protocolVersion });
|
|
322
347
|
} });
|
|
323
|
-
this.#activeClients.add(1, { [PROTOCOL_VERSION_ATTR]: protocolVersion });
|
|
348
|
+
this.#activeClients.add(1, { [PROTOCOL_VERSION_ATTR]: ctx.protocolVersion });
|
|
324
349
|
if (this.#clients.size === 0) this.#ttlClockBase = Date.now();
|
|
325
|
-
const newClient = new ClientHandler(lc, this.id, clientID, wsID, this.#shard, baseCookie, downstream);
|
|
326
|
-
this.#clients.get(clientID)?.close(`replaced by wsID: ${wsID}`);
|
|
327
|
-
this.#clients.set(clientID, newClient);
|
|
328
|
-
this.#runInLockForClient(ctx, initConnectionMessage, async (lc, clientID, msg, cvr) => {
|
|
350
|
+
const newClient = new ClientHandler(lc, this.id, ctx.clientID, ctx.wsID, this.#shard, ctx.baseCookie, downstream);
|
|
351
|
+
this.#clients.get(ctx.clientID)?.close(`replaced by wsID: ${ctx.wsID}`);
|
|
352
|
+
this.#clients.set(ctx.clientID, newClient);
|
|
353
|
+
startAsyncSpan(tracer, "vs.initConnection.async", () => this.#runInLockForClient(ctx, initConnectionMessage, async (lc, clientID, msg, cvr) => {
|
|
329
354
|
if (cvr.clientSchema === null && !msg.clientSchema) throw new ProtocolErrorWithLevel({
|
|
330
355
|
kind: InvalidConnectionRequest,
|
|
331
356
|
message: "The initConnection message for a new client group must include client schema.",
|
|
332
357
|
origin: ZeroCache
|
|
333
358
|
}, "warn");
|
|
334
|
-
await this.#
|
|
359
|
+
if (!await this.#validateConnection(ctx)) return;
|
|
360
|
+
await this.#handleConfigUpdate(lc, clientID, msg, cvr, "all", ctx.profileID ?? `cg${this.id}`, ctx);
|
|
335
361
|
this.#initialized.resolve("initialized");
|
|
336
|
-
}, newClient).catch((e) => newClient.fail(e));
|
|
362
|
+
}, newClient)).catch((e) => newClient.fail(e));
|
|
337
363
|
return downstream;
|
|
338
364
|
});
|
|
339
365
|
}
|
|
340
|
-
async changeDesiredQueries(
|
|
341
|
-
await this.#runInLockForClient(
|
|
342
|
-
let customQueryTransformMode = "missing";
|
|
343
|
-
const currentAuthRevision = this.#authSession.revision;
|
|
344
|
-
if (this.#lastAuthRevision < currentAuthRevision) {
|
|
345
|
-
customQueryTransformMode = "all";
|
|
346
|
-
lc.debug?.("Auth revision changed, setting customQueryTransformMode to all");
|
|
347
|
-
}
|
|
348
|
-
const result = await this.#handleConfigUpdate(lc, clientID, msg, cvr, customQueryTransformMode);
|
|
349
|
-
if (customQueryTransformMode === "all") this.#lastAuthRevision = currentAuthRevision;
|
|
350
|
-
return result;
|
|
351
|
-
});
|
|
366
|
+
async changeDesiredQueries(selector, msg) {
|
|
367
|
+
await this.#runInLockForClient(selector, msg, (lc, clientID, msg, cvr) => this.#handleConfigUpdate(lc, clientID, msg, cvr, "missing", void 0, this.contextManager.mustGetConnectionContext(selector)));
|
|
352
368
|
}
|
|
353
|
-
async updateAuth(
|
|
354
|
-
await this.#runInLockForClient(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
const currentAuthRevision = this.#authSession.revision;
|
|
358
|
-
if (this.#lastAuthRevision >= currentAuthRevision) {
|
|
359
|
-
lc.debug?.("Auth revision unchanged, skipping query re-transformation");
|
|
369
|
+
async updateAuth(selector, msg, authRevisionChanged) {
|
|
370
|
+
await this.#runInLockForClient(selector, msg, async (lc, clientID, _, cvr) => {
|
|
371
|
+
if (!authRevisionChanged) {
|
|
372
|
+
lc.debug?.("Auth unchanged, skipping query re-transformation");
|
|
360
373
|
return;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
374
|
+
}
|
|
375
|
+
lc.debug?.("Auth changed, re-validating and re-transforming queries");
|
|
376
|
+
const connection = this.contextManager.mustGetConnectionContext(selector);
|
|
377
|
+
if (!this.#pipelinesSynced) {
|
|
378
|
+
if (!await this.#validateConnection(connection)) return;
|
|
379
|
+
}
|
|
380
|
+
return await this.#handleConfigUpdate(lc, clientID, {}, cvr, "all", void 0, connection);
|
|
365
381
|
});
|
|
366
382
|
}
|
|
367
|
-
async deleteClients(
|
|
368
|
-
return await this.#runInLockForClient(
|
|
383
|
+
async deleteClients(selector, msg) {
|
|
384
|
+
return await this.#runInLockForClient(selector, [msg[0], { deleted: msg[1] }], (lc, clientID, msg, cvr) => this.#handleConfigUpdate(lc, clientID, msg, cvr, "missing", void 0, this.contextManager.mustGetConnectionContext(selector))) ?? [];
|
|
369
385
|
}
|
|
370
386
|
#getTTLClock(now) {
|
|
371
387
|
const delta = now - this.#ttlClockBase;
|
|
@@ -407,7 +423,7 @@ var ViewSyncerService = class {
|
|
|
407
423
|
lc.warn?.("failed to update TTL clock", rid, `after ${Date.now() - start} ms`, e);
|
|
408
424
|
});
|
|
409
425
|
}
|
|
410
|
-
async #updateCVRConfig(lc, cvr, clientID, customQueryTransformMode, fn) {
|
|
426
|
+
async #updateCVRConfig(lc, cvr, clientID, customQueryTransformMode, ctx, fn) {
|
|
411
427
|
const updater = new CVRConfigDrivenUpdater(this.#cvrStore, cvr, this.#shard);
|
|
412
428
|
updater.ensureClient(clientID);
|
|
413
429
|
const patches = fn(updater);
|
|
@@ -420,16 +436,16 @@ var ViewSyncerService = class {
|
|
|
420
436
|
await pokers.end(newCVR.version);
|
|
421
437
|
});
|
|
422
438
|
}
|
|
423
|
-
if (this.#pipelinesSynced) await this.#syncQueryPipelineSet(lc, this.#cvr, customQueryTransformMode);
|
|
439
|
+
if (this.#pipelinesSynced) await this.#syncQueryPipelineSet(lc, this.#cvr, customQueryTransformMode, ctx);
|
|
424
440
|
return this.#cvr;
|
|
425
441
|
}
|
|
426
442
|
/**
|
|
427
443
|
* Runs the given `fn` to process the `msg` from within the `#lock`,
|
|
428
444
|
* optionally adding the `newClient` if supplied.
|
|
429
445
|
*/
|
|
430
|
-
#runInLockForClient(
|
|
446
|
+
#runInLockForClient(selector, msg, fn, newClient) {
|
|
431
447
|
this.#lc.debug?.("viewSyncer.#runInLockForClient");
|
|
432
|
-
const { clientID, wsID } =
|
|
448
|
+
const { clientID, wsID } = selector;
|
|
433
449
|
const [cmd, body] = msg;
|
|
434
450
|
if (newClient || !this.#clients.has(clientID)) this.#lastConnectTime = Date.now();
|
|
435
451
|
return startAsyncSpan(tracer, `vs.#runInLockForClient(${cmd})`, async (span) => {
|
|
@@ -437,6 +453,7 @@ var ViewSyncerService = class {
|
|
|
437
453
|
span.setAttribute("clientID", clientID);
|
|
438
454
|
let client;
|
|
439
455
|
let result;
|
|
456
|
+
let ctx;
|
|
440
457
|
try {
|
|
441
458
|
await this.#runInLockWithCVR(async (lc, cvr) => {
|
|
442
459
|
lc = lc.withContext("clientID", clientID).withContext("wsID", wsID).withContext("cmd", cmd);
|
|
@@ -446,6 +463,7 @@ var ViewSyncerService = class {
|
|
|
446
463
|
lc.debug?.("mismatched wsID", client?.wsID, wsID);
|
|
447
464
|
return;
|
|
448
465
|
}
|
|
466
|
+
ctx = this.contextManager.getConnectionContext(selector);
|
|
449
467
|
if (newClient) {
|
|
450
468
|
assert(newClient === client, "newClient must match existing client");
|
|
451
469
|
checkClientAndCVRVersions(client.version(), cvr.version);
|
|
@@ -454,12 +472,8 @@ var ViewSyncerService = class {
|
|
|
454
472
|
result = await fn(lc, clientID, body, cvr);
|
|
455
473
|
});
|
|
456
474
|
} catch (e) {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
if (isTransformAuthFailure(e)) {
|
|
460
|
-
lc.debug?.("Auth failure detected in transform response");
|
|
461
|
-
this.clearAuth();
|
|
462
|
-
}
|
|
475
|
+
this.#lc.withContext("clientID", clientID).withContext("wsID", wsID).withContext("cmd", cmd)[getLogLevel(e)]?.(`closing connection with error`, e);
|
|
476
|
+
if (ctx) this.contextManager.failConnection(selector, ctx.revision);
|
|
463
477
|
if (client) client.fail(e);
|
|
464
478
|
else throw e;
|
|
465
479
|
}
|
|
@@ -470,10 +484,10 @@ var ViewSyncerService = class {
|
|
|
470
484
|
const clients = [...this.#clients.values()];
|
|
471
485
|
return atVersion ? clients.filter((c) => cmpVersions(c.version() ?? EMPTY_CVR_VERSION, atVersion) === 0) : clients;
|
|
472
486
|
}
|
|
473
|
-
#handleConfigUpdate = (lc, clientID, { clientSchema, deleted, desiredQueriesPatch, activeClients }, cvr, customQueryTransformMode, profileID) => startAsyncSpan(tracer, "vs.#handleConfigUpdate", async () => {
|
|
487
|
+
#handleConfigUpdate = (lc, clientID, { clientSchema, deleted, desiredQueriesPatch, activeClients }, cvr, customQueryTransformMode, profileID, ctx) => startAsyncSpan(tracer, "vs.#handleConfigUpdate", async () => {
|
|
474
488
|
const deletedClientIDs = [];
|
|
475
489
|
const deletedClientGroupIDs = [];
|
|
476
|
-
cvr = await this.#updateCVRConfig(lc, cvr, clientID, customQueryTransformMode, (updater) => {
|
|
490
|
+
cvr = await this.#updateCVRConfig(lc, cvr, clientID, customQueryTransformMode, ctx, (updater) => {
|
|
477
491
|
const { ttlClock } = cvr;
|
|
478
492
|
const patches = [];
|
|
479
493
|
if (clientSchema) updater.setClientSchema(lc, clientSchema);
|
|
@@ -570,16 +584,17 @@ var ViewSyncerService = class {
|
|
|
570
584
|
let customHashMismatchCount = 0;
|
|
571
585
|
let otherHashMismatchCount = 0;
|
|
572
586
|
if (customQueries.size > 0 && !this.#customQueryTransformer) lc.warn?.("Custom/named queries were requested but no `ZERO_QUERY_URL` is configured for Zero Cache.");
|
|
587
|
+
const backgroundContext = this.contextManager.mustGetBackgroundConnectionContext();
|
|
573
588
|
const customQueryTransformer = this.#customQueryTransformer;
|
|
574
589
|
if (customQueryTransformer && customQueries.size > 0) {
|
|
575
|
-
const transformedCustomQueries = await this.#runPriorityOp(lc, "#hydrateUnchangedQueries transforming custom queries", () => customQueryTransformer.transform(
|
|
576
|
-
if (
|
|
590
|
+
const transformedCustomQueries = await this.#runPriorityOp(lc, "#hydrateUnchangedQueries transforming custom queries", () => customQueryTransformer.transform(backgroundContext, customQueries.values()));
|
|
591
|
+
if (!transformedCustomQueries.cached) this.contextManager.validateConnection(backgroundContext, backgroundContext.revision);
|
|
592
|
+
if (Array.isArray(transformedCustomQueries.result)) for (const q of transformedCustomQueries.result) if ("error" in q) customErrorCount++;
|
|
577
593
|
else if (q.transformationHash !== customQueries.get(q.id)?.transformationHash) customHashMismatchCount++;
|
|
578
594
|
else transformedQueries.push(q);
|
|
579
595
|
}
|
|
580
596
|
for (const q of otherQueries) {
|
|
581
|
-
const
|
|
582
|
-
const transformed = transformAndHashQuery(lc, q.id, q.ast, must(this.#pipelines.currentPermissions()).permissions ?? { tables: {} }, auth?.type === "jwt" ? auth : void 0, q.type === "internal");
|
|
597
|
+
const transformed = transformAndHashQuery(lc, q.id, q.ast, must(this.#pipelines.currentPermissions()).permissions ?? { tables: {} }, backgroundContext.auth?.type === "jwt" ? backgroundContext.auth : void 0, q.type === "internal");
|
|
583
598
|
if (transformed.transformationHash === q.transformationHash) transformedQueries.push(transformed);
|
|
584
599
|
else otherHashMismatchCount++;
|
|
585
600
|
}
|
|
@@ -652,7 +667,7 @@ var ViewSyncerService = class {
|
|
|
652
667
|
*
|
|
653
668
|
* This must be called from within the #lock.
|
|
654
669
|
*/
|
|
655
|
-
#syncQueryPipelineSet(lc, cvr, customQueryTransformMode) {
|
|
670
|
+
#syncQueryPipelineSet(lc, cvr, customQueryTransformMode, ctx) {
|
|
656
671
|
return startAsyncSpan(tracer, "vs.#syncQueryPipelineSet", async (span) => {
|
|
657
672
|
span.setAttribute("clientGroupID", this.id);
|
|
658
673
|
assert(this.#pipelines.initialized(), "pipelines must be initialized (syncQueryPipelineSet)");
|
|
@@ -663,6 +678,7 @@ var ViewSyncerService = class {
|
|
|
663
678
|
const customQueries = /* @__PURE__ */ new Map();
|
|
664
679
|
const otherQueries = [];
|
|
665
680
|
const transformedQueries = [];
|
|
681
|
+
const resolvedContext = ctx ?? this.contextManager.mustGetBackgroundConnectionContext();
|
|
666
682
|
for (const [id, query] of cvrQueryEntires) if (query.type === "custom") {
|
|
667
683
|
assert(id === query.id, "custom query id mismatch");
|
|
668
684
|
customQueries.set(id, query);
|
|
@@ -672,8 +688,7 @@ var ViewSyncerService = class {
|
|
|
672
688
|
});
|
|
673
689
|
for (const { id, query: origQuery } of otherQueries) {
|
|
674
690
|
assert(id === origQuery.id, "query id mismatch");
|
|
675
|
-
const
|
|
676
|
-
const transformed = transformAndHashQuery(lc, origQuery.id, origQuery.ast, must(this.#pipelines.currentPermissions()).permissions ?? { tables: {} }, auth?.type === "jwt" ? auth : void 0, origQuery.type === "internal");
|
|
691
|
+
const transformed = transformAndHashQuery(lc, origQuery.id, origQuery.ast, must(this.#pipelines.currentPermissions()).permissions ?? { tables: {} }, resolvedContext.auth?.type === "jwt" ? resolvedContext.auth : void 0, origQuery.type === "internal");
|
|
677
692
|
transformedQueries.push({
|
|
678
693
|
id,
|
|
679
694
|
origQuery,
|
|
@@ -688,9 +703,12 @@ var ViewSyncerService = class {
|
|
|
688
703
|
const transformStart = performance.now();
|
|
689
704
|
let transformedCustomQueries;
|
|
690
705
|
try {
|
|
691
|
-
transformedCustomQueries = await this.#runPriorityOp(lc, "#syncQueryPipelineSet transforming custom queries", () => customQueryTransformer.transform(
|
|
692
|
-
if (
|
|
693
|
-
else
|
|
706
|
+
transformedCustomQueries = await this.#runPriorityOp(lc, "#syncQueryPipelineSet transforming custom queries", () => customQueryTransformer.transform(resolvedContext, customQueriesToTransform));
|
|
707
|
+
if ("kind" in transformedCustomQueries.result) throw new ProtocolErrorWithLevel(transformedCustomQueries.result, "warn");
|
|
708
|
+
else {
|
|
709
|
+
if (!transformedCustomQueries.cached) this.contextManager.validateConnection(resolvedContext, resolvedContext.revision);
|
|
710
|
+
this.#queryTransformations.add(1, { result: "success" });
|
|
711
|
+
}
|
|
694
712
|
} catch (e) {
|
|
695
713
|
this.#queryTransformations.add(1, { result: "error" });
|
|
696
714
|
throw e;
|
|
@@ -699,7 +717,7 @@ var ViewSyncerService = class {
|
|
|
699
717
|
this.#queryTransformationTime.record(transformDuration);
|
|
700
718
|
}
|
|
701
719
|
const successfullyTransformedCustomQueries = /* @__PURE__ */ new Map();
|
|
702
|
-
erroredQueryIDs = this.#processTransformedCustomQueries(lc, transformedCustomQueries, (q) => {
|
|
720
|
+
erroredQueryIDs = this.#processTransformedCustomQueries(lc, transformedCustomQueries.result, (q) => {
|
|
703
721
|
const origQuery = customQueries.get(q.id);
|
|
704
722
|
if (origQuery) {
|
|
705
723
|
successfullyTransformedCustomQueries.set(q.id, q);
|
|
@@ -981,14 +999,86 @@ var ViewSyncerService = class {
|
|
|
981
999
|
return "success";
|
|
982
1000
|
});
|
|
983
1001
|
}
|
|
984
|
-
async inspect(
|
|
985
|
-
await this.#runInLockForClient(
|
|
1002
|
+
async inspect(selector, msg) {
|
|
1003
|
+
await this.#runInLockForClient(selector, msg, this.#handleInspect);
|
|
986
1004
|
}
|
|
987
1005
|
#handleInspect = async (lc, clientID, body, cvr) => {
|
|
988
1006
|
const client = must(this.#clients.get(clientID));
|
|
989
|
-
const
|
|
990
|
-
|
|
1007
|
+
const ctx = this.contextManager.mustGetConnectionContext({
|
|
1008
|
+
clientID,
|
|
1009
|
+
wsID: client.wsID
|
|
1010
|
+
});
|
|
1011
|
+
return handleInspect(lc, body, cvr, client, this.#inspectorDelegate, this.id, this.#cvrStore, this.#config, ctx);
|
|
991
1012
|
};
|
|
1013
|
+
async #runBackgroundRetransform(lc) {
|
|
1014
|
+
const attemptRetransform = async (connection) => {
|
|
1015
|
+
await this.#syncQueryPipelineSet(lc, must(this.#cvr, "cvr missing during auth maintenance retransform"), "all", connection);
|
|
1016
|
+
this.contextManager.markBackgroundRetransformSuccess({
|
|
1017
|
+
clientID: connection.clientID,
|
|
1018
|
+
wsID: connection.wsID
|
|
1019
|
+
}, connection.revision);
|
|
1020
|
+
};
|
|
1021
|
+
let backgroundConnection = this.contextManager.getBackgroundConnectionContext();
|
|
1022
|
+
if (!backgroundConnection) {
|
|
1023
|
+
lc.debug?.("Skipping background retransform with no selected connection");
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
for (;;) {
|
|
1027
|
+
try {
|
|
1028
|
+
await attemptRetransform(backgroundConnection);
|
|
1029
|
+
return;
|
|
1030
|
+
} catch (e) {
|
|
1031
|
+
if (isProtocolError(e)) {
|
|
1032
|
+
if (isAuthErrorBody(e.errorBody)) {
|
|
1033
|
+
lc.warn?.("Background retransform auth failed; failing connection and searching for replacement", {
|
|
1034
|
+
clientID: backgroundConnection.clientID,
|
|
1035
|
+
message: e.message
|
|
1036
|
+
});
|
|
1037
|
+
this.#failMaintenanceConnection(backgroundConnection, e);
|
|
1038
|
+
} else if (isTransformFailedError(e)) {
|
|
1039
|
+
lc.warn?.("Background retransform failed; deferring auth maintenance", {
|
|
1040
|
+
clientID: backgroundConnection.clientID,
|
|
1041
|
+
message: e.message
|
|
1042
|
+
});
|
|
1043
|
+
this.contextManager.deferMaintenance("retransform");
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
} else throw e;
|
|
1047
|
+
}
|
|
1048
|
+
const replacement = this.contextManager.getBackgroundConnectionContext();
|
|
1049
|
+
if (!replacement) {
|
|
1050
|
+
lc.debug?.("No replacement connection available for background retransform");
|
|
1051
|
+
return;
|
|
1052
|
+
}
|
|
1053
|
+
lc.debug?.("Retrying background retransform with replacement connection", {
|
|
1054
|
+
clientID: replacement.clientID,
|
|
1055
|
+
wsID: replacement.wsID
|
|
1056
|
+
});
|
|
1057
|
+
backgroundConnection = replacement;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
async #validateConnection(ctx) {
|
|
1061
|
+
try {
|
|
1062
|
+
if (this.#customQueryTransformer) {
|
|
1063
|
+
const validation = await this.#customQueryTransformer.validate(ctx);
|
|
1064
|
+
if (validation !== void 0) throw new ProtocolErrorWithLevel(validation, "warn");
|
|
1065
|
+
}
|
|
1066
|
+
this.contextManager.validateConnection(ctx, ctx.revision);
|
|
1067
|
+
return true;
|
|
1068
|
+
} catch (e) {
|
|
1069
|
+
if (isProtocolError(e) && isAuthErrorBody(e.errorBody)) {
|
|
1070
|
+
this.#failMaintenanceConnection(ctx, e);
|
|
1071
|
+
return false;
|
|
1072
|
+
}
|
|
1073
|
+
throw e;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
#failMaintenanceConnection(ctx, error) {
|
|
1077
|
+
if (!this.contextManager.failConnection(ctx, ctx.revision)) return;
|
|
1078
|
+
const wrapped = wrapWithProtocolError(error);
|
|
1079
|
+
const client = this.#clients.get(ctx.clientID);
|
|
1080
|
+
if (client?.wsID === ctx.wsID) client.fail(wrapped);
|
|
1081
|
+
}
|
|
992
1082
|
stop() {
|
|
993
1083
|
this.#lc.info?.("stopping view syncer");
|
|
994
1084
|
this.#initialized.reject("shut down before initialization completed");
|
|
@@ -996,9 +1086,9 @@ var ViewSyncerService = class {
|
|
|
996
1086
|
return this.#stopped.promise;
|
|
997
1087
|
}
|
|
998
1088
|
async #cleanup(err) {
|
|
999
|
-
this.clearAuth();
|
|
1000
1089
|
this.#stopTTLClockInterval();
|
|
1001
1090
|
this.#stopExpireTimer();
|
|
1091
|
+
this.#stopAuthMaintenanceTimer();
|
|
1002
1092
|
for (const client of this.#clients.values()) if (err) client.fail(err);
|
|
1003
1093
|
else client.close(`closed clientGroupID=${this.id}`);
|
|
1004
1094
|
await this.#lock.withLock(() => {});
|
|
@@ -1034,9 +1124,8 @@ function checkClientAndCVRVersions(client, cvr) {
|
|
|
1034
1124
|
origin: ZeroCache
|
|
1035
1125
|
});
|
|
1036
1126
|
}
|
|
1037
|
-
function
|
|
1038
|
-
|
|
1039
|
-
return error.errorBody.kind === "TransformFailed" && error.errorBody.reason === "http" && (error.errorBody.status === 401 || error.errorBody.status === 403);
|
|
1127
|
+
function isTransformFailedError(error) {
|
|
1128
|
+
return error.errorBody.kind === "TransformFailed" && !isAuthErrorBody(error.errorBody);
|
|
1040
1129
|
}
|
|
1041
1130
|
/**
|
|
1042
1131
|
* A query must be expired for all clients in order to be considered
|