prostgles-client 4.0.360 → 4.0.362

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 (63) hide show
  1. package/dist/FunctionQueuer.js +51 -49
  2. package/dist/SyncedTable/SyncedTable.d.ts +3 -108
  3. package/dist/SyncedTable/SyncedTable.d.ts.map +1 -1
  4. package/dist/SyncedTable/SyncedTable.js +1 -628
  5. package/dist/SyncedTable/createSync.d.ts +3 -2
  6. package/dist/SyncedTable/createSync.d.ts.map +1 -1
  7. package/dist/SyncedTable/createSync.js +16 -9
  8. package/dist/SyncedTable/createSyncDataStore.d.ts +1 -1
  9. package/dist/SyncedTable/createSyncDataStore.d.ts.map +1 -1
  10. package/dist/SyncedTable/createSyncDataStore.js +2 -3
  11. package/dist/SyncedTable/createSyncStateUtils.d.ts +7 -4
  12. package/dist/SyncedTable/createSyncStateUtils.d.ts.map +1 -1
  13. package/dist/SyncedTable/createSyncStateUtils.js +32 -38
  14. package/dist/SyncedTable/createSyncSubscriptionManager.js +6 -10
  15. package/dist/auth/useAuthState.d.ts +2 -2
  16. package/dist/auth/useAuthState.d.ts.map +1 -1
  17. package/dist/auth/useAuthState.js +4 -5
  18. package/dist/getAuthHandler.js +7 -9
  19. package/dist/getDbHandler.d.ts +2 -6
  20. package/dist/getDbHandler.d.ts.map +1 -1
  21. package/dist/getDbHandler.js +37 -71
  22. package/dist/getMethods.js +1 -1
  23. package/dist/getSqlHandler.js +6 -8
  24. package/dist/getSubscriptionHandler.js +5 -5
  25. package/dist/getSyncHandlerV2.d.ts.map +1 -1
  26. package/dist/getSyncHandlerV2.js +3 -4
  27. package/dist/hooks/reactImports.js +2 -3
  28. package/dist/hooks/useAsyncEffectQueue.js +3 -4
  29. package/dist/hooks/useEffectAsync.js +1 -2
  30. package/dist/hooks/useEffectDeep.js +1 -1
  31. package/dist/hooks/useFetch.js +1 -1
  32. package/dist/hooks/useProstglesClient.d.ts +1 -1
  33. package/dist/hooks/useProstglesClient.d.ts.map +1 -1
  34. package/dist/hooks/useProstglesClient.js +5 -8
  35. package/dist/hooks/useSubscribe.js +1 -1
  36. package/dist/hooks/useSync.js +1 -1
  37. package/dist/{prostgles-full.d.ts → index.d.ts} +1 -3
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +36 -1
  40. package/dist/{prostgles-full-cdn.d.ts → index.umd.d.ts} +1 -1
  41. package/dist/index.umd.d.ts.map +1 -0
  42. package/dist/index.umd.js +1 -0
  43. package/dist/prostgles.d.ts +3 -3
  44. package/dist/prostgles.d.ts.map +1 -1
  45. package/dist/prostgles.js +11 -13
  46. package/package.json +3 -4
  47. package/tsconfig.json +5 -15
  48. package/webpack.dev.js +14 -15
  49. package/webpack.prod.js +2 -3
  50. package/dist/SyncedTable/getMultiSyncSubscription.d.ts +0 -12
  51. package/dist/SyncedTable/getMultiSyncSubscription.d.ts.map +0 -1
  52. package/dist/SyncedTable/getMultiSyncSubscription.js +0 -60
  53. package/dist/SyncedTable/getSingleSyncSubscription.d.ts +0 -1
  54. package/dist/SyncedTable/getSingleSyncSubscription.d.ts.map +0 -1
  55. package/dist/SyncedTable/getSingleSyncSubscription.js +0 -1
  56. package/dist/getSyncHandler.d.ts +0 -10
  57. package/dist/getSyncHandler.d.ts.map +0 -1
  58. package/dist/getSyncHandler.js +0 -199
  59. package/dist/index.no-sync.js +0 -1
  60. package/dist/prostgles-full-cdn.d.ts.map +0 -1
  61. package/dist/prostgles-full-cdn.js +0 -8
  62. package/dist/prostgles-full.d.ts.map +0 -1
  63. package/dist/prostgles-full.js +0 -38
