dexie-cloud-addon 4.1.0-beta.39 → 4.1.0-beta.41

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.
@@ -1,4 +1,3 @@
1
1
  import dexieCloudAddon from './dexie-cloud-client';
2
2
  export * from './dexie-cloud-client';
3
- export { defineYDocTrigger } from './define-ydoc-trigger';
4
3
  export default dexieCloudAddon;
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * ==========================================================================
10
10
  *
11
- * Version 4.1.0-beta.39, Mon Jan 20 2025
11
+ * Version 4.1.0-beta.41, Wed Jan 29 2025
12
12
  *
13
13
  * https://dexie.org
14
14
  *
@@ -8128,6 +8128,162 @@
8128
8128
  return realmId.startsWith('rlm~') ? realmId.substr(4) : null;
8129
8129
  }
8130
8130
 
8131
+ const ydocTriggers = {};
8132
+ const docIsAlreadyHooked = new WeakSet();
8133
+ const middlewares = new WeakMap();
8134
+ const createMiddleware = (db) => ({
8135
+ stack: 'dbcore',
8136
+ level: 10,
8137
+ name: 'yTriggerMiddleware',
8138
+ create: (down) => {
8139
+ return Object.assign(Object.assign({}, down), { transaction: (stores, mode, options) => {
8140
+ const idbtrans = down.transaction(stores, mode, options);
8141
+ idbtrans.addEventListener('complete', onTransactionCommitted);
8142
+ return idbtrans;
8143
+ }, table: (tblName) => {
8144
+ const coreTable = down.table(tblName);
8145
+ const triggerSpec = ydocTriggers[tblName];
8146
+ if (!triggerSpec)
8147
+ return coreTable;
8148
+ const { trigger, parentTable, prop } = triggerSpec;
8149
+ return Object.assign(Object.assign({}, coreTable), { mutate(req) {
8150
+ switch (req.type) {
8151
+ case 'add': {
8152
+ for (const yUpdateRow of req.values) {
8153
+ if (yUpdateRow.k == undefined)
8154
+ continue; // A syncer or garbage collection state does not point to a key
8155
+ const primaryKey = yUpdateRow.k;
8156
+ const doc = Dexie.DexieYProvider.getDocCache(db).find(parentTable, primaryKey, prop);
8157
+ if (doc) {
8158
+ if (!docIsAlreadyHooked.has(doc)) {
8159
+ hookToDoc(doc, primaryKey, trigger);
8160
+ docIsAlreadyHooked.add(doc);
8161
+ }
8162
+ }
8163
+ else {
8164
+ enqueueTrigger(db, tblName, primaryKey, trigger);
8165
+ }
8166
+ }
8167
+ break;
8168
+ }
8169
+ case 'delete':
8170
+ // @ts-ignore
8171
+ if (req.trans._rejecting_y_ypdate) {
8172
+ // The deletion came from a rejection, not garbage collection.
8173
+ // When that happens, let the triggers run to compute new values
8174
+ // based on the deleted updates.
8175
+ coreTable
8176
+ .getMany({
8177
+ keys: req.keys,
8178
+ trans: req.trans,
8179
+ cache: 'immutable',
8180
+ })
8181
+ .then((updates) => {
8182
+ const keySet = new Dexie.RangeSet();
8183
+ for (const { k } of updates) {
8184
+ if (k != undefined)
8185
+ keySet.addKey(k);
8186
+ }
8187
+ for (const interval of keySet) {
8188
+ enqueueTrigger(db, tblName, interval.from, trigger);
8189
+ }
8190
+ });
8191
+ }
8192
+ break;
8193
+ }
8194
+ return coreTable.mutate(req);
8195
+ } });
8196
+ } });
8197
+ },
8198
+ });
8199
+ let triggerExecPromise = null;
8200
+ let triggerScheduled = false;
8201
+ let scheduledTriggers = [];
8202
+ function $Y(db) {
8203
+ const $Y = db._options.Y;
8204
+ if (!$Y)
8205
+ throw new Error('Y library not supplied to Dexie constructor');
8206
+ return $Y;
8207
+ }
8208
+ function executeTriggers(triggersToRun) {
8209
+ return __awaiter(this, void 0, void 0, function* () {
8210
+ for (const { db, parentId, trigger, updatesTable } of triggersToRun) {
8211
+ // Load entire document into an Y.Doc instance:
8212
+ const updates = yield db
8213
+ .table(updatesTable)
8214
+ .where({ k: parentId })
8215
+ .toArray();
8216
+ const Y = $Y(db);
8217
+ const yDoc = new Y.Doc();
8218
+ for (const update of updates) {
8219
+ Y.applyUpdateV2(yDoc, update.u);
8220
+ }
8221
+ try {
8222
+ yield trigger(yDoc, parentId);
8223
+ }
8224
+ catch (error) {
8225
+ console.error(`Error in YDocTrigger ${error}`);
8226
+ }
8227
+ }
8228
+ });
8229
+ }
8230
+ function enqueueTrigger(db, updatesTable, parentId, trigger) {
8231
+ scheduledTriggers.push({
8232
+ db,
8233
+ updatesTable,
8234
+ parentId,
8235
+ trigger,
8236
+ });
8237
+ }
8238
+ function onTransactionCommitted() {
8239
+ return __awaiter(this, void 0, void 0, function* () {
8240
+ if (!triggerScheduled && scheduledTriggers.length > 0) {
8241
+ triggerScheduled = true;
8242
+ if (triggerExecPromise)
8243
+ yield triggerExecPromise.catch(() => { });
8244
+ setTimeout(() => {
8245
+ // setTimeout() is to escape from Promise.PSD zones and never run within liveQueries or transaction scopes
8246
+ triggerScheduled = false;
8247
+ const triggersToRun = scheduledTriggers;
8248
+ scheduledTriggers = [];
8249
+ triggerExecPromise = executeTriggers(triggersToRun).finally(() => (triggerExecPromise = null));
8250
+ }, 0);
8251
+ }
8252
+ });
8253
+ }
8254
+ function hookToDoc(doc, parentId, trigger) {
8255
+ // From now on, keep listening to doc updates and execute the trigger when it happens there instead
8256
+ doc.on('updateV2', (update, origin) => {
8257
+ //Dexie.ignoreTransaction(()=>{
8258
+ trigger(doc, parentId);
8259
+ //});
8260
+ });
8261
+ /*
8262
+ NOT NEEDED because DexieYProvider's docCache will also listen to destroy and remove it from its cache:
8263
+ doc.on('destroy', ()=>{
8264
+ docIsAlreadyHooked.delete(doc);
8265
+ })
8266
+ */
8267
+ }
8268
+ function defineYDocTrigger(table, prop, trigger) {
8269
+ var _a, _b;
8270
+ const updatesTable = (_b = (_a = table.schema.yProps) === null || _a === void 0 ? void 0 : _a.find((p) => p.prop === prop)) === null || _b === void 0 ? void 0 : _b.updatesTable;
8271
+ if (!updatesTable)
8272
+ throw new Error(`Table ${table.name} does not have a Yjs property named ${prop}`);
8273
+ ydocTriggers[updatesTable] = {
8274
+ trigger,
8275
+ parentTable: table.name,
8276
+ prop,
8277
+ };
8278
+ const db = table.db._novip;
8279
+ let mw = middlewares.get(db);
8280
+ if (!mw) {
8281
+ mw = createMiddleware(db);
8282
+ middlewares.set(db, mw);
8283
+ }
8284
+ db.use(mw);
8285
+ }
8286
+
8131
8287
  const DEFAULT_OPTIONS = {
8132
8288
  nameSuffix: true,
8133
8289
  };
