document-drive 1.29.4-dev.1 → 1.29.4-dev.3
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/prisma/schema.prisma +91 -0
- package/dist/src/server/base-server.d.ts.map +1 -1
- package/dist/src/server/base-server.js +13 -1
- package/dist/src/server/listener/listener-manager.d.ts.map +1 -1
- package/dist/src/server/listener/listener-manager.js +67 -44
- package/dist/src/server/listener/transmitter/pull-responder.d.ts +8 -0
- package/dist/src/server/listener/transmitter/pull-responder.d.ts.map +1 -1
- package/dist/src/server/listener/transmitter/pull-responder.js +158 -67
- package/dist/src/server/listener/transmitter/types.d.ts +3 -1
- package/dist/src/server/listener/transmitter/types.d.ts.map +1 -1
- package/dist/src/server/sync-manager.d.ts.map +1 -1
- package/dist/src/server/sync-manager.js +18 -0
- package/dist/src/storage/prisma/client/default.d.ts +1 -0
- package/dist/src/storage/prisma/client/default.js +1 -0
- package/dist/src/storage/prisma/client/edge.d.ts +1 -0
- package/dist/src/storage/prisma/client/edge.js +253 -0
- package/dist/src/storage/prisma/client/index-browser.js +244 -0
- package/dist/src/storage/prisma/client/index.d.ts +10447 -0
- package/dist/src/storage/prisma/client/index.js +274 -0
- package/dist/src/storage/prisma/client/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
- package/dist/src/storage/prisma/client/package.json +84 -0
- package/dist/src/storage/prisma/client/schema.prisma +91 -0
- package/dist/src/storage/prisma/client/wasm.d.ts +1 -0
- package/dist/src/storage/prisma/client/wasm.js +244 -0
- package/dist/src/storage/prisma/factory.d.ts.map +1 -1
- package/dist/src/storage/prisma/factory.js +1 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// This is your Prisma schema file,
|
|
2
|
+
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
3
|
+
|
|
4
|
+
generator client {
|
|
5
|
+
provider = "prisma-client-js"
|
|
6
|
+
output = "../src/storage/prisma/client"
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
datasource db {
|
|
10
|
+
provider = "postgresql"
|
|
11
|
+
url = env("DATABASE_URL")
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
model Drive {
|
|
15
|
+
id String @id
|
|
16
|
+
slug String @unique
|
|
17
|
+
driveDocuments DriveDocument[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
model Document {
|
|
21
|
+
id String @id
|
|
22
|
+
created DateTime @default(now())
|
|
23
|
+
lastModified DateTime @default(now())
|
|
24
|
+
isDrive Boolean
|
|
25
|
+
revision String
|
|
26
|
+
name String?
|
|
27
|
+
operations Operation[]
|
|
28
|
+
initialState String // json object with the scope as keys of the root object
|
|
29
|
+
documentType String
|
|
30
|
+
meta String?
|
|
31
|
+
synchronizationUnits SynchronizationUnit[]
|
|
32
|
+
driveDocuments DriveDocument[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Model to map the many-to-many relationship between drives and documents
|
|
36
|
+
model DriveDocument {
|
|
37
|
+
driveId String
|
|
38
|
+
documentId String
|
|
39
|
+
drive Drive @relation(fields: [driveId], references: [id], onDelete: Cascade)
|
|
40
|
+
document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
|
41
|
+
|
|
42
|
+
@@id([driveId, documentId])
|
|
43
|
+
@@index([driveId])
|
|
44
|
+
@@index([documentId])
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
model Operation {
|
|
48
|
+
id String @id @default(uuid())
|
|
49
|
+
opId String?
|
|
50
|
+
Document Document? @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
|
51
|
+
documentId String
|
|
52
|
+
scope String
|
|
53
|
+
branch String
|
|
54
|
+
index Int
|
|
55
|
+
skip Int
|
|
56
|
+
hash String
|
|
57
|
+
timestamp DateTime
|
|
58
|
+
input String
|
|
59
|
+
type String
|
|
60
|
+
attachments Attachment[]
|
|
61
|
+
syncId String?
|
|
62
|
+
clipboard Boolean? @default(false)
|
|
63
|
+
context Json?
|
|
64
|
+
resultingState Bytes?
|
|
65
|
+
|
|
66
|
+
SynchronizationUnit SynchronizationUnit? @relation(fields: [syncId], references: [id], onDelete: Cascade)
|
|
67
|
+
|
|
68
|
+
@@unique([documentId, scope, branch, index(sort: Asc)], name: "unique_operation")
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
model SynchronizationUnit {
|
|
72
|
+
id String @id
|
|
73
|
+
documentId String
|
|
74
|
+
|
|
75
|
+
Document Document @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
|
76
|
+
scope String
|
|
77
|
+
branch String
|
|
78
|
+
operations Operation[]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
model Attachment {
|
|
82
|
+
id String @id @default(uuid())
|
|
83
|
+
operationId String
|
|
84
|
+
Operation Operation @relation(fields: [operationId], references: [id], onDelete: Cascade)
|
|
85
|
+
|
|
86
|
+
mimeType String
|
|
87
|
+
data String
|
|
88
|
+
filename String?
|
|
89
|
+
extension String?
|
|
90
|
+
hash String
|
|
91
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-server.d.ts","sourceRoot":"","sources":["../../../src/server/base-server.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,aAAa,EAKnB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AAKvC,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAG3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,KAAK,MAAM,EAEX,KAAK,mBAAmB,EACxB,KAAK,SAAS,EAEd,KAAK,UAAU,EAYhB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAGL,cAAc,EACd,KAAK,gCAAgC,EACtC,MAAM,YAAY,CAAC;AAOpB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAExB,KAAK,0BAA0B,EAC/B,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAE5B,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,YAAY,EAEjB,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,YAAY,CAAC;AAGpB,qBAAa,uBACX,YAAW,wBAAwB,EAAE,qBAAqB;IAG1D,OAAO,CAAC,oBAAoB,CAAwB;IACpD,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,YAAY,CAAgB;IACpC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,0BAA0B,CAAC,CAAC;IACxD,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,sBAAsB,CAA0B;IAGxD,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,OAAO,CAAC,4BAA4B,CAIlC;IAEF,OAAO,CAAC,aAAa,CAgCnB;IAGF,OAAO,CAAC,UAAU,CAGd;IACJ,OAAO,CAAC,iBAAiB,CAA0B;gBAGjD,oBAAoB,EAAE,mBAAmB,EAAE,EAC3C,OAAO,EAAE,aAAa,EACtB,eAAe,EAAE,gBAAgB,EACjC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,aAAa,EAC3B,YAAY,EAAE,aAAa,EAC3B,sBAAsB,EAAE,uBAAuB,EAC/C,eAAe,EAAE,gBAAgB,EAEjC,OAAO,CAAC,EAAE,0BAA0B;IAsCtC,IAAI,SAAS,IAAI,gBAAgB,CAEhC;IAED,UAAU;YAII,WAAW;IA8BzB,uBAAuB,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,IAAI;IAM7D,6BAA6B;IAI7B,sBAAsB;IAItB,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB;IAIrE,8BAA8B,CAAC,KAAK,EAAE,sBAAsB;IAI5D,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,mBAAmB;IAmB3B,OAAO,CAAC,qBAAqB;YAOf,oBAAoB;YA2HpB,mBAAmB;YAgBnB,gBAAgB;
|
|
1
|
+
{"version":3,"file":"base-server.d.ts","sourceRoot":"","sources":["../../../src/server/base-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -236,15 +236,21 @@ export class BaseDocumentDriveServer {
|
|
|
236
236
|
}
|
|
237
237
|
async _initializeDrive(driveId) {
|
|
238
238
|
const drive = await this.getDrive(driveId);
|
|
239
|
+
logger.verbose(`[SYNC DEBUG] Initializing drive ${driveId} with slug "${drive.state.global.slug}"`);
|
|
239
240
|
await this.synchronizationManager.initializeDriveSyncStatus(driveId, drive);
|
|
240
241
|
if (this.shouldSyncRemoteDrive(drive)) {
|
|
242
|
+
logger.verbose(`[SYNC DEBUG] Starting sync for remote drive ${driveId}`);
|
|
241
243
|
await this.startSyncRemoteDrive(driveId);
|
|
242
244
|
}
|
|
243
245
|
// add switchboard push listeners
|
|
246
|
+
logger.verbose(`[SYNC DEBUG] Processing ${drive.state.local.listeners.length} listeners for drive ${driveId}`);
|
|
244
247
|
for (const zodListener of drive.state.local.listeners) {
|
|
245
248
|
if (zodListener.callInfo?.transmitterType === "SwitchboardPush") {
|
|
249
|
+
logger.verbose(`[SYNC DEBUG] Setting up SwitchboardPush listener ${zodListener.listenerId} for drive ${driveId}`);
|
|
246
250
|
const transmitter = new SwitchboardPushTransmitter(zodListener.callInfo?.data ?? "");
|
|
247
|
-
|
|
251
|
+
logger.verbose(`[SYNC DEBUG] Created SwitchboardPush transmitter with URL: ${zodListener.callInfo?.data || "none"}`);
|
|
252
|
+
await this.listenerManager
|
|
253
|
+
.setListener(driveId, {
|
|
248
254
|
block: zodListener.block,
|
|
249
255
|
driveId: drive.state.global.id,
|
|
250
256
|
filter: {
|
|
@@ -258,8 +264,14 @@ export class BaseDocumentDriveServer {
|
|
|
258
264
|
system: zodListener.system,
|
|
259
265
|
label: zodListener.label ?? "",
|
|
260
266
|
transmitter,
|
|
267
|
+
})
|
|
268
|
+
.then(() => {
|
|
269
|
+
logger.verbose(`[SYNC DEBUG] Successfully set up listener ${zodListener.listenerId} for drive ${driveId}`);
|
|
261
270
|
});
|
|
262
271
|
}
|
|
272
|
+
else {
|
|
273
|
+
logger.error(`Skipping listener ${zodListener.listenerId} with unsupported type ${zodListener.callInfo?.transmitterType || "unknown"}`);
|
|
274
|
+
}
|
|
263
275
|
}
|
|
264
276
|
}
|
|
265
277
|
// Delegate synchronization methods to synchronizationManager
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listener-manager.d.ts","sourceRoot":"","sources":["../../../../src/server/listener/listener-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAEL,KAAK,uBAAuB,EAE5B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,cAAc,EAEnB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,eAAe,CAAC;AAOvB,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,MAAM,CAAC,qBAAqB,SAAO;IAEnC,SAAS,CAAC,MAAM,gDAGb;IAEH,SAAS,CAAC,WAAW,EAAE,uBAAuB,CAAC;IAC/C,SAAS,CAAC,OAAO,EAAE,sBAAsB,CAAC;IAG1C,SAAS,CAAC,sBAAsB,0CAG5B;gBAGF,WAAW,EAAE,uBAAuB,EACpC,OAAO,GAAE,sBAAsD;IAQ3D,UAAU,CAAC,OAAO,EAAE,uBAAuB;IAcjD,iBAAiB,CAAC,OAAO,EAAE,MAAM;IAI3B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IA+B/C,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAWlD,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,EAAE,GAC/C,OAAO,CAAC,IAAI,CAAC;IAaV,8BAA8B,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,mBAAmB,EAAE,EAChC,MAAM,EAAE,kBAAkB,EAC1B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,EAC5C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,EAC1E,SAAS,UAAQ;IA2Cb,sBAAsB,CAC1B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAuBhB,aAAa,sEAOO,KAAK,WAAW,MAAM,YAAY,aAAa,KAAK,IAAI,+EAJ1E;YAEY,cAAc;IA8N5B,OAAO,CAAC,YAAY;IAsBpB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAexD,sBAAsB,CACpB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAehC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB3C,UAAU,CACd,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"listener-manager.d.ts","sourceRoot":"","sources":["../../../../src/server/listener/listener-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAEL,KAAK,uBAAuB,EAE5B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,cAAc,EAEnB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,eAAe,CAAC;AAOvB,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,MAAM,CAAC,qBAAqB,SAAO;IAEnC,SAAS,CAAC,MAAM,gDAGb;IAEH,SAAS,CAAC,WAAW,EAAE,uBAAuB,CAAC;IAC/C,SAAS,CAAC,OAAO,EAAE,sBAAsB,CAAC;IAG1C,SAAS,CAAC,sBAAsB,0CAG5B;gBAGF,WAAW,EAAE,uBAAuB,EACpC,OAAO,GAAE,sBAAsD;IAQ3D,UAAU,CAAC,OAAO,EAAE,uBAAuB;IAcjD,iBAAiB,CAAC,OAAO,EAAE,MAAM;IAI3B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;IA+B/C,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAWlD,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,EAAE,GAC/C,OAAO,CAAC,IAAI,CAAC;IAaV,8BAA8B,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,mBAAmB,EAAE,EAChC,MAAM,EAAE,kBAAkB,EAC1B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,EAC5C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,EAC1E,SAAS,UAAQ;IA2Cb,sBAAsB,CAC1B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAuBhB,aAAa,sEAOO,KAAK,WAAW,MAAM,YAAY,aAAa,KAAK,IAAI,+EAJ1E;YAEY,cAAc;IA8N5B,OAAO,CAAC,YAAY;IAsBpB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAexD,sBAAsB,CACpB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAehC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB3C,UAAU,CACd,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC;IAuH1B,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAepD,gBAAgB,CACd,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,aAAa;CAU/B"}
|
|
@@ -324,58 +324,81 @@ export class ListenerManager {
|
|
|
324
324
|
}
|
|
325
325
|
async getStrands(driveId, listenerId, options) {
|
|
326
326
|
// this will throw if listenerState is not found
|
|
327
|
-
|
|
327
|
+
this.logger.verbose(`[SYNC DEBUG] ListenerManager.getStrands called for drive: ${driveId}, listener: ${listenerId}, options: ${JSON.stringify(options || {})}`);
|
|
328
|
+
let listenerState;
|
|
329
|
+
try {
|
|
330
|
+
listenerState = this.getListenerState(driveId, listenerId);
|
|
331
|
+
this.logger.verbose(`[SYNC DEBUG] Found listener state for drive: ${driveId}, listener: ${listenerId}, status: ${listenerState.listenerStatus}`);
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
this.logger.error(`[SYNC DEBUG] Failed to find listener state for drive: ${driveId}, listener: ${listenerId}. Error: ${error}`);
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
328
337
|
// fetch operations from drive and prepare strands
|
|
329
338
|
const strands = [];
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
if (syncUnit.revision < 0) {
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
const entry = listenerState.syncUnits.get(syncUnit.syncId);
|
|
342
|
-
if (entry && entry.listenerRev >= syncUnit.revision) {
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
const { documentId, scope, branch } = syncUnit;
|
|
346
|
-
try {
|
|
347
|
-
const operations = await this.syncManager.getOperationData(
|
|
348
|
-
// DEAL WITH INVALID SYNC ID ERROR
|
|
349
|
-
driveId, syncUnit.syncId, {
|
|
350
|
-
since: options?.since,
|
|
351
|
-
fromRevision: options?.fromRevision ?? entry?.listenerRev,
|
|
352
|
-
limit: limit ? limit - operationsCount : undefined,
|
|
353
|
-
});
|
|
354
|
-
if (!operations.length) {
|
|
339
|
+
try {
|
|
340
|
+
const syncUnits = await this.getListenerSyncUnits(driveId, listenerId);
|
|
341
|
+
this.logger.verbose(`[SYNC DEBUG] Retrieved ${syncUnits.length} sync units for drive: ${driveId}, listener: ${listenerId}`);
|
|
342
|
+
const limit = options?.limit; // maximum number of operations to send across all sync units
|
|
343
|
+
let operationsCount = 0; // total amount of operations that have been retrieved
|
|
344
|
+
const tasks = syncUnits.map((syncUnit) => async () => {
|
|
345
|
+
if (limit && operationsCount >= limit) {
|
|
346
|
+
// break;
|
|
355
347
|
return;
|
|
356
348
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
349
|
+
if (syncUnit.revision < 0) {
|
|
350
|
+
this.logger.verbose(`[SYNC DEBUG] Skipping sync unit with negative revision: ${syncUnit.syncId}, revision: ${syncUnit.revision}`);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const entry = listenerState.syncUnits.get(syncUnit.syncId);
|
|
354
|
+
if (entry && entry.listenerRev >= syncUnit.revision) {
|
|
355
|
+
this.logger.verbose(`[SYNC DEBUG] Skipping sync unit - listener already up to date: ${syncUnit.syncId}, listenerRev: ${entry.listenerRev}, revision: ${syncUnit.revision}`);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const { documentId, scope, branch } = syncUnit;
|
|
359
|
+
try {
|
|
360
|
+
this.logger.verbose(`[SYNC DEBUG] Getting operations for syncUnit: ${syncUnit.syncId}, documentId: ${documentId}, scope: ${scope}, branch: ${branch}`);
|
|
361
|
+
const operations = await this.syncManager.getOperationData(
|
|
362
|
+
// DEAL WITH INVALID SYNC ID ERROR
|
|
363
|
+
driveId, syncUnit.syncId, {
|
|
364
|
+
since: options?.since,
|
|
365
|
+
fromRevision: options?.fromRevision ?? entry?.listenerRev,
|
|
366
|
+
limit: limit ? limit - operationsCount : undefined,
|
|
367
|
+
});
|
|
368
|
+
this.logger.verbose(`[SYNC DEBUG] Retrieved ${operations.length} operations for syncUnit: ${syncUnit.syncId}`);
|
|
369
|
+
if (!operations.length) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
operationsCount += operations.length;
|
|
373
|
+
strands.push({
|
|
374
|
+
driveId,
|
|
375
|
+
documentId,
|
|
376
|
+
scope: scope,
|
|
377
|
+
branch,
|
|
378
|
+
operations,
|
|
379
|
+
});
|
|
380
|
+
this.logger.verbose(`[SYNC DEBUG] Added strand with ${operations.length} operations for syncUnit: ${syncUnit.syncId}`);
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
this.logger.error(`Error getting operations for syncUnit: ${syncUnit.syncId}, error: ${error}`);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
if (this.options.sequentialUpdates) {
|
|
388
|
+
this.logger.verbose(`[SYNC DEBUG] Processing ${tasks.length} sync units sequentially`);
|
|
389
|
+
for (const task of tasks) {
|
|
390
|
+
await task();
|
|
391
|
+
}
|
|
369
392
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
await task();
|
|
393
|
+
else {
|
|
394
|
+
this.logger.verbose(`[SYNC DEBUG] Processing ${tasks.length} sync units in parallel`);
|
|
395
|
+
await Promise.all(tasks.map((task) => task()));
|
|
374
396
|
}
|
|
375
397
|
}
|
|
376
|
-
|
|
377
|
-
|
|
398
|
+
catch (error) {
|
|
399
|
+
this.logger.error(`Error in getStrands: ${error}`);
|
|
378
400
|
}
|
|
401
|
+
this.logger.verbose(`ListenerManager.getStrands returning ${strands.length} strands for drive: ${driveId}, listener: ${listenerId}`);
|
|
379
402
|
return strands;
|
|
380
403
|
}
|
|
381
404
|
getListenerState(driveId, listenerId) {
|
|
@@ -30,6 +30,14 @@ export declare class PullResponderTransmitter implements IPullResponderTransmitt
|
|
|
30
30
|
static registerPullResponder(driveId: string, url: string, filter: ListenerFilter): Promise<Listener["listenerId"]>;
|
|
31
31
|
static pullStrands(driveId: string, url: string, listenerId: string, options?: GetStrandsOptions): Promise<StrandUpdate[]>;
|
|
32
32
|
static acknowledgeStrands(url: string, listenerId: string, revisions: ListenerRevision[]): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* This function will only throw if `onError` throws an error (or there is
|
|
35
|
+
* an unintentionally unhandled error in the pull loop).
|
|
36
|
+
*
|
|
37
|
+
* All other errors are caught, logged, and passed to `onError`.
|
|
38
|
+
*
|
|
39
|
+
* Because of this, `onError` _may be called multiple times_.
|
|
40
|
+
*/
|
|
33
41
|
private static executePull;
|
|
34
42
|
static setupPull(driveId: string, trigger: PullResponderTrigger, onStrandUpdate: (strand: StrandUpdate, source: StrandUpdateSource) => Promise<IOperationResult>, onError: (error: Error) => void, onRevisions?: (revisions: ListenerRevisionWithError[]) => void, onAcknowledge?: (success: boolean) => void): CancelPullLoop;
|
|
35
43
|
static createPullResponderTrigger(driveId: string, url: string, options: Pick<RemoteDriveOptions, "pullInterval" | "pullFilter">): Promise<PullResponderTrigger>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull-responder.d.ts","sourceRoot":"","sources":["../../../../../src/server/listener/transmitter/pull-responder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,OAAO,EACb,MAAM,iCAAiC,CAAC;AAOzC,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,GAAG;IACpE,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE;QACN,IAAI,EAAE;YACJ,OAAO,EAAE,mBAAmB,EAAE,CAAC;SAChC,CAAC;KACH,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC;AAExC,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG;IACnE,UAAU,EAAE,sBAAsB,EAAE,CAAC;CACtC,CAAC;AAEF,MAAM,WAAW,yBAA0B,SAAQ,YAAY;IAC7D,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAClE;AAID,qBAAa,wBAAyB,YAAW,yBAAyB;IACxE,OAAO,CAAC,MAAM,CAAC,YAAY,CAGxB;IAEH,OAAO,CAAC,MAAM,CAGX;IAEH,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,OAAO,CAAmB;gBAEtB,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB;IAMzD,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"pull-responder.d.ts","sourceRoot":"","sources":["../../../../../src/server/listener/transmitter/pull-responder.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,8 +22,21 @@ export class PullResponderTransmitter {
|
|
|
22
22
|
this.logger.verbose(`constructor(listener: ${listener.listenerId})`);
|
|
23
23
|
}
|
|
24
24
|
getStrands(options) {
|
|
25
|
-
this.logger.verbose(`getStrands
|
|
26
|
-
return this.manager
|
|
25
|
+
this.logger.verbose(`[SYNC DEBUG] PullResponderTransmitter.getStrands called for drive: ${this.listener.driveId}, listener: ${this.listener.listenerId}, options: ${JSON.stringify(options || {})}`);
|
|
26
|
+
return this.manager
|
|
27
|
+
.getStrands(this.listener.driveId, this.listener.listenerId, options)
|
|
28
|
+
.then((strands) => {
|
|
29
|
+
this.logger.verbose(`[SYNC DEBUG] PullResponderTransmitter.getStrands returning ${strands.length} strands for drive: ${this.listener.driveId}, listener: ${this.listener.listenerId}`);
|
|
30
|
+
if (strands.length === 0) {
|
|
31
|
+
this.logger.verbose(`[SYNC DEBUG] No strands returned for drive: ${this.listener.driveId}, listener: ${this.listener.listenerId}`);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
for (const strand of strands) {
|
|
35
|
+
this.logger.verbose(`[SYNC DEBUG] Strand for drive: ${strand.driveId}, document: ${strand.documentId}, scope: ${strand.scope}, operations: ${strand.operations.length}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return strands;
|
|
39
|
+
});
|
|
27
40
|
}
|
|
28
41
|
disconnect() {
|
|
29
42
|
// TODO remove listener from switchboard
|
|
@@ -66,7 +79,7 @@ export class PullResponderTransmitter {
|
|
|
66
79
|
return result.registerPullResponderListener.listenerId;
|
|
67
80
|
}
|
|
68
81
|
static async pullStrands(driveId, url, listenerId, options) {
|
|
69
|
-
this.staticLogger.verbose(`pullStrands
|
|
82
|
+
this.staticLogger.verbose(`[SYNC DEBUG] PullResponderTransmitter.pullStrands called for drive: ${driveId}, url: ${url}, listener: ${listenerId}, options: ${JSON.stringify(options || {})}`);
|
|
70
83
|
const result = await requestGraphql(url, gql `
|
|
71
84
|
query strands($listenerId: ID!) {
|
|
72
85
|
system {
|
|
@@ -106,18 +119,25 @@ export class PullResponderTransmitter {
|
|
|
106
119
|
`, { listenerId });
|
|
107
120
|
const error = result.errors?.at(0);
|
|
108
121
|
if (error) {
|
|
122
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Error pulling strands for drive: ${driveId}, listener: ${listenerId}, error: ${JSON.stringify(error)}`);
|
|
109
123
|
throw error;
|
|
110
124
|
}
|
|
111
125
|
if (!result.system) {
|
|
126
|
+
this.staticLogger.verbose(`[SYNC DEBUG] No system data returned when pulling strands for drive: ${driveId}, listener: ${listenerId}`);
|
|
112
127
|
return [];
|
|
113
128
|
}
|
|
114
|
-
|
|
129
|
+
const strands = result.system.sync.strands.map((s) => ({
|
|
115
130
|
...s,
|
|
116
131
|
operations: s.operations.map((o) => ({
|
|
117
132
|
...o,
|
|
118
133
|
input: JSON.parse(o.input),
|
|
119
134
|
})),
|
|
120
135
|
}));
|
|
136
|
+
this.staticLogger.verbose(`[SYNC DEBUG] PullResponderTransmitter.pullStrands returning ${strands.length} strands for drive: ${driveId}, listener: ${listenerId}`);
|
|
137
|
+
if (strands.length > 0) {
|
|
138
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Strands being returned: ${strands.map((s) => `${s.documentId}:${s.scope}`).join(", ")}`);
|
|
139
|
+
}
|
|
140
|
+
return strands;
|
|
121
141
|
}
|
|
122
142
|
static async acknowledgeStrands(url, listenerId, revisions) {
|
|
123
143
|
this.staticLogger.verbose(`acknowledgeStrands(url: ${url}, listener: ${listenerId})`, revisions);
|
|
@@ -153,84 +173,147 @@ export class PullResponderTransmitter {
|
|
|
153
173
|
throw new Error("Error acknowledging strands");
|
|
154
174
|
}
|
|
155
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* This function will only throw if `onError` throws an error (or there is
|
|
178
|
+
* an unintentionally unhandled error in the pull loop).
|
|
179
|
+
*
|
|
180
|
+
* All other errors are caught, logged, and passed to `onError`.
|
|
181
|
+
*
|
|
182
|
+
* Because of this, `onError` _may be called multiple times_.
|
|
183
|
+
*/
|
|
156
184
|
static async executePull(driveId, trigger, onStrandUpdate, onError, onRevisions, onAcknowledge) {
|
|
157
185
|
this.staticLogger.verbose(`executePull(driveId: ${driveId}), trigger:`, trigger);
|
|
186
|
+
this.staticLogger.info(`[SYNC DEBUG] PullResponderTransmitter.executePull starting for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
187
|
+
const { url } = trigger.data;
|
|
188
|
+
let strands;
|
|
189
|
+
let error;
|
|
158
190
|
try {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
this.staticLogger.verbose("Processing strand...");
|
|
176
|
-
let error = undefined;
|
|
177
|
-
try {
|
|
178
|
-
const result = await onStrandUpdate(strand, {
|
|
179
|
-
type: "trigger",
|
|
180
|
-
trigger,
|
|
181
|
-
});
|
|
182
|
-
if (result.error) {
|
|
183
|
-
throw result.error;
|
|
191
|
+
strands = await PullResponderTransmitter.pullStrands(driveId, url, trigger.data.listenerId);
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
error = e;
|
|
195
|
+
const errors = error.response.errors;
|
|
196
|
+
for (const error of errors) {
|
|
197
|
+
if (error.message === "Listener not found") {
|
|
198
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Auto-registering pull responder for drive: ${driveId}`);
|
|
199
|
+
// register a new pull responder
|
|
200
|
+
const listenerId = await PullResponderTransmitter.registerPullResponder(trigger.driveId, url, trigger.filter);
|
|
201
|
+
// update the trigger with the new listenerId
|
|
202
|
+
trigger.data.listenerId = listenerId;
|
|
203
|
+
// try again
|
|
204
|
+
try {
|
|
205
|
+
strands = await PullResponderTransmitter.pullStrands(driveId, url, listenerId);
|
|
206
|
+
this.staticLogger.verbose(`Successfully auto-registerd and pulled strands for drive: ${driveId}, listenerId: ${listenerId}`);
|
|
184
207
|
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
this.staticLogger.error(`Could not resolve 'Listener not found' error by registering a new pull responder for drive: ${driveId}, listenerId: ${listenerId}: ${error}`);
|
|
210
|
+
onError(error);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
break;
|
|
185
214
|
}
|
|
186
|
-
catch (e) {
|
|
187
|
-
error = e;
|
|
188
|
-
onError(error);
|
|
189
|
-
}
|
|
190
|
-
listenerRevisions.push({
|
|
191
|
-
branch: strand.branch,
|
|
192
|
-
documentId: strand.documentId || "",
|
|
193
|
-
driveId: strand.driveId,
|
|
194
|
-
revision: operations.pop()?.index ?? -1,
|
|
195
|
-
scope: strand.scope,
|
|
196
|
-
status: error
|
|
197
|
-
? error instanceof OperationError
|
|
198
|
-
? error.status
|
|
199
|
-
: "ERROR"
|
|
200
|
-
: "SUCCESS",
|
|
201
|
-
error,
|
|
202
|
-
});
|
|
203
215
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
this.staticLogger.
|
|
207
|
-
|
|
216
|
+
}
|
|
217
|
+
if (!strands) {
|
|
218
|
+
this.staticLogger.error(`Error pulling strands for drive, and could not auto-register: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error}`);
|
|
219
|
+
onError(error);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
// if there are no new strands then do nothing
|
|
223
|
+
if (!strands.length) {
|
|
224
|
+
this.staticLogger.verbose(`[SYNC DEBUG] No strands returned in pull cycle for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
208
225
|
try {
|
|
209
|
-
|
|
210
|
-
const { error, ...rest } = revision;
|
|
211
|
-
return rest;
|
|
212
|
-
}));
|
|
213
|
-
success = true;
|
|
226
|
+
onRevisions?.([]);
|
|
214
227
|
}
|
|
215
228
|
catch (error) {
|
|
216
|
-
this.staticLogger.error(
|
|
229
|
+
this.staticLogger.error(`Error calling onRevisions for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error}`);
|
|
230
|
+
// pass the error to the caller
|
|
231
|
+
onError(error);
|
|
217
232
|
}
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Processing ${strands.length} strands in pull cycle for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
236
|
+
const listenerRevisions = [];
|
|
237
|
+
// todo: evaluate whether or not we can process strands in parallel
|
|
238
|
+
for (const strand of strands) {
|
|
239
|
+
const operations = strand.operations.map((op) => ({
|
|
240
|
+
...op,
|
|
241
|
+
scope: strand.scope,
|
|
242
|
+
branch: strand.branch,
|
|
243
|
+
}));
|
|
244
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Processing strand for drive: ${strand.driveId}, document: ${strand.documentId}, scope: ${strand.scope}, with ${operations.length} operations`);
|
|
245
|
+
let error = undefined;
|
|
246
|
+
try {
|
|
247
|
+
const result = await onStrandUpdate(strand, {
|
|
248
|
+
type: "trigger",
|
|
249
|
+
trigger,
|
|
250
|
+
});
|
|
251
|
+
if (result.error) {
|
|
252
|
+
throw result.error;
|
|
253
|
+
}
|
|
220
254
|
}
|
|
221
|
-
|
|
222
|
-
this.staticLogger.error(
|
|
255
|
+
catch (e) {
|
|
256
|
+
this.staticLogger.error(`Error processing strand for drive: ${strand.driveId}, document: ${strand.documentId}, scope: ${strand.scope}, with ${operations.length} operations: ${e}`);
|
|
257
|
+
error = e;
|
|
258
|
+
onError(error);
|
|
259
|
+
// continue
|
|
223
260
|
}
|
|
224
|
-
|
|
261
|
+
listenerRevisions.push({
|
|
262
|
+
branch: strand.branch,
|
|
263
|
+
documentId: strand.documentId || "",
|
|
264
|
+
driveId: strand.driveId,
|
|
265
|
+
revision: operations.pop()?.index ?? -1,
|
|
266
|
+
scope: strand.scope,
|
|
267
|
+
status: error
|
|
268
|
+
? error instanceof OperationError
|
|
269
|
+
? error.status
|
|
270
|
+
: "ERROR"
|
|
271
|
+
: "SUCCESS",
|
|
272
|
+
error,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
this.staticLogger.verbose("Processed strands...");
|
|
276
|
+
// do not let a listener kill the pull loop
|
|
277
|
+
try {
|
|
278
|
+
onRevisions?.(listenerRevisions);
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
this.staticLogger.error(`Error calling onRevisions for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error}`);
|
|
282
|
+
// pass the error to the caller
|
|
283
|
+
onError(error);
|
|
284
|
+
}
|
|
285
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Acknowledging ${listenerRevisions.length} strands for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
286
|
+
let success = false;
|
|
287
|
+
try {
|
|
288
|
+
await PullResponderTransmitter.acknowledgeStrands(url, trigger.data.listenerId, listenerRevisions.map((revision) => {
|
|
289
|
+
const { error, ...rest } = revision;
|
|
290
|
+
return rest;
|
|
291
|
+
}));
|
|
292
|
+
success = true;
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
this.staticLogger.error(`Error acknowledging strands for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error}`);
|
|
296
|
+
// pass the error to the caller
|
|
297
|
+
onError(error);
|
|
298
|
+
}
|
|
299
|
+
if (success) {
|
|
300
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Successfully acknowledged strands for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
this.staticLogger.error("Failed to acknowledge strands");
|
|
304
|
+
}
|
|
305
|
+
// let this throw separately
|
|
306
|
+
try {
|
|
225
307
|
onAcknowledge?.(success);
|
|
226
308
|
}
|
|
227
309
|
catch (error) {
|
|
228
|
-
this.staticLogger.error(
|
|
310
|
+
this.staticLogger.error(`Error calling onAcknowledge for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error}`);
|
|
311
|
+
// pass the error to the caller
|
|
229
312
|
onError(error);
|
|
230
313
|
}
|
|
231
314
|
}
|
|
232
315
|
static setupPull(driveId, trigger, onStrandUpdate, onError, onRevisions, onAcknowledge) {
|
|
233
|
-
this.staticLogger.verbose(`setupPull
|
|
316
|
+
this.staticLogger.verbose(`[SYNC DEBUG] PullResponderTransmitter.setupPull initiated for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
234
317
|
const { interval } = trigger.data;
|
|
235
318
|
let loopInterval = PULL_DRIVE_INTERVAL;
|
|
236
319
|
if (interval) {
|
|
@@ -244,20 +327,25 @@ export class PullResponderTransmitter {
|
|
|
244
327
|
// ignore invalid interval
|
|
245
328
|
}
|
|
246
329
|
}
|
|
330
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Pull interval set to ${loopInterval}ms for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
247
331
|
let isCancelled = false;
|
|
248
332
|
let timeout;
|
|
249
333
|
const executeLoop = async () => {
|
|
250
334
|
while (!isCancelled) {
|
|
251
|
-
this.staticLogger.verbose(
|
|
335
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Starting pull cycle for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
252
336
|
await this.executePull(driveId, trigger, onStrandUpdate, onError, onRevisions, onAcknowledge);
|
|
337
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Completed pull cycle for drive: ${driveId}, listenerId: ${trigger.data.listenerId}, waiting ${loopInterval}ms for next cycle`);
|
|
253
338
|
await new Promise((resolve) => {
|
|
254
339
|
this.staticLogger.verbose(`Scheduling next pull in ${loopInterval} ms`);
|
|
255
340
|
timeout = setTimeout(resolve, loopInterval);
|
|
256
341
|
});
|
|
257
342
|
}
|
|
258
343
|
};
|
|
259
|
-
executeLoop().catch(
|
|
344
|
+
executeLoop().catch((error) => {
|
|
345
|
+
this.staticLogger.error(`Error in executeLoop for drive: ${driveId}, listenerId: ${trigger.data.listenerId}: ${error}`);
|
|
346
|
+
});
|
|
260
347
|
return () => {
|
|
348
|
+
this.staticLogger.verbose(`[SYNC DEBUG] Cancelling pull loop for drive: ${driveId}, listenerId: ${trigger.data.listenerId}`);
|
|
261
349
|
isCancelled = true;
|
|
262
350
|
if (timeout !== undefined) {
|
|
263
351
|
clearTimeout(timeout);
|
|
@@ -267,15 +355,18 @@ export class PullResponderTransmitter {
|
|
|
267
355
|
static async createPullResponderTrigger(driveId, url, options) {
|
|
268
356
|
this.staticLogger.verbose(`createPullResponderTrigger(drive: ${driveId}, url: ${url})`);
|
|
269
357
|
const { pullFilter, pullInterval } = options;
|
|
270
|
-
const
|
|
358
|
+
const filter = pullFilter ?? {
|
|
271
359
|
documentId: ["*"],
|
|
272
360
|
documentType: ["*"],
|
|
273
361
|
branch: ["*"],
|
|
274
362
|
scope: ["*"],
|
|
275
|
-
}
|
|
363
|
+
};
|
|
364
|
+
const listenerId = await PullResponderTransmitter.registerPullResponder(driveId, url, filter);
|
|
276
365
|
const pullTrigger = {
|
|
277
366
|
id: generateUUID(),
|
|
278
367
|
type: "PullResponder",
|
|
368
|
+
driveId,
|
|
369
|
+
filter,
|
|
279
370
|
data: {
|
|
280
371
|
url,
|
|
281
372
|
listenerId,
|