@rebasepro/server 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{GCSStorageController-C7ARrDAp.js → GCSStorageController-40FyFeSx.js} +8 -4
- package/dist/GCSStorageController-40FyFeSx.js.map +1 -0
- package/dist/{S3StorageController-qevJ0pVE.js → S3StorageController-Bl5shp94.js} +8 -4
- package/dist/S3StorageController-Bl5shp94.js.map +1 -0
- package/dist/access-BFAUvsSs.js +1897 -0
- package/dist/access-BFAUvsSs.js.map +1 -0
- package/dist/api/branch-routes.d.ts +25 -0
- package/dist/api/closed-database.d.ts +25 -0
- package/dist/api/live-schema-routes.d.ts +10 -0
- package/dist/api/rest/api-generator.d.ts +9 -1
- package/dist/api/rest/idempotency.d.ts +15 -1
- package/dist/api/root-error-handler.d.ts +6 -5
- package/dist/api/types.d.ts +12 -0
- package/dist/{ast-schema-editor-mCeSC03x.js → ast-schema-editor-madTa9Hh.js} +2 -2
- package/dist/{ast-schema-editor-mCeSC03x.js.map → ast-schema-editor-madTa9Hh.js.map} +1 -1
- package/dist/auth/access.d.ts +10 -0
- package/dist/auth/adapter-middleware.d.ts +2 -1
- package/dist/auth/adapter-service-key.d.ts +24 -0
- package/dist/auth/api-keys/api-key-middleware.d.ts +21 -1
- package/dist/auth/api-keys/api-key-store.d.ts +8 -1
- package/dist/auth/api-keys/key-grant.d.ts +18 -1
- package/dist/auth/expired-token-sweep.d.ts +5 -0
- package/dist/auth/impersonation.d.ts +3 -1
- package/dist/auth/jwt.d.ts +8 -2
- package/dist/auth/oauth-signin-policy.d.ts +21 -35
- package/dist/auth/rls-scope.d.ts +17 -7
- package/dist/auth/rls-simulator-routes.d.ts +51 -0
- package/dist/auth/simulation-read-only.d.ts +28 -0
- package/dist/auth/simulation.d.ts +141 -0
- package/dist/auth/sql-rate-limit-store.d.ts +15 -1
- package/dist/{auth-CteGWxsL.js → auth-izI7AEzC.js} +391 -1893
- package/dist/auth-izI7AEzC.js.map +1 -0
- package/dist/auth_adapter-B7RUMk6e.js +89 -0
- package/dist/auth_adapter-B7RUMk6e.js.map +1 -0
- package/dist/backend/boot-announcements.d.ts +13 -0
- package/dist/backend/create-backend.d.ts +10 -0
- package/dist/backend/options.d.ts +9 -4
- package/dist/{backend-DTAOsLQc.js → backend-CaG_Jyso.js} +9 -2
- package/dist/backend-CaG_Jyso.js.map +1 -0
- package/dist/{backup-Dq0lyJ_D.js → backup-BVbHoKo8.js} +8 -8
- package/dist/{backup-Dq0lyJ_D.js.map → backup-BVbHoKo8.js.map} +1 -1
- package/dist/boot/boot.d.ts +2 -15
- package/dist/boot/ddl-bootstrap.d.ts +34 -0
- package/dist/boot/env.d.ts +6 -0
- package/dist/boot/fetch-bundle.d.ts +5 -1
- package/dist/boot/provision-only.d.ts +23 -0
- package/dist/boot/provision.d.ts +53 -2
- package/dist/boot/role.d.ts +2 -0
- package/dist/boot/schema-change-recorder.d.ts +45 -0
- package/dist/boot/security-headers.d.ts +22 -0
- package/dist/branch-routes-B2vvEx53.js +84 -0
- package/dist/branch-routes-B2vvEx53.js.map +1 -0
- package/dist/{contract-routes-DiFwiLg2.js → contract-routes-CU2A3JnF.js} +3 -3
- package/dist/{contract-routes-DiFwiLg2.js.map → contract-routes-CU2A3JnF.js.map} +1 -1
- package/dist/cron/cron-store.d.ts +8 -1
- package/dist/{cron-loader-NHqRfKF0.js → cron-loader-mMhqbVsl.js} +3 -3
- package/dist/{cron-loader-NHqRfKF0.js.map → cron-loader-mMhqbVsl.js.map} +1 -1
- package/dist/{cron-routes-Dhf82HzT.js → cron-routes-Cs33j_Kr.js} +5 -5
- package/dist/{cron-routes-Dhf82HzT.js.map → cron-routes-Cs33j_Kr.js.map} +1 -1
- package/dist/{cron-scheduler-D1DT0nw5.js → cron-scheduler-Be7CNghL.js} +3 -3
- package/dist/{cron-scheduler-D1DT0nw5.js.map → cron-scheduler-Be7CNghL.js.map} +1 -1
- package/dist/{cron-store-DEpVstUU.js → cron-store-DLn11M8H.js} +11 -10
- package/dist/cron-store-DLn11M8H.js.map +1 -0
- package/dist/{strings.es-BeZWAodn.js → data_driver-D0mg1Y_x.js} +2 -90
- package/dist/data_driver-D0mg1Y_x.js.map +1 -0
- package/dist/{ddl-bootstrap-BNqi2NZe.js → ddl-bootstrap-CjRrn12l.js} +92 -3
- package/dist/ddl-bootstrap-CjRrn12l.js.map +1 -0
- package/dist/deploy/pod-contract.d.ts +1 -1
- package/dist/email/dev-sink.d.ts +6 -0
- package/dist/email/index.d.ts +1 -1
- package/dist/{errors-_ytoGi8A.js → errors-OMWkKSH-.js} +66 -5
- package/dist/errors-OMWkKSH-.js.map +1 -0
- package/dist/{soft-delete-params-BAgpmBvp.js → field-access-DYsvjI_P.js} +27 -57
- package/dist/field-access-DYsvjI_P.js.map +1 -0
- package/dist/{filter-dialect-O1HK6Nvr.js → filter-dialect-TrKFWLqT.js} +3 -3
- package/dist/{filter-dialect-O1HK6Nvr.js.map → filter-dialect-TrKFWLqT.js.map} +1 -1
- package/dist/{function-loader-DbCSoNJj.js → function-loader-B8YzXEsQ.js} +22 -15
- package/dist/function-loader-B8YzXEsQ.js.map +1 -0
- package/dist/{function-routes-DNV4RUF0.js → function-routes-RxrCHNuM.js} +2 -2
- package/dist/{function-routes-DNV4RUF0.js.map → function-routes-RxrCHNuM.js.map} +1 -1
- package/dist/functions/hono-like.d.ts +12 -0
- package/dist/functions/index.js +37 -2
- package/dist/functions/index.js.map +1 -1
- package/dist/functions/request-timeout.d.ts +3 -3
- package/dist/history/history-routes.d.ts +6 -0
- package/dist/history/retention-sweep.d.ts +5 -0
- package/dist/{history-recorder-RZ1Ow4YY.js → history-recorder-Bsau7h4X.js} +7 -7
- package/dist/history-recorder-Bsau7h4X.js.map +1 -0
- package/dist/{history-store-DPofGVDp.js → history-store-BQz5YCkW.js} +26 -2
- package/dist/history-store-BQz5YCkW.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.es.js +3003 -681
- package/dist/index.es.js.map +1 -1
- package/dist/init/process-safety.d.ts +4 -3
- package/dist/init/shutdown.d.ts +8 -0
- package/dist/init.d.ts +6 -1
- package/dist/jobs/job-store.d.ts +8 -1
- package/dist/{jobs-8G-_agld.js → jobs-Co6Ni5HP.js} +7 -7
- package/dist/jobs-Co6Ni5HP.js.map +1 -0
- package/dist/{jwt-YhciR93H.js → jwt-rDS0884_.js} +5 -4
- package/dist/{jwt-YhciR93H.js.map → jwt-rDS0884_.js.map} +1 -1
- package/dist/{keys-COzQ2aE8.js → keys-BXcdRNhJ.js} +2 -2
- package/dist/{keys-COzQ2aE8.js.map → keys-BXcdRNhJ.js.map} +1 -1
- package/dist/{logger-Bt32sHFw.js → logger-CW8pmTS6.js} +35 -3
- package/dist/logger-CW8pmTS6.js.map +1 -0
- package/dist/{logs-routes-CelTiS7C.js → logs-routes-CBt7mMIL.js} +3 -3
- package/dist/{logs-routes-CelTiS7C.js.map → logs-routes-CBt7mMIL.js.map} +1 -1
- package/dist/mcp/consent-page.d.ts +38 -1
- package/dist/mcp/mcp-routes.d.ts +9 -0
- package/dist/mcp/mcp-tools.d.ts +7 -1
- package/dist/mcp/oauth-store.d.ts +12 -5
- package/dist/metrics/history-recorder.d.ts +4 -1
- package/dist/metrics/history-store.d.ts +8 -0
- package/dist/{offline-BrqCRgih-BtDB1ecy.js → offline-AvuEcg7u-DFHL98OT.js} +127 -40
- package/dist/offline-AvuEcg7u-DFHL98OT.js.map +1 -0
- package/dist/{offline-store-BhYXViha-BW5j1We_.js → offline-store-BhYXViha-YTmjBpo2.js} +5 -5
- package/dist/{offline-store-BhYXViha-BW5j1We_.js.map → offline-store-BhYXViha-YTmjBpo2.js.map} +1 -1
- package/dist/{openapi-generator-BamY6-ga.js → openapi-generator-CyxEtYEX.js} +61 -22
- package/dist/openapi-generator-CyxEtYEX.js.map +1 -0
- package/dist/{proxy-BEKbsil6.js → proxy-BYir8tWK.js} +5 -7
- package/dist/proxy-BYir8tWK.js.map +1 -0
- package/dist/{query-parser-CGohjyWI.js → query-parser-CDXWf2hH.js} +7 -6
- package/dist/{query-parser-CGohjyWI.js.map → query-parser-CDXWf2hH.js.map} +1 -1
- package/dist/{request-timeout-CRny5KD0.js → request-timeout-DVjo-c_8.js} +6 -6
- package/dist/request-timeout-DVjo-c_8.js.map +1 -0
- package/dist/rls-simulator-routes-bEY7-5-u.js +190 -0
- package/dist/rls-simulator-routes-bEY7-5-u.js.map +1 -0
- package/dist/schema-edit/deployed-schema-guard.d.ts +47 -0
- package/dist/{schema-editor-routes-CnNGCayU.js → schema-editor-routes-Dc3DU_jm.js} +4 -4
- package/dist/{schema-editor-routes-CnNGCayU.js.map → schema-editor-routes-Dc3DU_jm.js.map} +1 -1
- package/dist/soft-delete-params-BRONCOA2.js +59 -0
- package/dist/soft-delete-params-BRONCOA2.js.map +1 -0
- package/dist/{sql-export-routes-BgTJ7K3S.js → sql-export-routes-QycX8W8S.js} +40 -6
- package/dist/sql-export-routes-QycX8W8S.js.map +1 -0
- package/dist/{src-D5Y3N-S4.js → src-Bh9LRPb9.js} +21 -2
- package/dist/{src-D5Y3N-S4.js.map → src-Bh9LRPb9.js.map} +1 -1
- package/dist/storage/GCSStorageController.d.ts +2 -0
- package/dist/storage/LocalStorageController.d.ts +8 -3
- package/dist/storage/S3StorageController.d.ts +2 -0
- package/dist/storage/maintenance-keys.d.ts +17 -0
- package/dist/storage/maintenance-routes.d.ts +28 -5
- package/dist/storage/maintenance.d.ts +136 -4
- package/dist/storage/orphan-scans.d.ts +120 -0
- package/dist/storage/types.d.ts +11 -0
- package/dist/strings.es-B7QLnHh2.js +96 -0
- package/dist/strings.es-B7QLnHh2.js.map +1 -0
- package/dist/{upload-validation-I9cCUBIW.js → upload-validation-Bgo626uY.js} +2 -2
- package/dist/upload-validation-Bgo626uY.js.map +1 -0
- package/dist/utils/dev-dependency-command.d.ts +15 -0
- package/dist/utils/dev-port.d.ts +8 -0
- package/dist/utils/logger.d.ts +24 -0
- package/package.json +5 -5
- package/dist/GCSStorageController-C7ARrDAp.js.map +0 -1
- package/dist/S3StorageController-qevJ0pVE.js.map +0 -1
- package/dist/auth-CteGWxsL.js.map +0 -1
- package/dist/auth_adapter-CIItCTc8.js +0 -21
- package/dist/auth_adapter-CIItCTc8.js.map +0 -1
- package/dist/backend-DTAOsLQc.js.map +0 -1
- package/dist/cron-store-DEpVstUU.js.map +0 -1
- package/dist/ddl-bootstrap-BNqi2NZe.js.map +0 -1
- package/dist/errors-_ytoGi8A.js.map +0 -1
- package/dist/function-loader-DbCSoNJj.js.map +0 -1
- package/dist/history-recorder-RZ1Ow4YY.js.map +0 -1
- package/dist/history-store-DPofGVDp.js.map +0 -1
- package/dist/jobs-8G-_agld.js.map +0 -1
- package/dist/logger-Bt32sHFw.js.map +0 -1
- package/dist/offline-BrqCRgih-BtDB1ecy.js.map +0 -1
- package/dist/openapi-generator-BamY6-ga.js.map +0 -1
- package/dist/proxy-BEKbsil6.js.map +0 -1
- package/dist/request-timeout-CRny5KD0.js.map +0 -1
- package/dist/soft-delete-params-BAgpmBvp.js.map +0 -1
- package/dist/sql-export-routes-BgTJ7K3S.js.map +0 -1
- package/dist/strings.es-BeZWAodn.js.map +0 -1
- package/dist/upload-validation-I9cCUBIW.js.map +0 -1
|
@@ -2,11 +2,12 @@ import { createRequire as __rebaseCreateRequire } from "module";
|
|
|
2
2
|
import __rebaseProcess from "process";
|
|
3
3
|
globalThis.process ??= __rebaseProcess;
|
|
4
4
|
__rebaseCreateRequire(import.meta.url);
|
|
5
|
-
import {
|
|
6
|
-
import { D as Vector, E as GeoPoint, S as hasFieldOperation, T as EntityRelation, _ as normalizeOrderBy, c as collectAllPages, l as paginateFind, u as resolveFindWindow, w as EntityReference } from "./filter-dialect-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
5
|
+
import { a as RebaseClientError, i as RebaseApiError, o as isUnsupported } from "./data_driver-D0mg1Y_x.js";
|
|
6
|
+
import { D as Vector, E as GeoPoint, S as hasFieldOperation, T as EntityRelation, _ as normalizeOrderBy, c as collectAllPages, l as paginateFind, u as resolveFindWindow, w as EntityReference } from "./filter-dialect-TrKFWLqT.js";
|
|
7
|
+
import { et as parseRelationAggregateSort, nt as toCanonicalOp } from "./src-Bh9LRPb9.js";
|
|
8
|
+
import { t as splitSearchTerms } from "./strings.es-B7QLnHh2.js";
|
|
9
|
+
import { a as byIdRead, f as rebaseReviver, h as unref, i as buildQueryString, m as withETag, n as MemoryOfflineStore, p as etagOf, r as SDKQueryBuilder, s as createMutationId, t as IndexedDBOfflineStore, u as invalidBulkBody } from "./offline-store-BhYXViha-YTmjBpo2.js";
|
|
10
|
+
//#region ../client/dist/offline-AvuEcg7u.js
|
|
10
11
|
/**
|
|
11
12
|
* Lossless round-tripping of rows through the offline store.
|
|
12
13
|
*
|
|
@@ -901,6 +902,13 @@ function isPlainObject(value) {
|
|
|
901
902
|
const proto = Object.getPrototypeOf(value);
|
|
902
903
|
return proto === null || Object.getPrototypeOf(proto) === null;
|
|
903
904
|
}
|
|
905
|
+
/**
|
|
906
|
+
* The key a folded run is sent under: its first and last member and its
|
|
907
|
+
* length, which fixes its composition.
|
|
908
|
+
*/
|
|
909
|
+
function runKey(run) {
|
|
910
|
+
return `${run[0].mutationId}..${run[run.length - 1].mutationId}:${run.length}`;
|
|
911
|
+
}
|
|
904
912
|
/** Whether a queued write's payload mentions `id` anywhere — see {@link replaceMintedId}. */
|
|
905
913
|
function mentionsMintedId(op, id) {
|
|
906
914
|
return [op.data, ...(op.updates ?? []).map((u) => u.data)].some((payload) => replaceMintedId(payload, id, "").changed);
|
|
@@ -1324,19 +1332,45 @@ var OfflineManager = class {
|
|
|
1324
1332
|
*/
|
|
1325
1333
|
ticket() {
|
|
1326
1334
|
if (this.scopeHold) return void 0;
|
|
1327
|
-
return
|
|
1328
|
-
scope: this.scope,
|
|
1329
|
-
epoch: this.scopeEpoch
|
|
1330
|
-
};
|
|
1335
|
+
return this.currentTicket();
|
|
1331
1336
|
}
|
|
1332
1337
|
/** The ticket of whoever the held scope turns out to be. */
|
|
1333
1338
|
async nextTicket() {
|
|
1334
1339
|
await this.scopeKnown();
|
|
1335
|
-
return
|
|
1340
|
+
return this.currentTicket();
|
|
1341
|
+
}
|
|
1342
|
+
currentTicket() {
|
|
1343
|
+
return this.unverified ? {
|
|
1344
|
+
scope: this.scope,
|
|
1345
|
+
epoch: this.scopeEpoch,
|
|
1346
|
+
unverified: true
|
|
1347
|
+
} : {
|
|
1336
1348
|
scope: this.scope,
|
|
1337
1349
|
epoch: this.scopeEpoch
|
|
1338
1350
|
};
|
|
1339
1351
|
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Whether a write may go to the server now. Not while the scope is the last
|
|
1354
|
+
* user's, unconfirmed: it would go out with no credentials, as nobody. It
|
|
1355
|
+
* queues for its author instead, as it does offline.
|
|
1356
|
+
*/
|
|
1357
|
+
sendsWrites() {
|
|
1358
|
+
return this.connectivity.shouldAttempt() && !this.unverified;
|
|
1359
|
+
}
|
|
1360
|
+
reachedUnconfirmedListeners = /* @__PURE__ */ new Set();
|
|
1361
|
+
/**
|
|
1362
|
+
* `listener` runs when a request made while the scope is unconfirmed
|
|
1363
|
+
* reached the server: the connection is back, so the session can be asked
|
|
1364
|
+
* about. The client wires it to the same confirmation the status listener
|
|
1365
|
+
* runs — the status may never have said the connection was gone.
|
|
1366
|
+
*/
|
|
1367
|
+
onReachedUnconfirmed(listener) {
|
|
1368
|
+
this.reachedUnconfirmedListeners.add(listener);
|
|
1369
|
+
return () => this.reachedUnconfirmedListeners.delete(listener);
|
|
1370
|
+
}
|
|
1371
|
+
reachedUnconfirmed() {
|
|
1372
|
+
for (const listener of this.reachedUnconfirmedListeners) callSafely(listener);
|
|
1373
|
+
}
|
|
1340
1374
|
/** Whether an operation's user is still the signed-in one. */
|
|
1341
1375
|
isCurrent(ticket) {
|
|
1342
1376
|
return ticket.epoch === this.scopeEpoch;
|
|
@@ -1393,15 +1427,18 @@ var OfflineManager = class {
|
|
|
1393
1427
|
const res = await inner.find(params);
|
|
1394
1428
|
this.connectivity.markSuccess();
|
|
1395
1429
|
if (!this.isCurrent(ticket)) return res;
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1430
|
+
if (ticket.unverified) this.reachedUnconfirmed();
|
|
1431
|
+
else {
|
|
1432
|
+
await this.ingest(slug, res.data ?? [], ticket, isProjection(params));
|
|
1433
|
+
if (!this.isCurrent(ticket)) return res;
|
|
1434
|
+
const snapshot = this.recordSnapshot(slug, params, res, ticket);
|
|
1435
|
+
const answer = this.answer(slug, params, snapshot);
|
|
1436
|
+
this.notifyCollection(slug, false);
|
|
1437
|
+
return {
|
|
1438
|
+
data: answer.data,
|
|
1439
|
+
meta: answer.meta
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1405
1442
|
} catch (error) {
|
|
1406
1443
|
if (!isNetworkError(error)) {
|
|
1407
1444
|
if (isRetryableError(error) && this.hasLocalAnswer(state, slug, params) && !(walk && !this.snapshotFor(slug, params))) {
|
|
@@ -1435,10 +1472,16 @@ var OfflineManager = class {
|
|
|
1435
1472
|
const row = await inner.findById(id, options);
|
|
1436
1473
|
this.connectivity.markSuccess();
|
|
1437
1474
|
if (!this.isCurrent(ticket)) return row;
|
|
1475
|
+
if (ticket.unverified) {
|
|
1476
|
+
this.reachedUnconfirmed();
|
|
1477
|
+
return this.localRow(slug, id);
|
|
1478
|
+
}
|
|
1438
1479
|
if (row !== void 0) await this.ingest(slug, [row], ticket);
|
|
1439
1480
|
else if (!this.hasPending(slug, id)) this.removeLocalRow(slug, id, ticket, true);
|
|
1440
1481
|
this.notifyCollection(slug, false);
|
|
1441
|
-
|
|
1482
|
+
const local = this.localRow(slug, id);
|
|
1483
|
+
const etag = etagOf(row);
|
|
1484
|
+
return etag && local !== void 0 && !this.hasPending(slug, id) ? withETag({ ...local }, etag) : local;
|
|
1442
1485
|
} catch (error) {
|
|
1443
1486
|
if (!isNetworkError(error)) throw error;
|
|
1444
1487
|
this.connectivity.markFailure();
|
|
@@ -1461,7 +1504,7 @@ var OfflineManager = class {
|
|
|
1461
1504
|
await this.ensureCollection(slug);
|
|
1462
1505
|
const idempotencyKey = options?.idempotencyKey ?? createMutationId();
|
|
1463
1506
|
let sent = false;
|
|
1464
|
-
if (this.
|
|
1507
|
+
if (this.sendsWrites()) try {
|
|
1465
1508
|
const row = await inner.create(data, id, {
|
|
1466
1509
|
...options,
|
|
1467
1510
|
idempotencyKey
|
|
@@ -1503,7 +1546,7 @@ var OfflineManager = class {
|
|
|
1503
1546
|
if (data.length === 0) return [];
|
|
1504
1547
|
const idempotencyKey = options?.idempotencyKey ?? createMutationId();
|
|
1505
1548
|
let sent = false;
|
|
1506
|
-
if (this.
|
|
1549
|
+
if (this.sendsWrites()) try {
|
|
1507
1550
|
const rows = await inner.createMany(data, {
|
|
1508
1551
|
...options,
|
|
1509
1552
|
idempotencyKey
|
|
@@ -1555,7 +1598,7 @@ var OfflineManager = class {
|
|
|
1555
1598
|
upsert: async (data, options) => {
|
|
1556
1599
|
const ticket = this.ticket() ?? await this.nextTicket();
|
|
1557
1600
|
await this.ensureCollection(slug);
|
|
1558
|
-
if (this.
|
|
1601
|
+
if (this.sendsWrites()) try {
|
|
1559
1602
|
const row = await inner.upsert(data, options);
|
|
1560
1603
|
this.connectivity.markSuccess();
|
|
1561
1604
|
await this.ingest(slug, [row], ticket);
|
|
@@ -1586,7 +1629,7 @@ var OfflineManager = class {
|
|
|
1586
1629
|
if (!Array.isArray(updates)) throw invalidBulkBody("updateMany expects an array of { id, data } entries.");
|
|
1587
1630
|
if (updates.length === 0) return [];
|
|
1588
1631
|
const anyPending = updates.some((u) => this.hasPending(slug, u.id));
|
|
1589
|
-
if (this.
|
|
1632
|
+
if (this.sendsWrites() && !anyPending) try {
|
|
1590
1633
|
const rows = await inner.updateMany(updates, options);
|
|
1591
1634
|
this.connectivity.markSuccess();
|
|
1592
1635
|
await this.ingest(slug, rows, ticket);
|
|
@@ -1625,7 +1668,7 @@ var OfflineManager = class {
|
|
|
1625
1668
|
if (!Array.isArray(ids)) throw invalidBulkBody("deleteMany expects an array of ids.");
|
|
1626
1669
|
if (ids.length === 0) return;
|
|
1627
1670
|
const anyPending = ids.some((id) => this.hasPending(slug, id));
|
|
1628
|
-
if (this.
|
|
1671
|
+
if (this.sendsWrites() && !anyPending) try {
|
|
1629
1672
|
await inner.deleteMany(ids, options);
|
|
1630
1673
|
this.connectivity.markSuccess();
|
|
1631
1674
|
for (const id of ids) this.removeLocalRow(slug, id, ticket, true);
|
|
@@ -1653,7 +1696,7 @@ var OfflineManager = class {
|
|
|
1653
1696
|
const idempotencyKey = options?.idempotencyKey ?? createMutationId();
|
|
1654
1697
|
let sent = false;
|
|
1655
1698
|
let sendFailure;
|
|
1656
|
-
if (this.
|
|
1699
|
+
if (this.sendsWrites() && !this.hasPending(slug, id)) try {
|
|
1657
1700
|
const row = await inner.update(id, data, {
|
|
1658
1701
|
...options,
|
|
1659
1702
|
idempotencyKey
|
|
@@ -1678,7 +1721,7 @@ var OfflineManager = class {
|
|
|
1678
1721
|
throw new RebaseClientError(`Cannot apply a field operation to "${slug}" while offline: it is evaluated against the stored value, which this device does not have a current copy of. Send the value itself, or retry when the connection is back.`, { code: "OFFLINE_FIELD_OP_UNSUPPORTED" });
|
|
1679
1722
|
}
|
|
1680
1723
|
const base = this.rawLocalRow(slug, id);
|
|
1681
|
-
const ifMatch =
|
|
1724
|
+
const ifMatch = options?.ifMatch ?? (this.onConflict && !this.hasPending(slug, id) ? this.etagFor(slug, id) : void 0);
|
|
1682
1725
|
await this.enqueue({
|
|
1683
1726
|
collection: slug,
|
|
1684
1727
|
type: "update",
|
|
@@ -1701,7 +1744,7 @@ var OfflineManager = class {
|
|
|
1701
1744
|
await this.ensureCollection(slug);
|
|
1702
1745
|
const idempotencyKey = options?.idempotencyKey ?? createMutationId();
|
|
1703
1746
|
let sent = false;
|
|
1704
|
-
if (this.
|
|
1747
|
+
if (this.sendsWrites() && !this.hasPending(slug, id)) try {
|
|
1705
1748
|
await inner.delete(id, {
|
|
1706
1749
|
...options,
|
|
1707
1750
|
idempotencyKey
|
|
@@ -1721,6 +1764,7 @@ var OfflineManager = class {
|
|
|
1721
1764
|
type: "delete",
|
|
1722
1765
|
id,
|
|
1723
1766
|
...sent ? { sent: { idempotencyKey } } : {},
|
|
1767
|
+
...options?.ifMatch ? { ifMatch: options.ifMatch } : {},
|
|
1724
1768
|
rollback: { rows: { [String(id)]: this.rawLocalRow(slug, id) ?? null } }
|
|
1725
1769
|
}, ticket);
|
|
1726
1770
|
this.removeLocalRow(slug, id, ticket);
|
|
@@ -1733,6 +1777,12 @@ var OfflineManager = class {
|
|
|
1733
1777
|
const n = await inner.count(params);
|
|
1734
1778
|
this.connectivity.markSuccess();
|
|
1735
1779
|
if (!this.isCurrent(ticket)) return n;
|
|
1780
|
+
if (ticket.unverified) {
|
|
1781
|
+
this.reachedUnconfirmed();
|
|
1782
|
+
const cached = await this.readCache(this.countKey(slug, params));
|
|
1783
|
+
if (cached !== void 0) return Math.max(0, cached + this.pendingDelta(slug, params));
|
|
1784
|
+
throw offlineError(`No count of "${slug}" for the last user is cached, and their session is not confirmed yet.`);
|
|
1785
|
+
}
|
|
1736
1786
|
this.writeCache(this.countKey(slug, params), n);
|
|
1737
1787
|
return Math.max(0, n + this.pendingDelta(slug, params));
|
|
1738
1788
|
} catch (error) {
|
|
@@ -1771,6 +1821,15 @@ var OfflineManager = class {
|
|
|
1771
1821
|
onUpdate(response);
|
|
1772
1822
|
return;
|
|
1773
1823
|
}
|
|
1824
|
+
if (ticket.unverified) {
|
|
1825
|
+
const answer = this.localFind(slug, params);
|
|
1826
|
+
onUpdate({
|
|
1827
|
+
...response,
|
|
1828
|
+
data: answer.data,
|
|
1829
|
+
meta: answer.meta
|
|
1830
|
+
});
|
|
1831
|
+
return;
|
|
1832
|
+
}
|
|
1774
1833
|
this.ingest(slug, response.data ?? [], ticket, isProjection(params)).then(() => {
|
|
1775
1834
|
if (!this.isCurrent(ticket)) return;
|
|
1776
1835
|
const snapshot = this.recordSnapshot(slug, params, response, ticket);
|
|
@@ -1789,6 +1848,10 @@ var OfflineManager = class {
|
|
|
1789
1848
|
onUpdate(row);
|
|
1790
1849
|
return;
|
|
1791
1850
|
}
|
|
1851
|
+
if (ticket.unverified) {
|
|
1852
|
+
onUpdate(this.localRow(slug, id));
|
|
1853
|
+
return;
|
|
1854
|
+
}
|
|
1792
1855
|
if (!row) {
|
|
1793
1856
|
if (!this.hasPending(slug, id)) this.removeLocalRow(slug, id, ticket, true);
|
|
1794
1857
|
this.notifyCollection(slug, false);
|
|
@@ -1820,7 +1883,7 @@ var OfflineManager = class {
|
|
|
1820
1883
|
wrapTrash(slug, inner) {
|
|
1821
1884
|
const online = async (what, call) => {
|
|
1822
1885
|
const message = `Offline: ${what} on the trash of "${slug}" needs the server; the trash is never cached on this device.`;
|
|
1823
|
-
if (!this.
|
|
1886
|
+
if (!this.sendsWrites()) throw offlineError(message);
|
|
1824
1887
|
try {
|
|
1825
1888
|
const result = await call();
|
|
1826
1889
|
this.connectivity.markSuccess();
|
|
@@ -1934,7 +1997,7 @@ var OfflineManager = class {
|
|
|
1934
1997
|
})();
|
|
1935
1998
|
if (options?.realtime !== false && !isUnsupported(inner.listen)) unlisten = inner.listen(params, (response) => {
|
|
1936
1999
|
const ticket = this.ticket();
|
|
1937
|
-
if (!ticket) return;
|
|
2000
|
+
if (!ticket || ticket.unverified) return;
|
|
1938
2001
|
this.ingest(slug, response.data ?? [], ticket, isProjection(params)).then(() => {
|
|
1939
2002
|
this.recordSnapshot(slug, params, response, ticket);
|
|
1940
2003
|
this.notifyCollection(slug, false);
|
|
@@ -1989,7 +2052,7 @@ var OfflineManager = class {
|
|
|
1989
2052
|
})();
|
|
1990
2053
|
if (options?.realtime !== false && !isUnsupported(inner.listenById)) unlisten = inner.listenById(id, (row) => {
|
|
1991
2054
|
const ticket = this.ticket();
|
|
1992
|
-
if (!ticket) return;
|
|
2055
|
+
if (!ticket || ticket.unverified) return;
|
|
1993
2056
|
if (!row) {
|
|
1994
2057
|
if (!this.hasPending(slug, id)) this.removeLocalRow(slug, id, ticket, true);
|
|
1995
2058
|
this.notifyCollection(slug, false);
|
|
@@ -2314,6 +2377,7 @@ var OfflineManager = class {
|
|
|
2314
2377
|
*/
|
|
2315
2378
|
removeLocalRow(slug, id, ticket, known = false) {
|
|
2316
2379
|
if (!this.isCurrent(ticket)) return;
|
|
2380
|
+
if (known && ticket.unverified) return;
|
|
2317
2381
|
const state = this.collectionState(slug);
|
|
2318
2382
|
const key = String(id);
|
|
2319
2383
|
const existed = state.rows.delete(key);
|
|
@@ -2346,7 +2410,7 @@ var OfflineManager = class {
|
|
|
2346
2410
|
* dropdown elsewhere asked for titles.
|
|
2347
2411
|
*/
|
|
2348
2412
|
async ingest(slug, rows, ticket, projection = false) {
|
|
2349
|
-
if (rows.length === 0 || !this.isCurrent(ticket)) return;
|
|
2413
|
+
if (rows.length === 0 || !this.isCurrent(ticket) || ticket.unverified) return;
|
|
2350
2414
|
const state = await this.ensureCollection(slug);
|
|
2351
2415
|
if (!this.isCurrent(ticket)) return;
|
|
2352
2416
|
const cachedAt = Date.now();
|
|
@@ -2450,7 +2514,7 @@ var OfflineManager = class {
|
|
|
2450
2514
|
hasMore: meta.hasMore ?? false,
|
|
2451
2515
|
...isProjection(params) ? { rows: (result.data ?? []).map((row) => ({ ...row })) } : {}
|
|
2452
2516
|
};
|
|
2453
|
-
if (!this.isCurrent(ticket)) return snapshot;
|
|
2517
|
+
if (!this.isCurrent(ticket) || ticket.unverified) return snapshot;
|
|
2454
2518
|
const state = this.collectionState(slug);
|
|
2455
2519
|
const key = buildQueryString(params);
|
|
2456
2520
|
state.snapshots.set(key, snapshot);
|
|
@@ -2548,7 +2612,7 @@ var OfflineManager = class {
|
|
|
2548
2612
|
}
|
|
2549
2613
|
if (mutation.type === "update") {
|
|
2550
2614
|
const tail = this.queue[this.queue.length - 1];
|
|
2551
|
-
if (tail && !this.inFlight.has(tail.mutationId) && tail.sent === void 0 && (tail.schemaVersion ?? 1) <= 1 && tail.collection === mutation.collection && (tail.type === "create" || tail.type === "update") && tail.id === mutation.id) {
|
|
2615
|
+
if (tail && !this.inFlight.has(tail.mutationId) && tail.sent === void 0 && (tail.schemaVersion ?? 1) <= 1 && tail.collection === mutation.collection && (tail.type === "create" || tail.type === "update") && tail.id === mutation.id && (mutation.ifMatch === void 0 || mutation.ifMatch === tail.ifMatch)) {
|
|
2552
2616
|
if (tail.type === "update") tail.parts = [...tail.parts ?? [{ ...tail.data }], { ...mutation.data }];
|
|
2553
2617
|
tail.data = {
|
|
2554
2618
|
...tail.data,
|
|
@@ -2729,7 +2793,7 @@ var OfflineManager = class {
|
|
|
2729
2793
|
this.connectivity.markFailure();
|
|
2730
2794
|
break;
|
|
2731
2795
|
}
|
|
2732
|
-
if (op.type === "update" && op.ifMatch && isPreconditionFailed(error)) {
|
|
2796
|
+
if ((op.type === "update" || op.type === "delete") && op.ifMatch && this.onConflict && isPreconditionFailed(error)) {
|
|
2733
2797
|
this.connectivity.markSuccess();
|
|
2734
2798
|
await this.resolveConflict(op, error, ticket);
|
|
2735
2799
|
continue;
|
|
@@ -2800,16 +2864,18 @@ var OfflineManager = class {
|
|
|
2800
2864
|
*/
|
|
2801
2865
|
foldableRun(unbatched) {
|
|
2802
2866
|
if (this.replayBatchSize < 2) return [];
|
|
2803
|
-
const foldable = (op, collection) => op !== void 0 && op.type === "create" && op.generatedId === true && typeof op.id === "string" && op.sent === void 0 && !op.upsert && (op.schemaVersion ?? 1) <= 1 && !unbatched.has(op.mutationId) && (collection === void 0 || op.collection === collection);
|
|
2804
2867
|
const head = this.queue[0];
|
|
2868
|
+
const resent = head?.sent?.run;
|
|
2869
|
+
const foldable = (op, collection) => op !== void 0 && op.type === "create" && op.generatedId === true && typeof op.id === "string" && (resent === void 0 ? op.sent === void 0 : op.sent?.run === resent) && !op.upsert && (op.schemaVersion ?? 1) <= 1 && !unbatched.has(op.mutationId) && (collection === void 0 || op.collection === collection);
|
|
2805
2870
|
if (!foldable(head)) return [];
|
|
2806
2871
|
const run = [head];
|
|
2807
|
-
for (let i = 1; i < this.queue.length && run.length < this.replayBatchSize; i++) {
|
|
2872
|
+
for (let i = 1; i < this.queue.length && (resent !== void 0 || run.length < this.replayBatchSize); i++) {
|
|
2808
2873
|
const next = this.queue[i];
|
|
2809
2874
|
if (!foldable(next, head.collection)) break;
|
|
2810
2875
|
if (run.some((member) => mentionsMintedId(next, member.id))) break;
|
|
2811
2876
|
run.push(next);
|
|
2812
2877
|
}
|
|
2878
|
+
if (resent !== void 0 && runKey(run) !== resent) return [];
|
|
2813
2879
|
return run;
|
|
2814
2880
|
}
|
|
2815
2881
|
/**
|
|
@@ -2830,9 +2896,10 @@ var OfflineManager = class {
|
|
|
2830
2896
|
*/
|
|
2831
2897
|
async replayRun(run, ticket) {
|
|
2832
2898
|
const inner = this.innerFor(run[0].collection);
|
|
2833
|
-
const idempotencyKey =
|
|
2899
|
+
const idempotencyKey = runKey(run);
|
|
2834
2900
|
for (const member of run) this.inFlight.add(member.mutationId);
|
|
2835
2901
|
try {
|
|
2902
|
+
for (const member of run) await this.markCreateSent(member, ticket, idempotencyKey);
|
|
2836
2903
|
let rows;
|
|
2837
2904
|
try {
|
|
2838
2905
|
rows = await inner.createMany(run.map((member) => member.data), { idempotencyKey });
|
|
@@ -2854,6 +2921,7 @@ var OfflineManager = class {
|
|
|
2854
2921
|
async replay(op, ticket) {
|
|
2855
2922
|
const inner = this.innerFor(op.collection);
|
|
2856
2923
|
if (op.type === "create") {
|
|
2924
|
+
await this.markCreateSent(op, ticket);
|
|
2857
2925
|
let row;
|
|
2858
2926
|
try {
|
|
2859
2927
|
row = await this.sendQueuedWrite(op, (idempotencyKey) => inner.create(op.data, void 0, { idempotencyKey }), (sent) => inner.create(sent.data, sent.id, { idempotencyKey: sent.idempotencyKey }));
|
|
@@ -2906,11 +2974,30 @@ var OfflineManager = class {
|
|
|
2906
2974
|
}
|
|
2907
2975
|
for (const id of ids) this.removeLocalRow(op.collection, id, ticket, true);
|
|
2908
2976
|
} else if (op.type === "delete") {
|
|
2909
|
-
await inner.delete(op.id, {
|
|
2977
|
+
await inner.delete(op.id, {
|
|
2978
|
+
idempotencyKey: op.sent?.idempotencyKey ?? op.mutationId,
|
|
2979
|
+
...op.ifMatch ? { ifMatch: op.ifMatch } : {}
|
|
2980
|
+
});
|
|
2910
2981
|
this.removeLocalRow(op.collection, op.id, ticket, true);
|
|
2911
2982
|
}
|
|
2912
2983
|
}
|
|
2913
2984
|
/**
|
|
2985
|
+
* Record a queued create as sent, with the request about to go out, and
|
|
2986
|
+
* persist it — before the request, so a lost answer cannot leave it
|
|
2987
|
+
* unmarked. One already marked (sent online before it was queued, or by
|
|
2988
|
+
* an earlier replay) keeps what it holds: that is the request the server
|
|
2989
|
+
* may have stored.
|
|
2990
|
+
*/
|
|
2991
|
+
async markCreateSent(op, ticket, run) {
|
|
2992
|
+
if (op.sent) return;
|
|
2993
|
+
op.sent = {
|
|
2994
|
+
idempotencyKey: op.mutationId,
|
|
2995
|
+
data: { ...op.data },
|
|
2996
|
+
...run ? { run } : {}
|
|
2997
|
+
};
|
|
2998
|
+
await this.persistMutation(`${ticket.scope}|${op.mutationId}`, op).catch(() => void 0);
|
|
2999
|
+
}
|
|
3000
|
+
/**
|
|
2914
3001
|
* Send a queued write under its key.
|
|
2915
3002
|
*
|
|
2916
3003
|
* A write the queue sent once already, before it was queued, carries that
|
|
@@ -3302,4 +3389,4 @@ var OfflineManager = class {
|
|
|
3302
3389
|
//#endregion
|
|
3303
3390
|
export { OfflineManager };
|
|
3304
3391
|
|
|
3305
|
-
//# sourceMappingURL=offline-
|
|
3392
|
+
//# sourceMappingURL=offline-AvuEcg7u-DFHL98OT.js.map
|