dexie-cloud-addon 4.1.0-beta.41 → 4.1.0-beta.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modern/dexie-cloud-addon.js +137 -107
- package/dist/modern/dexie-cloud-addon.js.map +1 -1
- package/dist/modern/dexie-cloud-addon.min.js +1 -1
- package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
- package/dist/modern/helpers/dbOnClosed.d.ts +2 -0
- package/dist/modern/service-worker.js +54 -24
- package/dist/modern/service-worker.js.map +1 -1
- package/dist/modern/service-worker.min.js +1 -1
- package/dist/modern/service-worker.min.js.map +1 -1
- package/dist/umd/dexie-cloud-addon.js +137 -107
- package/dist/umd/dexie-cloud-addon.js.map +1 -1
- package/dist/umd/dexie-cloud-addon.min.js +1 -1
- package/dist/umd/dexie-cloud-addon.min.js.map +1 -1
- package/dist/umd/helpers/dbOnClosed.d.ts +2 -0
- package/dist/umd/service-worker.js +54 -24
- package/dist/umd/service-worker.js.map +1 -1
- package/dist/umd/service-worker.min.js +1 -1
- package/dist/umd/service-worker.min.js.map +1 -1
- package/package.json +3 -3
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* ==========================================================================
|
|
10
10
|
*
|
|
11
|
-
* Version 4.1.0-beta.
|
|
11
|
+
* Version 4.1.0-beta.43, Fri Feb 07 2025
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -3035,19 +3035,25 @@ function triggerSync(db, purpose) {
|
|
|
3035
3035
|
}
|
|
3036
3036
|
}
|
|
3037
3037
|
|
|
3038
|
+
const hasArrayBufferB64 = "fromBase64" in Uint8Array; // https://github.com/tc39/proposal-arraybuffer-base64;
|
|
3038
3039
|
const b64decode = typeof Buffer !== "undefined"
|
|
3039
|
-
? (base64) => Buffer.from(base64, "base64")
|
|
3040
|
-
:
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3040
|
+
? (base64) => Buffer.from(base64, "base64") // Node
|
|
3041
|
+
: hasArrayBufferB64
|
|
3042
|
+
? // @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64
|
|
3043
|
+
(base64) => Uint8Array.fromBase64(base64) // Modern javascript standard
|
|
3044
|
+
: (base64) => {
|
|
3045
|
+
// Legacy DOM workaround
|
|
3046
|
+
const binary_string = atob(base64);
|
|
3047
|
+
const len = binary_string.length;
|
|
3048
|
+
const bytes = new Uint8Array(len);
|
|
3049
|
+
for (var i = 0; i < len; i++) {
|
|
3050
|
+
bytes[i] = binary_string.charCodeAt(i);
|
|
3051
|
+
}
|
|
3052
|
+
return bytes;
|
|
3053
|
+
};
|
|
3049
3054
|
const b64encode = typeof Buffer !== "undefined"
|
|
3050
3055
|
? (b) => {
|
|
3056
|
+
// Node
|
|
3051
3057
|
if (ArrayBuffer.isView(b)) {
|
|
3052
3058
|
return Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString("base64");
|
|
3053
3059
|
}
|
|
@@ -3055,16 +3061,20 @@ const b64encode = typeof Buffer !== "undefined"
|
|
|
3055
3061
|
return Buffer.from(b).toString("base64");
|
|
3056
3062
|
}
|
|
3057
3063
|
}
|
|
3058
|
-
:
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
const
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3064
|
+
: hasArrayBufferB64
|
|
3065
|
+
? // @ts-ignore https://github.com/tc39/proposal-arraybuffer-base64
|
|
3066
|
+
(b) => b.toBase64() // Modern Javascript standard
|
|
3067
|
+
: (b) => {
|
|
3068
|
+
// Legacy DOM workaround
|
|
3069
|
+
const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);
|
|
3070
|
+
const CHUNK_SIZE = 0x1000;
|
|
3071
|
+
const strs = [];
|
|
3072
|
+
for (let i = 0, l = u8a.length; i < l; i += CHUNK_SIZE) {
|
|
3073
|
+
const chunk = u8a.subarray(i, i + CHUNK_SIZE);
|
|
3074
|
+
strs.push(String.fromCharCode.apply(null, chunk));
|
|
3075
|
+
}
|
|
3076
|
+
return btoa(strs.join(""));
|
|
3077
|
+
};
|
|
3068
3078
|
|
|
3069
3079
|
class TokenErrorResponseError extends Error {
|
|
3070
3080
|
constructor({ title, message, messageCode, messageParams, }) {
|
|
@@ -4551,6 +4561,26 @@ var undefinedDef = {
|
|
|
4551
4561
|
},
|
|
4552
4562
|
};
|
|
4553
4563
|
|
|
4564
|
+
var FileDef = {
|
|
4565
|
+
File: {
|
|
4566
|
+
test: (file, toStringTag) => toStringTag === "File",
|
|
4567
|
+
replace: (file) => ({
|
|
4568
|
+
$t: "File",
|
|
4569
|
+
v: b64encode(string2ArrayBuffer(readBlobSync(file))),
|
|
4570
|
+
type: file.type,
|
|
4571
|
+
name: file.name,
|
|
4572
|
+
lastModified: new Date(file.lastModified).toISOString(),
|
|
4573
|
+
}),
|
|
4574
|
+
revive: ({ type, v, name, lastModified }) => {
|
|
4575
|
+
const ab = b64decode(v);
|
|
4576
|
+
return new File([ab], name, {
|
|
4577
|
+
type,
|
|
4578
|
+
lastModified: new Date(lastModified).getTime(),
|
|
4579
|
+
});
|
|
4580
|
+
},
|
|
4581
|
+
},
|
|
4582
|
+
};
|
|
4583
|
+
|
|
4554
4584
|
// Since server revisions are stored in bigints, we need to handle clients without
|
|
4555
4585
|
// bigint support to not fail when serverRevision is passed over to client.
|
|
4556
4586
|
// We need to not fail when reviving it and we need to somehow store the information.
|
|
@@ -4586,7 +4616,7 @@ const bigIntDef = hasBigIntSupport
|
|
|
4586
4616
|
revive: ({ v }) => new FakeBigInt(v),
|
|
4587
4617
|
},
|
|
4588
4618
|
};
|
|
4589
|
-
const defs = Object.assign(Object.assign(Object.assign({}, undefinedDef), bigIntDef), { PropModification: {
|
|
4619
|
+
const defs = Object.assign(Object.assign(Object.assign(Object.assign({}, undefinedDef), bigIntDef), FileDef), { PropModification: {
|
|
4590
4620
|
test: (val) => val instanceof PropModification,
|
|
4591
4621
|
replace: (propModification) => {
|
|
4592
4622
|
return Object.assign({ $t: 'PropModification' }, propModification['@@propmod']);
|
|
@@ -4961,7 +4991,7 @@ function listUpdatesSince(yTable, sinceIncluding) {
|
|
|
4961
4991
|
.toArray();
|
|
4962
4992
|
}
|
|
4963
4993
|
|
|
4964
|
-
function $Y
|
|
4994
|
+
function $Y(db) {
|
|
4965
4995
|
const $Y = db.dx._options.Y;
|
|
4966
4996
|
if (!$Y)
|
|
4967
4997
|
throw new Error('Y library not supplied to Dexie constructor');
|
|
@@ -4991,7 +5021,7 @@ function listYClientMessagesAndStateVector(db, tablesToSync) {
|
|
|
4991
5021
|
for (const table of tablesToSync) {
|
|
4992
5022
|
if (table.schema.yProps) {
|
|
4993
5023
|
for (const yProp of table.schema.yProps) {
|
|
4994
|
-
const Y = $Y
|
|
5024
|
+
const Y = $Y(db); // This is how we retrieve the user-provided Y library
|
|
4995
5025
|
const yTable = db.table(yProp.updatesTable); // the updates-table for this combo of table+propName
|
|
4996
5026
|
const syncState = (yield yTable.get(DEXIE_CLOUD_SYNCER_ID));
|
|
4997
5027
|
// unsentFrom = the `i` value of updates that aren't yet sent to server (or at least not acked by the server yet)
|
|
@@ -8106,7 +8136,7 @@ function createAwareness(db, doc, provider) {
|
|
|
8106
8136
|
if (provider.destroyed || currentFlowId !== myFlow || !connected)
|
|
8107
8137
|
return;
|
|
8108
8138
|
if (serverUpdatesSinceLastSync.length > 0) {
|
|
8109
|
-
const Y = $Y
|
|
8139
|
+
const Y = $Y(db); // Get the Yjs library from Dexie constructor options
|
|
8110
8140
|
const mergedUpdate = Y.mergeUpdatesV2(serverUpdatesSinceLastSync.map((update) => update.u));
|
|
8111
8141
|
const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);
|
|
8112
8142
|
docOpenMsg.sv = stateVector;
|
|
@@ -8126,8 +8156,68 @@ function getTiedObjectId(realmId) {
|
|
|
8126
8156
|
}
|
|
8127
8157
|
|
|
8128
8158
|
const ydocTriggers = {};
|
|
8129
|
-
const docIsAlreadyHooked = new WeakSet();
|
|
8130
8159
|
const middlewares = new WeakMap();
|
|
8160
|
+
const txRunner = TriggerRunner("tx");
|
|
8161
|
+
const unloadRunner = TriggerRunner("unload");
|
|
8162
|
+
function TriggerRunner(name) {
|
|
8163
|
+
let triggerExecPromise = null;
|
|
8164
|
+
let triggerScheduled = false;
|
|
8165
|
+
let registry = new Map();
|
|
8166
|
+
function execute(registryCopy) {
|
|
8167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8168
|
+
for (const { db, parentId, triggers, parentTable, prop, } of registryCopy.values()) {
|
|
8169
|
+
const yDoc = DexieYProvider.getOrCreateDocument(db, parentTable, prop, parentId);
|
|
8170
|
+
try {
|
|
8171
|
+
DexieYProvider.load(yDoc); // If doc is open, this would just be a ++refount
|
|
8172
|
+
yield yDoc.whenLoaded; // If doc is loaded, this would resolve immediately
|
|
8173
|
+
for (const trigger of triggers) {
|
|
8174
|
+
yield trigger(yDoc, parentId);
|
|
8175
|
+
}
|
|
8176
|
+
}
|
|
8177
|
+
catch (error) {
|
|
8178
|
+
console.error(`Error in YDocTrigger ${error}`);
|
|
8179
|
+
}
|
|
8180
|
+
finally {
|
|
8181
|
+
DexieYProvider.release(yDoc);
|
|
8182
|
+
}
|
|
8183
|
+
}
|
|
8184
|
+
});
|
|
8185
|
+
}
|
|
8186
|
+
return {
|
|
8187
|
+
name,
|
|
8188
|
+
run() {
|
|
8189
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8190
|
+
if (!triggerScheduled && registry.size > 0) {
|
|
8191
|
+
triggerScheduled = true;
|
|
8192
|
+
if (triggerExecPromise)
|
|
8193
|
+
yield triggerExecPromise.catch(() => { });
|
|
8194
|
+
setTimeout(() => {
|
|
8195
|
+
// setTimeout() is to escape from Promise.PSD zones and never run within liveQueries or transaction scopes
|
|
8196
|
+
triggerScheduled = false;
|
|
8197
|
+
const registryCopy = registry;
|
|
8198
|
+
registry = new Map();
|
|
8199
|
+
triggerExecPromise = execute(registryCopy).finally(() => (triggerExecPromise = null));
|
|
8200
|
+
}, 0);
|
|
8201
|
+
}
|
|
8202
|
+
});
|
|
8203
|
+
},
|
|
8204
|
+
enqueue(db, parentTable, parentId, prop, trigger) {
|
|
8205
|
+
const key = `${db.name}:${parentTable}:${parentId}:${prop}`;
|
|
8206
|
+
let entry = registry.get(key);
|
|
8207
|
+
if (!entry) {
|
|
8208
|
+
entry = {
|
|
8209
|
+
db,
|
|
8210
|
+
parentTable,
|
|
8211
|
+
parentId,
|
|
8212
|
+
prop,
|
|
8213
|
+
triggers: new Set(),
|
|
8214
|
+
};
|
|
8215
|
+
registry.set(key, entry);
|
|
8216
|
+
}
|
|
8217
|
+
entry.triggers.add(trigger);
|
|
8218
|
+
},
|
|
8219
|
+
};
|
|
8220
|
+
}
|
|
8131
8221
|
const createMiddleware = (db) => ({
|
|
8132
8222
|
stack: 'dbcore',
|
|
8133
8223
|
level: 10,
|
|
@@ -8135,15 +8225,20 @@ const createMiddleware = (db) => ({
|
|
|
8135
8225
|
create: (down) => {
|
|
8136
8226
|
return Object.assign(Object.assign({}, down), { transaction: (stores, mode, options) => {
|
|
8137
8227
|
const idbtrans = down.transaction(stores, mode, options);
|
|
8228
|
+
if (mode === 'readonly')
|
|
8229
|
+
return idbtrans;
|
|
8230
|
+
if (!stores.some((store) => ydocTriggers[store]))
|
|
8231
|
+
return idbtrans;
|
|
8138
8232
|
idbtrans.addEventListener('complete', onTransactionCommitted);
|
|
8139
8233
|
return idbtrans;
|
|
8140
|
-
}, table: (
|
|
8141
|
-
const coreTable = down.table(
|
|
8142
|
-
const triggerSpec = ydocTriggers[
|
|
8234
|
+
}, table: (updatesTable) => {
|
|
8235
|
+
const coreTable = down.table(updatesTable);
|
|
8236
|
+
const triggerSpec = ydocTriggers[updatesTable];
|
|
8143
8237
|
if (!triggerSpec)
|
|
8144
8238
|
return coreTable;
|
|
8145
8239
|
const { trigger, parentTable, prop } = triggerSpec;
|
|
8146
8240
|
return Object.assign(Object.assign({}, coreTable), { mutate(req) {
|
|
8241
|
+
var _a;
|
|
8147
8242
|
switch (req.type) {
|
|
8148
8243
|
case 'add': {
|
|
8149
8244
|
for (const yUpdateRow of req.values) {
|
|
@@ -8151,15 +8246,10 @@ const createMiddleware = (db) => ({
|
|
|
8151
8246
|
continue; // A syncer or garbage collection state does not point to a key
|
|
8152
8247
|
const primaryKey = yUpdateRow.k;
|
|
8153
8248
|
const doc = DexieYProvider.getDocCache(db).find(parentTable, primaryKey, prop);
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
}
|
|
8159
|
-
}
|
|
8160
|
-
else {
|
|
8161
|
-
enqueueTrigger(db, tblName, primaryKey, trigger);
|
|
8162
|
-
}
|
|
8249
|
+
const runner = doc && ((_a = DexieYProvider.for(doc)) === null || _a === void 0 ? void 0 : _a.refCount)
|
|
8250
|
+
? unloadRunner // Document is open. Wait with trigger until it's closed.
|
|
8251
|
+
: txRunner; // Document is closed. Run trigger immediately after transaction commits.
|
|
8252
|
+
runner.enqueue(db, parentTable, primaryKey, prop, trigger);
|
|
8163
8253
|
}
|
|
8164
8254
|
break;
|
|
8165
8255
|
}
|
|
@@ -8182,7 +8272,7 @@ const createMiddleware = (db) => ({
|
|
|
8182
8272
|
keySet.addKey(k);
|
|
8183
8273
|
}
|
|
8184
8274
|
for (const interval of keySet) {
|
|
8185
|
-
|
|
8275
|
+
txRunner.enqueue(db, parentTable, interval.from, prop, trigger);
|
|
8186
8276
|
}
|
|
8187
8277
|
});
|
|
8188
8278
|
}
|
|
@@ -8193,74 +8283,11 @@ const createMiddleware = (db) => ({
|
|
|
8193
8283
|
} });
|
|
8194
8284
|
},
|
|
8195
8285
|
});
|
|
8196
|
-
let triggerExecPromise = null;
|
|
8197
|
-
let triggerScheduled = false;
|
|
8198
|
-
let scheduledTriggers = [];
|
|
8199
|
-
function $Y(db) {
|
|
8200
|
-
const $Y = db._options.Y;
|
|
8201
|
-
if (!$Y)
|
|
8202
|
-
throw new Error('Y library not supplied to Dexie constructor');
|
|
8203
|
-
return $Y;
|
|
8204
|
-
}
|
|
8205
|
-
function executeTriggers(triggersToRun) {
|
|
8206
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
8207
|
-
for (const { db, parentId, trigger, updatesTable } of triggersToRun) {
|
|
8208
|
-
// Load entire document into an Y.Doc instance:
|
|
8209
|
-
const updates = yield db
|
|
8210
|
-
.table(updatesTable)
|
|
8211
|
-
.where({ k: parentId })
|
|
8212
|
-
.toArray();
|
|
8213
|
-
const Y = $Y(db);
|
|
8214
|
-
const yDoc = new Y.Doc();
|
|
8215
|
-
for (const update of updates) {
|
|
8216
|
-
Y.applyUpdateV2(yDoc, update.u);
|
|
8217
|
-
}
|
|
8218
|
-
try {
|
|
8219
|
-
yield trigger(yDoc, parentId);
|
|
8220
|
-
}
|
|
8221
|
-
catch (error) {
|
|
8222
|
-
console.error(`Error in YDocTrigger ${error}`);
|
|
8223
|
-
}
|
|
8224
|
-
}
|
|
8225
|
-
});
|
|
8226
|
-
}
|
|
8227
|
-
function enqueueTrigger(db, updatesTable, parentId, trigger) {
|
|
8228
|
-
scheduledTriggers.push({
|
|
8229
|
-
db,
|
|
8230
|
-
updatesTable,
|
|
8231
|
-
parentId,
|
|
8232
|
-
trigger,
|
|
8233
|
-
});
|
|
8234
|
-
}
|
|
8235
8286
|
function onTransactionCommitted() {
|
|
8236
|
-
|
|
8237
|
-
if (!triggerScheduled && scheduledTriggers.length > 0) {
|
|
8238
|
-
triggerScheduled = true;
|
|
8239
|
-
if (triggerExecPromise)
|
|
8240
|
-
yield triggerExecPromise.catch(() => { });
|
|
8241
|
-
setTimeout(() => {
|
|
8242
|
-
// setTimeout() is to escape from Promise.PSD zones and never run within liveQueries or transaction scopes
|
|
8243
|
-
triggerScheduled = false;
|
|
8244
|
-
const triggersToRun = scheduledTriggers;
|
|
8245
|
-
scheduledTriggers = [];
|
|
8246
|
-
triggerExecPromise = executeTriggers(triggersToRun).finally(() => (triggerExecPromise = null));
|
|
8247
|
-
}, 0);
|
|
8248
|
-
}
|
|
8249
|
-
});
|
|
8287
|
+
txRunner.run();
|
|
8250
8288
|
}
|
|
8251
|
-
function
|
|
8252
|
-
|
|
8253
|
-
doc.on('updateV2', (update, origin) => {
|
|
8254
|
-
//Dexie.ignoreTransaction(()=>{
|
|
8255
|
-
trigger(doc, parentId);
|
|
8256
|
-
//});
|
|
8257
|
-
});
|
|
8258
|
-
/*
|
|
8259
|
-
NOT NEEDED because DexieYProvider's docCache will also listen to destroy and remove it from its cache:
|
|
8260
|
-
doc.on('destroy', ()=>{
|
|
8261
|
-
docIsAlreadyHooked.delete(doc);
|
|
8262
|
-
})
|
|
8263
|
-
*/
|
|
8289
|
+
function beforeProviderUnload() {
|
|
8290
|
+
unloadRunner.run();
|
|
8264
8291
|
}
|
|
8265
8292
|
function defineYDocTrigger(table, prop, trigger) {
|
|
8266
8293
|
var _a, _b;
|
|
@@ -8279,6 +8306,9 @@ function defineYDocTrigger(table, prop, trigger) {
|
|
|
8279
8306
|
middlewares.set(db, mw);
|
|
8280
8307
|
}
|
|
8281
8308
|
db.use(mw);
|
|
8309
|
+
{
|
|
8310
|
+
DexieYProvider.on('beforeunload', beforeProviderUnload);
|
|
8311
|
+
}
|
|
8282
8312
|
}
|
|
8283
8313
|
|
|
8284
8314
|
const DEFAULT_OPTIONS = {
|
|
@@ -8321,7 +8351,7 @@ function dexieCloud(dexie) {
|
|
|
8321
8351
|
const syncComplete = new Subject();
|
|
8322
8352
|
dexie.cloud = {
|
|
8323
8353
|
// @ts-ignore
|
|
8324
|
-
version: "4.1.0-beta.
|
|
8354
|
+
version: "4.1.0-beta.43",
|
|
8325
8355
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
8326
8356
|
schema: null,
|
|
8327
8357
|
get currentUserId() {
|
|
@@ -8639,7 +8669,7 @@ function dexieCloud(dexie) {
|
|
|
8639
8669
|
}
|
|
8640
8670
|
}
|
|
8641
8671
|
// @ts-ignore
|
|
8642
|
-
dexieCloud.version = "4.1.0-beta.
|
|
8672
|
+
dexieCloud.version = "4.1.0-beta.43";
|
|
8643
8673
|
Dexie.Cloud = dexieCloud;
|
|
8644
8674
|
|
|
8645
8675
|
export { dexieCloud as default, defineYDocTrigger, dexieCloud, getTiedObjectId, getTiedRealmId, resolveText };
|