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