@rocicorp/zero 0.13.2025020402 → 0.13.2025020501
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/{chunk-ADFMUREC.js → chunk-453TFLSU.js} +1055 -868
- package/out/chunk-453TFLSU.js.map +7 -0
- package/out/replicache/src/persist/collect-idb-databases.d.ts +2 -2
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +2 -1
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/sync/patch.d.ts +5 -1
- package/out/replicache/src/sync/patch.d.ts.map +1 -1
- package/out/replicache/src/sync/pull.d.ts +2 -0
- package/out/replicache/src/sync/pull.d.ts.map +1 -1
- package/out/solid.js +1 -1
- package/out/zero-cache/src/db/migration.d.ts.map +1 -1
- package/out/zero-cache/src/db/migration.js +1 -2
- package/out/zero-cache/src/db/migration.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 +1 -1
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/main.js +1 -1
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +9 -7
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/init.d.ts +2 -2
- package/out/zero-cache/src/services/change-streamer/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/init.js +40 -27
- package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +5 -4
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js +44 -19
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +21 -9
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +57 -35
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +3 -3
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js +61 -33
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.js +56 -43
- package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
- 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 +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +1 -1
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/crud.d.ts +5 -4
- package/out/zero-client/src/client/crud.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/ivm-source-repo.d.ts +13 -3
- package/out/zero-client/src/client/ivm-source-repo.d.ts.map +1 -1
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js +8 -20
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero-schema/src/name-mapper.d.ts +2 -2
- package/out/zero-schema/src/name-mapper.d.ts.map +1 -1
- package/out/zero-schema/src/name-mapper.js.map +1 -1
- package/out/zero.js +1 -1
- package/out/zql/src/query/query.d.ts +1 -1
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/package.json +1 -1
- package/out/chunk-ADFMUREC.js.map +0 -7
|
@@ -3789,6 +3789,10 @@ async function readFromHead(name, dagRead, formatVersion) {
|
|
|
3789
3789
|
const commit = await commitFromHead(name, dagRead);
|
|
3790
3790
|
return readFromCommit(commit, dagRead, formatVersion);
|
|
3791
3791
|
}
|
|
3792
|
+
async function readFromHash(hash2, dagRead, formatVersion) {
|
|
3793
|
+
const commit = await commitFromHash(hash2, dagRead);
|
|
3794
|
+
return readFromCommit(commit, dagRead, formatVersion);
|
|
3795
|
+
}
|
|
3792
3796
|
function readFromCommit(commit, dagRead, formatVersion) {
|
|
3793
3797
|
const indexes = readIndexesForRead(commit, dagRead, formatVersion);
|
|
3794
3798
|
const map = new BTreeRead(dagRead, formatVersion, commit.valueHash);
|
|
@@ -4995,10 +4999,27 @@ var CookieMismatch = 2;
|
|
|
4995
4999
|
|
|
4996
5000
|
// ../replicache/src/sync/patch.ts
|
|
4997
5001
|
async function apply(lc, dbWrite, patch) {
|
|
5002
|
+
const ret = [];
|
|
4998
5003
|
for (const p of patch) {
|
|
4999
5004
|
switch (p.op) {
|
|
5000
5005
|
case "put": {
|
|
5001
|
-
await dbWrite.
|
|
5006
|
+
const existing = await dbWrite.get(p.key);
|
|
5007
|
+
const frozen = deepFreeze(p.value);
|
|
5008
|
+
await dbWrite.put(lc, p.key, frozen);
|
|
5009
|
+
if (existing === void 0) {
|
|
5010
|
+
ret.push({
|
|
5011
|
+
op: "add",
|
|
5012
|
+
key: p.key,
|
|
5013
|
+
newValue: frozen
|
|
5014
|
+
});
|
|
5015
|
+
} else {
|
|
5016
|
+
ret.push({
|
|
5017
|
+
op: "change",
|
|
5018
|
+
key: p.key,
|
|
5019
|
+
oldValue: existing,
|
|
5020
|
+
newValue: frozen
|
|
5021
|
+
});
|
|
5022
|
+
}
|
|
5002
5023
|
break;
|
|
5003
5024
|
}
|
|
5004
5025
|
case "update": {
|
|
@@ -5018,17 +5039,46 @@ async function apply(lc, dbWrite, patch) {
|
|
|
5018
5039
|
if (p.merge) {
|
|
5019
5040
|
addToEntries(p.merge);
|
|
5020
5041
|
}
|
|
5021
|
-
|
|
5042
|
+
const frozen = deepFreeze(Object.fromEntries(entries));
|
|
5043
|
+
await dbWrite.put(lc, p.key, frozen);
|
|
5044
|
+
if (existing === void 0) {
|
|
5045
|
+
ret.push({
|
|
5046
|
+
op: "add",
|
|
5047
|
+
key: p.key,
|
|
5048
|
+
newValue: frozen
|
|
5049
|
+
});
|
|
5050
|
+
} else {
|
|
5051
|
+
ret.push({
|
|
5052
|
+
op: "change",
|
|
5053
|
+
key: p.key,
|
|
5054
|
+
oldValue: existing,
|
|
5055
|
+
newValue: frozen
|
|
5056
|
+
});
|
|
5057
|
+
}
|
|
5022
5058
|
break;
|
|
5023
5059
|
}
|
|
5024
|
-
case "del":
|
|
5060
|
+
case "del": {
|
|
5061
|
+
const existing = await dbWrite.get(p.key);
|
|
5062
|
+
if (existing === void 0) {
|
|
5063
|
+
continue;
|
|
5064
|
+
}
|
|
5025
5065
|
await dbWrite.del(lc, p.key);
|
|
5066
|
+
ret.push({
|
|
5067
|
+
op: "del",
|
|
5068
|
+
key: p.key,
|
|
5069
|
+
oldValue: existing
|
|
5070
|
+
});
|
|
5026
5071
|
break;
|
|
5072
|
+
}
|
|
5027
5073
|
case "clear":
|
|
5028
5074
|
await dbWrite.clear();
|
|
5075
|
+
ret.push({
|
|
5076
|
+
op: "clear"
|
|
5077
|
+
});
|
|
5029
5078
|
break;
|
|
5030
5079
|
}
|
|
5031
5080
|
}
|
|
5081
|
+
return ret;
|
|
5032
5082
|
}
|
|
5033
5083
|
|
|
5034
5084
|
// ../replicache/src/sync/pull-error.ts
|
|
@@ -5195,10 +5245,11 @@ function handlePullResponseV1(lc, store, expectedBaseCookie, response, clientID,
|
|
|
5195
5245
|
clientID,
|
|
5196
5246
|
formatVersion
|
|
5197
5247
|
);
|
|
5198
|
-
await apply(lc, dbWrite, response.patch);
|
|
5248
|
+
const diffs = await apply(lc, dbWrite, response.patch);
|
|
5199
5249
|
return {
|
|
5200
5250
|
type: Applied,
|
|
5201
|
-
syncHead: await dbWrite.commit(SYNC_HEAD_NAME)
|
|
5251
|
+
syncHead: await dbWrite.commit(SYNC_HEAD_NAME),
|
|
5252
|
+
diffs
|
|
5202
5253
|
};
|
|
5203
5254
|
});
|
|
5204
5255
|
}
|
|
@@ -7285,6 +7336,7 @@ var ReplicacheImpl = class {
|
|
|
7285
7336
|
void this.#open(
|
|
7286
7337
|
indexes,
|
|
7287
7338
|
enableClientGroupForking,
|
|
7339
|
+
enableMutationRecovery,
|
|
7288
7340
|
clientMaxAgeMs,
|
|
7289
7341
|
profileIDResolver.resolve,
|
|
7290
7342
|
clientGroupIDResolver.resolve,
|
|
@@ -7292,7 +7344,7 @@ var ReplicacheImpl = class {
|
|
|
7292
7344
|
onClientsDeleted
|
|
7293
7345
|
);
|
|
7294
7346
|
}
|
|
7295
|
-
async #open(indexes, enableClientGroupForking, clientMaxAgeMs, profileIDResolver, resolveClientGroupID, resolveReady, onClientsDeleted) {
|
|
7347
|
+
async #open(indexes, enableClientGroupForking, enableMutationRecovery, clientMaxAgeMs, profileIDResolver, resolveClientGroupID, resolveReady, onClientsDeleted) {
|
|
7296
7348
|
const { clientID } = this;
|
|
7297
7349
|
await closingInstances.get(this.name);
|
|
7298
7350
|
await this.#idbDatabases.getProfileID().then(profileIDResolver);
|
|
@@ -7342,6 +7394,7 @@ var ReplicacheImpl = class {
|
|
|
7342
7394
|
COLLECT_IDB_INTERVAL,
|
|
7343
7395
|
INITIAL_COLLECT_IDB_DELAY,
|
|
7344
7396
|
2 * clientMaxAgeMs,
|
|
7397
|
+
enableMutationRecovery,
|
|
7345
7398
|
onClientsDeleted,
|
|
7346
7399
|
this.#lc,
|
|
7347
7400
|
signal
|
|
@@ -7719,7 +7772,7 @@ var ReplicacheImpl = class {
|
|
|
7719
7772
|
*
|
|
7720
7773
|
* @experimental This method is under development and its semantics will change.
|
|
7721
7774
|
*/
|
|
7722
|
-
async poke(poke) {
|
|
7775
|
+
async poke(poke, pullApplied) {
|
|
7723
7776
|
await this.#ready;
|
|
7724
7777
|
const { clientID } = this;
|
|
7725
7778
|
const requestID = newRequestID(clientID);
|
|
@@ -7743,6 +7796,7 @@ var ReplicacheImpl = class {
|
|
|
7743
7796
|
);
|
|
7744
7797
|
switch (result.type) {
|
|
7745
7798
|
case Applied:
|
|
7799
|
+
await pullApplied(this.memdag, result.syncHead, result.diffs);
|
|
7746
7800
|
await this.maybeEndPull(result.syncHead, requestID);
|
|
7747
7801
|
break;
|
|
7748
7802
|
case CookieMismatch:
|
|
@@ -8164,7 +8218,7 @@ function getKVStoreProvider(lc, kvStore) {
|
|
|
8164
8218
|
// ../replicache/src/persist/collect-idb-databases.ts
|
|
8165
8219
|
var COLLECT_IDB_INTERVAL = 12 * 60 * 60 * 1e3;
|
|
8166
8220
|
var INITIAL_COLLECT_IDB_DELAY = 5 * 60 * 1e3;
|
|
8167
|
-
function initCollectIDBDatabases(idbDatabasesStore, kvDropStore, collectInterval, initialCollectDelay, maxAge, onClientsDeleted, lc, signal) {
|
|
8221
|
+
function initCollectIDBDatabases(idbDatabasesStore, kvDropStore, collectInterval, initialCollectDelay, maxAge, enableMutationRecovery, onClientsDeleted, lc, signal) {
|
|
8168
8222
|
let initial = true;
|
|
8169
8223
|
initBgIntervalProcess(
|
|
8170
8224
|
"CollectIDBDatabases",
|
|
@@ -8174,6 +8228,7 @@ function initCollectIDBDatabases(idbDatabasesStore, kvDropStore, collectInterval
|
|
|
8174
8228
|
Date.now(),
|
|
8175
8229
|
maxAge,
|
|
8176
8230
|
kvDropStore,
|
|
8231
|
+
enableMutationRecovery,
|
|
8177
8232
|
onClientsDeleted
|
|
8178
8233
|
);
|
|
8179
8234
|
},
|
|
@@ -8188,14 +8243,20 @@ function initCollectIDBDatabases(idbDatabasesStore, kvDropStore, collectInterval
|
|
|
8188
8243
|
signal
|
|
8189
8244
|
);
|
|
8190
8245
|
}
|
|
8191
|
-
async function collectIDBDatabases(idbDatabasesStore, now, maxAge, kvDropStore, onClientsDeleted, newDagStore = defaultNewDagStore) {
|
|
8246
|
+
async function collectIDBDatabases(idbDatabasesStore, now, maxAge, kvDropStore, enableMutationRecovery, onClientsDeleted, newDagStore = defaultNewDagStore) {
|
|
8192
8247
|
const databases = await idbDatabasesStore.getDatabases();
|
|
8193
8248
|
const dbs = Object.values(databases);
|
|
8194
8249
|
const collectResults = await Promise.all(
|
|
8195
8250
|
dbs.map(
|
|
8196
8251
|
async (db) => [
|
|
8197
8252
|
db.name,
|
|
8198
|
-
await gatherDatabaseInfoForCollect(
|
|
8253
|
+
await gatherDatabaseInfoForCollect(
|
|
8254
|
+
db,
|
|
8255
|
+
now,
|
|
8256
|
+
maxAge,
|
|
8257
|
+
enableMutationRecovery,
|
|
8258
|
+
newDagStore
|
|
8259
|
+
)
|
|
8199
8260
|
]
|
|
8200
8261
|
)
|
|
8201
8262
|
);
|
|
@@ -8245,7 +8306,7 @@ function defaultNewDagStore(name) {
|
|
|
8245
8306
|
const perKvStore = new IDBStore(name);
|
|
8246
8307
|
return new StoreImpl(perKvStore, newRandomHash, assertHash);
|
|
8247
8308
|
}
|
|
8248
|
-
function gatherDatabaseInfoForCollect(db, now, maxAge, newDagStore) {
|
|
8309
|
+
function gatherDatabaseInfoForCollect(db, now, maxAge, enableMutationRecovery, newDagStore) {
|
|
8249
8310
|
if (db.replicacheFormatVersion > Latest) {
|
|
8250
8311
|
return [false];
|
|
8251
8312
|
}
|
|
@@ -8256,7 +8317,10 @@ function gatherDatabaseInfoForCollect(db, now, maxAge, newDagStore) {
|
|
|
8256
8317
|
assert(
|
|
8257
8318
|
db.replicacheFormatVersion === DD31 || db.replicacheFormatVersion === V6 || db.replicacheFormatVersion === V7
|
|
8258
8319
|
);
|
|
8259
|
-
return
|
|
8320
|
+
return canDatabaseBeCollectedAndGetDeletedClientIDs(
|
|
8321
|
+
enableMutationRecovery,
|
|
8322
|
+
newDagStore(db.name)
|
|
8323
|
+
);
|
|
8260
8324
|
}
|
|
8261
8325
|
async function dropDatabase(dbName, opts) {
|
|
8262
8326
|
const logContext = createLogContext(opts?.logLevel, opts?.logSinks, {
|
|
@@ -8280,12 +8344,14 @@ async function dropAllDatabases(opts) {
|
|
|
8280
8344
|
const result = await dropDatabases(store, dbNames, kvStoreProvider.drop);
|
|
8281
8345
|
return result;
|
|
8282
8346
|
}
|
|
8283
|
-
function
|
|
8347
|
+
function canDatabaseBeCollectedAndGetDeletedClientIDs(enableMutationRecovery, perdag) {
|
|
8284
8348
|
return withRead(perdag, async (read) => {
|
|
8285
|
-
|
|
8286
|
-
|
|
8287
|
-
|
|
8288
|
-
|
|
8349
|
+
if (enableMutationRecovery) {
|
|
8350
|
+
const clientGroups = await getClientGroups(read);
|
|
8351
|
+
for (const clientGroup of clientGroups.values()) {
|
|
8352
|
+
if (clientGroupHasPendingMutations(clientGroup)) {
|
|
8353
|
+
return [false];
|
|
8354
|
+
}
|
|
8289
8355
|
}
|
|
8290
8356
|
}
|
|
8291
8357
|
const clients = await getClients(read);
|
|
@@ -11976,25 +12042,16 @@ var pushBodySchema = valita_exports.object({
|
|
|
11976
12042
|
var pushMessageSchema = valita_exports.tuple([valita_exports.literal("push"), pushBodySchema]);
|
|
11977
12043
|
function mapCRUD(arg, map) {
|
|
11978
12044
|
return {
|
|
11979
|
-
ops: arg.ops.map(
|
|
11980
|
-
|
|
11981
|
-
|
|
11982
|
-
|
|
11983
|
-
|
|
11984
|
-
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
11988
|
-
|
|
11989
|
-
default:
|
|
11990
|
-
return {
|
|
11991
|
-
op,
|
|
11992
|
-
tableName: map.tableName(tableName),
|
|
11993
|
-
primaryKey: map.columns(tableName, primaryKey),
|
|
11994
|
-
value: map.row(tableName, value)
|
|
11995
|
-
};
|
|
11996
|
-
}
|
|
11997
|
-
})
|
|
12045
|
+
ops: arg.ops.map(
|
|
12046
|
+
({ op, tableName, primaryKey, value }) => ({
|
|
12047
|
+
op,
|
|
12048
|
+
tableName: map.tableName(tableName),
|
|
12049
|
+
primaryKey: map.columns(tableName, primaryKey),
|
|
12050
|
+
value: map.row(tableName, value)
|
|
12051
|
+
// The cast is necessary because ts objects to the `value` field
|
|
12052
|
+
// for "delete" ops being different.
|
|
12053
|
+
})
|
|
12054
|
+
)
|
|
11998
12055
|
};
|
|
11999
12056
|
}
|
|
12000
12057
|
|
|
@@ -12550,931 +12607,1061 @@ var MemoryStorage = class {
|
|
|
12550
12607
|
}
|
|
12551
12608
|
};
|
|
12552
12609
|
|
|
12553
|
-
// ../
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
function toDesiredQueriesKey(clientID, hash2) {
|
|
12562
|
-
return DESIRED_QUERIES_KEY_PREFIX + clientID + "/" + hash2;
|
|
12563
|
-
}
|
|
12564
|
-
function desiredQueriesPrefixForClient(clientID) {
|
|
12565
|
-
return DESIRED_QUERIES_KEY_PREFIX + clientID + "/";
|
|
12566
|
-
}
|
|
12567
|
-
function toGotQueriesKey(hash2) {
|
|
12568
|
-
return GOT_QUERIES_KEY_PREFIX + hash2;
|
|
12610
|
+
// ../zql/src/ivm/constraint.ts
|
|
12611
|
+
function constraintMatchesRow(constraint, row) {
|
|
12612
|
+
for (const key in constraint) {
|
|
12613
|
+
if (!valuesEqual(row[key], constraint[key])) {
|
|
12614
|
+
return false;
|
|
12615
|
+
}
|
|
12616
|
+
}
|
|
12617
|
+
return true;
|
|
12569
12618
|
}
|
|
12570
|
-
function
|
|
12571
|
-
|
|
12572
|
-
|
|
12619
|
+
function constraintMatchesPrimaryKey(constraint, primary) {
|
|
12620
|
+
const constraintKeys = Object.keys(constraint);
|
|
12621
|
+
if (constraintKeys.length !== primary.length) {
|
|
12622
|
+
return false;
|
|
12573
12623
|
}
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
|
|
12624
|
+
constraintKeys.sort(stringCompare);
|
|
12625
|
+
for (let i = 0; i < constraintKeys.length; i++) {
|
|
12626
|
+
if (constraintKeys[i][0] !== primary[i]) {
|
|
12627
|
+
return false;
|
|
12628
|
+
}
|
|
12629
|
+
}
|
|
12630
|
+
return true;
|
|
12578
12631
|
}
|
|
12579
12632
|
|
|
12580
|
-
// ../
|
|
12581
|
-
var
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
#
|
|
12587
|
-
#
|
|
12588
|
-
#
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
this.#
|
|
12593
|
-
this.#
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
|
|
12633
|
+
// ../zql/src/ivm/memory-source.ts
|
|
12634
|
+
var MemorySource = class _MemorySource {
|
|
12635
|
+
#tableName;
|
|
12636
|
+
#columns;
|
|
12637
|
+
#primaryKey;
|
|
12638
|
+
#primaryIndexSort;
|
|
12639
|
+
#indexes = /* @__PURE__ */ new Map();
|
|
12640
|
+
#connections = [];
|
|
12641
|
+
#overlay;
|
|
12642
|
+
constructor(tableName, columns, primaryKey, primaryIndexData) {
|
|
12643
|
+
this.#tableName = tableName;
|
|
12644
|
+
this.#columns = columns;
|
|
12645
|
+
this.#primaryKey = primaryKey;
|
|
12646
|
+
this.#primaryIndexSort = primaryKey.map((k) => [k, "asc"]);
|
|
12647
|
+
const comparator2 = makeBoundComparator(this.#primaryIndexSort);
|
|
12648
|
+
this.#indexes.set(JSON.stringify(this.#primaryIndexSort), {
|
|
12649
|
+
comparator: comparator2,
|
|
12650
|
+
data: primaryIndexData ?? new BTreeSet(comparator2),
|
|
12651
|
+
usedBy: /* @__PURE__ */ new Set()
|
|
12652
|
+
});
|
|
12653
|
+
assertOrderingIncludesPK(this.#primaryIndexSort, this.#primaryKey);
|
|
12598
12654
|
}
|
|
12599
|
-
|
|
12600
|
-
|
|
12655
|
+
// Mainly for tests.
|
|
12656
|
+
getSchemaInfo() {
|
|
12657
|
+
return {
|
|
12658
|
+
tableName: this.#tableName,
|
|
12659
|
+
columns: this.#columns,
|
|
12660
|
+
primaryKey: this.#primaryKey
|
|
12661
|
+
};
|
|
12601
12662
|
}
|
|
12602
|
-
|
|
12603
|
-
|
|
12663
|
+
fork() {
|
|
12664
|
+
const primaryIndex = this.#getPrimaryIndex();
|
|
12665
|
+
return new _MemorySource(
|
|
12666
|
+
this.#tableName,
|
|
12667
|
+
this.#columns,
|
|
12668
|
+
this.#primaryKey,
|
|
12669
|
+
primaryIndex.data.clone()
|
|
12670
|
+
);
|
|
12604
12671
|
}
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
this.#
|
|
12672
|
+
#getSchema(connection) {
|
|
12673
|
+
return {
|
|
12674
|
+
tableName: this.#tableName,
|
|
12675
|
+
columns: this.#columns,
|
|
12676
|
+
primaryKey: this.#primaryKey,
|
|
12677
|
+
sort: connection.sort,
|
|
12678
|
+
system: "client",
|
|
12679
|
+
relationships: {},
|
|
12680
|
+
isHidden: false,
|
|
12681
|
+
compareRows: connection.compareRows
|
|
12609
12682
|
};
|
|
12610
12683
|
}
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
12617
|
-
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
|
|
12622
|
-
|
|
12684
|
+
connect(sort, filters) {
|
|
12685
|
+
const transformedFilters = transformFilters(filters);
|
|
12686
|
+
const input = {
|
|
12687
|
+
getSchema: () => schema,
|
|
12688
|
+
fetch: (req) => this.#fetch(req, connection),
|
|
12689
|
+
cleanup: (req) => this.#cleanup(req, connection),
|
|
12690
|
+
setOutput: (output) => {
|
|
12691
|
+
connection.output = output;
|
|
12692
|
+
},
|
|
12693
|
+
destroy: () => {
|
|
12694
|
+
this.#disconnect(input);
|
|
12695
|
+
},
|
|
12696
|
+
fullyAppliedFilters: !transformedFilters.conditionsRemoved
|
|
12697
|
+
};
|
|
12698
|
+
const connection = {
|
|
12699
|
+
input,
|
|
12700
|
+
output: void 0,
|
|
12701
|
+
sort,
|
|
12702
|
+
compareRows: makeComparator(sort),
|
|
12703
|
+
filters: transformedFilters.filters ? {
|
|
12704
|
+
condition: transformedFilters.filters,
|
|
12705
|
+
predicate: createPredicate(transformedFilters.filters)
|
|
12706
|
+
} : void 0
|
|
12707
|
+
};
|
|
12708
|
+
const schema = this.#getSchema(connection);
|
|
12709
|
+
assertOrderingIncludesPK(sort, this.#primaryKey);
|
|
12710
|
+
this.#connections.push(connection);
|
|
12711
|
+
return input;
|
|
12623
12712
|
}
|
|
12624
|
-
|
|
12625
|
-
this.
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
case "del":
|
|
12638
|
-
assert(typeof diff2.oldValue === "object");
|
|
12639
|
-
source.push({
|
|
12640
|
-
type: "remove",
|
|
12641
|
-
row: diff2.oldValue
|
|
12642
|
-
});
|
|
12643
|
-
break;
|
|
12644
|
-
case "add":
|
|
12645
|
-
assert(typeof diff2.newValue === "object");
|
|
12646
|
-
source.push({
|
|
12647
|
-
type: "add",
|
|
12648
|
-
row: diff2.newValue
|
|
12649
|
-
});
|
|
12650
|
-
break;
|
|
12651
|
-
case "change":
|
|
12652
|
-
assert(typeof diff2.newValue === "object");
|
|
12653
|
-
assert(typeof diff2.oldValue === "object");
|
|
12654
|
-
source.push({
|
|
12655
|
-
type: "edit",
|
|
12656
|
-
row: diff2.newValue,
|
|
12657
|
-
oldRow: diff2.oldValue
|
|
12658
|
-
});
|
|
12659
|
-
break;
|
|
12660
|
-
default:
|
|
12661
|
-
unreachable(diff2);
|
|
12662
|
-
}
|
|
12663
|
-
}
|
|
12664
|
-
} finally {
|
|
12665
|
-
this.#endTransaction();
|
|
12713
|
+
#disconnect(input) {
|
|
12714
|
+
const idx = this.#connections.findIndex((c) => c.input === input);
|
|
12715
|
+
assert(idx !== -1, "Connection not found");
|
|
12716
|
+
const connection = this.#connections[idx];
|
|
12717
|
+
this.#connections.splice(idx, 1);
|
|
12718
|
+
const primaryIndexKey = JSON.stringify(this.#primaryIndexSort);
|
|
12719
|
+
for (const [key, index] of this.#indexes) {
|
|
12720
|
+
if (key === primaryIndexKey) {
|
|
12721
|
+
continue;
|
|
12722
|
+
}
|
|
12723
|
+
index.usedBy.delete(connection);
|
|
12724
|
+
if (index.usedBy.size === 0) {
|
|
12725
|
+
this.#indexes.delete(key);
|
|
12666
12726
|
}
|
|
12667
|
-
});
|
|
12668
|
-
}
|
|
12669
|
-
#endTransaction() {
|
|
12670
|
-
for (const listener of this.#commitListeners) {
|
|
12671
|
-
listener();
|
|
12672
12727
|
}
|
|
12673
12728
|
}
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12684
|
-
|
|
12685
|
-
try {
|
|
12686
|
-
const ops = [];
|
|
12687
|
-
const m = {};
|
|
12688
|
-
for (const name of Object.keys(schema.tables)) {
|
|
12689
|
-
m[name] = makeBatchCRUDMutate(name, schema, ops);
|
|
12690
|
-
}
|
|
12691
|
-
const rv = await body(m);
|
|
12692
|
-
await zeroCRUD({ ops });
|
|
12693
|
-
return rv;
|
|
12694
|
-
} finally {
|
|
12695
|
-
inBatch = false;
|
|
12729
|
+
#getPrimaryIndex() {
|
|
12730
|
+
const index = this.#indexes.get(JSON.stringify(this.#primaryIndexSort));
|
|
12731
|
+
assert(index, "Primary index not found");
|
|
12732
|
+
return index;
|
|
12733
|
+
}
|
|
12734
|
+
#getOrCreateIndex(sort, usedBy) {
|
|
12735
|
+
const key = JSON.stringify(sort);
|
|
12736
|
+
const index = this.#indexes.get(key);
|
|
12737
|
+
if (index) {
|
|
12738
|
+
index.usedBy.add(usedBy);
|
|
12739
|
+
return index;
|
|
12696
12740
|
}
|
|
12697
|
-
|
|
12698
|
-
|
|
12699
|
-
|
|
12700
|
-
|
|
12741
|
+
const comparator2 = makeBoundComparator(sort);
|
|
12742
|
+
const data = new BTreeSet(comparator2);
|
|
12743
|
+
for (const row of this.#getPrimaryIndex().data) {
|
|
12744
|
+
data.add(row);
|
|
12701
12745
|
}
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
|
|
12705
|
-
mutate[name] = makeEntityCRUDMutate(
|
|
12706
|
-
name,
|
|
12707
|
-
tableSchema.primaryKey,
|
|
12708
|
-
zeroCRUD,
|
|
12709
|
-
assertNotInBatch
|
|
12710
|
-
);
|
|
12746
|
+
const newIndex = { comparator: comparator2, data, usedBy: /* @__PURE__ */ new Set([usedBy]) };
|
|
12747
|
+
this.#indexes.set(key, newIndex);
|
|
12748
|
+
return newIndex;
|
|
12711
12749
|
}
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
}
|
|
12716
|
-
|
|
12717
|
-
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
}
|
|
12727
|
-
return zeroCRUD({ ops: [op] });
|
|
12728
|
-
},
|
|
12729
|
-
upsert: (value) => {
|
|
12730
|
-
assertNotInBatch(tableName, "upsert");
|
|
12731
|
-
const op = {
|
|
12732
|
-
op: "upsert",
|
|
12733
|
-
tableName,
|
|
12734
|
-
primaryKey,
|
|
12735
|
-
value
|
|
12736
|
-
};
|
|
12737
|
-
return zeroCRUD({ ops: [op] });
|
|
12738
|
-
},
|
|
12739
|
-
update: (value) => {
|
|
12740
|
-
assertNotInBatch(tableName, "update");
|
|
12741
|
-
const op = {
|
|
12742
|
-
op: "update",
|
|
12743
|
-
tableName,
|
|
12744
|
-
primaryKey,
|
|
12745
|
-
value
|
|
12746
|
-
};
|
|
12747
|
-
return zeroCRUD({ ops: [op] });
|
|
12748
|
-
},
|
|
12749
|
-
delete: (id) => {
|
|
12750
|
-
assertNotInBatch(tableName, "delete");
|
|
12751
|
-
const op = {
|
|
12752
|
-
op: "delete",
|
|
12753
|
-
tableName,
|
|
12754
|
-
primaryKey,
|
|
12755
|
-
value: id
|
|
12756
|
-
};
|
|
12757
|
-
return zeroCRUD({ ops: [op] });
|
|
12750
|
+
// For unit testing that we correctly clean up indexes.
|
|
12751
|
+
getIndexKeys() {
|
|
12752
|
+
return [...this.#indexes.keys()];
|
|
12753
|
+
}
|
|
12754
|
+
*#fetch(req, from) {
|
|
12755
|
+
let overlay;
|
|
12756
|
+
const callingConnectionNum = this.#connections.indexOf(from);
|
|
12757
|
+
assert(callingConnectionNum !== -1, "Output not found");
|
|
12758
|
+
const conn = this.#connections[callingConnectionNum];
|
|
12759
|
+
const { sort: requestedSort } = conn;
|
|
12760
|
+
const indexSort = [];
|
|
12761
|
+
if (req.constraint) {
|
|
12762
|
+
for (const key of Object.keys(req.constraint)) {
|
|
12763
|
+
indexSort.push([key, "asc"]);
|
|
12764
|
+
}
|
|
12758
12765
|
}
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
function makeBatchCRUDMutate(tableName, schema, ops) {
|
|
12762
|
-
const { primaryKey } = schema.tables[tableName];
|
|
12763
|
-
return {
|
|
12764
|
-
insert: (value) => {
|
|
12765
|
-
const op = {
|
|
12766
|
-
op: "insert",
|
|
12767
|
-
tableName,
|
|
12768
|
-
primaryKey,
|
|
12769
|
-
value
|
|
12770
|
-
};
|
|
12771
|
-
ops.push(op);
|
|
12772
|
-
return promiseVoid;
|
|
12773
|
-
},
|
|
12774
|
-
upsert: (value) => {
|
|
12775
|
-
const op = {
|
|
12776
|
-
op: "upsert",
|
|
12777
|
-
tableName,
|
|
12778
|
-
primaryKey,
|
|
12779
|
-
value
|
|
12780
|
-
};
|
|
12781
|
-
ops.push(op);
|
|
12782
|
-
return promiseVoid;
|
|
12783
|
-
},
|
|
12784
|
-
update: (value) => {
|
|
12785
|
-
const op = {
|
|
12786
|
-
op: "update",
|
|
12787
|
-
tableName,
|
|
12788
|
-
primaryKey,
|
|
12789
|
-
value
|
|
12790
|
-
};
|
|
12791
|
-
ops.push(op);
|
|
12792
|
-
return promiseVoid;
|
|
12793
|
-
},
|
|
12794
|
-
delete: (id) => {
|
|
12795
|
-
const op = {
|
|
12796
|
-
op: "delete",
|
|
12797
|
-
tableName,
|
|
12798
|
-
primaryKey,
|
|
12799
|
-
value: id
|
|
12800
|
-
};
|
|
12801
|
-
ops.push(op);
|
|
12802
|
-
return promiseVoid;
|
|
12766
|
+
if (this.#primaryKey.length > 1 || !req.constraint || !constraintMatchesPrimaryKey(req.constraint, this.#primaryKey)) {
|
|
12767
|
+
indexSort.push(...requestedSort);
|
|
12803
12768
|
}
|
|
12804
|
-
|
|
12805
|
-
}
|
|
12806
|
-
|
|
12807
|
-
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
case "insert":
|
|
12811
|
-
await insertImpl(tx, op, schema);
|
|
12812
|
-
break;
|
|
12813
|
-
case "upsert":
|
|
12814
|
-
await upsertImpl(tx, op, schema);
|
|
12815
|
-
break;
|
|
12816
|
-
case "update":
|
|
12817
|
-
await updateImpl(tx, op, schema);
|
|
12818
|
-
break;
|
|
12819
|
-
case "delete":
|
|
12820
|
-
await deleteImpl(tx, op, schema);
|
|
12821
|
-
break;
|
|
12769
|
+
const index = this.#getOrCreateIndex(indexSort, from);
|
|
12770
|
+
const { data, comparator: compare } = index;
|
|
12771
|
+
const comparator2 = (r1, r2) => compare(r1, r2) * (req.reverse ? -1 : 1);
|
|
12772
|
+
if (this.#overlay) {
|
|
12773
|
+
if (callingConnectionNum <= this.#overlay.outputIndex) {
|
|
12774
|
+
overlay = this.#overlay;
|
|
12822
12775
|
}
|
|
12823
12776
|
}
|
|
12824
|
-
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
|
|
12777
|
+
const startAt = req.start?.row;
|
|
12778
|
+
let scanStart;
|
|
12779
|
+
if (req.constraint) {
|
|
12780
|
+
scanStart = {};
|
|
12781
|
+
for (const [key, dir] of indexSort) {
|
|
12782
|
+
if (hasOwn(req.constraint, key)) {
|
|
12783
|
+
scanStart[key] = req.constraint[key];
|
|
12784
|
+
} else {
|
|
12785
|
+
if (req.reverse) {
|
|
12786
|
+
scanStart[key] = dir === "asc" ? maxValue : minValue;
|
|
12787
|
+
} else {
|
|
12788
|
+
scanStart[key] = dir === "asc" ? minValue : maxValue;
|
|
12789
|
+
}
|
|
12790
|
+
}
|
|
12791
|
+
}
|
|
12792
|
+
} else {
|
|
12793
|
+
scanStart = startAt;
|
|
12831
12794
|
}
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
arg.value
|
|
12840
|
-
);
|
|
12841
|
-
if (!await tx.has(key)) {
|
|
12842
|
-
const val = defaultOptionalFieldsToNull(
|
|
12843
|
-
schema.tables[arg.tableName],
|
|
12844
|
-
arg.value
|
|
12795
|
+
const withOverlay = generateWithOverlay(
|
|
12796
|
+
startAt,
|
|
12797
|
+
generateRows(data, scanStart, req.reverse),
|
|
12798
|
+
req.constraint,
|
|
12799
|
+
overlay,
|
|
12800
|
+
comparator2,
|
|
12801
|
+
conn.filters?.predicate
|
|
12845
12802
|
);
|
|
12846
|
-
|
|
12803
|
+
const withConstraint = generateWithConstraint(
|
|
12804
|
+
generateWithStart(withOverlay, req.start, comparator2),
|
|
12805
|
+
req.constraint
|
|
12806
|
+
);
|
|
12807
|
+
yield* conn.filters ? generateWithFilter(withConstraint, conn.filters.predicate) : withConstraint;
|
|
12847
12808
|
}
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
const key = toPrimaryKeyString(
|
|
12851
|
-
arg.tableName,
|
|
12852
|
-
schema.tables[arg.tableName].primaryKey,
|
|
12853
|
-
arg.value
|
|
12854
|
-
);
|
|
12855
|
-
const val = defaultOptionalFieldsToNull(
|
|
12856
|
-
schema.tables[arg.tableName],
|
|
12857
|
-
arg.value
|
|
12858
|
-
);
|
|
12859
|
-
await tx.set(key, val);
|
|
12860
|
-
}
|
|
12861
|
-
async function updateImpl(tx, arg, schema) {
|
|
12862
|
-
const key = toPrimaryKeyString(
|
|
12863
|
-
arg.tableName,
|
|
12864
|
-
schema.tables[arg.tableName].primaryKey,
|
|
12865
|
-
arg.value
|
|
12866
|
-
);
|
|
12867
|
-
const prev = await tx.get(key);
|
|
12868
|
-
if (prev === void 0) {
|
|
12869
|
-
return;
|
|
12809
|
+
#cleanup(req, connection) {
|
|
12810
|
+
return this.#fetch(req, connection);
|
|
12870
12811
|
}
|
|
12871
|
-
|
|
12872
|
-
|
|
12873
|
-
for (const k in update) {
|
|
12874
|
-
if (update[k] !== void 0) {
|
|
12875
|
-
next[k] = update[k];
|
|
12812
|
+
push(change) {
|
|
12813
|
+
for (const _ of this.genPush(change)) {
|
|
12876
12814
|
}
|
|
12877
12815
|
}
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
|
|
12889
|
-
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
|
|
12898
|
-
|
|
12899
|
-
|
|
12900
|
-
|
|
12901
|
-
|
|
12902
|
-
|
|
12903
|
-
|
|
12904
|
-
|
|
12816
|
+
*genPush(change) {
|
|
12817
|
+
const primaryIndex = this.#getPrimaryIndex();
|
|
12818
|
+
const { data } = primaryIndex;
|
|
12819
|
+
switch (change.type) {
|
|
12820
|
+
case "add":
|
|
12821
|
+
assert(
|
|
12822
|
+
!data.has(change.row),
|
|
12823
|
+
() => `Row already exists ${JSON.stringify(change)}`
|
|
12824
|
+
);
|
|
12825
|
+
break;
|
|
12826
|
+
case "remove":
|
|
12827
|
+
assert(
|
|
12828
|
+
data.has(change.row),
|
|
12829
|
+
() => `Row not found ${JSON.stringify(change)}`
|
|
12830
|
+
);
|
|
12831
|
+
break;
|
|
12832
|
+
case "edit":
|
|
12833
|
+
assert(
|
|
12834
|
+
data.has(change.oldRow),
|
|
12835
|
+
() => `Row not found ${JSON.stringify(change)}`
|
|
12836
|
+
);
|
|
12837
|
+
break;
|
|
12838
|
+
default:
|
|
12839
|
+
unreachable(change);
|
|
12840
|
+
}
|
|
12841
|
+
const outputChange = change.type === "edit" ? {
|
|
12842
|
+
type: change.type,
|
|
12843
|
+
oldNode: {
|
|
12844
|
+
row: change.oldRow,
|
|
12845
|
+
relationships: {}
|
|
12846
|
+
},
|
|
12847
|
+
node: {
|
|
12848
|
+
row: change.row,
|
|
12849
|
+
relationships: {}
|
|
12850
|
+
}
|
|
12851
|
+
} : {
|
|
12852
|
+
type: change.type,
|
|
12853
|
+
node: {
|
|
12854
|
+
row: change.row,
|
|
12855
|
+
relationships: {}
|
|
12856
|
+
}
|
|
12857
|
+
};
|
|
12858
|
+
for (const [
|
|
12859
|
+
outputIndex,
|
|
12860
|
+
{ output, filters }
|
|
12861
|
+
] of this.#connections.entries()) {
|
|
12862
|
+
if (output) {
|
|
12863
|
+
this.#overlay = { outputIndex, change };
|
|
12864
|
+
filterPush(outputChange, output, filters?.predicate);
|
|
12865
|
+
yield;
|
|
12866
|
+
}
|
|
12867
|
+
}
|
|
12868
|
+
this.#overlay = void 0;
|
|
12869
|
+
for (const { data: data2 } of this.#indexes.values()) {
|
|
12870
|
+
switch (change.type) {
|
|
12871
|
+
case "add": {
|
|
12872
|
+
const added = data2.add(change.row);
|
|
12873
|
+
assert(added);
|
|
12874
|
+
break;
|
|
12875
|
+
}
|
|
12876
|
+
case "remove": {
|
|
12877
|
+
const removed = data2.delete(change.row);
|
|
12878
|
+
assert(removed);
|
|
12879
|
+
break;
|
|
12880
|
+
}
|
|
12881
|
+
case "edit": {
|
|
12882
|
+
const removed = data2.delete(change.oldRow);
|
|
12883
|
+
assert(removed);
|
|
12884
|
+
data2.add(change.row);
|
|
12885
|
+
break;
|
|
12886
|
+
}
|
|
12887
|
+
default:
|
|
12888
|
+
unreachable(change);
|
|
12889
|
+
}
|
|
12890
|
+
}
|
|
12905
12891
|
}
|
|
12906
|
-
clientID;
|
|
12907
|
-
mutationID;
|
|
12908
|
-
reason;
|
|
12909
|
-
mutate;
|
|
12910
|
-
query;
|
|
12911
12892
|
};
|
|
12912
|
-
function
|
|
12913
|
-
|
|
12914
|
-
|
|
12915
|
-
|
|
12916
|
-
|
|
12917
|
-
|
|
12918
|
-
function makeSchemaQuery(schema, ivmBranch) {
|
|
12919
|
-
const rv = {};
|
|
12920
|
-
const context = new ZeroContext(
|
|
12921
|
-
ivmBranch,
|
|
12922
|
-
() => () => {
|
|
12923
|
-
},
|
|
12924
|
-
(applyViewUpdates) => applyViewUpdates()
|
|
12925
|
-
);
|
|
12926
|
-
for (const name of Object.keys(schema.tables)) {
|
|
12927
|
-
rv[name] = newQuery(context, schema, name);
|
|
12893
|
+
function* generateWithConstraint(it, constraint) {
|
|
12894
|
+
for (const node of it) {
|
|
12895
|
+
if (constraint && !constraintMatchesRow(constraint, node.row)) {
|
|
12896
|
+
break;
|
|
12897
|
+
}
|
|
12898
|
+
yield node;
|
|
12928
12899
|
}
|
|
12929
|
-
return rv;
|
|
12930
12900
|
}
|
|
12931
|
-
function
|
|
12932
|
-
const
|
|
12933
|
-
|
|
12934
|
-
|
|
12901
|
+
function* generateWithFilter(it, filter) {
|
|
12902
|
+
for (const node of it) {
|
|
12903
|
+
if (filter(node.row)) {
|
|
12904
|
+
yield node;
|
|
12905
|
+
}
|
|
12935
12906
|
}
|
|
12936
|
-
return mutate;
|
|
12937
12907
|
}
|
|
12938
|
-
function
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
insert: (value) => insertImpl(tx, { op: "insert", tableName, primaryKey, value }, schema),
|
|
12943
|
-
upsert: (value) => upsertImpl(tx, { op: "upsert", tableName, primaryKey, value }, schema),
|
|
12944
|
-
update: (value) => updateImpl(tx, { op: "update", tableName, primaryKey, value }, schema),
|
|
12945
|
-
delete: (id) => deleteImpl(tx, { op: "delete", tableName, primaryKey, value: id }, schema)
|
|
12946
|
-
};
|
|
12947
|
-
}
|
|
12948
|
-
|
|
12949
|
-
// ../zero-client/src/client/enable-analytics.ts
|
|
12950
|
-
var IPV4_ADDRESS_REGEX = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
12951
|
-
var IPV6_ADDRESS_HOSTNAME_REGEX = /^\[[a-fA-F0-9:]*:[a-fA-F0-9:]*\]$/;
|
|
12952
|
-
var IP_ADDRESS_HOSTNAME_REGEX = new RegExp(
|
|
12953
|
-
`(${IPV4_ADDRESS_REGEX.source}|${IPV6_ADDRESS_HOSTNAME_REGEX.source})`
|
|
12954
|
-
);
|
|
12955
|
-
function shouldEnableAnalytics(server, enableAnalytics = true) {
|
|
12956
|
-
if (!enableAnalytics) {
|
|
12957
|
-
return false;
|
|
12908
|
+
function* generateWithStart(nodes, start, compare) {
|
|
12909
|
+
if (!start) {
|
|
12910
|
+
yield* nodes;
|
|
12911
|
+
return;
|
|
12958
12912
|
}
|
|
12959
|
-
|
|
12960
|
-
const
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
}
|
|
12971
|
-
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
for (const key in constraint) {
|
|
12975
|
-
if (!valuesEqual(row[key], constraint[key])) {
|
|
12976
|
-
return false;
|
|
12913
|
+
let started = false;
|
|
12914
|
+
for (const node of nodes) {
|
|
12915
|
+
if (!started) {
|
|
12916
|
+
if (start.basis === "at") {
|
|
12917
|
+
if (compare(node.row, start.row) >= 0) {
|
|
12918
|
+
started = true;
|
|
12919
|
+
}
|
|
12920
|
+
} else if (start.basis === "after") {
|
|
12921
|
+
if (compare(node.row, start.row) > 0) {
|
|
12922
|
+
started = true;
|
|
12923
|
+
}
|
|
12924
|
+
}
|
|
12925
|
+
}
|
|
12926
|
+
if (started) {
|
|
12927
|
+
yield node;
|
|
12977
12928
|
}
|
|
12978
12929
|
}
|
|
12979
|
-
return true;
|
|
12980
12930
|
}
|
|
12981
|
-
function
|
|
12982
|
-
const
|
|
12983
|
-
|
|
12984
|
-
|
|
12931
|
+
function* generateWithOverlay(startAt, rows, constraint, overlay, compare, filterPredicate) {
|
|
12932
|
+
const overlays = computeOverlays(
|
|
12933
|
+
startAt,
|
|
12934
|
+
constraint,
|
|
12935
|
+
overlay,
|
|
12936
|
+
compare,
|
|
12937
|
+
filterPredicate
|
|
12938
|
+
);
|
|
12939
|
+
yield* generateWithOverlayInner(rows, overlays, compare);
|
|
12940
|
+
}
|
|
12941
|
+
function computeOverlays(startAt, constraint, overlay, compare, filterPredicate) {
|
|
12942
|
+
let overlays = {
|
|
12943
|
+
add: void 0,
|
|
12944
|
+
remove: void 0
|
|
12945
|
+
};
|
|
12946
|
+
switch (overlay?.change.type) {
|
|
12947
|
+
case "add":
|
|
12948
|
+
overlays = {
|
|
12949
|
+
add: overlay.change.row,
|
|
12950
|
+
remove: void 0
|
|
12951
|
+
};
|
|
12952
|
+
break;
|
|
12953
|
+
case "remove":
|
|
12954
|
+
overlays = {
|
|
12955
|
+
add: void 0,
|
|
12956
|
+
remove: overlay.change.row
|
|
12957
|
+
};
|
|
12958
|
+
break;
|
|
12959
|
+
case "edit":
|
|
12960
|
+
overlays = {
|
|
12961
|
+
add: overlay.change.row,
|
|
12962
|
+
remove: overlay.change.oldRow
|
|
12963
|
+
};
|
|
12964
|
+
break;
|
|
12985
12965
|
}
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
if (constraintKeys[i][0] !== primary[i]) {
|
|
12989
|
-
return false;
|
|
12990
|
-
}
|
|
12966
|
+
if (startAt) {
|
|
12967
|
+
overlays = overlaysForStartAt(overlays, startAt, compare);
|
|
12991
12968
|
}
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
|
|
12995
|
-
// ../zql/src/ivm/memory-source.ts
|
|
12996
|
-
var MemorySource = class _MemorySource {
|
|
12997
|
-
#tableName;
|
|
12998
|
-
#columns;
|
|
12999
|
-
#primaryKey;
|
|
13000
|
-
#primaryIndexSort;
|
|
13001
|
-
#indexes = /* @__PURE__ */ new Map();
|
|
13002
|
-
#connections = [];
|
|
13003
|
-
#overlay;
|
|
13004
|
-
constructor(tableName, columns, primaryKey, primaryIndexData) {
|
|
13005
|
-
this.#tableName = tableName;
|
|
13006
|
-
this.#columns = columns;
|
|
13007
|
-
this.#primaryKey = primaryKey;
|
|
13008
|
-
this.#primaryIndexSort = primaryKey.map((k) => [k, "asc"]);
|
|
13009
|
-
const comparator2 = makeBoundComparator(this.#primaryIndexSort);
|
|
13010
|
-
this.#indexes.set(JSON.stringify(this.#primaryIndexSort), {
|
|
13011
|
-
comparator: comparator2,
|
|
13012
|
-
data: primaryIndexData ?? new BTreeSet(comparator2),
|
|
13013
|
-
usedBy: /* @__PURE__ */ new Set()
|
|
13014
|
-
});
|
|
13015
|
-
assertOrderingIncludesPK(this.#primaryIndexSort, this.#primaryKey);
|
|
12969
|
+
if (constraint) {
|
|
12970
|
+
overlays = overlaysForConstraint(overlays, constraint);
|
|
13016
12971
|
}
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
return {
|
|
13020
|
-
tableName: this.#tableName,
|
|
13021
|
-
columns: this.#columns,
|
|
13022
|
-
primaryKey: this.#primaryKey
|
|
13023
|
-
};
|
|
13024
|
-
}
|
|
13025
|
-
fork() {
|
|
13026
|
-
const primaryIndex = this.#getPrimaryIndex();
|
|
13027
|
-
return new _MemorySource(
|
|
13028
|
-
this.#tableName,
|
|
13029
|
-
this.#columns,
|
|
13030
|
-
this.#primaryKey,
|
|
13031
|
-
primaryIndex.data.clone()
|
|
13032
|
-
);
|
|
13033
|
-
}
|
|
13034
|
-
#getSchema(connection) {
|
|
13035
|
-
return {
|
|
13036
|
-
tableName: this.#tableName,
|
|
13037
|
-
columns: this.#columns,
|
|
13038
|
-
primaryKey: this.#primaryKey,
|
|
13039
|
-
sort: connection.sort,
|
|
13040
|
-
system: "client",
|
|
13041
|
-
relationships: {},
|
|
13042
|
-
isHidden: false,
|
|
13043
|
-
compareRows: connection.compareRows
|
|
13044
|
-
};
|
|
13045
|
-
}
|
|
13046
|
-
connect(sort, filters) {
|
|
13047
|
-
const transformedFilters = transformFilters(filters);
|
|
13048
|
-
const input = {
|
|
13049
|
-
getSchema: () => schema,
|
|
13050
|
-
fetch: (req) => this.#fetch(req, connection),
|
|
13051
|
-
cleanup: (req) => this.#cleanup(req, connection),
|
|
13052
|
-
setOutput: (output) => {
|
|
13053
|
-
connection.output = output;
|
|
13054
|
-
},
|
|
13055
|
-
destroy: () => {
|
|
13056
|
-
this.#disconnect(input);
|
|
13057
|
-
},
|
|
13058
|
-
fullyAppliedFilters: !transformedFilters.conditionsRemoved
|
|
13059
|
-
};
|
|
13060
|
-
const connection = {
|
|
13061
|
-
input,
|
|
13062
|
-
output: void 0,
|
|
13063
|
-
sort,
|
|
13064
|
-
compareRows: makeComparator(sort),
|
|
13065
|
-
filters: transformedFilters.filters ? {
|
|
13066
|
-
condition: transformedFilters.filters,
|
|
13067
|
-
predicate: createPredicate(transformedFilters.filters)
|
|
13068
|
-
} : void 0
|
|
13069
|
-
};
|
|
13070
|
-
const schema = this.#getSchema(connection);
|
|
13071
|
-
assertOrderingIncludesPK(sort, this.#primaryKey);
|
|
13072
|
-
this.#connections.push(connection);
|
|
13073
|
-
return input;
|
|
12972
|
+
if (filterPredicate) {
|
|
12973
|
+
overlays = overlaysForFilterPredicate(overlays, filterPredicate);
|
|
13074
12974
|
}
|
|
13075
|
-
|
|
13076
|
-
|
|
13077
|
-
|
|
13078
|
-
|
|
13079
|
-
|
|
13080
|
-
|
|
13081
|
-
|
|
13082
|
-
|
|
13083
|
-
|
|
12975
|
+
return overlays;
|
|
12976
|
+
}
|
|
12977
|
+
function overlaysForStartAt({ add, remove }, startAt, compare) {
|
|
12978
|
+
const undefinedIfBeforeStartAt = (row) => row === void 0 || compare(row, startAt) < 0 ? void 0 : row;
|
|
12979
|
+
return {
|
|
12980
|
+
add: undefinedIfBeforeStartAt(add),
|
|
12981
|
+
remove: undefinedIfBeforeStartAt(remove)
|
|
12982
|
+
};
|
|
12983
|
+
}
|
|
12984
|
+
function overlaysForConstraint({ add, remove }, constraint) {
|
|
12985
|
+
const undefinedIfDoesntMatchConstraint = (row) => row === void 0 || !constraintMatchesRow(constraint, row) ? void 0 : row;
|
|
12986
|
+
return {
|
|
12987
|
+
add: undefinedIfDoesntMatchConstraint(add),
|
|
12988
|
+
remove: undefinedIfDoesntMatchConstraint(remove)
|
|
12989
|
+
};
|
|
12990
|
+
}
|
|
12991
|
+
function overlaysForFilterPredicate({ add, remove }, filterPredicate) {
|
|
12992
|
+
const undefinedIfDoesntMatchFilter = (row) => row === void 0 || !filterPredicate(row) ? void 0 : row;
|
|
12993
|
+
return {
|
|
12994
|
+
add: undefinedIfDoesntMatchFilter(add),
|
|
12995
|
+
remove: undefinedIfDoesntMatchFilter(remove)
|
|
12996
|
+
};
|
|
12997
|
+
}
|
|
12998
|
+
function* generateWithOverlayInner(rowIterator, overlays, compare) {
|
|
12999
|
+
let addOverlayYielded = false;
|
|
13000
|
+
let removeOverlaySkipped = false;
|
|
13001
|
+
for (const row of rowIterator) {
|
|
13002
|
+
if (!addOverlayYielded && overlays.add) {
|
|
13003
|
+
const cmp2 = compare(overlays.add, row);
|
|
13004
|
+
if (cmp2 < 0) {
|
|
13005
|
+
addOverlayYielded = true;
|
|
13006
|
+
yield { row: overlays.add, relationships: {} };
|
|
13084
13007
|
}
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
|
|
13008
|
+
}
|
|
13009
|
+
if (!removeOverlaySkipped && overlays.remove) {
|
|
13010
|
+
const cmp2 = compare(overlays.remove, row);
|
|
13011
|
+
if (cmp2 === 0) {
|
|
13012
|
+
removeOverlaySkipped = true;
|
|
13013
|
+
continue;
|
|
13088
13014
|
}
|
|
13089
13015
|
}
|
|
13016
|
+
yield { row, relationships: {} };
|
|
13090
13017
|
}
|
|
13091
|
-
|
|
13092
|
-
|
|
13093
|
-
assert(index, "Primary index not found");
|
|
13094
|
-
return index;
|
|
13018
|
+
if (!addOverlayYielded && overlays.add) {
|
|
13019
|
+
yield { row: overlays.add, relationships: {} };
|
|
13095
13020
|
}
|
|
13096
|
-
|
|
13097
|
-
|
|
13098
|
-
|
|
13099
|
-
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13021
|
+
}
|
|
13022
|
+
var minValue = Symbol("min-value");
|
|
13023
|
+
var maxValue = Symbol("max-value");
|
|
13024
|
+
function makeBoundComparator(sort) {
|
|
13025
|
+
return (a, b) => {
|
|
13026
|
+
for (const entry of sort) {
|
|
13027
|
+
const key = entry[0];
|
|
13028
|
+
const cmp2 = compareBounds(a[key], b[key]);
|
|
13029
|
+
if (cmp2 !== 0) {
|
|
13030
|
+
return entry[1] === "asc" ? cmp2 : -cmp2;
|
|
13031
|
+
}
|
|
13107
13032
|
}
|
|
13108
|
-
|
|
13109
|
-
|
|
13110
|
-
|
|
13033
|
+
return 0;
|
|
13034
|
+
};
|
|
13035
|
+
}
|
|
13036
|
+
function compareBounds(a, b) {
|
|
13037
|
+
if (a === b) {
|
|
13038
|
+
return 0;
|
|
13111
13039
|
}
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
return [...this.#indexes.keys()];
|
|
13040
|
+
if (a === minValue) {
|
|
13041
|
+
return -1;
|
|
13115
13042
|
}
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13124
|
-
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
|
|
13129
|
-
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
|
|
13135
|
-
|
|
13136
|
-
|
|
13137
|
-
|
|
13138
|
-
|
|
13139
|
-
|
|
13140
|
-
|
|
13141
|
-
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13145
|
-
|
|
13146
|
-
|
|
13147
|
-
|
|
13148
|
-
|
|
13149
|
-
|
|
13150
|
-
|
|
13043
|
+
if (b === minValue) {
|
|
13044
|
+
return 1;
|
|
13045
|
+
}
|
|
13046
|
+
if (a === maxValue) {
|
|
13047
|
+
return 1;
|
|
13048
|
+
}
|
|
13049
|
+
if (b === maxValue) {
|
|
13050
|
+
return -1;
|
|
13051
|
+
}
|
|
13052
|
+
return compareValues(a, b);
|
|
13053
|
+
}
|
|
13054
|
+
function* generateRows(data, scanStart, reverse) {
|
|
13055
|
+
yield* data[reverse ? "valuesFromReversed" : "valuesFrom"](
|
|
13056
|
+
scanStart
|
|
13057
|
+
);
|
|
13058
|
+
}
|
|
13059
|
+
|
|
13060
|
+
// ../zero-client/src/client/keys.ts
|
|
13061
|
+
var CLIENTS_KEY_PREFIX = "c/";
|
|
13062
|
+
var DESIRED_QUERIES_KEY_PREFIX = "d/";
|
|
13063
|
+
var GOT_QUERIES_KEY_PREFIX = "g/";
|
|
13064
|
+
var ENTITIES_KEY_PREFIX = "e/";
|
|
13065
|
+
function toClientsKey(clientID) {
|
|
13066
|
+
return CLIENTS_KEY_PREFIX + clientID;
|
|
13067
|
+
}
|
|
13068
|
+
function toDesiredQueriesKey(clientID, hash2) {
|
|
13069
|
+
return DESIRED_QUERIES_KEY_PREFIX + clientID + "/" + hash2;
|
|
13070
|
+
}
|
|
13071
|
+
function desiredQueriesPrefixForClient(clientID) {
|
|
13072
|
+
return DESIRED_QUERIES_KEY_PREFIX + clientID + "/";
|
|
13073
|
+
}
|
|
13074
|
+
function toGotQueriesKey(hash2) {
|
|
13075
|
+
return GOT_QUERIES_KEY_PREFIX + hash2;
|
|
13076
|
+
}
|
|
13077
|
+
function toPrimaryKeyString(tableName, primaryKey, value) {
|
|
13078
|
+
if (primaryKey.length === 1) {
|
|
13079
|
+
return ENTITIES_KEY_PREFIX + tableName + "/" + parse(value[primaryKey[0]], primaryKeyValueSchema);
|
|
13080
|
+
}
|
|
13081
|
+
const values = primaryKey.map((k) => parse(value[k], primaryKeyValueSchema));
|
|
13082
|
+
const str = JSON.stringify(values);
|
|
13083
|
+
const idSegment = h128(str);
|
|
13084
|
+
return ENTITIES_KEY_PREFIX + tableName + "/" + idSegment;
|
|
13085
|
+
}
|
|
13086
|
+
|
|
13087
|
+
// ../zero-client/src/client/ivm-source-repo.ts
|
|
13088
|
+
var IVMSourceRepo = class {
|
|
13089
|
+
#main;
|
|
13090
|
+
#tables;
|
|
13091
|
+
/**
|
|
13092
|
+
* Sync is lazily created when the first response from the server is received.
|
|
13093
|
+
*/
|
|
13094
|
+
#sync;
|
|
13095
|
+
/**
|
|
13096
|
+
* Rebase is created when the sync head is advanced and points to a fork
|
|
13097
|
+
* of the sync head. This is used to rebase optimistic mutations.
|
|
13098
|
+
*/
|
|
13099
|
+
#rebase;
|
|
13100
|
+
constructor(tables) {
|
|
13101
|
+
this.#main = new IVMSourceBranch(tables);
|
|
13102
|
+
this.#tables = tables;
|
|
13103
|
+
}
|
|
13104
|
+
get main() {
|
|
13105
|
+
return this.#main;
|
|
13106
|
+
}
|
|
13107
|
+
/**
|
|
13108
|
+
* Used for reads in `zero.TransactionImpl`.
|
|
13109
|
+
* Writes in `zero.TransactionImpl` also get applied to the rebase branch.
|
|
13110
|
+
*
|
|
13111
|
+
* The rebase branch is always forked off of the sync branch when a rebase begins.
|
|
13112
|
+
*/
|
|
13113
|
+
get rebase() {
|
|
13114
|
+
return must(this.#rebase, "rebase branch does not exist!");
|
|
13115
|
+
}
|
|
13116
|
+
advanceSyncHead = async (store, syncHeadHash, patches) => {
|
|
13117
|
+
if (this.#sync === void 0) {
|
|
13118
|
+
await withRead(store, async (dagRead) => {
|
|
13119
|
+
const syncSources = new IVMSourceBranch(this.#tables);
|
|
13120
|
+
const read = await readFromHash(
|
|
13121
|
+
syncHeadHash,
|
|
13122
|
+
dagRead,
|
|
13123
|
+
Latest
|
|
13124
|
+
);
|
|
13125
|
+
for await (const entry of read.map.scan(ENTITIES_KEY_PREFIX)) {
|
|
13126
|
+
if (!entry[0].startsWith(ENTITIES_KEY_PREFIX)) {
|
|
13127
|
+
break;
|
|
13151
13128
|
}
|
|
13129
|
+
const name = nameFromKey(entry[0]);
|
|
13130
|
+
const source = must(syncSources.getSource(name));
|
|
13131
|
+
source.push({
|
|
13132
|
+
type: "add",
|
|
13133
|
+
row: entry[1]
|
|
13134
|
+
});
|
|
13152
13135
|
}
|
|
13153
|
-
|
|
13136
|
+
this.#sync = syncSources;
|
|
13137
|
+
});
|
|
13154
13138
|
} else {
|
|
13155
|
-
|
|
13139
|
+
for (const patch of patches) {
|
|
13140
|
+
if (patch.op === "clear") {
|
|
13141
|
+
this.#sync.clear();
|
|
13142
|
+
continue;
|
|
13143
|
+
}
|
|
13144
|
+
const { key } = patch;
|
|
13145
|
+
if (!key.startsWith(ENTITIES_KEY_PREFIX)) {
|
|
13146
|
+
continue;
|
|
13147
|
+
}
|
|
13148
|
+
const name = nameFromKey(key);
|
|
13149
|
+
const source = must(this.#sync.getSource(name));
|
|
13150
|
+
switch (patch.op) {
|
|
13151
|
+
case "del":
|
|
13152
|
+
source.push({
|
|
13153
|
+
type: "remove",
|
|
13154
|
+
row: patch.oldValue
|
|
13155
|
+
});
|
|
13156
|
+
break;
|
|
13157
|
+
case "add":
|
|
13158
|
+
source.push({
|
|
13159
|
+
type: "add",
|
|
13160
|
+
row: patch.newValue
|
|
13161
|
+
});
|
|
13162
|
+
break;
|
|
13163
|
+
case "change":
|
|
13164
|
+
source.push({
|
|
13165
|
+
type: "edit",
|
|
13166
|
+
row: patch.newValue,
|
|
13167
|
+
oldRow: patch.oldValue
|
|
13168
|
+
});
|
|
13169
|
+
break;
|
|
13170
|
+
}
|
|
13171
|
+
}
|
|
13156
13172
|
}
|
|
13157
|
-
|
|
13158
|
-
|
|
13159
|
-
|
|
13160
|
-
|
|
13161
|
-
|
|
13162
|
-
|
|
13163
|
-
|
|
13164
|
-
|
|
13165
|
-
|
|
13166
|
-
|
|
13167
|
-
|
|
13173
|
+
this.#rebase = must(this.#sync).fork();
|
|
13174
|
+
};
|
|
13175
|
+
};
|
|
13176
|
+
function nameFromKey(key) {
|
|
13177
|
+
const slash = key.indexOf("/", ENTITIES_KEY_PREFIX.length);
|
|
13178
|
+
return key.slice(ENTITIES_KEY_PREFIX.length, slash);
|
|
13179
|
+
}
|
|
13180
|
+
var IVMSourceBranch = class _IVMSourceBranch {
|
|
13181
|
+
#sources;
|
|
13182
|
+
#tables;
|
|
13183
|
+
constructor(tables, sources = /* @__PURE__ */ new Map()) {
|
|
13184
|
+
this.#tables = tables;
|
|
13185
|
+
this.#sources = sources;
|
|
13186
|
+
}
|
|
13187
|
+
getSource(name) {
|
|
13188
|
+
if (this.#sources.has(name)) {
|
|
13189
|
+
return this.#sources.get(name);
|
|
13190
|
+
}
|
|
13191
|
+
const schema = this.#tables[name];
|
|
13192
|
+
const source = schema ? new MemorySource(name, schema.columns, schema.primaryKey) : void 0;
|
|
13193
|
+
this.#sources.set(name, source);
|
|
13194
|
+
return source;
|
|
13195
|
+
}
|
|
13196
|
+
clear() {
|
|
13197
|
+
this.#sources.clear();
|
|
13198
|
+
}
|
|
13199
|
+
/**
|
|
13200
|
+
* Creates a new IVMSourceBranch that is a copy of the current one.
|
|
13201
|
+
* This is a cheap operation since the b-trees are shared until a write is performed
|
|
13202
|
+
* and then only the modified nodes are copied.
|
|
13203
|
+
*
|
|
13204
|
+
* This is used when:
|
|
13205
|
+
* 1. We need to rebase a change. We fork the `sync` branch and run the mutations against the fork.
|
|
13206
|
+
* 2. We need to create `main` at startup.
|
|
13207
|
+
* 3. We need to create a new `sync` head because we got a new server snapshot.
|
|
13208
|
+
* The old `sync` head is forked and the new server snapshot is applied to the fork.
|
|
13209
|
+
*/
|
|
13210
|
+
fork() {
|
|
13211
|
+
return new _IVMSourceBranch(
|
|
13212
|
+
this.#tables,
|
|
13213
|
+
new Map(
|
|
13214
|
+
wrapIterable(this.#sources.entries()).map(([name, source]) => [
|
|
13215
|
+
name,
|
|
13216
|
+
source?.fork()
|
|
13217
|
+
])
|
|
13218
|
+
)
|
|
13168
13219
|
);
|
|
13169
|
-
yield* conn.filters ? generateWithFilter(withConstraint, conn.filters.predicate) : withConstraint;
|
|
13170
13220
|
}
|
|
13171
|
-
|
|
13172
|
-
|
|
13221
|
+
};
|
|
13222
|
+
|
|
13223
|
+
// ../zero-client/src/client/context.ts
|
|
13224
|
+
var ZeroContext = class {
|
|
13225
|
+
// It is a bummer to have to maintain separate MemorySources here and copy the
|
|
13226
|
+
// data in from the Replicache db. But we want the data to be accessible via
|
|
13227
|
+
// pipelines *synchronously* and the core Replicache infra is all async. So
|
|
13228
|
+
// that needs to be fixed.
|
|
13229
|
+
#mainSources;
|
|
13230
|
+
#addQuery;
|
|
13231
|
+
#batchViewUpdates;
|
|
13232
|
+
#commitListeners = /* @__PURE__ */ new Set();
|
|
13233
|
+
staticQueryParameters = void 0;
|
|
13234
|
+
constructor(mainSources, addQuery, batchViewUpdates) {
|
|
13235
|
+
this.#mainSources = mainSources;
|
|
13236
|
+
this.#addQuery = addQuery;
|
|
13237
|
+
this.#batchViewUpdates = batchViewUpdates;
|
|
13173
13238
|
}
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
}
|
|
13239
|
+
getSource(name) {
|
|
13240
|
+
return this.#mainSources.getSource(name);
|
|
13177
13241
|
}
|
|
13178
|
-
|
|
13179
|
-
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
|
|
13183
|
-
|
|
13184
|
-
|
|
13185
|
-
|
|
13186
|
-
|
|
13187
|
-
|
|
13188
|
-
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
13197
|
-
|
|
13198
|
-
|
|
13199
|
-
|
|
13200
|
-
|
|
13201
|
-
|
|
13202
|
-
|
|
13203
|
-
|
|
13204
|
-
|
|
13205
|
-
|
|
13206
|
-
|
|
13207
|
-
|
|
13208
|
-
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13219
|
-
|
|
13220
|
-
|
|
13221
|
-
|
|
13222
|
-
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
|
|
13232
|
-
|
|
13233
|
-
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
|
|
13237
|
-
|
|
13238
|
-
|
|
13239
|
-
|
|
13240
|
-
|
|
13241
|
-
break;
|
|
13242
|
-
}
|
|
13243
|
-
case "edit": {
|
|
13244
|
-
const removed = data2.delete(change.oldRow);
|
|
13245
|
-
assert(removed);
|
|
13246
|
-
data2.add(change.row);
|
|
13247
|
-
break;
|
|
13242
|
+
addServerQuery(ast, gotCallback) {
|
|
13243
|
+
return this.#addQuery(ast, gotCallback);
|
|
13244
|
+
}
|
|
13245
|
+
createStorage() {
|
|
13246
|
+
return new MemoryStorage();
|
|
13247
|
+
}
|
|
13248
|
+
onTransactionCommit(cb) {
|
|
13249
|
+
this.#commitListeners.add(cb);
|
|
13250
|
+
return () => {
|
|
13251
|
+
this.#commitListeners.delete(cb);
|
|
13252
|
+
};
|
|
13253
|
+
}
|
|
13254
|
+
batchViewUpdates(applyViewUpdates) {
|
|
13255
|
+
let result;
|
|
13256
|
+
let viewChangesPerformed = false;
|
|
13257
|
+
this.#batchViewUpdates(() => {
|
|
13258
|
+
result = applyViewUpdates();
|
|
13259
|
+
viewChangesPerformed = true;
|
|
13260
|
+
});
|
|
13261
|
+
assert(
|
|
13262
|
+
viewChangesPerformed,
|
|
13263
|
+
"batchViewUpdates must call applyViewUpdates synchronously."
|
|
13264
|
+
);
|
|
13265
|
+
return result;
|
|
13266
|
+
}
|
|
13267
|
+
processChanges(changes) {
|
|
13268
|
+
this.batchViewUpdates(() => {
|
|
13269
|
+
try {
|
|
13270
|
+
for (const diff2 of changes) {
|
|
13271
|
+
const { key } = diff2;
|
|
13272
|
+
assert(key.startsWith(ENTITIES_KEY_PREFIX));
|
|
13273
|
+
const name = nameFromKey(key);
|
|
13274
|
+
const source = this.getSource(name);
|
|
13275
|
+
if (!source) {
|
|
13276
|
+
continue;
|
|
13277
|
+
}
|
|
13278
|
+
switch (diff2.op) {
|
|
13279
|
+
case "del":
|
|
13280
|
+
assert(typeof diff2.oldValue === "object");
|
|
13281
|
+
source.push({
|
|
13282
|
+
type: "remove",
|
|
13283
|
+
row: diff2.oldValue
|
|
13284
|
+
});
|
|
13285
|
+
break;
|
|
13286
|
+
case "add":
|
|
13287
|
+
assert(typeof diff2.newValue === "object");
|
|
13288
|
+
source.push({
|
|
13289
|
+
type: "add",
|
|
13290
|
+
row: diff2.newValue
|
|
13291
|
+
});
|
|
13292
|
+
break;
|
|
13293
|
+
case "change":
|
|
13294
|
+
assert(typeof diff2.newValue === "object");
|
|
13295
|
+
assert(typeof diff2.oldValue === "object");
|
|
13296
|
+
source.push({
|
|
13297
|
+
type: "edit",
|
|
13298
|
+
row: diff2.newValue,
|
|
13299
|
+
oldRow: diff2.oldValue
|
|
13300
|
+
});
|
|
13301
|
+
break;
|
|
13302
|
+
default:
|
|
13303
|
+
unreachable(diff2);
|
|
13304
|
+
}
|
|
13248
13305
|
}
|
|
13249
|
-
|
|
13250
|
-
|
|
13306
|
+
} finally {
|
|
13307
|
+
this.#endTransaction();
|
|
13251
13308
|
}
|
|
13252
|
-
}
|
|
13309
|
+
});
|
|
13253
13310
|
}
|
|
13254
|
-
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
if (constraint && !constraintMatchesRow(constraint, node.row)) {
|
|
13258
|
-
break;
|
|
13311
|
+
#endTransaction() {
|
|
13312
|
+
for (const listener of this.#commitListeners) {
|
|
13313
|
+
listener();
|
|
13259
13314
|
}
|
|
13260
|
-
yield node;
|
|
13261
13315
|
}
|
|
13262
|
-
}
|
|
13263
|
-
|
|
13264
|
-
|
|
13265
|
-
|
|
13266
|
-
|
|
13316
|
+
};
|
|
13317
|
+
|
|
13318
|
+
// ../zero-client/src/client/crud.ts
|
|
13319
|
+
function makeCRUDMutate(schema, repMutate) {
|
|
13320
|
+
const { [CRUD_MUTATION_NAME]: zeroCRUD } = repMutate;
|
|
13321
|
+
let inBatch = false;
|
|
13322
|
+
const mutateBatch = async (body) => {
|
|
13323
|
+
if (inBatch) {
|
|
13324
|
+
throw new Error("Cannot call mutate inside a batch");
|
|
13267
13325
|
}
|
|
13268
|
-
|
|
13269
|
-
|
|
13270
|
-
|
|
13271
|
-
|
|
13272
|
-
|
|
13273
|
-
|
|
13274
|
-
}
|
|
13275
|
-
let started = false;
|
|
13276
|
-
for (const node of nodes) {
|
|
13277
|
-
if (!started) {
|
|
13278
|
-
if (start.basis === "at") {
|
|
13279
|
-
if (compare(node.row, start.row) >= 0) {
|
|
13280
|
-
started = true;
|
|
13281
|
-
}
|
|
13282
|
-
} else if (start.basis === "after") {
|
|
13283
|
-
if (compare(node.row, start.row) > 0) {
|
|
13284
|
-
started = true;
|
|
13285
|
-
}
|
|
13326
|
+
inBatch = true;
|
|
13327
|
+
try {
|
|
13328
|
+
const ops = [];
|
|
13329
|
+
const m = {};
|
|
13330
|
+
for (const name of Object.keys(schema.tables)) {
|
|
13331
|
+
m[name] = makeBatchCRUDMutate(name, schema, ops);
|
|
13286
13332
|
}
|
|
13333
|
+
const rv = await body(m);
|
|
13334
|
+
await zeroCRUD({ ops });
|
|
13335
|
+
return rv;
|
|
13336
|
+
} finally {
|
|
13337
|
+
inBatch = false;
|
|
13287
13338
|
}
|
|
13288
|
-
|
|
13289
|
-
|
|
13339
|
+
};
|
|
13340
|
+
const assertNotInBatch = (tableName, op) => {
|
|
13341
|
+
if (inBatch) {
|
|
13342
|
+
throw new Error(`Cannot call mutate.${tableName}.${op} inside a batch`);
|
|
13290
13343
|
}
|
|
13291
|
-
}
|
|
13292
|
-
}
|
|
13293
|
-
function* generateWithOverlay(startAt, rows, constraint, overlay, compare, filterPredicate) {
|
|
13294
|
-
const overlays = computeOverlays(
|
|
13295
|
-
startAt,
|
|
13296
|
-
constraint,
|
|
13297
|
-
overlay,
|
|
13298
|
-
compare,
|
|
13299
|
-
filterPredicate
|
|
13300
|
-
);
|
|
13301
|
-
yield* generateWithOverlayInner(rows, overlays, compare);
|
|
13302
|
-
}
|
|
13303
|
-
function computeOverlays(startAt, constraint, overlay, compare, filterPredicate) {
|
|
13304
|
-
let overlays = {
|
|
13305
|
-
add: void 0,
|
|
13306
|
-
remove: void 0
|
|
13307
13344
|
};
|
|
13308
|
-
|
|
13309
|
-
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
overlays = {
|
|
13317
|
-
add: void 0,
|
|
13318
|
-
remove: overlay.change.row
|
|
13319
|
-
};
|
|
13320
|
-
break;
|
|
13321
|
-
case "edit":
|
|
13322
|
-
overlays = {
|
|
13323
|
-
add: overlay.change.row,
|
|
13324
|
-
remove: overlay.change.oldRow
|
|
13325
|
-
};
|
|
13326
|
-
break;
|
|
13327
|
-
}
|
|
13328
|
-
if (startAt) {
|
|
13329
|
-
overlays = overlaysForStartAt(overlays, startAt, compare);
|
|
13330
|
-
}
|
|
13331
|
-
if (constraint) {
|
|
13332
|
-
overlays = overlaysForConstraint(overlays, constraint);
|
|
13333
|
-
}
|
|
13334
|
-
if (filterPredicate) {
|
|
13335
|
-
overlays = overlaysForFilterPredicate(overlays, filterPredicate);
|
|
13345
|
+
const mutate = {};
|
|
13346
|
+
for (const [name, tableSchema] of Object.entries(schema.tables)) {
|
|
13347
|
+
mutate[name] = makeEntityCRUDMutate(
|
|
13348
|
+
name,
|
|
13349
|
+
tableSchema.primaryKey,
|
|
13350
|
+
zeroCRUD,
|
|
13351
|
+
assertNotInBatch
|
|
13352
|
+
);
|
|
13336
13353
|
}
|
|
13337
|
-
return overlays;
|
|
13338
|
-
}
|
|
13339
|
-
function overlaysForStartAt({ add, remove }, startAt, compare) {
|
|
13340
|
-
const undefinedIfBeforeStartAt = (row) => row === void 0 || compare(row, startAt) < 0 ? void 0 : row;
|
|
13341
13354
|
return {
|
|
13342
|
-
|
|
13343
|
-
|
|
13355
|
+
mutate,
|
|
13356
|
+
mutateBatch
|
|
13344
13357
|
};
|
|
13345
13358
|
}
|
|
13346
|
-
function
|
|
13347
|
-
const undefinedIfDoesntMatchConstraint = (row) => row === void 0 || !constraintMatchesRow(constraint, row) ? void 0 : row;
|
|
13359
|
+
function makeEntityCRUDMutate(tableName, primaryKey, zeroCRUD, assertNotInBatch) {
|
|
13348
13360
|
return {
|
|
13349
|
-
|
|
13350
|
-
|
|
13361
|
+
insert: (value) => {
|
|
13362
|
+
assertNotInBatch(tableName, "insert");
|
|
13363
|
+
const op = {
|
|
13364
|
+
op: "insert",
|
|
13365
|
+
tableName,
|
|
13366
|
+
primaryKey,
|
|
13367
|
+
value
|
|
13368
|
+
};
|
|
13369
|
+
return zeroCRUD({ ops: [op] });
|
|
13370
|
+
},
|
|
13371
|
+
upsert: (value) => {
|
|
13372
|
+
assertNotInBatch(tableName, "upsert");
|
|
13373
|
+
const op = {
|
|
13374
|
+
op: "upsert",
|
|
13375
|
+
tableName,
|
|
13376
|
+
primaryKey,
|
|
13377
|
+
value
|
|
13378
|
+
};
|
|
13379
|
+
return zeroCRUD({ ops: [op] });
|
|
13380
|
+
},
|
|
13381
|
+
update: (value) => {
|
|
13382
|
+
assertNotInBatch(tableName, "update");
|
|
13383
|
+
const op = {
|
|
13384
|
+
op: "update",
|
|
13385
|
+
tableName,
|
|
13386
|
+
primaryKey,
|
|
13387
|
+
value
|
|
13388
|
+
};
|
|
13389
|
+
return zeroCRUD({ ops: [op] });
|
|
13390
|
+
},
|
|
13391
|
+
delete: (id) => {
|
|
13392
|
+
assertNotInBatch(tableName, "delete");
|
|
13393
|
+
const op = {
|
|
13394
|
+
op: "delete",
|
|
13395
|
+
tableName,
|
|
13396
|
+
primaryKey,
|
|
13397
|
+
value: id
|
|
13398
|
+
};
|
|
13399
|
+
return zeroCRUD({ ops: [op] });
|
|
13400
|
+
}
|
|
13351
13401
|
};
|
|
13352
13402
|
}
|
|
13353
|
-
function
|
|
13354
|
-
const
|
|
13403
|
+
function makeBatchCRUDMutate(tableName, schema, ops) {
|
|
13404
|
+
const { primaryKey } = schema.tables[tableName];
|
|
13355
13405
|
return {
|
|
13356
|
-
|
|
13357
|
-
|
|
13406
|
+
insert: (value) => {
|
|
13407
|
+
const op = {
|
|
13408
|
+
op: "insert",
|
|
13409
|
+
tableName,
|
|
13410
|
+
primaryKey,
|
|
13411
|
+
value
|
|
13412
|
+
};
|
|
13413
|
+
ops.push(op);
|
|
13414
|
+
return promiseVoid;
|
|
13415
|
+
},
|
|
13416
|
+
upsert: (value) => {
|
|
13417
|
+
const op = {
|
|
13418
|
+
op: "upsert",
|
|
13419
|
+
tableName,
|
|
13420
|
+
primaryKey,
|
|
13421
|
+
value
|
|
13422
|
+
};
|
|
13423
|
+
ops.push(op);
|
|
13424
|
+
return promiseVoid;
|
|
13425
|
+
},
|
|
13426
|
+
update: (value) => {
|
|
13427
|
+
const op = {
|
|
13428
|
+
op: "update",
|
|
13429
|
+
tableName,
|
|
13430
|
+
primaryKey,
|
|
13431
|
+
value
|
|
13432
|
+
};
|
|
13433
|
+
ops.push(op);
|
|
13434
|
+
return promiseVoid;
|
|
13435
|
+
},
|
|
13436
|
+
delete: (id) => {
|
|
13437
|
+
const op = {
|
|
13438
|
+
op: "delete",
|
|
13439
|
+
tableName,
|
|
13440
|
+
primaryKey,
|
|
13441
|
+
value: id
|
|
13442
|
+
};
|
|
13443
|
+
ops.push(op);
|
|
13444
|
+
return promiseVoid;
|
|
13445
|
+
}
|
|
13358
13446
|
};
|
|
13359
13447
|
}
|
|
13360
|
-
function
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
|
|
13364
|
-
|
|
13365
|
-
|
|
13366
|
-
|
|
13367
|
-
|
|
13368
|
-
|
|
13448
|
+
function makeCRUDMutator(schema) {
|
|
13449
|
+
return async function zeroCRUDMutator(tx, crudArg) {
|
|
13450
|
+
for (const op of crudArg.ops) {
|
|
13451
|
+
switch (op.op) {
|
|
13452
|
+
case "insert":
|
|
13453
|
+
await insertImpl(tx, op, schema, void 0);
|
|
13454
|
+
break;
|
|
13455
|
+
case "upsert":
|
|
13456
|
+
await upsertImpl(tx, op, schema, void 0);
|
|
13457
|
+
break;
|
|
13458
|
+
case "update":
|
|
13459
|
+
await updateImpl(tx, op, schema, void 0);
|
|
13460
|
+
break;
|
|
13461
|
+
case "delete":
|
|
13462
|
+
await deleteImpl(tx, op, schema, void 0);
|
|
13463
|
+
break;
|
|
13369
13464
|
}
|
|
13370
13465
|
}
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
|
|
13374
|
-
|
|
13375
|
-
|
|
13376
|
-
|
|
13466
|
+
};
|
|
13467
|
+
}
|
|
13468
|
+
function defaultOptionalFieldsToNull(schema, value) {
|
|
13469
|
+
let rv = value;
|
|
13470
|
+
for (const name in schema.columns) {
|
|
13471
|
+
if (rv[name] === void 0) {
|
|
13472
|
+
rv = { ...rv, [name]: null };
|
|
13377
13473
|
}
|
|
13378
|
-
yield { row, relationships: {} };
|
|
13379
|
-
}
|
|
13380
|
-
if (!addOverlayYielded && overlays.add) {
|
|
13381
|
-
yield { row: overlays.add, relationships: {} };
|
|
13382
13474
|
}
|
|
13475
|
+
return rv;
|
|
13383
13476
|
}
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13477
|
+
async function insertImpl(tx, arg, schema, ivmBranch) {
|
|
13478
|
+
const key = toPrimaryKeyString(
|
|
13479
|
+
arg.tableName,
|
|
13480
|
+
schema.tables[arg.tableName].primaryKey,
|
|
13481
|
+
arg.value
|
|
13482
|
+
);
|
|
13483
|
+
if (!await tx.has(key)) {
|
|
13484
|
+
const val = defaultOptionalFieldsToNull(
|
|
13485
|
+
schema.tables[arg.tableName],
|
|
13486
|
+
arg.value
|
|
13487
|
+
);
|
|
13488
|
+
await tx.set(key, val);
|
|
13489
|
+
if (ivmBranch) {
|
|
13490
|
+
must(ivmBranch.getSource(arg.tableName)).push({
|
|
13491
|
+
type: "add",
|
|
13492
|
+
row: arg.value
|
|
13493
|
+
});
|
|
13394
13494
|
}
|
|
13395
|
-
return 0;
|
|
13396
|
-
};
|
|
13397
|
-
}
|
|
13398
|
-
function compareBounds(a, b) {
|
|
13399
|
-
if (a === b) {
|
|
13400
|
-
return 0;
|
|
13401
13495
|
}
|
|
13402
|
-
|
|
13403
|
-
|
|
13496
|
+
}
|
|
13497
|
+
async function upsertImpl(tx, arg, schema, ivmBranch) {
|
|
13498
|
+
const key = toPrimaryKeyString(
|
|
13499
|
+
arg.tableName,
|
|
13500
|
+
schema.tables[arg.tableName].primaryKey,
|
|
13501
|
+
arg.value
|
|
13502
|
+
);
|
|
13503
|
+
const val = defaultOptionalFieldsToNull(
|
|
13504
|
+
schema.tables[arg.tableName],
|
|
13505
|
+
arg.value
|
|
13506
|
+
);
|
|
13507
|
+
await tx.set(key, val);
|
|
13508
|
+
if (ivmBranch) {
|
|
13509
|
+
must(ivmBranch.getSource(arg.tableName)).push({
|
|
13510
|
+
type: "add",
|
|
13511
|
+
row: arg.value
|
|
13512
|
+
});
|
|
13404
13513
|
}
|
|
13405
|
-
|
|
13406
|
-
|
|
13514
|
+
}
|
|
13515
|
+
async function updateImpl(tx, arg, schema, ivmBranch) {
|
|
13516
|
+
const key = toPrimaryKeyString(
|
|
13517
|
+
arg.tableName,
|
|
13518
|
+
schema.tables[arg.tableName].primaryKey,
|
|
13519
|
+
arg.value
|
|
13520
|
+
);
|
|
13521
|
+
const prev = await tx.get(key);
|
|
13522
|
+
if (prev === void 0) {
|
|
13523
|
+
return;
|
|
13407
13524
|
}
|
|
13408
|
-
|
|
13409
|
-
|
|
13525
|
+
const update = arg.value;
|
|
13526
|
+
const next = { ...prev };
|
|
13527
|
+
for (const k in update) {
|
|
13528
|
+
if (update[k] !== void 0) {
|
|
13529
|
+
next[k] = update[k];
|
|
13530
|
+
}
|
|
13410
13531
|
}
|
|
13411
|
-
|
|
13412
|
-
|
|
13532
|
+
await tx.set(key, next);
|
|
13533
|
+
if (ivmBranch) {
|
|
13534
|
+
must(ivmBranch.getSource(arg.tableName)).push({
|
|
13535
|
+
type: "edit",
|
|
13536
|
+
oldRow: prev,
|
|
13537
|
+
row: next
|
|
13538
|
+
});
|
|
13413
13539
|
}
|
|
13414
|
-
return compareValues(a, b);
|
|
13415
13540
|
}
|
|
13416
|
-
function
|
|
13417
|
-
|
|
13418
|
-
|
|
13541
|
+
async function deleteImpl(tx, arg, schema, ivmBranch) {
|
|
13542
|
+
const key = toPrimaryKeyString(
|
|
13543
|
+
arg.tableName,
|
|
13544
|
+
schema.tables[arg.tableName].primaryKey,
|
|
13545
|
+
arg.value
|
|
13419
13546
|
);
|
|
13420
|
-
|
|
13421
|
-
|
|
13422
|
-
|
|
13423
|
-
var IVMSourceRepo = class {
|
|
13424
|
-
#main;
|
|
13425
|
-
#tables;
|
|
13426
|
-
sync;
|
|
13427
|
-
constructor(tables) {
|
|
13428
|
-
this.#main = new IVMSourceBranch(tables);
|
|
13429
|
-
this.#tables = tables;
|
|
13547
|
+
const prev = await tx.get(key);
|
|
13548
|
+
if (prev === void 0) {
|
|
13549
|
+
return;
|
|
13430
13550
|
}
|
|
13431
|
-
|
|
13432
|
-
|
|
13551
|
+
await tx.del(key);
|
|
13552
|
+
if (ivmBranch) {
|
|
13553
|
+
must(ivmBranch.getSource(arg.tableName)).push({
|
|
13554
|
+
type: "remove",
|
|
13555
|
+
row: prev
|
|
13556
|
+
});
|
|
13433
13557
|
}
|
|
13434
|
-
|
|
13435
|
-
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13558
|
+
}
|
|
13559
|
+
|
|
13560
|
+
// ../zero-client/src/client/custom.ts
|
|
13561
|
+
var TransactionImpl = class {
|
|
13562
|
+
constructor(repTx, schema, ivmSourceRepo) {
|
|
13563
|
+
must(repTx.reason === "initial" || repTx.reason === "rebase");
|
|
13564
|
+
this.clientID = repTx.clientID;
|
|
13565
|
+
this.mutationID = repTx.mutationID;
|
|
13566
|
+
this.reason = repTx.reason === "initial" ? "optimistic" : "rebase";
|
|
13567
|
+
this.mutate = makeSchemaCRUD(
|
|
13568
|
+
schema,
|
|
13569
|
+
repTx,
|
|
13570
|
+
// Mutators do not write to the main IVM sources during optimistic mutations
|
|
13571
|
+
// so we pass undefined here.
|
|
13572
|
+
// ExperimentalWatch handles updating main.
|
|
13573
|
+
this.reason === "optimistic" ? void 0 : ivmSourceRepo.rebase
|
|
13574
|
+
);
|
|
13575
|
+
this.query = makeSchemaQuery(
|
|
13576
|
+
schema,
|
|
13577
|
+
this.reason === "optimistic" ? ivmSourceRepo.main : ivmSourceRepo.rebase
|
|
13578
|
+
);
|
|
13439
13579
|
}
|
|
13580
|
+
clientID;
|
|
13581
|
+
mutationID;
|
|
13582
|
+
reason;
|
|
13583
|
+
mutate;
|
|
13584
|
+
query;
|
|
13440
13585
|
};
|
|
13441
|
-
|
|
13442
|
-
|
|
13443
|
-
|
|
13444
|
-
|
|
13445
|
-
|
|
13446
|
-
|
|
13586
|
+
function makeReplicacheMutator(mutator, schema, ivmSourceRepo) {
|
|
13587
|
+
return (repTx, args) => {
|
|
13588
|
+
const tx = new TransactionImpl(repTx, schema, ivmSourceRepo);
|
|
13589
|
+
return mutator(tx, args);
|
|
13590
|
+
};
|
|
13591
|
+
}
|
|
13592
|
+
function makeSchemaQuery(schema, ivmBranch) {
|
|
13593
|
+
const rv = {};
|
|
13594
|
+
const context = new ZeroContext(
|
|
13595
|
+
ivmBranch,
|
|
13596
|
+
() => () => {
|
|
13597
|
+
},
|
|
13598
|
+
(applyViewUpdates) => applyViewUpdates()
|
|
13599
|
+
);
|
|
13600
|
+
for (const name of Object.keys(schema.tables)) {
|
|
13601
|
+
rv[name] = newQuery(context, schema, name);
|
|
13447
13602
|
}
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13452
|
-
|
|
13453
|
-
|
|
13454
|
-
this.#sources.set(name, source);
|
|
13455
|
-
return source;
|
|
13603
|
+
return rv;
|
|
13604
|
+
}
|
|
13605
|
+
function makeSchemaCRUD(schema, tx, ivmBranch) {
|
|
13606
|
+
const mutate = {};
|
|
13607
|
+
for (const [name] of Object.entries(schema.tables)) {
|
|
13608
|
+
mutate[name] = makeTableCRUD(schema, name, tx, ivmBranch);
|
|
13456
13609
|
}
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
)
|
|
13610
|
+
return mutate;
|
|
13611
|
+
}
|
|
13612
|
+
function makeTableCRUD(schema, tableName, tx, ivmBranch) {
|
|
13613
|
+
const table2 = must(schema.tables[tableName]);
|
|
13614
|
+
const { primaryKey } = table2;
|
|
13615
|
+
return {
|
|
13616
|
+
insert: (value) => insertImpl(
|
|
13617
|
+
tx,
|
|
13618
|
+
{ op: "insert", tableName, primaryKey, value },
|
|
13619
|
+
schema,
|
|
13620
|
+
ivmBranch
|
|
13621
|
+
),
|
|
13622
|
+
upsert: (value) => upsertImpl(
|
|
13623
|
+
tx,
|
|
13624
|
+
{ op: "upsert", tableName, primaryKey, value },
|
|
13625
|
+
schema,
|
|
13626
|
+
ivmBranch
|
|
13627
|
+
),
|
|
13628
|
+
update: (value) => updateImpl(
|
|
13629
|
+
tx,
|
|
13630
|
+
{ op: "update", tableName, primaryKey, value },
|
|
13631
|
+
schema,
|
|
13632
|
+
ivmBranch
|
|
13633
|
+
),
|
|
13634
|
+
delete: (id) => deleteImpl(
|
|
13635
|
+
tx,
|
|
13636
|
+
{ op: "delete", tableName, primaryKey, value: id },
|
|
13637
|
+
schema,
|
|
13638
|
+
ivmBranch
|
|
13639
|
+
)
|
|
13640
|
+
};
|
|
13641
|
+
}
|
|
13642
|
+
|
|
13643
|
+
// ../zero-client/src/client/enable-analytics.ts
|
|
13644
|
+
var IPV4_ADDRESS_REGEX = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
13645
|
+
var IPV6_ADDRESS_HOSTNAME_REGEX = /^\[[a-fA-F0-9:]*:[a-fA-F0-9:]*\]$/;
|
|
13646
|
+
var IP_ADDRESS_HOSTNAME_REGEX = new RegExp(
|
|
13647
|
+
`(${IPV4_ADDRESS_REGEX.source}|${IPV6_ADDRESS_HOSTNAME_REGEX.source})`
|
|
13648
|
+
);
|
|
13649
|
+
function shouldEnableAnalytics(server, enableAnalytics = true) {
|
|
13650
|
+
if (!enableAnalytics) {
|
|
13651
|
+
return false;
|
|
13476
13652
|
}
|
|
13477
|
-
|
|
13653
|
+
const serverURL = server === null ? null : new URL(server);
|
|
13654
|
+
const socketHostname = serverURL?.hostname;
|
|
13655
|
+
return server !== null && socketHostname !== void 0 && socketHostname !== "localhost" && !IP_ADDRESS_HOSTNAME_REGEX.test(socketHostname);
|
|
13656
|
+
}
|
|
13657
|
+
|
|
13658
|
+
// ../zero-client/src/client/http-string.ts
|
|
13659
|
+
function toWSString(url) {
|
|
13660
|
+
return "ws" + url.slice(4);
|
|
13661
|
+
}
|
|
13662
|
+
function appendPath(url, toAppend) {
|
|
13663
|
+
return url + (url.endsWith("/") ? toAppend.substring(1) : toAppend);
|
|
13664
|
+
}
|
|
13478
13665
|
|
|
13479
13666
|
// ../zero-client/src/client/log-options.ts
|
|
13480
13667
|
import {
|
|
@@ -13701,7 +13888,7 @@ function makeMessage(message, context, logLevel) {
|
|
|
13701
13888
|
}
|
|
13702
13889
|
|
|
13703
13890
|
// ../zero-client/src/client/version.ts
|
|
13704
|
-
var version2 = "0.13.
|
|
13891
|
+
var version2 = "0.13.2025020501";
|
|
13705
13892
|
|
|
13706
13893
|
// ../zero-client/src/client/log-options.ts
|
|
13707
13894
|
var LevelFilterLogSink = class {
|
|
@@ -14900,7 +15087,7 @@ var Zero = class {
|
|
|
14900
15087
|
});
|
|
14901
15088
|
this.#metrics.tags.push(`version:${this.version}`);
|
|
14902
15089
|
this.#pokeHandler = new PokeHandler(
|
|
14903
|
-
(poke) => this.#rep.poke(poke),
|
|
15090
|
+
(poke) => this.#rep.poke(poke, this.#ivmSources.advanceSyncHead),
|
|
14904
15091
|
() => this.#onPokeError(),
|
|
14905
15092
|
rep.clientID,
|
|
14906
15093
|
schema,
|
|
@@ -15813,4 +16000,4 @@ export {
|
|
|
15813
16000
|
escapeLike,
|
|
15814
16001
|
Zero
|
|
15815
16002
|
};
|
|
15816
|
-
//# sourceMappingURL=chunk-
|
|
16003
|
+
//# sourceMappingURL=chunk-453TFLSU.js.map
|