remult 3.3.19-next.2 → 3.4.0-next.2

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.
Files changed (58) hide show
  1. package/SseSubscriptionServer.d.ts +2 -0
  2. package/SseSubscriptionServer.js +4 -2
  3. package/esm/SseSubscriptionServer.js +3 -1
  4. package/esm/index.js +6 -7
  5. package/esm/live-query/data-provider-live-query-storage.js +3 -1
  6. package/esm/remult-d1.js +0 -1
  7. package/esm/remult-knex/index.js +2 -112
  8. package/esm/remult-mongo.js +8 -17
  9. package/esm/remult-sqlite-core.js +0 -1
  10. package/esm/server/remult-api-server.js +6 -1
  11. package/esm/src/data-api.js +1 -0
  12. package/esm/src/data-interfaces.js +4 -4
  13. package/esm/src/data-providers/array-entity-data-provider.js +2 -14
  14. package/esm/src/data-providers/json-data-provider.js +2 -2
  15. package/esm/src/data-providers/rest-data-provider.js +12 -11
  16. package/esm/src/data-providers/sql-database.js +43 -110
  17. package/esm/src/live-query/LiveQueryClient.js +163 -52
  18. package/esm/src/live-query/SseSubscriptionClient.js +101 -43
  19. package/esm/src/live-query/SubscriptionChannel.js +37 -3
  20. package/esm/src/live-query/SubscriptionServer.js +11 -3
  21. package/esm/src/remult3/RepositoryImplementation.js +60 -90
  22. package/esm/src/remult3/remult3.js +6 -0
  23. package/index.d.ts +17 -31
  24. package/index.js +2 -5
  25. package/live-query/data-provider-live-query-storage.d.ts +4 -1
  26. package/live-query/data-provider-live-query-storage.js +18 -15
  27. package/package.json +1 -1
  28. package/remult-d1.d.ts +0 -1
  29. package/remult-d1.js +0 -1
  30. package/remult-knex/index.js +44 -329
  31. package/remult-mongo.js +36 -80
  32. package/remult-sqlite-core.d.ts +0 -1
  33. package/remult-sqlite-core.js +0 -1
  34. package/server/remult-api-server.js +13 -9
  35. package/src/data-api.js +1 -0
  36. package/src/data-interfaces.d.ts +3 -2
  37. package/src/data-interfaces.js +4 -4
  38. package/src/data-providers/array-entity-data-provider.d.ts +2 -2
  39. package/src/data-providers/array-entity-data-provider.js +14 -92
  40. package/src/data-providers/json-data-provider.js +2 -2
  41. package/src/data-providers/rest-data-provider.d.ts +3 -2
  42. package/src/data-providers/rest-data-provider.js +17 -18
  43. package/src/data-providers/sql-database.js +105 -254
  44. package/src/live-query/LiveQueryClient.js +215 -97
  45. package/src/live-query/SseSubscriptionClient.js +143 -83
  46. package/src/live-query/SubscriptionChannel.d.ts +8 -0
  47. package/src/live-query/SubscriptionChannel.js +47 -9
  48. package/src/live-query/SubscriptionServer.d.ts +7 -2
  49. package/src/live-query/SubscriptionServer.js +20 -10
  50. package/src/remult3/RepositoryImplementation.d.ts +1 -1
  51. package/src/remult3/RepositoryImplementation.js +270 -384
  52. package/src/remult3/remult3.d.ts +8 -2
  53. package/src/remult3/remult3.js +6 -0
  54. package/src/sql-command.d.ts +0 -2
  55. package/src/standard-schema/index.d.ts +1 -1
  56. package/esm/src/data-providers/indexed-db-data-provider.js +0 -811
  57. package/src/data-providers/indexed-db-data-provider.d.ts +0 -39
  58. package/src/data-providers/indexed-db-data-provider.js +0 -1387
@@ -5,6 +5,7 @@ var tslib_1 = require("tslib");
5
5
  var buildRestDataProvider_js_1 = require("../buildRestDataProvider.js");
6
6
  var rest_data_provider_js_1 = require("../data-providers/rest-data-provider.js");
7
7
  var remult_static_js_1 = require("../remult-static.js");
8
+ var remult3_js_1 = require("../remult3/remult3.js");
8
9
  var repository_internals_js_1 = require("../remult3/repository-internals.js");
9
10
  var SubscriptionChannel_js_1 = require("./SubscriptionChannel.js");
10
11
  /* @internal*/