@@ -1,635 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.quickClone = exports.mergeDeep = exports.SyncedTable = void 0;
3
+ exports.quickClone = exports.mergeDeep = void 0;
4
4
  const prostgles_types_1 = require("prostgles-types");
5
- const getMultiSyncSubscription_1 = require("./getMultiSyncSubscription");
6
- const WAL_1 = require("prostgles-types/dist/WAL");
7
5
  const hasWnd = typeof window !== "undefined";
8
- class SyncedTable {
9
- /**
10
- * add debug mode to fix sudden no data and sync listeners bug
11
- */
12
- set multiSubscriptions(mSubs) {
13
- this._multiSubscriptions = mSubs.slice(0);
14
- }
15
- get multiSubscriptions() {
16
- return this._multiSubscriptions;
17
- }
18
- set singleSubscriptions(sSubs) {
19
- this._singleSubscriptions = sSubs.slice(0);
20
- }
21
- get singleSubscriptions() {
22
- return this._singleSubscriptions;
23
- }
24
- constructor(options) {
25
- var _a;
26
- this.throttle = 100;
27
- this.batch_size = 50;
28
- this.columns = [];
29
- this._multiSubscriptions = [];
30
- this._singleSubscriptions = [];
31
- this.itemsMap = new Map();
32
- this.isSynced = false;
33
- /**
34
- * Notifies multi subs with ALL data + deltas. Attaches handles on data if required
35
- * @param newData -> updates. Must include id_fields + updates
36
- */
37
- this._notifySubscribers = (changes = []) => {
38
- var _a, _b;
39
- if (!this.isSynced) {
40
- (_a = this.onDebug) === null || _a === void 0 ? void 0 : _a.call(this, { command: "notifySubscribers", data: [], info: "not synced yet" });
41
- return;
42
- }
43
- else {
44
- (_b = this.onDebug) === null || _b === void 0 ? void 0 : _b.call(this, { command: "notifySubscribers", data: changes });
45
- }
46
- /* Deleted items (changes = []) do not trigger singleSubscriptions notify because it might break things */
47
- const items = [], deltas = [], ids = [];
48
- changes.map(({ idObj, newItem, delta }) => {
49
- /* Single subs do not care about the filter */
50
- this.singleSubscriptions
51
- .filter((s) => this.matchesIdObj(s.idObj, idObj))
52
- .map(async (s) => {
53
- try {
54
- await s.notify(newItem, delta);
55
- }
56
- catch (e) {
57
- console.error("SyncedTable failed to notify: ", e);
58
- }
59
- });
60
- /* Preparing data for multi subs */
61
- if (this.matchesFilter(newItem)) {
62
- items.push(newItem);
63
- deltas.push(delta);
64
- ids.push(idObj);
65
- }
66
- });
67
- if (this.multiSubscriptions.length) {
68
- const allItems = [], allDeltas = [];
69
- this.getItems().map((d) => {
70
- allItems.push({ ...d });
71
- const dIdx = items.findIndex((_d) => this.matchesIdObj(d, _d));
72
- allDeltas.push(deltas[dIdx]);
73
- });
74
- /* Multisubs must not forget about the original filter */
75
- this.multiSubscriptions.map(async (s) => {
76
- try {
77
- await s.notify(allItems, allDeltas);
78
- }
79
- catch (e) {
80
- console.error("SyncedTable failed to notify: ", e);
81
- }
82
- });
83
- }
84
- };
85
- this.unsubscribe = (onChange) => {
86
- this.singleSubscriptions = this.singleSubscriptions.filter((s) => s._onChange !== onChange);
87
- this.multiSubscriptions = this.multiSubscriptions.filter((s) => s._onChange !== onChange);
88
- return "ok";
89
- };
90
- this.unsync = () => {
91
- var _a;
92
- (_a = this.dbSync) === null || _a === void 0 ? void 0 : _a.unsync();
93
- };
94
- this.destroy = () => {
95
- this.unsync();
96
- this.multiSubscriptions = [];
97
- this.singleSubscriptions = [];
98
- this.itemsMap.clear();
99
- };
100
- this.delete = async (item, from_server = false) => {
101
- var _a;
102
- const idObj = this.getIdObj(item);
103
- this.setItem(idObj, true, true);
104
- if (!from_server && ((_a = this.tableHandler) === null || _a === void 0 ? void 0 : _a.delete)) {
105
- await this.tableHandler.delete(idObj);
106
- }
107
- this._notifySubscribers();
108
- return true;
109
- };
110
- /**
111
- * Ensures that all object keys match valid column names
112
- */
113
- this.checkItemCols = (item) => {
114
- if (this.columns.length) {
115
- const badCols = Object.keys({ ...item }).filter((k) => !this.columns.find((c) => c.name === k));
116
- if (badCols.length) {
117
- throw `Unexpected columns in sync item update: ` + badCols.join(", ");
118
- }
119
- }
120
- };
121
- /**
122
- * Upserts data locally -> notify subs -> sends to server if required
123
- * synced_field is populated if data is not from server
124
- * @param items <{ idObj: object, delta: object }[]> Data items that changed
125
- * @param from_server : <boolean> If false then updates will be sent to server
126
- */
127
- this.upsert = async (items, from_server = false) => {
128
- var _a, _b;
129
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
130
- if ((!items || !items.length) && !from_server)
131
- throw "No data provided for upsert";
132
- /* If data has been deleted then wait for it to sync with server before continuing */
133
- // if(from_server && this.getDeleted().length){
134
- // await this.syncDeleted();
135
- // }
136
- const results = [];
137
- let status;
138
- const walItems = [];
139
- await Promise.all(items.map(async (item, i) => {
140
- var _a;
141
- // let d = { ...item.idObj, ...item.delta };
142
- const idObj = { ...item.idObj };
143
- let delta = { ...item.delta };
144
- /* Convert undefined to null because:
145
- 1) JSON.stringify drops these keys
146
- 2) Postgres does not have undefined
147
- */
148
- Object.keys(delta).map((k) => {
149
- if (delta[k] === undefined)
150
- delta[k] = null;
151
- });
152
- if (!from_server) {
153
- this.checkItemCols({ ...item.delta, ...item.idObj });
154
- }
155
- const oldItem = this.getItem(idObj);
156
- /* Calc delta if missing or if from server */
157
- if ((from_server || (0, prostgles_types_1.isEmpty)(delta)) && !(0, prostgles_types_1.isEmpty)(oldItem)) {
158
- delta = this.getDelta(oldItem || {}, delta);
159
- }
160
- /* Add synced if local update */
161
- /** Will need to check client clock shift */
162
- if (!from_server) {
163
- delta[this.synced_field] = Date.now();
164
- }
165
- let newItem = { ...oldItem, ...delta, ...idObj };
166
- if (oldItem && !from_server) {
167
- /**
168
- * Merge deep
169
- */
170
- if ((_a = item.opts) === null || _a === void 0 ? void 0 : _a.deepMerge) {
171
- newItem = (0, exports.mergeDeep)({ ...oldItem, ...idObj }, { ...delta });
172
- }
173
- }
174
- /* Update existing -> Expecting delta */
175
- if (oldItem) {
176
- status =
177
- oldItem[this.synced_field] < newItem[this.synced_field] ? "updated" : "unchanged";
178
- /* Insert new item */
179
- }
180
- else {
181
- status = "inserted";
182
- }
183
- this.setItem(newItem);
184
- // if(!status) throw "changeInfo status missing"
185
- const changeInfo = { idObj, delta, oldItem, newItem, status, from_server };
186
- // const idStr = this.getIdStr(idObj);
187
- /* IF Local updates then Keep any existing oldItem to revert to the earliest working item */
188
- if (!from_server) {
189
- /* Patch server data if necessary and update separately to account for errors */
190
- // let updatedWithPatch = false;
191
- // if(this.columns && this.columns.length && (this.patchText || this.patchJSON)){
192
- // // const jCols = this.columns.filter(c => c.data_type === "json")
193
- // const txtCols = this.columns.filter(c => c.data_type === "text");
194
- // if(this.patchText && txtCols.length && this.db[this.name].update){
195
- // let patchedDelta;
196
- // txtCols.map(c => {
197
- // if(c.name in changeInfo.delta){
198
- // patchedDelta = patchedDelta || {
199
- // ...changeInfo.delta,
200
- // }
201
- // patchedDelta[c.name] = getTextPatch(changeInfo.oldItem[c.name], changeInfo.delta[c.name]);
202
- // }
203
- // });
204
- // if(patchedDelta){
205
- // try {
206
- // await this.db[this.name].update(idObj, patchedDelta);
207
- // updatedWithPatch = true;
208
- // } catch(e) {
209
- // console.log("failed to patch update", e)
210
- // }
211
- // }
212
- // // console.log("json-stable-stringify ???")
213
- // }
214
- // }
215
- walItems.push({
216
- initial: oldItem,
217
- current: { ...newItem },
218
- });
219
- }
220
- if (!(0, prostgles_types_1.isEmpty)(changeInfo.delta)) {
221
- results.push(changeInfo);
222
- }
223
- /* TODO: Deletes from server */
224
- // if(allow_deletes){
225
- // items = this.getItems();
226
- // }
227
- return true;
228
- })).catch((err) => {
229
- console.error("SyncedTable failed upsert: ", err);
230
- });
231
- (_a = this.notifyWal) === null || _a === void 0 ? void 0 : _a.addData(results.map((d) => ({ initial: d.oldItem, current: d.newItem })));
232
- /* Push to server */
233
- if (!from_server && walItems.length) {
234
- (_b = this.wal) === null || _b === void 0 ? void 0 : _b.addData(walItems);
235
- }
236
- };
237
- /**
238
- * Sets the current data
239
- */
240
- this.setItems = (_items) => {
241
- const items = (0, exports.quickClone)(_items);
242
- this.itemsMap = new Map(items.map((item) => {
243
- const id = this.getIdStr(item);
244
- return [id, { ...item }];
245
- }));
246
- };
247
- /**
248
- * Returns the current data ordered by synced_field ASC and matching the main filter;
249
- */
250
- this.getItems = () => {
251
- let items = [];
252
- items = Array.from(this.itemsMap.values()).map((d) => ({ ...d }));
253
- const syncFields = [this.synced_field, ...this.id_fields.sort()];
254
- items = items
255
- .filter((d) => {
256
- return !this.filter || !(0, prostgles_types_1.getKeys)(this.filter).find((key) => d[key] !== this.filter[key]);
257
- })
258
- .sort((a, b) => syncFields
259
- .map((key) => (a[key] < b[key] ? -1
260
- : a[key] > b[key] ? 1
261
- : 0))
262
- .find((v) => v));
263
- return (0, exports.quickClone)(items);
264
- };
265
- /**
266
- * Sync data request
267
- */
268
- this.getBatch = ({ from_synced, to_synced, offset, limit } = { offset: 0, limit: undefined }) => {
269
- const items = this.getItems();
270
- let res = items
271
- .map((c) => ({ ...c }))
272
- .filter((c) => (!Number.isFinite(from_synced) || +c[this.synced_field] >= +from_synced) &&
273
- (!Number.isFinite(to_synced) || +c[this.synced_field] <= +to_synced));
274
- if (offset || limit) {
275
- res = res.splice(offset !== null && offset !== void 0 ? offset : 0, limit || res.length);
276
- }
277
- return res;
278
- };
279
- const { name, filter = {}, onReady, onDebug, db, select = "*", onError } = options;
280
- this.name = name;
281
- this.filter = filter;
282
- this.select = select;
283
- if (onDebug) {
284
- this.onDebug = (evt) => onDebug({
285
- ...evt,
286
- type: "sync",
287
- tableName: name,
288
- channelName: (0, prostgles_types_1.getSyncChannelName)({ filter, select, tableName: name }),
289
- options,
290
- });
291
- this.onDebug({ command: "create", data: { name, filter, select } });
292
- }
293
- const tableHandler = db[name];
294
- if (!tableHandler) {
295
- throw `${name} table not found in db`;
296
- }
297
- this.db = db;
298
- const { _sync, _syncInfo } = tableHandler;
299
- if (!_sync || !_syncInfo) {
300
- throw `${name} table does not support sync`;
301
- }
302
- const { id_fields, synced_field, throttle = 100, batch_size = 50 } = _syncInfo;
303
- if (!id_fields.length || !synced_field) {
304
- throw "id_fields/synced_field missing";
305
- }
306
- this.id_fields = id_fields;
307
- this.synced_field = synced_field;
308
- this.batch_size = batch_size;
309
- this.throttle = throttle;
310
- this.multiSubscriptions = [];
311
- this.singleSubscriptions = [];
312
- this.onError =
313
- onError ||
314
- function (err) {
315
- console.error("Sync internal error: ", err);
316
- };
317
- const onSyncRequest = (syncBatchParams) => {
318
- var _a;
319
- let clientSyncInfo = { c_lr: undefined, c_fr: undefined, c_count: 0 };
320
- const batch = this.getBatch(syncBatchParams);
321
- if (batch.length) {
322
- clientSyncInfo = {
323
- c_fr: this.getRowSyncObj(batch[0]),
324
- c_lr: this.getRowSyncObj(batch[batch.length - 1]),
325
- c_count: batch.length,
326
- };
327
- }
328
- (_a = this.onDebug) === null || _a === void 0 ? void 0 : _a.call(this, { command: "onUpdates", data: { syncBatchParams, batch, clientSyncInfo } });
329
- return clientSyncInfo;
330
- }, onPullRequest = async (syncBatchParams) => {
331
- var _a;
332
- // if(this.getDeleted().length){
333
- // await this.syncDeleted();
334
- // }
335
- const data = this.getBatch(syncBatchParams);
336
- await ((_a = this.onDebug) === null || _a === void 0 ? void 0 : _a.call(this, { command: "onPullRequest", data: { syncBatchParams, data } }));
337
- return { data };
338
- }, onUpdates = async (onUpdatesParams) => {
339
- var _a, _b;
340
- await ((_a = this.onDebug) === null || _a === void 0 ? void 0 : _a.call(this, { command: "onUpdates", data: { onUpdatesParams } }));
341
- if ("err" in onUpdatesParams && onUpdatesParams.err) {
342
- (_b = this.onError) === null || _b === void 0 ? void 0 : _b.call(this, onUpdatesParams.err);
343
- }
344
- else if ("isSynced" in onUpdatesParams && onUpdatesParams.isSynced && !this.isSynced) {
345
- this.isSynced = onUpdatesParams.isSynced;
346
- const items = this.getItems().map((d) => ({ ...d }));
347
- this.setItems([]);
348
- const updateItems = items.map((d) => ({
349
- idObj: this.getIdObj(d),
350
- delta: { ...d },
351
- }));
352
- await this.upsert(updateItems, true);
353
- }
354
- else if ("data" in onUpdatesParams) {
355
- /* Delta left empty so we can prepare it here */
356
- const updateItems = onUpdatesParams.data.map((d) => {
357
- return {
358
- idObj: this.getIdObj(d),
359
- delta: d,
360
- };
361
- });
362
- await this.upsert(updateItems, true);
363
- }
364
- else {
365
- console.error("Unexpected onUpdates");
366
- }
367
- return true;
368
- };
369
- const opts = {
370
- id_fields,
371
- synced_field,
372
- throttle,
373
- };
374
- _sync(filter, { select }, { onSyncRequest, onPullRequest, onUpdates }).then((s) => {
375
- this.dbSync = s;
376
- function confirmExit() {
377
- return "Data may be lost. Are you sure?";
378
- }
379
- /**
380
- * Some syncs can be read only. Any changes are local
381
- */
382
- this.wal = new WAL_1.WAL({
383
- ...opts,
384
- batch_size,
385
- onSendStart: () => {
386
- if (hasWnd)
387
- window.onbeforeunload = confirmExit;
388
- },
389
- onSend: async (data, walData) => {
390
- const _data = walData.map((d) => d.current);
391
- if (!_data.length)
392
- return [];
393
- return s.syncData(data);
394
- }, //, deletedData);,
395
- onSendEnd: () => {
396
- if (hasWnd)
397
- window.onbeforeunload = null;
398
- },
399
- });
400
- this.notifyWal = new WAL_1.WAL({
401
- ...opts,
402
- batch_size: Infinity,
403
- throttle: 5,
404
- onSend: async (_, fullItems) => {
405
- this._notifySubscribers(fullItems.map((d) => {
406
- var _a;
407
- return ({
408
- delta: this.getDelta((_a = d.initial) !== null && _a !== void 0 ? _a : {}, d.current),
409
- idObj: this.getIdObj(d.current),
410
- newItem: d.current,
411
- });
412
- }));
413
- },
414
- });
415
- onReady();
416
- });
417
- (_a = tableHandler.getColumns) === null || _a === void 0 ? void 0 : _a.call(tableHandler).then((cols) => {
418
- this.columns = cols;
419
- });
420
- }
421
- static create(opts) {
422
- return new Promise((resolve, reject) => {
423
- try {
424
- const res = new SyncedTable({
425
- ...opts,
426
- onReady: () => {
427
- setTimeout(() => {
428
- resolve(res);
429
- }, 0);
430
- },
431
- onError: (err) => {
432
- console.error("Sync internal error: ", err);
433
- reject(err);
434
- },
435
- });
436
- }
437
- catch (err) {
438
- reject(err);
439
- }
440
- });
441
- }
442
- /**
443
- * Returns a sync handler to all records within the SyncedTable instance
444
- * @param onChange change listener <(items: object[], delta: object[]) => any >
445
- * @param handlesOnData If true then $upsert and $unsync handles will be added on each data item. True by default;
446
- */
447
- sync(onChange, handlesOnData = true) {
448
- const { sub, handles } = getMultiSyncSubscription_1.getMultiSyncSubscription.bind(this)({
449
- onChange: onChange,
450
- handlesOnData,
451
- });
452
- this.multiSubscriptions.push(sub);
453
- setTimeout(() => {
454
- const items = this.getItems();
455
- sub.notify(items, items);
456
- }, 0);
457
- return Object.freeze({ ...handles });
458
- }
459
- makeSingleSyncHandles(idObj, onChange) {
460
- const handles = {
461
- $get: () => this.getItem(idObj),
462
- $find: (idObject) => this.getItem(idObject),
463
- $unsync: () => {
464
- return this.unsubscribe(onChange);
465
- },
466
- $delete: () => {
467
- return this.delete(idObj);
468
- },
469
- $update: (newData, opts) => {
470
- /* DROPPED SYNC BUG */
471
- if (!this.singleSubscriptions.length && !this.multiSubscriptions.length) {
472
- console.warn("No sync listeners");
473
- }
474
- return this.upsert([{ idObj, delta: newData, opts }]);
475
- },
476
- $cloneSync: (onChange) => this.syncOne(idObj, onChange),
477
- // TODO: add clone sync hook
478
- // $useCloneSync: () => {
479
- // const handles = this.syncOne<T, Full>(idObj, item => {
480
- // setItem()
481
- // });
482
- // return handles.$unsync;
483
- // },
484
- $cloneMultiSync: (onChange) => this.sync(onChange, true),
485
- };
486
- return handles;
487
- }
488
- /**
489
- * Returns a sync handler to a specific record within the SyncedTable instance
490
- * @param idObj object containing the target id_fields properties
491
- * @param onChange change listener <(item: object, delta: object) => any >
492
- * @param handlesOnData If true then $update, $delete and $unsync handles will be added on the data item. True by default;
493
- */
494
- syncOne(idObj, onChange, handlesOnData = true) {
495
- const handles = this.makeSingleSyncHandles(idObj, onChange);
496
- const sub = {
497
- _onChange: onChange,
498
- idObj,
499
- handlesOnData,
500
- handles,
501
- notify: (data, delta) => {
502
- const newData = { ...data };
503
- if (handlesOnData) {
504
- newData.$get = handles.$get;
505
- newData.$find = handles.$find;
506
- newData.$update = handles.$update;
507
- newData.$delete = handles.$delete;
508
- newData.$unsync = handles.$unsync;
509
- newData.$cloneSync = handles.$cloneSync;
510
- }
511
- return onChange(newData, delta);
512
- },
513
- };
514
- this.singleSubscriptions.push(sub);
515
- setTimeout(() => {
516
- const existingData = handles.$get();
517
- if (existingData) {
518
- sub.notify(existingData, existingData);
519
- }
520
- }, 0);
521
- return Object.freeze({ ...handles });
522
- }
523
- getIdStr(d) {
524
- return this.id_fields
525
- .sort()
526
- .map((key) => `${d[key] || ""}`)
527
- .join(".");
528
- }
529
- getIdObj(d) {
530
- const res = {};
531
- this.id_fields.sort().map((key) => {
532
- res[key] = d[key];
533
- });
534
- return res;
535
- }
536
- getRowSyncObj(d) {
537
- const res = {};
538
- [this.synced_field, ...this.id_fields].sort().map((key) => {
539
- res[key] = d[key];
540
- });
541
- return res;
542
- }
543
- matchesFilter(item) {
544
- return Boolean(item &&
545
- (!this.filter ||
546
- (0, prostgles_types_1.isEmpty)(this.filter) ||
547
- !Object.keys(this.filter).find((k) => this.filter[k] !== item[k])));
548
- }
549
- matchesIdObj(a, b) {
550
- return Boolean(a && b && !this.id_fields.sort().find((k) => a[k] !== b[k]));
551
- }
552
- // TODO: offline-first deletes if allow_delete = true
553
- // setDeleted(idObj, fullArray){
554
- // let deleted: object[] = [];
555
- // if(fullArray) deleted = fullArray;
556
- // else {
557
- // deleted = this.getDeleted();
558
- // deleted.push(idObj);
559
- // }
560
- // if(hasWnd) window.localStorage.setItem(this.name + "_$$psql$$_deleted", <any>deleted);
561
- // }
562
- // getDeleted(){
563
- // const delStr = if(hasWnd) window.localStorage.getItem(this.name + "_$$psql$$_deleted") || '[]';
564
- // return JSON.parse(delStr);
565
- // }
566
- // syncDeleted = async () => {
567
- // try {
568
- // await Promise.all(this.getDeleted().map(async idObj => {
569
- // return this.db[this.name].delete(idObj);
570
- // }));
571
- // this.setDeleted(null, []);
572
- // return true;
573
- // } catch(e){
574
- // throw e;
575
- // }
576
- // }
577
- /**
578
- * Returns properties that are present in {n} and are different to {o}
579
- * @param o current full data item
580
- * @param n new data item
581
- */
582
- getDelta(o, n) {
583
- if ((0, prostgles_types_1.isEmpty)(o))
584
- return { ...n };
585
- return Object.fromEntries(Object.entries({ ...n })
586
- .filter(([k]) => !this.id_fields.includes(k))
587
- .map(([k, v]) => {
588
- if (!(0, prostgles_types_1.isEqual)(v, o[k])) {
589
- const vClone = (0, prostgles_types_1.isObject)(v) ? { ...v }
590
- : Array.isArray(v) ? v.slice(0)
591
- : v;
592
- return [k, vClone];
593
- }
594
- })
595
- .filter(prostgles_types_1.isDefined));
596
- }
597
- deleteAll() {
598
- this.getItems().map((d) => this.delete(d));
599
- }
600
- get tableHandler() {
601
- const tblHandler = this.db[this.name];
602
- if ((tblHandler === null || tblHandler === void 0 ? void 0 : tblHandler.update) && tblHandler.updateBatch) {
603
- return tblHandler;
604
- }
605
- return undefined;
606
- }
607
- /* Returns an item by idObj from the local store */
608
- getItem(idObj) {
609
- const d = this.itemsMap.get(this.getIdStr(idObj));
610
- return (0, exports.quickClone)(d);
611
- }
612
- /**
613
- *
614
- * @param item data to be inserted/updated/deleted. Must include id_fields
615
- * @param index (optional) index within array
616
- * @param isFullData
617
- * @param deleteItem
618
- */
619
- setItem(_item, isFullData = false, deleteItem = false) {
620
- var _a;
621
- const item = (0, exports.quickClone)(_item);
622
- const id = this.getIdStr(item);
623
- if (deleteItem) {
624
- this.itemsMap.delete(id);
625
- }
626
- else {
627
- const existing = (_a = this.itemsMap.get(id)) !== null && _a !== void 0 ? _a : {};
628
- this.itemsMap.set(id, isFullData ? { ...item } : { ...existing, ...item });
629
- }
630
- }
631
- }
632
- exports.SyncedTable = SyncedTable;
633
6
  const mergeDeep = (_target, _source) => {
634
7
  const target = _target ? (0, exports.quickClone)(_target) : _target;
635
8
  const source = _source ? (0, exports.quickClone)(_source) : _source;
@@ -1,9 +1,10 @@
1
+ import { type AnyObject } from "prostgles-types";
1
2
  import { WAL } from "prostgles-types/dist/WAL";
2
3
  import { type SyncedTableOptions } from "./SyncedTable";
3
4
  import type { Socket } from "socket.io-client";
4
5
  export declare const createSync: (socket: Socket, options: Omit<SyncedTableOptions, "onReady">) => Promise<{
5
- sync: <T extends import("prostgles-types").AnyObject = import("prostgles-types").AnyObject>(onChange: import("./SyncedTable").MultiChangeListener<T>, handlesOnData?: boolean) => import("./SyncedTable").MultiSyncHandles<T>;
6
- syncOne: <T extends import("prostgles-types").AnyObject = import("prostgles-types").AnyObject, Full extends boolean = false>(idObj: Partial<T>, onChange: import("./SyncedTable").SingleChangeListener<T, Full>, handlesOnData?: boolean) => import("./SyncedTable").SingleSyncHandles<T, Full>;
6
+ sync: <T extends AnyObject = AnyObject>(onChange: import("./SyncedTable").MultiChangeListener<T>, handlesOnData?: boolean) => import("./SyncedTable").MultiSyncHandles<T>;
7
+ syncOne: <T extends AnyObject = AnyObject, Full extends boolean = false>(idObj: Partial<T>, onChange: import("./SyncedTable").SingleChangeListener<T, Full>, handlesOnData?: boolean) => import("./SyncedTable").SingleSyncHandles<T, Full>;
7
8
  notifyWal: WAL;
8
9
  }>;
9
10
  //# sourceMappingURL=createSync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createSync.d.ts","sourceRoot":"","sources":["../../lib/SyncedTable/createSync.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,GAAG,EAAgB,MAAM,0BAA0B,CAAC;AAI7D,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,eAAO,MAAM,UAAU,GAAU,QAAQ,MAAM,EAAE,SAAS,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC;;;;EA0N5F,CAAC"}
1
+ {"version":3,"file":"createSync.d.ts","sourceRoot":"","sources":["../../lib/SyncedTable/createSync.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAIf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,GAAG,EAAgB,MAAM,0BAA0B,CAAC;AAI7D,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,eAAO,MAAM,UAAU,GAAU,QAAQ,MAAM,EAAE,SAAS,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC;;;;EAiO5F,CAAC"}