prostgles-server 4.2.534 → 4.2.537
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/Auth/AuthHandler.js +1 -1
- package/dist/Auth/AuthHandler.js.map +1 -1
- package/dist/Auth/getClientAuth.js +2 -2
- package/dist/Auth/getClientAuth.js.map +1 -1
- package/dist/DboBuilder/DboBuilder.d.ts +1 -1
- package/dist/DboBuilder/DboBuilderTypes.d.ts +3 -1
- package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts +3 -1
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +20 -6
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/runSql/runSqlUtils.d.ts +1 -1
- package/dist/DboBuilder/schema/getTablesForSchemaPostgresSQL.d.ts.map +1 -1
- package/dist/DboBuilder/schema/getTablesForSchemaPostgresSQL.js +0 -4
- package/dist/DboBuilder/schema/getTablesForSchemaPostgresSQL.js.map +1 -1
- package/dist/JSONBSchemaValidation/validateJSONBSchemaSQL.d.ts +1 -1
- package/dist/Logging.d.ts +4 -1
- package/dist/Logging.d.ts.map +1 -1
- package/dist/PubSubManager/PubSubManager.d.ts +5 -4
- package/dist/PubSubManager/PubSubManager.d.ts.map +1 -1
- package/dist/PubSubManager/PubSubManager.js +4 -2
- package/dist/PubSubManager/PubSubManager.js.map +1 -1
- package/dist/PubSubManager/SyncReplication/fetchSyncServerData.d.ts +11 -0
- package/dist/PubSubManager/SyncReplication/fetchSyncServerData.d.ts.map +1 -0
- package/dist/PubSubManager/SyncReplication/fetchSyncServerData.js +25 -0
- package/dist/PubSubManager/SyncReplication/fetchSyncServerData.js.map +1 -0
- package/dist/PubSubManager/SyncReplication/getSyncBatchOptions.d.ts +14 -0
- package/dist/PubSubManager/SyncReplication/getSyncBatchOptions.d.ts.map +1 -0
- package/dist/PubSubManager/SyncReplication/getSyncBatchOptions.js +19 -0
- package/dist/PubSubManager/SyncReplication/getSyncBatchOptions.js.map +1 -0
- package/dist/PubSubManager/SyncReplication/getSyncOrderByAndFields.d.ts +8 -0
- package/dist/PubSubManager/SyncReplication/getSyncOrderByAndFields.d.ts.map +1 -0
- package/dist/PubSubManager/SyncReplication/getSyncOrderByAndFields.js +9 -0
- package/dist/PubSubManager/SyncReplication/getSyncOrderByAndFields.js.map +1 -0
- package/dist/PubSubManager/SyncReplication/getSyncUtilFunctions.d.ts +40 -0
- package/dist/PubSubManager/SyncReplication/getSyncUtilFunctions.d.ts.map +1 -0
- package/dist/{SyncReplication.js → PubSubManager/SyncReplication/getSyncUtilFunctions.js} +84 -214
- package/dist/PubSubManager/SyncReplication/getSyncUtilFunctions.js.map +1 -0
- package/dist/{SyncReplication.d.ts → PubSubManager/SyncReplication/syncData.d.ts} +4 -4
- package/dist/PubSubManager/SyncReplication/syncData.d.ts.map +1 -0
- package/dist/PubSubManager/SyncReplication/syncData.js +131 -0
- package/dist/PubSubManager/SyncReplication/syncData.js.map +1 -0
- package/dist/PubSubManager/addSync.d.ts.map +1 -1
- package/dist/PubSubManager/addSync.js +15 -10
- package/dist/PubSubManager/addSync.js.map +1 -1
- package/dist/WebsocketAPI/onSocketConnected.js +1 -1
- package/dist/WebsocketAPI/onSocketConnected.js.map +1 -1
- package/lib/Auth/AuthHandler.ts +1 -1
- package/lib/Auth/getClientAuth.ts +2 -2
- package/lib/DboBuilder/DboBuilderTypes.ts +2 -1
- package/lib/DboBuilder/TableHandler/TableHandler.ts +26 -8
- package/lib/DboBuilder/schema/getTablesForSchemaPostgresSQL.ts +0 -4
- package/lib/Logging.ts +13 -1
- package/lib/PubSubManager/PubSubManager.ts +7 -5
- package/lib/PubSubManager/SyncReplication/fetchSyncServerData.ts +55 -0
- package/lib/PubSubManager/SyncReplication/getSyncBatchOptions.ts +31 -0
- package/lib/PubSubManager/SyncReplication/getSyncOrderByAndFields.ts +11 -0
- package/lib/{SyncReplication.ts → PubSubManager/SyncReplication/getSyncUtilFunctions.ts} +144 -310
- package/lib/PubSubManager/SyncReplication/syncData.ts +194 -0
- package/lib/PubSubManager/addSync.ts +19 -20
- package/lib/WebsocketAPI/onSocketConnected.ts +7 -7
- package/package.json +2 -2
- package/dist/SyncReplication.d.ts.map +0 -1
- package/dist/SyncReplication.js.map +0 -1
|
@@ -1,98 +1,44 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
from_synced: number | null;
|
|
27
|
-
to_synced: number | null;
|
|
28
|
-
end_offset: number | null;
|
|
29
|
-
}>;
|
|
30
|
-
|
|
31
|
-
export type onSyncRequestResponse =
|
|
32
|
-
| {
|
|
33
|
-
onSyncRequest?: ClientSyncInfo;
|
|
34
|
-
}
|
|
35
|
-
| {
|
|
36
|
-
err: AnyObject | string;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export type ClientExpressData = ClientSyncInfo & {
|
|
40
|
-
data?: AnyObject[];
|
|
41
|
-
deleted?: AnyObject[];
|
|
1
|
+
import {
|
|
2
|
+
isDefined,
|
|
3
|
+
omitKeys,
|
|
4
|
+
pickKeys,
|
|
5
|
+
type AnyObject,
|
|
6
|
+
type SyncBatchParams,
|
|
7
|
+
} from "prostgles-types";
|
|
8
|
+
import type { PRGLIOSocket } from "../../DboBuilder/DboBuilder";
|
|
9
|
+
import type { TableHandler } from "../../DboBuilder/TableHandler/TableHandler";
|
|
10
|
+
import { getSyncOrderByAndFields } from "./getSyncOrderByAndFields";
|
|
11
|
+
import type { PubSubManager, SyncParams } from "../PubSubManager";
|
|
12
|
+
import { fetchSyncServerData } from "./fetchSyncServerData";
|
|
13
|
+
import type {
|
|
14
|
+
ClientSyncInfo,
|
|
15
|
+
onSyncRequestResponse,
|
|
16
|
+
ServerSyncInfo,
|
|
17
|
+
SyncBatchInfo,
|
|
18
|
+
} from "./syncData";
|
|
19
|
+
import { log } from "../PubSubManagerUtils";
|
|
20
|
+
|
|
21
|
+
type Args = {
|
|
22
|
+
socket: PRGLIOSocket;
|
|
23
|
+
tableHandler: TableHandler;
|
|
24
|
+
sync: SyncParams;
|
|
25
|
+
pubSubManager: PubSubManager;
|
|
42
26
|
};
|
|
43
27
|
|
|
44
|
-
|
|
45
|
-
return numberArr.filter((v) => v !== null && v !== undefined && Number.isFinite(+v)) as number[];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Server or client requested data sync
|
|
50
|
-
*/
|
|
51
|
-
export async function syncData(
|
|
52
|
-
this: PubSubManager,
|
|
53
|
-
sync: SyncParams,
|
|
54
|
-
clientData: ClientExpressData | undefined,
|
|
55
|
-
source: "trigger" | "client",
|
|
56
|
-
) {
|
|
57
|
-
await this._log({
|
|
58
|
-
type: "sync",
|
|
59
|
-
command: "syncData",
|
|
60
|
-
tableName: sync.table_name,
|
|
61
|
-
sid: sync.sid,
|
|
62
|
-
source,
|
|
63
|
-
...pickKeys(sync, ["socket_id", "condition", "last_synced", "is_syncing"]),
|
|
64
|
-
lr: JSON.stringify(sync.lr),
|
|
65
|
-
connectedSocketIds: this.dboBuilder.prostgles.connectedSockets.map((s) => s.id),
|
|
66
|
-
localParams: undefined,
|
|
67
|
-
duration: -1,
|
|
68
|
-
socketId: sync.socket_id,
|
|
69
|
-
});
|
|
70
|
-
|
|
28
|
+
export const getSyncUtilFunctions = ({ socket, tableHandler, sync, pubSubManager }: Args) => {
|
|
71
29
|
const {
|
|
30
|
+
synced_field,
|
|
72
31
|
socket_id,
|
|
73
|
-
|
|
74
|
-
table_name,
|
|
32
|
+
id_fields,
|
|
75
33
|
filter,
|
|
76
34
|
table_rules,
|
|
77
|
-
params,
|
|
78
|
-
synced_field,
|
|
79
|
-
id_fields = [],
|
|
80
35
|
batch_size,
|
|
81
|
-
|
|
82
|
-
|
|
36
|
+
channel_name,
|
|
37
|
+
table_name,
|
|
38
|
+
params,
|
|
83
39
|
} = sync;
|
|
84
40
|
|
|
85
|
-
const
|
|
86
|
-
if (!socket) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const tableHandler = this.dbo[table_name];
|
|
90
|
-
if (!tableHandler?.find) {
|
|
91
|
-
throw `dbo.${table_name}.find missing or not allowed`;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const sync_fields = [synced_field, ...id_fields.sort()],
|
|
95
|
-
orderByAsc: OrderBy = sync_fields.reduce((a, v) => ({ ...a, [v]: true }), {}),
|
|
41
|
+
const { orderByAsc, sync_fields } = getSyncOrderByAndFields({ synced_field, id_fields }),
|
|
96
42
|
rowsIdsMatch = (a?: AnyObject, b?: AnyObject) => {
|
|
97
43
|
return a && b && !id_fields.find((key) => a[key].toString() !== b[key].toString());
|
|
98
44
|
},
|
|
@@ -100,30 +46,31 @@ export async function syncData(
|
|
|
100
46
|
return rowsIdsMatch(a, b) && a?.[synced_field].toString() === b?.[synced_field].toString();
|
|
101
47
|
},
|
|
102
48
|
getServerRowInfo = async (args: SyncBatchParams = {}): Promise<ServerSyncInfo> => {
|
|
103
|
-
const { from_synced
|
|
104
|
-
const
|
|
49
|
+
const { from_synced, to_synced, offset = 0, limit } = args;
|
|
50
|
+
const batchFilter = { ...filter };
|
|
105
51
|
|
|
106
|
-
if (from_synced || to_synced) {
|
|
107
|
-
|
|
108
|
-
...(from_synced ? { $gte: from_synced } : {}),
|
|
109
|
-
...(to_synced ? { $lte: to_synced } : {}),
|
|
52
|
+
if (isDefined(from_synced) || isDefined(to_synced)) {
|
|
53
|
+
batchFilter[synced_field] = {
|
|
54
|
+
...(isDefined(from_synced) ? { $gte: from_synced } : {}),
|
|
55
|
+
...(isDefined(to_synced) ? { $lte: to_synced } : {}),
|
|
110
56
|
};
|
|
111
57
|
}
|
|
112
58
|
|
|
113
|
-
const first_rows = await tableHandler.find(
|
|
114
|
-
|
|
59
|
+
const first_rows = (await tableHandler.find(
|
|
60
|
+
batchFilter,
|
|
115
61
|
{ orderBy: orderByAsc, select: sync_fields, limit, offset },
|
|
116
62
|
undefined,
|
|
117
63
|
table_rules,
|
|
118
64
|
{ clientReq: { socket } },
|
|
119
|
-
);
|
|
65
|
+
)) as AnyObject[];
|
|
66
|
+
|
|
120
67
|
const last_rows = first_rows.slice(-1); // Why not logic below?
|
|
121
68
|
// const last_rows = await _this?.dbo[table_name]?.find?.(_filter, { orderBy: (orderByDesc as OrderBy), select: sync_fields, limit: 1, offset: -offset || 0 }, null, table_rules);
|
|
122
|
-
const count = await tableHandler.count(
|
|
69
|
+
const count = await tableHandler.count(batchFilter, undefined, undefined, table_rules);
|
|
123
70
|
|
|
124
71
|
return {
|
|
125
|
-
s_fr: first_rows[0]
|
|
126
|
-
s_lr: last_rows[0]
|
|
72
|
+
s_fr: first_rows[0],
|
|
73
|
+
s_lr: last_rows[0],
|
|
127
74
|
s_count: count,
|
|
128
75
|
};
|
|
129
76
|
},
|
|
@@ -183,30 +130,10 @@ export async function syncData(
|
|
|
183
130
|
}
|
|
184
131
|
},
|
|
185
132
|
getServerData = async (from_synced = 0, offset = 0): Promise<AnyObject[]> => {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
try {
|
|
192
|
-
const res = await tableHandler.find(
|
|
193
|
-
_filter,
|
|
194
|
-
{
|
|
195
|
-
select: params.select,
|
|
196
|
-
orderBy: orderByAsc as OrderBy,
|
|
197
|
-
offset: offset || 0,
|
|
198
|
-
limit: batch_size,
|
|
199
|
-
},
|
|
200
|
-
undefined,
|
|
201
|
-
table_rules,
|
|
202
|
-
{ clientReq: { socket } },
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
return res;
|
|
206
|
-
} catch (e) {
|
|
207
|
-
console.error("Sync getServerData failed: ", e);
|
|
208
|
-
throw "INTERNAL ERROR";
|
|
209
|
-
}
|
|
133
|
+
return fetchSyncServerData(
|
|
134
|
+
{ tableHandler, socket, from_synced, offset },
|
|
135
|
+
{ filter, id_fields, params, synced_field, batch_size, table_rules },
|
|
136
|
+
);
|
|
210
137
|
},
|
|
211
138
|
deleteData = async (deleted: AnyObject[]) => {
|
|
212
139
|
// console.log("deleteData deleteData deleteData " + deleted.length);
|
|
@@ -215,7 +142,7 @@ export async function syncData(
|
|
|
215
142
|
// deleted.map(async (d) => {
|
|
216
143
|
// const id_filter = pickKeys(d, id_fields);
|
|
217
144
|
// try {
|
|
218
|
-
// await (
|
|
145
|
+
// await (pubSubManager.dbo[table_name] as TableHandler).delete(
|
|
219
146
|
// id_filter,
|
|
220
147
|
// undefined,
|
|
221
148
|
// undefined,
|
|
@@ -238,66 +165,59 @@ export async function syncData(
|
|
|
238
165
|
*/
|
|
239
166
|
upsertData = async (data: AnyObject[]) => {
|
|
240
167
|
const start = Date.now();
|
|
241
|
-
const result = await
|
|
168
|
+
const result = await pubSubManager.dboBuilder
|
|
242
169
|
.getTX(async (dbTX) => {
|
|
243
170
|
const tableHandlerTx = dbTX[table_name] as TableHandler;
|
|
244
171
|
const existingData = await tableHandlerTx.find(
|
|
245
172
|
{ $or: data.map((d) => pickKeys(d, id_fields)) },
|
|
246
173
|
{
|
|
247
174
|
select: [synced_field, ...id_fields],
|
|
248
|
-
orderBy: orderByAsc
|
|
175
|
+
orderBy: orderByAsc,
|
|
249
176
|
},
|
|
250
177
|
undefined,
|
|
251
178
|
table_rules,
|
|
252
179
|
{ clientReq: { socket } },
|
|
253
180
|
);
|
|
254
|
-
let
|
|
255
|
-
let
|
|
256
|
-
existingData.find(
|
|
181
|
+
let rowsToInsert = data.filter((d) => !existingData.find((ed) => rowsIdsMatch(ed, d)));
|
|
182
|
+
let rowsToUpdate = data.filter((d) =>
|
|
183
|
+
existingData.find(
|
|
184
|
+
(ed) => rowsIdsMatch(ed, d) && Number(ed[synced_field]) < Number(d[synced_field]),
|
|
185
|
+
),
|
|
257
186
|
);
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
table_rules,
|
|
290
|
-
{ clientReq: { socket } },
|
|
291
|
-
);
|
|
292
|
-
} else {
|
|
293
|
-
inserts = [];
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return { inserts, updates };
|
|
297
|
-
} catch (e) {
|
|
298
|
-
console.trace(e);
|
|
299
|
-
throw e;
|
|
187
|
+
|
|
188
|
+
if (table_rules.update && rowsToUpdate.length) {
|
|
189
|
+
const batchUpdates: [AnyObject, AnyObject][] = rowsToUpdate.map((rowToUpdate) => {
|
|
190
|
+
const id_filter = pickKeys(rowToUpdate, id_fields);
|
|
191
|
+
const syncSafeFilter = {
|
|
192
|
+
$and: [id_filter, { [synced_field]: { "<": rowToUpdate[synced_field] } }],
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return [syncSafeFilter, omitKeys(rowToUpdate, id_fields)];
|
|
196
|
+
});
|
|
197
|
+
await tableHandlerTx.updateBatch(
|
|
198
|
+
batchUpdates,
|
|
199
|
+
{ removeDisallowedFields: true },
|
|
200
|
+
undefined,
|
|
201
|
+
table_rules,
|
|
202
|
+
{ clientReq: { socket } },
|
|
203
|
+
);
|
|
204
|
+
} else {
|
|
205
|
+
rowsToUpdate = [];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (table_rules.insert && rowsToInsert.length) {
|
|
209
|
+
await tableHandlerTx.insert(
|
|
210
|
+
rowsToInsert,
|
|
211
|
+
{ removeDisallowedFields: true },
|
|
212
|
+
undefined,
|
|
213
|
+
table_rules,
|
|
214
|
+
{ clientReq: { socket } },
|
|
215
|
+
);
|
|
216
|
+
} else {
|
|
217
|
+
rowsToInsert = [];
|
|
300
218
|
}
|
|
219
|
+
|
|
220
|
+
return { inserts: rowsToInsert, updates: rowsToUpdate };
|
|
301
221
|
})
|
|
302
222
|
.then(({ inserts, updates }) => {
|
|
303
223
|
log(
|
|
@@ -318,15 +238,17 @@ export async function syncData(
|
|
|
318
238
|
return Promise.reject(new Error("Something went wrong with syncing to server: "));
|
|
319
239
|
});
|
|
320
240
|
|
|
321
|
-
await
|
|
241
|
+
await pubSubManager._log({
|
|
322
242
|
type: "sync",
|
|
323
243
|
command: "upsertData",
|
|
244
|
+
channelName: channel_name,
|
|
324
245
|
tableName: sync.table_name,
|
|
325
246
|
rows: data.length,
|
|
326
247
|
socketId: socket_id,
|
|
327
248
|
sid: sync.sid,
|
|
328
249
|
duration: Date.now() - start,
|
|
329
|
-
connectedSocketIds:
|
|
250
|
+
connectedSocketIds: pubSubManager.dboBuilder.prostgles.connectedSockets.map((s) => s.id),
|
|
251
|
+
syncParams: sync,
|
|
330
252
|
});
|
|
331
253
|
|
|
332
254
|
return result;
|
|
@@ -335,13 +257,18 @@ export async function syncData(
|
|
|
335
257
|
* Pushes the given data to client
|
|
336
258
|
* @param isSynced = true if
|
|
337
259
|
*/
|
|
338
|
-
pushData = async (data
|
|
260
|
+
pushData = async (data: AnyObject[], isSynced = false) => {
|
|
339
261
|
const start = Date.now();
|
|
340
|
-
const result = await new Promise
|
|
262
|
+
const result = await new Promise<{
|
|
263
|
+
pushed: number;
|
|
264
|
+
resp: {
|
|
265
|
+
ok: boolean;
|
|
266
|
+
};
|
|
267
|
+
}>((resolve, reject) => {
|
|
341
268
|
socket.emit(channel_name, { data, isSynced }, (resp?: { ok: boolean }) => {
|
|
342
269
|
if (resp && resp.ok) {
|
|
343
270
|
// console.log("PUSHED to client: fr/lr", data[0], data[data.length - 1]);
|
|
344
|
-
resolve({ pushed: data
|
|
271
|
+
resolve({ pushed: data.length, resp });
|
|
345
272
|
} else {
|
|
346
273
|
reject(resp);
|
|
347
274
|
console.error("Unexpected response");
|
|
@@ -349,15 +276,17 @@ export async function syncData(
|
|
|
349
276
|
});
|
|
350
277
|
});
|
|
351
278
|
|
|
352
|
-
await
|
|
279
|
+
await pubSubManager._log({
|
|
353
280
|
type: "sync",
|
|
354
281
|
command: "pushData",
|
|
355
282
|
tableName: sync.table_name,
|
|
356
|
-
rows: data
|
|
283
|
+
rows: data.length,
|
|
357
284
|
socketId: socket_id,
|
|
358
285
|
duration: Date.now() - start,
|
|
359
286
|
sid: sync.sid,
|
|
360
|
-
connectedSocketIds:
|
|
287
|
+
connectedSocketIds: pubSubManager.dboBuilder.prostgles.connectedSockets.map((s) => s.id),
|
|
288
|
+
channelName: channel_name,
|
|
289
|
+
syncParams: sync,
|
|
361
290
|
});
|
|
362
291
|
|
|
363
292
|
return result;
|
|
@@ -416,7 +345,7 @@ export async function syncData(
|
|
|
416
345
|
sync_fields.map((key) => {
|
|
417
346
|
_filter[key] = c_lr[key];
|
|
418
347
|
});
|
|
419
|
-
server_row = await
|
|
348
|
+
server_row = await tableHandler.find(
|
|
420
349
|
_filter,
|
|
421
350
|
{ select: sync_fields, limit: 1 },
|
|
422
351
|
undefined,
|
|
@@ -443,20 +372,21 @@ export async function syncData(
|
|
|
443
372
|
|
|
444
373
|
return result;
|
|
445
374
|
},
|
|
446
|
-
updateSyncLR = (data: AnyObject) => {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
sync.
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
sync.last_synced = +sync.lr?.[synced_field];
|
|
375
|
+
updateSyncLR = (data: AnyObject[]) => {
|
|
376
|
+
const lastRow = data.at(-1);
|
|
377
|
+
if (!lastRow) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (sync.lr?.[synced_field] && +sync.lr[synced_field] > +lastRow[synced_field]) {
|
|
381
|
+
console.error(
|
|
382
|
+
{
|
|
383
|
+
syncIssue: "sync.lr[synced_field] is greater than lastRow[synced_field]",
|
|
384
|
+
},
|
|
385
|
+
sync.table_name,
|
|
386
|
+
);
|
|
459
387
|
}
|
|
388
|
+
sync.lr = lastRow;
|
|
389
|
+
sync.last_synced = +sync.lr[synced_field];
|
|
460
390
|
},
|
|
461
391
|
/**
|
|
462
392
|
* Will push pull sync between client and server from a given from_synced value
|
|
@@ -465,8 +395,7 @@ export async function syncData(
|
|
|
465
395
|
let offset = 0,
|
|
466
396
|
canContinue = true;
|
|
467
397
|
const limit = batch_size,
|
|
468
|
-
min_synced = from_synced || 0
|
|
469
|
-
max_synced = from_synced;
|
|
398
|
+
min_synced = from_synced || 0;
|
|
470
399
|
|
|
471
400
|
let inserted = 0,
|
|
472
401
|
updated = 0,
|
|
@@ -490,7 +419,7 @@ export async function syncData(
|
|
|
490
419
|
serverData = await getServerData(min_synced, offset);
|
|
491
420
|
} catch (e) {
|
|
492
421
|
console.trace("sync getServerData err", e);
|
|
493
|
-
await pushData(undefined, undefined, "Internal error. Check server logs");
|
|
422
|
+
// await pushData(undefined, undefined, "Internal error. Check server logs");
|
|
494
423
|
throw " d";
|
|
495
424
|
}
|
|
496
425
|
|
|
@@ -503,7 +432,7 @@ export async function syncData(
|
|
|
503
432
|
// await Promise.all(
|
|
504
433
|
// to_delete.map((d) => {
|
|
505
434
|
// deleted++;
|
|
506
|
-
// return (
|
|
435
|
+
// return (pubSubManager.dbo[table_name] as TableHandler).delete(
|
|
507
436
|
// pickKeys(d, id_fields),
|
|
508
437
|
// {},
|
|
509
438
|
// undefined,
|
|
@@ -520,7 +449,7 @@ export async function syncData(
|
|
|
520
449
|
);
|
|
521
450
|
});
|
|
522
451
|
if (forClient.length) {
|
|
523
|
-
const res
|
|
452
|
+
const res = await pushData(
|
|
524
453
|
forClient.filter((d) => !sync.wal || !sync.wal.isInHistory(d)),
|
|
525
454
|
);
|
|
526
455
|
pushed += res.pushed;
|
|
@@ -532,9 +461,7 @@ export async function syncData(
|
|
|
532
461
|
}
|
|
533
462
|
offset += serverData.length;
|
|
534
463
|
|
|
535
|
-
// canContinue = offset >= limit;
|
|
536
464
|
canContinue = serverData.length >= limit;
|
|
537
|
-
// console.log(`sData ${sData.length} limit ${limit}`);
|
|
538
465
|
}
|
|
539
466
|
log(
|
|
540
467
|
`server.syncBatch ${table_name}: inserted( ${inserted} ) updated( ${updated} ) deleted( ${deleted} ) pushed to client( ${pushed} ) total( ${total} )`,
|
|
@@ -544,115 +471,22 @@ export async function syncData(
|
|
|
544
471
|
return true;
|
|
545
472
|
};
|
|
546
473
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
// console.log("WAL upsertData END")
|
|
566
|
-
|
|
567
|
-
/******** */
|
|
568
|
-
/* TO DO -> Store and push patch updates instead of full data if and where possible */
|
|
569
|
-
/******** */
|
|
570
|
-
// 1. Store successfully upserted wal items for a couple of seconds
|
|
571
|
-
// 2. When pushing data to clients check if any matching wal items exist
|
|
572
|
-
// 3. Replace text fields with matching patched data
|
|
573
|
-
|
|
574
|
-
return res;
|
|
575
|
-
},
|
|
576
|
-
onSendEnd: (batch) => {
|
|
577
|
-
updateSyncLR(batch);
|
|
578
|
-
sync.is_syncing = false;
|
|
579
|
-
// console.log("syncData from WAL.onSendEnd")
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* After all data was inserted request SyncInfo from client and sync again if necessary
|
|
583
|
-
*/
|
|
584
|
-
void this.syncData(sync, undefined, source);
|
|
585
|
-
},
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
/* Debounce sync requests */
|
|
590
|
-
if (!sync.wal) throw "sync.wal missing";
|
|
591
|
-
if (!sync.wal.isSending() && sync.is_syncing) {
|
|
592
|
-
if (!this.syncTimeout) {
|
|
593
|
-
this.syncTimeout = setTimeout(() => {
|
|
594
|
-
this.syncTimeout = undefined;
|
|
595
|
-
// console.log("SYNC FROM TIMEOUT")
|
|
596
|
-
void this.syncData(sync, undefined, source);
|
|
597
|
-
}, throttle);
|
|
598
|
-
}
|
|
599
|
-
// console.log("SYNC THROTTLE")
|
|
600
|
-
return;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// console.log("syncData", clientData)
|
|
604
|
-
|
|
605
|
-
/**
|
|
606
|
-
* Express data sent from a client that has already been synced
|
|
607
|
-
* Add to WAL manager which will sync at the end
|
|
608
|
-
*/
|
|
609
|
-
if (clientData) {
|
|
610
|
-
if (clientData.data && Array.isArray(clientData.data) && clientData.data.length) {
|
|
611
|
-
return sync.wal.addData(clientData.data.map((d) => ({ current: d })));
|
|
612
|
-
|
|
613
|
-
// await upsertData(clientData.data, true);
|
|
614
|
-
|
|
615
|
-
/* Not expecting this anymore. use normal db.table.delete channel */
|
|
616
|
-
} else if (
|
|
617
|
-
clientData.deleted &&
|
|
618
|
-
Array.isArray(clientData.deleted) &&
|
|
619
|
-
clientData.deleted.length
|
|
620
|
-
) {
|
|
621
|
-
await deleteData(clientData.deleted);
|
|
622
|
-
}
|
|
623
|
-
} else {
|
|
624
|
-
// do nothing
|
|
625
|
-
}
|
|
626
|
-
if (sync.wal.isSending()) return;
|
|
627
|
-
|
|
628
|
-
sync.is_syncing = true;
|
|
629
|
-
|
|
630
|
-
// from synced does not make sense. It should be sync.lr only!!!
|
|
631
|
-
let from_synced = null;
|
|
632
|
-
|
|
633
|
-
/** Sync was already synced */
|
|
634
|
-
if (sync.lr) {
|
|
635
|
-
const { s_lr } = await getServerRowInfo();
|
|
636
|
-
|
|
637
|
-
/* Make sure trigger is not firing on freshly synced data */
|
|
638
|
-
if (!rowsFullyMatch(sync.lr, s_lr)) {
|
|
639
|
-
from_synced = sync.last_synced;
|
|
640
|
-
} else {
|
|
641
|
-
// console.log("rowsFullyMatch")
|
|
642
|
-
}
|
|
643
|
-
// console.log(table_name, sync.lr[synced_field])
|
|
644
|
-
} else {
|
|
645
|
-
from_synced = await getLastSynced(clientData);
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
if (from_synced !== null) {
|
|
649
|
-
await syncBatch(from_synced);
|
|
650
|
-
} else {
|
|
651
|
-
// console.log("from_synced is null")
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
await pushData([], true);
|
|
655
|
-
|
|
656
|
-
sync.is_syncing = false;
|
|
657
|
-
// console.log(`Finished sync for ${table_name}`, socket._user);
|
|
474
|
+
return {
|
|
475
|
+
rowsIdsMatch,
|
|
476
|
+
rowsFullyMatch,
|
|
477
|
+
getServerRowInfo,
|
|
478
|
+
getClientRowInfo,
|
|
479
|
+
getClientData,
|
|
480
|
+
getServerData,
|
|
481
|
+
deleteData,
|
|
482
|
+
upsertData,
|
|
483
|
+
pushData,
|
|
484
|
+
getLastSynced,
|
|
485
|
+
updateSyncLR,
|
|
486
|
+
syncBatch,
|
|
487
|
+
};
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
function getNumbers(numberArr: (null | undefined | string | number)[]): number[] {
|
|
491
|
+
return numberArr.filter((v) => v !== null && v !== undefined && Number.isFinite(+v)) as number[];
|
|
658
492
|
}
|