@@ -14,6 +15,9 @@ var LiveQueryClient = /** @class */ (function () {
14
15
  this.getUserId = getUserId;
15
16
  this.queries = new Map();
16
17
  this.channels = new Map();
18
+ this.lastKeepAliveAt = 0;
19
+ this.keepAliveBackoffMs = remult3_js_1.flags.liveQueryPollWhenStaleMs;
20
+ this.detachForeground = function () { };
17
21
  }
18
22
  LiveQueryClient.prototype.wrapMessageHandling = function (handleMessage) {
19
23
  var x = this.apiProvider().wrapMessageHandling;
@@ -31,6 +35,7 @@ var LiveQueryClient = /** @class */ (function () {
31
35
  LiveQueryClient.prototype.close = function () {
32
36
  this.queries.clear();
33
37
  this.channels.clear();
38
+ this.detachForeground();
34
39
  this.closeIfNoListeners();
35
40
  };
36
41
  LiveQueryClient.prototype.subscribeChannel = function (key, onResult) {
@@ -88,13 +93,15 @@ var LiveQueryClient = /** @class */ (function () {
88
93
  });
89
94
  };
90
95
  LiveQueryClient.prototype.closeIfNoListeners = function () {
91
- if (this.client)
92
- if (this.queries.size === 0 && this.channels.size === 0) {
93
- this.runPromise(this.client.then(function (x) { return x.close(); }));
94
- this.client = undefined;
95
- clearInterval(this.interval);
96
- this.interval = undefined;
97
- }
96
+ if (this.queries.size === 0 && this.channels.size === 0) {
97
+ if (this.client)
98
+ this.runPromise(this.client.then(function (x) { return x.close(); }).catch(function () { }));
99
+ this.client = undefined;
100
+ this.openedConnection = undefined;
101
+ this.detachForeground();
102
+ clearInterval(this.interval);
103
+ this.interval = undefined;
104
+ }
98
105
  };
99
106
  LiveQueryClient.prototype.subscribe = function (repo, options, listener) {
100
107
  var _this = this;
@@ -115,43 +122,56 @@ var LiveQueryClient = /** @class */ (function () {
115
122
  if (!q) {
116
123
  _this.queries.set(eventTypeKey, (q = new SubscriptionChannel_js_1.LiveQuerySubscriber(repo, { entityKey: repo.metadata.key, options: options }, _this.getUserId())));
117
124
  q.subscribeCode = function () {
118
- if (q.unsubscribe) {
119
- q.unsubscribe();
125
+ q.unsubscribeChannel();
126
+ var unsubscribeToChannel = function () { };
127
+ q.unsubscribeChannel = function () {
128
+ unsubscribeToChannel();
129
+ unsubscribeToChannel = function () { };
130
+ };
131
+ q.unsubscribe = function () {
120
132
  q.unsubscribe = function () { };
121
- }
133
+ q.unsubscribeChannel();
134
+ q.unsubscribeQuery();
135
+ };
136
+ var snapshotDone = false;
137
+ var applySnapshot = function (r) {
138
+ if (q.listeners.length === 0) {
139
+ r.unsubscribe();
140
+ return;
141
+ }
142
+ q.unsubscribeQuery = function () {
143
+ _this.runPromise(r.unsubscribe());
144
+ };
145
+ snapshotDone = true;
146
+ return _this.runPromise(q.setAllItems(r.result));
147
+ };
122
148
  _this.runPromise(_this.subscribeChannel(q.queryChannel, {
123
149
  next: function (value) { return _this.runPromise(q.handle(value)); },
124
150
  complete: function () { },
125
151
  error: function (er) {
126
152
  q.listeners.forEach(function (l) { return l.error(er); });
127
153
  },
128
- }).then(function (unsubscribeToChannel) {
154
+ })
155
+ .then(function (unsub) {
129
156
  if (q.listeners.length == 0) {
130
- unsubscribeToChannel();
157
+ unsub();
131
158
  return;
132
159
  }
133
- _this.runPromise(subscribe(q.queryChannel)
134
- .then(function (r) {
135
- if (q.listeners.length === 0) {
136
- r.unsubscribe();
137
- unsubscribeToChannel();
138
- return;
139
- }
140
- _this.runPromise(q.setAllItems(r.result));
141
- q.unsubscribe = function () {
142
- q.unsubscribe = function () { };
143
- unsubscribeToChannel();
144
- _this.runPromise(r.unsubscribe());
145
- };
146
- })
147
- .catch(function (err) {
148
- q.listeners.forEach(function (l) { return l.error(err); });
149
- unsubscribeToChannel();
150
- _this.queries.delete(eventTypeKey);
151
- }));
152
- })).catch(function (err) {
160
+ unsubscribeToChannel = unsub;
161
+ if (snapshotDone)
162
+ return _this.runPromise(_this.runKeepAlive({ checkVersions: true }));
163
+ })
164
+ .catch(function (err) {
165
+ q.listeners.forEach(function (l) { return l.error(err); });
166
+ }));
167
+ _this.runPromise(subscribe(q.queryChannel)
168
+ .then(applySnapshot)
169
+ .catch(function (err) {
153
170
  q.listeners.forEach(function (l) { return l.error(err); });
154
- });
171
+ unsubscribeToChannel();
172
+ _this.queries.delete(eventTypeKey);
173
+ _this.closeIfNoListeners();
174
+ }));
155
175
  };
156
176
  q.subscribeCode();
157
177
  }
@@ -176,84 +196,182 @@ var LiveQueryClient = /** @class */ (function () {
176
196
  onUnsubscribe();
177
197
  };
178
198
  };
179
- LiveQueryClient.prototype.openIfNoOpened = function () {
180
- var _this = this;
181
- if (!this.client) {
182
- this.interval = setInterval(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
183
- var ids, _a, _b, q, p_1, invalidIds, _c, invalidIds_1, invalidIds_1_1, id, _d, _e, q;
184
- var e_1, _f, e_2, _g, e_3, _h;
185
- return tslib_1.__generator(this, function (_j) {
186
- switch (_j.label) {
187
- case 0:
188
- ids = [];
199
+ LiveQueryClient.prototype.isSseStale = function () {
200
+ var conn = this.openedConnection;
201
+ if (!conn || conn.lastServerEvent === undefined)
202
+ return false;
203
+ return Date.now() - conn.lastServerEvent > remult3_js_1.flags.sseStaleMs;
204
+ };
205
+ LiveQueryClient.prototype.runKeepAlive = function (opts) {
206
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
207
+ var _this = this;
208
+ return tslib_1.__generator(this, function (_a) {
209
+ if (this.keepAliveInFlight)
210
+ return [2 /*return*/, this.keepAliveInFlight];
211
+ this.keepAliveInFlight = this.sendKeepAlive(opts).finally(function () {
212
+ _this.keepAliveInFlight = undefined;
213
+ });
214
+ return [2 /*return*/, this.keepAliveInFlight];
215
+ });
216
+ });
217
+ };
218
+ LiveQueryClient.prototype.sendKeepAlive = function (opts) {
219
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
220
+ var ids, _a, _b, q, p, raw, unknownIds, versions, stale, reloaded, _c, _d, q, serverVersion, unknown, mismatch;
221
+ var e_1, _e, e_2, _f;
222
+ var _g, _h;
223
+ return tslib_1.__generator(this, function (_j) {
224
+ switch (_j.label) {
225
+ case 0:
226
+ ids = [];
227
+ try {
228
+ for (_a = tslib_1.__values(this.queries.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
229
+ q = _b.value;
230
+ ids.push(q.queryChannel);
231
+ }
232
+ }
233
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
234
+ finally {
189
235
  try {
190
- for (_a = tslib_1.__values(this.queries.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
191
- q = _b.value;
192
- ids.push(q.queryChannel);
193
- }
236
+ if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
194
237
  }
195
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
196
- finally {
197
- try {
198
- if (_b && !_b.done && (_f = _a.return)) _f.call(_a);
238
+ finally { if (e_1) throw e_1.error; }
239
+ }
240
+ if (ids.length === 0)
241
+ return [2 /*return*/];
242
+ p = this.apiProvider();
243
+ return [4 /*yield*/, this.runPromise(remult_static_js_1.remultStatic.actionInfo.runActionWithoutBlockingUI(function () {
244
+ return (0, buildRestDataProvider_js_1.buildRestDataProvider)(p.httpClient).post(p.url + '/' + SubscriptionChannel_js_1.liveQueryKeepAliveRoute, { queryIds: ids });
245
+ }))];
246
+ case 1:
247
+ raw = _j.sent();
248
+ unknownIds = Array.isArray(raw)
249
+ ? raw
250
+ : ((_g = raw === null || raw === void 0 ? void 0 : raw.unknownQueryIds) !== null && _g !== void 0 ? _g : []);
251
+ versions = Array.isArray(raw)
252
+ ? {}
253
+ : ((_h = raw === null || raw === void 0 ? void 0 : raw.versions) !== null && _h !== void 0 ? _h : {});
254
+ stale = (opts === null || opts === void 0 ? void 0 : opts.checkVersions) || this.isSseStale();
255
+ reloaded = false;
256
+ try {
257
+ for (_c = tslib_1.__values(this.queries.values()), _d = _c.next(); !_d.done; _d = _c.next()) {
258
+ q = _d.value;
259
+ serverVersion = versions[q.queryChannel];
260
+ unknown = unknownIds.includes(q.queryChannel);
261
+ mismatch = stale && serverVersion !== undefined && serverVersion !== q.version;
262
+ if (unknown || mismatch) {
263
+ reloaded = true;
264
+ if (serverVersion !== undefined)
265
+ q.version = serverVersion;
266
+ q.subscribeCode();
199
267
  }
200
- finally { if (e_1) throw e_1.error; }
201
268
  }
202
- if (!(ids.length > 0)) return [3 /*break*/, 3];
203
- p_1 = this.apiProvider();
204
- _c = this.runPromise;
205
- return [4 /*yield*/, remult_static_js_1.remultStatic.actionInfo.runActionWithoutBlockingUI(function () {
206
- return (0, buildRestDataProvider_js_1.buildRestDataProvider)(p_1.httpClient).post(p_1.url + '/' + SubscriptionChannel_js_1.liveQueryKeepAliveRoute, ids);
207
- })];
208
- case 1: return [4 /*yield*/, _c.apply(this, [_j.sent()])];
209
- case 2:
210
- invalidIds = _j.sent();
269
+ }
270
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
271
+ finally {
211
272
  try {
212
- for (invalidIds_1 = tslib_1.__values(invalidIds), invalidIds_1_1 = invalidIds_1.next(); !invalidIds_1_1.done; invalidIds_1_1 = invalidIds_1.next()) {
213
- id = invalidIds_1_1.value;
214
- try {
215
- for (_d = (e_3 = void 0, tslib_1.__values(this.queries.values())), _e = _d.next(); !_e.done; _e = _d.next()) {
216
- q = _e.value;
217
- if (q.queryChannel === id)
218
- q.subscribeCode();
219
- }
220
- }
221
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
222
- finally {
223
- try {
224
- if (_e && !_e.done && (_h = _d.return)) _h.call(_d);
225
- }
226
- finally { if (e_3) throw e_3.error; }
227
- }
228
- }
229
- }
230
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
231
- finally {
232
- try {
233
- if (invalidIds_1_1 && !invalidIds_1_1.done && (_g = invalidIds_1.return)) _g.call(invalidIds_1);
234
- }
235
- finally { if (e_2) throw e_2.error; }
273
+ if (_d && !_d.done && (_f = _c.return)) _f.call(_c);
236
274
  }
237
- _j.label = 3;
238
- case 3: return [2 /*return*/];
239
- }
240
- });
241
- }); }, 30000);
242
- return this.runPromise((this.client = this.apiProvider().subscriptionClient.openConnection(function () {
243
- var e_4, _a;
275
+ finally { if (e_2) throw e_2.error; }
276
+ }
277
+ if (this.isSseStale()) {
278
+ this.keepAliveBackoffMs = reloaded
279
+ ? remult3_js_1.flags.liveQueryPollWhenStaleMs
280
+ : Math.min(this.keepAliveBackoffMs * 2, remult3_js_1.flags.liveQueryKeepAliveMs);
281
+ }
282
+ else {
283
+ this.keepAliveBackoffMs = remult3_js_1.flags.liveQueryPollWhenStaleMs;
284
+ }
285
+ return [2 /*return*/];
286
+ }
287
+ });
288
+ });
289
+ };
290
+ LiveQueryClient.prototype.maybeKeepAlive = function () {
291
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
292
+ var stale, interval;
293
+ var _a, _b;
294
+ return tslib_1.__generator(this, function (_c) {
295
+ switch (_c.label) {
296
+ case 0:
297
+ stale = this.isSseStale();
298
+ if (!stale)
299
+ this.keepAliveBackoffMs = remult3_js_1.flags.liveQueryPollWhenStaleMs;
300
+ interval = stale
301
+ ? this.keepAliveBackoffMs
302
+ : remult3_js_1.flags.liveQueryKeepAliveMs;
303
+ if (Date.now() - this.lastKeepAliveAt < interval)
304
+ return [2 /*return*/];
305
+ this.lastKeepAliveAt = Date.now();
306
+ if (stale)
307
+ (_b = (_a = this.openedConnection) === null || _a === void 0 ? void 0 : _a.resume) === null || _b === void 0 ? void 0 : _b.call(_a, true);
308
+ return [4 /*yield*/, this.runKeepAlive()];
309
+ case 1:
310
+ _c.sent();
311
+ return [2 /*return*/];
312
+ }
313
+ });
314
+ });
315
+ };
316
+ LiveQueryClient.prototype.attachForeground = function () {
317
+ var _this = this;
318
+ this.detachForeground();
319
+ var unsub = (0, SubscriptionChannel_js_1.onBrowserForeground)(function () {
320
+ var _a, _b;
321
+ (_b = (_a = _this.openedConnection) === null || _a === void 0 ? void 0 : _a.resume) === null || _b === void 0 ? void 0 : _b.call(_a);
322
+ if (_this.foregroundKeepAliveTimer !== undefined)
323
+ clearTimeout(_this.foregroundKeepAliveTimer);
324
+ _this.foregroundKeepAliveTimer = setTimeout(function () {
325
+ _this.foregroundKeepAliveTimer = undefined;
326
+ _this.keepAliveBackoffMs = remult3_js_1.flags.liveQueryPollWhenStaleMs;
327
+ _this.lastKeepAliveAt = 0;
328
+ _this.runPromise(_this.runKeepAlive({ checkVersions: true }));
329
+ }, 300);
330
+ });
331
+ this.detachForeground = function () {
332
+ unsub();
333
+ if (_this.foregroundKeepAliveTimer !== undefined) {
334
+ clearTimeout(_this.foregroundKeepAliveTimer);
335
+ _this.foregroundKeepAliveTimer = undefined;
336
+ }
337
+ _this.detachForeground = function () { };
338
+ };
339
+ };
340
+ LiveQueryClient.prototype.openIfNoOpened = function () {
341
+ var _this = this;
342
+ if (!this.client) {
343
+ this.lastKeepAliveAt = Date.now();
344
+ this.keepAliveBackoffMs = remult3_js_1.flags.liveQueryPollWhenStaleMs;
345
+ this.attachForeground();
346
+ this.interval = setInterval(function () {
347
+ _this.runPromise(_this.maybeKeepAlive());
348
+ }, Math.min(remult3_js_1.flags.liveQueryPollWhenStaleMs, remult3_js_1.flags.liveQueryKeepAliveMs));
349
+ return this.runPromise((this.client = this.apiProvider()
350
+ .subscriptionClient.openConnection(function () {
351
+ var e_3, _a;
244
352
  try {
245
353
  for (var _b = tslib_1.__values(_this.queries.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
246
354
  var q = _c.value;
247
355
  q.subscribeCode();
248
356
  }
249
357
  }
250
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
358
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
251
359
  finally {
252
360
  try {
253
361
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
254
362
  }
255
- finally { if (e_4) throw e_4.error; }
363
+ finally { if (e_3) throw e_3.error; }
256
364
  }
365
+ })
366
+ .then(function (c) {
367
+ _this.openedConnection = c;
368
+ return c;
369
+ })
370
+ .catch(function (err) {
371
+ _this.client = undefined;
372
+ _this.openedConnection = undefined;
373
+ _this.closeIfNoListeners();
374
+ throw err;
257
375
  })));
258
376
  }
259
377
  return this.client;
@@ -269,7 +387,7 @@ var MessageChannel = /** @class */ (function () {
269
387
  MessageChannel.prototype.handle = function (message) {
270
388
  return tslib_1.__awaiter(this, void 0, void 0, function () {
271
389
  var _a, _b, l;
272
- var e_5, _c;
390
+ var e_4, _c;
273
391
  return tslib_1.__generator(this, function (_d) {
274
392
  try {
275
393
  for (_a = tslib_1.__values(this.listeners), _b = _a.next(); !_b.done; _b = _a.next()) {
@@ -277,12 +395,12 @@ var MessageChannel = /** @class */ (function () {
277
395
  l.next(message);
278
396
  }
279
397
  }
280
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
398
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
281
399
  finally {
282
400
  try {
283
401
  if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
284
402
  }
285
- finally { if (e_5) throw e_5.error; }
403
+ finally { if (e_4) throw e_4.error; }
286
404
  }
287
405
  return [2 /*return*/];
288
406
  });