@@ -8168,7 +8324,7 @@
8168
8324
  const syncComplete = new rxjs.Subject();
8169
8325
  dexie.cloud = {
8170
8326
  // @ts-ignore
8171
- version: "4.1.0-beta.39",
8327
+ version: "4.1.0-beta.41",
8172
8328
  options: Object.assign({}, DEFAULT_OPTIONS),
8173
8329
  schema: null,
8174
8330
  get currentUserId() {
@@ -8486,165 +8642,9 @@
8486
8642
  }
8487
8643
  }
8488
8644
  // @ts-ignore
8489
- dexieCloud.version = "4.1.0-beta.39";
8645
+ dexieCloud.version = "4.1.0-beta.41";
8490
8646
  Dexie.Cloud = dexieCloud;
8491
8647
 
8492
- const ydocTriggers = {};
8493
- const docIsAlreadyHooked = new WeakSet();
8494
- const middlewares = new WeakMap();
8495
- const createMiddleware = (db) => ({
8496
- stack: 'dbcore',
8497
- level: 10,
8498
- name: 'yTriggerMiddleware',
8499
- create: (down) => {
8500
- return Object.assign(Object.assign({}, down), { transaction: (stores, mode, options) => {
8501
- const idbtrans = down.transaction(stores, mode, options);
8502
- idbtrans.addEventListener('complete', onTransactionCommitted);
8503
- return idbtrans;
8504
- }, table: (tblName) => {
8505
- const coreTable = down.table(tblName);
8506
- const triggerSpec = ydocTriggers[tblName];
8507
- if (!triggerSpec)
8508
- return coreTable;
8509
- const { trigger, parentTable, prop } = triggerSpec;
8510
- return Object.assign(Object.assign({}, coreTable), { mutate(req) {
8511
- switch (req.type) {
8512
- case 'add': {
8513
- for (const yUpdateRow of req.values) {
8514
- if (yUpdateRow.k == undefined)
8515
- continue; // A syncer or garbage collection state does not point to a key
8516
- const primaryKey = yUpdateRow.k;
8517
- const doc = Dexie.DexieYProvider.getDocCache(db).find(parentTable, primaryKey, prop);
8518
- if (doc) {
8519
- if (!docIsAlreadyHooked.has(doc)) {
8520
- hookToDoc(doc, primaryKey, trigger);
8521
- docIsAlreadyHooked.add(doc);
8522
- }
8523
- }
8524
- else {
8525
- enqueueTrigger(db, tblName, primaryKey, trigger);
8526
- }
8527
- }
8528
- break;
8529
- }
8530
- case 'delete':
8531
- // @ts-ignore
8532
- if (req.trans._rejecting_y_ypdate) {
8533
- // The deletion came from a rejection, not garbage collection.
8534
- // When that happens, let the triggers run to compute new values
8535
- // based on the deleted updates.
8536
- coreTable
8537
- .getMany({
8538
- keys: req.keys,
8539
- trans: req.trans,
8540
- cache: 'immutable',
8541
- })
8542
- .then((updates) => {
8543
- const keySet = new Dexie.RangeSet();
8544
- for (const { k } of updates) {
8545
- if (k != undefined)
8546
- keySet.addKey(k);
8547
- }
8548
- for (const interval of keySet) {
8549
- enqueueTrigger(db, tblName, interval.from, trigger);
8550
- }
8551
- });
8552
- }
8553
- break;
8554
- }
8555
- return coreTable.mutate(req);
8556
- } });
8557
- } });
8558
- },
8559
- });
8560
- let triggerExecPromise = null;
8561
- let triggerScheduled = false;
8562
- let scheduledTriggers = [];
8563
- function $Y(db) {
8564
- const $Y = db._options.Y;
8565
- if (!$Y)
8566
- throw new Error('Y library not supplied to Dexie constructor');
8567
- return $Y;
8568
- }
8569
- function executeTriggers(triggersToRun) {
8570
- return __awaiter(this, void 0, void 0, function* () {
8571
- for (const { db, parentId, trigger, updatesTable } of triggersToRun) {
8572
- // Load entire document into an Y.Doc instance:
8573
- const updates = yield db
8574
- .table(updatesTable)
8575
- .where({ k: parentId })
8576
- .toArray();
8577
- const Y = $Y(db);
8578
- const yDoc = new Y.Doc();
8579
- for (const update of updates) {
8580
- Y.applyUpdateV2(yDoc, update.u);
8581
- }
8582
- try {
8583
- yield trigger(yDoc, parentId);
8584
- }
8585
- catch (error) {
8586
- console.error(`Error in YDocTrigger ${error}`);
8587
- }
8588
- }
8589
- });
8590
- }
8591
- function enqueueTrigger(db, updatesTable, parentId, trigger) {
8592
- scheduledTriggers.push({
8593
- db,
8594
- updatesTable,
8595
- parentId,
8596
- trigger,
8597
- });
8598
- }
8599
- function onTransactionCommitted() {
8600
- return __awaiter(this, void 0, void 0, function* () {
8601
- if (!triggerScheduled && scheduledTriggers.length > 0) {
8602
- triggerScheduled = true;
8603
- if (triggerExecPromise)
8604
- yield triggerExecPromise.catch(() => { });
8605
- setTimeout(() => {
8606
- // setTimeout() is to escape from Promise.PSD zones and never run within liveQueries or transaction scopes
8607
- triggerScheduled = false;
8608
- const triggersToRun = scheduledTriggers;
8609
- scheduledTriggers = [];
8610
- triggerExecPromise = executeTriggers(triggersToRun).finally(() => (triggerExecPromise = null));
8611
- }, 0);
8612
- }
8613
- });
8614
- }
8615
- function hookToDoc(doc, parentId, trigger) {
8616
- // From now on, keep listening to doc updates and execute the trigger when it happens there instead
8617
- doc.on('updateV2', (update, origin) => {
8618
- //Dexie.ignoreTransaction(()=>{
8619
- trigger(doc, parentId);
8620
- //});
8621
- });
8622
- /*
8623
- NOT NEEDED because DexieYProvider's docCache will also listen to destroy and remove it from its cache:
8624
- doc.on('destroy', ()=>{
8625
- docIsAlreadyHooked.delete(doc);
8626
- })
8627
- */
8628
- }
8629
- function defineYDocTrigger(table, prop, trigger) {
8630
- var _a, _b;
8631
- const updatesTable = (_b = (_a = table.schema.yProps) === null || _a === void 0 ? void 0 : _a.find((p) => p.prop === prop)) === null || _b === void 0 ? void 0 : _b.updatesTable;
8632
- if (!updatesTable)
8633
- throw new Error(`Table ${table.name} does not have a Yjs property named ${prop}`);
8634
- ydocTriggers[updatesTable] = {
8635
- trigger,
8636
- parentTable: table.name,
8637
- prop,
8638
- };
8639
- const db = table.db._novip;
8640
- let mw = middlewares.get(db);
8641
- if (!mw) {
8642
- mw = createMiddleware(db);
8643
- middlewares.set(db, mw);
8644
- }
8645
- db.use(mw);
8646
- }
8647
-
8648
8648
  exports.default = dexieCloud;
8649
8649
  exports.defineYDocTrigger = defineYDocTrigger;
8650
8650
  exports.dexieCloud = dexieCloud;