@powerhousedao/reactor 5.0.1-staging.15 → 5.0.1-staging.17

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 (130) hide show
  1. package/dist/src/client/reactor-client.d.ts +5 -3
  2. package/dist/src/client/reactor-client.d.ts.map +1 -1
  3. package/dist/src/client/reactor-client.js +142 -37
  4. package/dist/src/client/reactor-client.js.map +1 -1
  5. package/dist/src/core/builder.d.ts +15 -2
  6. package/dist/src/core/builder.d.ts.map +1 -1
  7. package/dist/src/core/builder.js +48 -7
  8. package/dist/src/core/builder.js.map +1 -1
  9. package/dist/src/core/reactor-builder.d.ts +8 -0
  10. package/dist/src/core/reactor-builder.d.ts.map +1 -1
  11. package/dist/src/core/reactor-builder.js +26 -7
  12. package/dist/src/core/reactor-builder.js.map +1 -1
  13. package/dist/src/core/reactor.d.ts +14 -3
  14. package/dist/src/core/reactor.d.ts.map +1 -1
  15. package/dist/src/core/reactor.js +96 -95
  16. package/dist/src/core/reactor.js.map +1 -1
  17. package/dist/src/core/types.d.ts +22 -3
  18. package/dist/src/core/types.d.ts.map +1 -1
  19. package/dist/src/core/utils.d.ts +0 -4
  20. package/dist/src/core/utils.d.ts.map +1 -1
  21. package/dist/src/core/utils.js +0 -9
  22. package/dist/src/core/utils.js.map +1 -1
  23. package/dist/src/events/types.d.ts +28 -0
  24. package/dist/src/events/types.d.ts.map +1 -1
  25. package/dist/src/events/types.js +2 -0
  26. package/dist/src/events/types.js.map +1 -1
  27. package/dist/src/executor/simple-job-executor-manager.d.ts.map +1 -1
  28. package/dist/src/executor/simple-job-executor-manager.js +19 -3
  29. package/dist/src/executor/simple-job-executor-manager.js.map +1 -1
  30. package/dist/src/executor/simple-job-executor.d.ts.map +1 -1
  31. package/dist/src/executor/simple-job-executor.js +21 -7
  32. package/dist/src/executor/simple-job-executor.js.map +1 -1
  33. package/dist/src/index.d.ts +3 -1
  34. package/dist/src/index.d.ts.map +1 -1
  35. package/dist/src/index.js +4 -1
  36. package/dist/src/index.js.map +1 -1
  37. package/dist/src/job-tracker/in-memory-job-tracker.d.ts +11 -2
  38. package/dist/src/job-tracker/in-memory-job-tracker.d.ts.map +1 -1
  39. package/dist/src/job-tracker/in-memory-job-tracker.js +54 -26
  40. package/dist/src/job-tracker/in-memory-job-tracker.js.map +1 -1
  41. package/dist/src/job-tracker/interfaces.d.ts +6 -9
  42. package/dist/src/job-tracker/interfaces.d.ts.map +1 -1
  43. package/dist/src/read-models/coordinator.d.ts.map +1 -1
  44. package/dist/src/read-models/coordinator.js +11 -0
  45. package/dist/src/read-models/coordinator.js.map +1 -1
  46. package/dist/src/read-models/document-view.d.ts +1 -0
  47. package/dist/src/read-models/document-view.d.ts.map +1 -1
  48. package/dist/src/read-models/document-view.js +72 -2
  49. package/dist/src/read-models/document-view.js.map +1 -1
  50. package/dist/src/shared/awaiter.d.ts +11 -8
  51. package/dist/src/shared/awaiter.d.ts.map +1 -1
  52. package/dist/src/shared/awaiter.js +66 -75
  53. package/dist/src/shared/awaiter.js.map +1 -1
  54. package/dist/src/shared/types.d.ts +4 -2
  55. package/dist/src/shared/types.d.ts.map +1 -1
  56. package/dist/src/shared/types.js +4 -2
  57. package/dist/src/shared/types.js.map +1 -1
  58. package/dist/src/storage/index.d.ts +4 -0
  59. package/dist/src/storage/index.d.ts.map +1 -0
  60. package/dist/src/storage/index.js +3 -0
  61. package/dist/src/storage/index.js.map +1 -0
  62. package/dist/src/storage/interfaces.d.ts +79 -0
  63. package/dist/src/storage/interfaces.d.ts.map +1 -1
  64. package/dist/src/storage/interfaces.js.map +1 -1
  65. package/dist/src/storage/kysely/sync-cursor-storage.d.ts +13 -0
  66. package/dist/src/storage/kysely/sync-cursor-storage.d.ts.map +1 -0
  67. package/dist/src/storage/kysely/sync-cursor-storage.js +93 -0
  68. package/dist/src/storage/kysely/sync-cursor-storage.js.map +1 -0
  69. package/dist/src/storage/kysely/sync-remote-storage.d.ts +13 -0
  70. package/dist/src/storage/kysely/sync-remote-storage.d.ts.map +1 -0
  71. package/dist/src/storage/kysely/sync-remote-storage.js +134 -0
  72. package/dist/src/storage/kysely/sync-remote-storage.js.map +1 -0
  73. package/dist/src/storage/kysely/types.d.ts +35 -0
  74. package/dist/src/storage/kysely/types.d.ts.map +1 -1
  75. package/dist/src/storage/migrations/010_create_sync_tables.d.ts +3 -0
  76. package/dist/src/storage/migrations/010_create_sync_tables.d.ts.map +1 -0
  77. package/dist/src/storage/migrations/010_create_sync_tables.js +43 -0
  78. package/dist/src/storage/migrations/010_create_sync_tables.js.map +1 -0
  79. package/dist/src/storage/migrations/migrator.d.ts.map +1 -1
  80. package/dist/src/storage/migrations/migrator.js +2 -0
  81. package/dist/src/storage/migrations/migrator.js.map +1 -1
  82. package/dist/src/sync/channels/index.d.ts +3 -0
  83. package/dist/src/sync/channels/index.d.ts.map +1 -0
  84. package/dist/src/sync/channels/index.js +3 -0
  85. package/dist/src/sync/channels/index.js.map +1 -0
  86. package/dist/src/sync/channels/internal-channel.d.ts +57 -0
  87. package/dist/src/sync/channels/internal-channel.d.ts.map +1 -0
  88. package/dist/src/sync/channels/internal-channel.js +106 -0
  89. package/dist/src/sync/channels/internal-channel.js.map +1 -0
  90. package/dist/src/sync/channels/utils.d.ts +15 -0
  91. package/dist/src/sync/channels/utils.d.ts.map +1 -0
  92. package/dist/src/sync/channels/utils.js +26 -0
  93. package/dist/src/sync/channels/utils.js.map +1 -0
  94. package/dist/src/sync/errors.d.ts +10 -0
  95. package/dist/src/sync/errors.d.ts.map +1 -0
  96. package/dist/src/sync/errors.js +17 -0
  97. package/dist/src/sync/errors.js.map +1 -0
  98. package/dist/src/sync/index.d.ts +12 -0
  99. package/dist/src/sync/index.d.ts.map +1 -0
  100. package/dist/src/sync/index.js +9 -0
  101. package/dist/src/sync/index.js.map +1 -0
  102. package/dist/src/sync/interfaces.d.ts +150 -0
  103. package/dist/src/sync/interfaces.d.ts.map +1 -0
  104. package/dist/src/sync/interfaces.js +2 -0
  105. package/dist/src/sync/interfaces.js.map +1 -0
  106. package/dist/src/sync/mailbox.d.ts +21 -0
  107. package/dist/src/sync/mailbox.d.ts.map +1 -0
  108. package/dist/src/sync/mailbox.js +59 -0
  109. package/dist/src/sync/mailbox.js.map +1 -0
  110. package/dist/src/sync/sync-builder.d.ts +17 -0
  111. package/dist/src/sync/sync-builder.d.ts.map +1 -0
  112. package/dist/src/sync/sync-builder.js +29 -0
  113. package/dist/src/sync/sync-builder.js.map +1 -0
  114. package/dist/src/sync/sync-manager.d.ts +33 -0
  115. package/dist/src/sync/sync-manager.d.ts.map +1 -0
  116. package/dist/src/sync/sync-manager.js +197 -0
  117. package/dist/src/sync/sync-manager.js.map +1 -0
  118. package/dist/src/sync/sync-operation.d.ts +28 -0
  119. package/dist/src/sync/sync-operation.d.ts.map +1 -0
  120. package/dist/src/sync/sync-operation.js +63 -0
  121. package/dist/src/sync/sync-operation.js.map +1 -0
  122. package/dist/src/sync/types.d.ts +61 -0
  123. package/dist/src/sync/types.d.ts.map +1 -0
  124. package/dist/src/sync/types.js +16 -0
  125. package/dist/src/sync/types.js.map +1 -0
  126. package/dist/src/sync/utils.d.ts +17 -0
  127. package/dist/src/sync/utils.d.ts.map +1 -0
  128. package/dist/src/sync/utils.js +34 -0
  129. package/dist/src/sync/utils.js.map +1 -0
  130. package/package.json +4 -3
@@ -0,0 +1,57 @@
1
+ import type { ISyncCursorStorage } from "../../storage/interfaces.js";
2
+ import type { IChannel } from "../interfaces.js";
3
+ import type { SyncOperation } from "../sync-operation.js";
4
+ import { Mailbox } from "../mailbox.js";
5
+ import type { SyncEnvelope } from "../types.js";
6
+ /**
7
+ * In-memory synchronization channel for testing purposes only.
8
+ *
9
+ * InternalChannel enables direct bidirectional communication between two reactor
10
+ * instances without network transport. Channels are wired together by passing
11
+ * a send function that delivers envelopes to the peer's inbox.
12
+ */
13
+ export declare class InternalChannel implements IChannel {
14
+ readonly inbox: Mailbox<SyncOperation>;
15
+ readonly outbox: Mailbox<SyncOperation>;
16
+ readonly deadLetter: Mailbox<SyncOperation>;
17
+ private readonly channelId;
18
+ private readonly remoteName;
19
+ private readonly cursorStorage;
20
+ private readonly send;
21
+ private isShutdown;
22
+ constructor(channelId: string, remoteName: string, cursorStorage: ISyncCursorStorage, send: (envelope: SyncEnvelope) => void);
23
+ /**
24
+ * Shuts down the channel and prevents further operations.
25
+ */
26
+ shutdown(): void;
27
+ /**
28
+ * Receives a sync envelope from a peer channel.
29
+ *
30
+ * This method is called by the peer's send function to deliver an envelope
31
+ * to this channel's inbox.
32
+ *
33
+ * @param envelope - The sync envelope to receive
34
+ * @throws {InternalChannelError} If channel is shutdown
35
+ */
36
+ receive(envelope: SyncEnvelope): void;
37
+ /**
38
+ * Updates the synchronization cursor for this channel's remote.
39
+ *
40
+ * Cursors track progress through the operation stream and enable resuming
41
+ * synchronization after restarts. The cursor is exclusive - the next sync
42
+ * will start at cursorOrdinal + 1.
43
+ *
44
+ * @param cursorOrdinal - The last processed ordinal (exclusive)
45
+ */
46
+ updateCursor(cursorOrdinal: number): Promise<void>;
47
+ /**
48
+ * Handles sync operations added to the outbox by sending them to the peer.
49
+ *
50
+ * This method is called automatically via the outbox.onAdded callback.
51
+ * It converts the sync operation to a SyncEnvelope and sends it via the send function.
52
+ *
53
+ * @param syncOp - The sync operation to transport
54
+ */
55
+ private handleOutboxAdded;
56
+ }
57
+ //# sourceMappingURL=internal-channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-channel.d.ts","sourceRoot":"","sources":["../../../../src/sync/channels/internal-channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAgB,YAAY,EAAE,MAAM,aAAa,CAAC;AAI9D;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAE5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmC;IACxD,OAAO,CAAC,UAAU,CAAU;gBAG1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,kBAAkB,EACjC,IAAI,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI;IAiBxC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAcrC;;;;;;;;OAQG;IACG,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxD;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB;CAuB1B"}
@@ -0,0 +1,106 @@
1
+ import { ChannelError, InternalChannelError } from "../errors.js";
2
+ import { Mailbox } from "../mailbox.js";
3
+ import { ChannelErrorSource } from "../types.js";
4
+ import { envelopeToSyncOperation } from "./utils.js";
5
+ /**
6
+ * In-memory synchronization channel for testing purposes only.
7
+ *
8
+ * InternalChannel enables direct bidirectional communication between two reactor
9
+ * instances without network transport. Channels are wired together by passing
10
+ * a send function that delivers envelopes to the peer's inbox.
11
+ */
12
+ export class InternalChannel {
13
+ inbox;
14
+ outbox;
15
+ deadLetter;
16
+ channelId;
17
+ remoteName;
18
+ cursorStorage;
19
+ send;
20
+ isShutdown;
21
+ constructor(channelId, remoteName, cursorStorage, send) {
22
+ this.channelId = channelId;
23
+ this.remoteName = remoteName;
24
+ this.cursorStorage = cursorStorage;
25
+ this.send = send;
26
+ this.isShutdown = false;
27
+ this.inbox = new Mailbox();
28
+ this.outbox = new Mailbox();
29
+ this.deadLetter = new Mailbox();
30
+ this.outbox.onAdded((syncOp) => {
31
+ this.handleOutboxAdded(syncOp);
32
+ });
33
+ }
34
+ /**
35
+ * Shuts down the channel and prevents further operations.
36
+ */
37
+ shutdown() {
38
+ this.isShutdown = true;
39
+ }
40
+ /**
41
+ * Receives a sync envelope from a peer channel.
42
+ *
43
+ * This method is called by the peer's send function to deliver an envelope
44
+ * to this channel's inbox.
45
+ *
46
+ * @param envelope - The sync envelope to receive
47
+ * @throws {InternalChannelError} If channel is shutdown
48
+ */
49
+ receive(envelope) {
50
+ if (this.isShutdown) {
51
+ throw new InternalChannelError(`Channel ${this.channelId} is shutdown and cannot receive envelopes`);
52
+ }
53
+ if (envelope.type === "operations" && envelope.operations) {
54
+ const syncOp = envelopeToSyncOperation(envelope, this.remoteName);
55
+ syncOp.transported();
56
+ this.inbox.add(syncOp);
57
+ }
58
+ }
59
+ /**
60
+ * Updates the synchronization cursor for this channel's remote.
61
+ *
62
+ * Cursors track progress through the operation stream and enable resuming
63
+ * synchronization after restarts. The cursor is exclusive - the next sync
64
+ * will start at cursorOrdinal + 1.
65
+ *
66
+ * @param cursorOrdinal - The last processed ordinal (exclusive)
67
+ */
68
+ async updateCursor(cursorOrdinal) {
69
+ const cursor = {
70
+ remoteName: this.remoteName,
71
+ cursorOrdinal,
72
+ lastSyncedAtUtcMs: Date.now(),
73
+ };
74
+ await this.cursorStorage.upsert(cursor);
75
+ }
76
+ /**
77
+ * Handles sync operations added to the outbox by sending them to the peer.
78
+ *
79
+ * This method is called automatically via the outbox.onAdded callback.
80
+ * It converts the sync operation to a SyncEnvelope and sends it via the send function.
81
+ *
82
+ * @param syncOp - The sync operation to transport
83
+ */
84
+ handleOutboxAdded(syncOp) {
85
+ if (this.isShutdown) {
86
+ return;
87
+ }
88
+ try {
89
+ syncOp.started();
90
+ const envelope = {
91
+ type: "operations",
92
+ channelMeta: { id: this.channelId },
93
+ operations: syncOp.operations,
94
+ };
95
+ this.send(envelope);
96
+ }
97
+ catch (error) {
98
+ const err = error instanceof Error ? error : new Error(String(error));
99
+ const channelError = new ChannelError(ChannelErrorSource.Outbox, err);
100
+ syncOp.failed(channelError);
101
+ this.deadLetter.add(syncOp);
102
+ this.outbox.remove(syncOp);
103
+ }
104
+ }
105
+ }
106
+ //# sourceMappingURL=internal-channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-channel.js","sourceRoot":"","sources":["../../../../src/sync/channels/internal-channel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { SyncOperation } from "../sync-operation.js";
2
+ import type { SyncEnvelope } from "../types.js";
3
+ /**
4
+ * Converts a SyncEnvelope containing operations into a SyncOperation.
5
+ *
6
+ * Extracts the necessary metadata from the envelope's operations to create
7
+ * a sync operation that can be processed by the receiving channel.
8
+ *
9
+ * @param envelope - The sync envelope containing operations
10
+ * @param remoteName - The name of the remote this sync operation is associated with
11
+ * @returns A new SyncOperation containing the envelope's operations
12
+ * @throws Error if envelope has no operations or operations array is empty
13
+ */
14
+ export declare function envelopeToSyncOperation(envelope: SyncEnvelope, remoteName: string): SyncOperation;
15
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/sync/channels/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,YAAY,EACtB,UAAU,EAAE,MAAM,GACjB,aAAa,CAuBf"}
@@ -0,0 +1,26 @@
1
+ import { SyncOperation } from "../sync-operation.js";
2
+ let syncOpCounter = 0;
3
+ /**
4
+ * Converts a SyncEnvelope containing operations into a SyncOperation.
5
+ *
6
+ * Extracts the necessary metadata from the envelope's operations to create
7
+ * a sync operation that can be processed by the receiving channel.
8
+ *
9
+ * @param envelope - The sync envelope containing operations
10
+ * @param remoteName - The name of the remote this sync operation is associated with
11
+ * @returns A new SyncOperation containing the envelope's operations
12
+ * @throws Error if envelope has no operations or operations array is empty
13
+ */
14
+ export function envelopeToSyncOperation(envelope, remoteName) {
15
+ if (!envelope.operations || envelope.operations.length === 0) {
16
+ throw new Error("Cannot create SyncOperation from envelope without operations");
17
+ }
18
+ const operations = envelope.operations;
19
+ const firstOp = operations[0];
20
+ const documentId = firstOp.context.documentId;
21
+ const branch = firstOp.context.branch;
22
+ const scopes = [...new Set(operations.map((op) => op.context.scope))];
23
+ const syncOpId = `syncop-${envelope.channelMeta.id}-${Date.now()}-${syncOpCounter++}`;
24
+ return new SyncOperation(syncOpId, remoteName, documentId, scopes, branch, operations);
25
+ }
26
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/sync/channels/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,IAAI,aAAa,GAAG,CAAC,CAAC;AAEtB;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAAsB,EACtB,UAAkB;IAElB,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;IACvC,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;IAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;IACtC,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEtE,MAAM,QAAQ,GAAG,UAAU,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,aAAa,EAAE,EAAE,CAAC;IAEtF,OAAO,IAAI,aAAa,CACtB,QAAQ,EACR,UAAU,EACV,UAAU,EACV,MAAM,EACN,MAAM,EACN,UAAU,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ChannelErrorSource } from "./types.js";
2
+ export declare class InternalChannelError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare class ChannelError extends Error {
6
+ source: ChannelErrorSource;
7
+ error: Error;
8
+ constructor(source: ChannelErrorSource, error: Error);
9
+ }
10
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/sync/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,YAAa,SAAQ,KAAK;IACrC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC;gBAED,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK;CAMrD"}
@@ -0,0 +1,17 @@
1
+ export class InternalChannelError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "InternalChannelError";
5
+ }
6
+ }
7
+ export class ChannelError extends Error {
8
+ source;
9
+ error;
10
+ constructor(source, error) {
11
+ super(`ChannelError[${source}]: ${error.message}`);
12
+ this.name = "ChannelError";
13
+ this.source = source;
14
+ this.error = error;
15
+ }
16
+ }
17
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/sync/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,MAAM,CAAqB;IAC3B,KAAK,CAAQ;IAEb,YAAY,MAA0B,EAAE,KAAY;QAClD,KAAK,CAAC,gBAAgB,MAAM,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ export type { IChannel, IChannelFactory, ISyncManager, Remote, } from "./interfaces.js";
2
+ export type { ShutdownStatus } from "../shared/types.js";
3
+ export type { ChannelConfig, ChannelHealth, SyncOperationErrorType, RemoteFilter, RemoteOptions, RemoteRecord, RemoteCursor, RemoteStatus, SyncEnvelope, SyncEnvelopeType, ChannelMeta, } from "./types.js";
4
+ export { ChannelErrorSource, SyncOperationStatus } from "./types.js";
5
+ export { SyncOperation, SyncOperationAggregateError, } from "./sync-operation.js";
6
+ export { Mailbox, type MailboxItem } from "./mailbox.js";
7
+ export { ChannelError, InternalChannelError } from "./errors.js";
8
+ export { InternalChannel } from "./channels/index.js";
9
+ export { SyncManager } from "./sync-manager.js";
10
+ export { SyncBuilder } from "./sync-builder.js";
11
+ export { createIdleHealth, filterOperations } from "./utils.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,MAAM,GACP,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,YAAY,EACV,aAAa,EACb,aAAa,EACb,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE,OAAO,EACL,aAAa,EACb,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,9 @@
1
+ export { ChannelErrorSource, SyncOperationStatus } from "./types.js";
2
+ export { SyncOperation, SyncOperationAggregateError, } from "./sync-operation.js";
3
+ export { Mailbox } from "./mailbox.js";
4
+ export { ChannelError, InternalChannelError } from "./errors.js";
5
+ export { InternalChannel } from "./channels/index.js";
6
+ export { SyncManager } from "./sync-manager.js";
7
+ export { SyncBuilder } from "./sync-builder.js";
8
+ export { createIdleHealth, filterOperations } from "./utils.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE,OAAO,EACL,aAAa,EACb,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAoB,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,150 @@
1
+ import type { ShutdownStatus } from "../shared/types.js";
2
+ import type { ISyncCursorStorage } from "../storage/interfaces.js";
3
+ import type { SyncOperation } from "./sync-operation.js";
4
+ import type { Mailbox } from "./mailbox.js";
5
+ import type { ChannelConfig, RemoteFilter, RemoteOptions } from "./types.js";
6
+ /**
7
+ * Represents a bidirectional synchronization channel between two reactor instances.
8
+ *
9
+ * A channel manages three mailboxes:
10
+ * - inbox: Sync operations received from the remote that need to be applied locally
11
+ * - outbox: Sync operations to be sent to the remote
12
+ * - deadLetter: Sync operations that failed and cannot be retried
13
+ *
14
+ * Channels are responsible for:
15
+ * - Transporting sync envelopes between reactor instances
16
+ * - Managing sync operation lifecycle through status transitions
17
+ * - Handling errors and moving failed sync operations to dead letter queue
18
+ * - Updating cursors as operations are applied
19
+ */
20
+ export interface IChannel {
21
+ /**
22
+ * Mailbox containing sync operations received from the remote that need to be applied locally.
23
+ * Consumers should register callbacks via onAdded to process incoming sync operations.
24
+ */
25
+ inbox: Mailbox<SyncOperation>;
26
+ /**
27
+ * Mailbox containing sync operations that need to be sent to the remote.
28
+ * The channel is responsible for transporting these sync operations and handling ACKs.
29
+ */
30
+ outbox: Mailbox<SyncOperation>;
31
+ /**
32
+ * Mailbox containing sync operations that failed and cannot be retried.
33
+ * These sync operations require manual intervention or should be logged for debugging.
34
+ */
35
+ deadLetter: Mailbox<SyncOperation>;
36
+ /**
37
+ * Shuts down the channel and prevents further operations.
38
+ */
39
+ shutdown(): void;
40
+ }
41
+ /**
42
+ * Factory for creating channel instances.
43
+ *
44
+ * Different channel implementations (InternalChannel, GqlChannel, etc.) will have
45
+ * their own factories that implement this interface.
46
+ */
47
+ export interface IChannelFactory {
48
+ /**
49
+ * Creates a new channel instance with the given configuration.
50
+ *
51
+ * @param config - Channel configuration including type and parameters
52
+ * @param cursorStorage - Storage for persisting synchronization cursors
53
+ * @returns A new channel instance
54
+ */
55
+ instance(config: ChannelConfig, cursorStorage: ISyncCursorStorage): IChannel;
56
+ }
57
+ /**
58
+ * Represents a configured remote with an active channel.
59
+ *
60
+ * A remote defines what to synchronize (collectionId, filter) and how to synchronize it (channel).
61
+ * The remote name is used as a unique identifier across the system.
62
+ */
63
+ export type Remote = {
64
+ /**
65
+ * Unique name for this remote.
66
+ */
67
+ name: string;
68
+ /**
69
+ * Collection ID to synchronize.
70
+ * Typically created via driveCollectionId(branch, documentId) for drive-level sync.
71
+ */
72
+ collectionId: string;
73
+ /**
74
+ * Filter to apply to operations.
75
+ * Can filter by documentId, scope, and branch.
76
+ */
77
+ filter: RemoteFilter;
78
+ /**
79
+ * Additional configuration options for the remote.
80
+ */
81
+ options: RemoteOptions;
82
+ /**
83
+ * Active channel for bidirectional communication with the remote.
84
+ */
85
+ channel: IChannel;
86
+ };
87
+ /**
88
+ * Orchestrates all synchronization activity for a reactor instance.
89
+ */
90
+ export interface ISyncManager {
91
+ /**
92
+ * Starts the synchronization manager.
93
+ *
94
+ * This recreates all remotes from storage and prepares channels for synchronization.
95
+ * Each remote's channel will begin processing its inbox/outbox mailboxes.
96
+ *
97
+ * @returns Promise that resolves when the manager is started
98
+ */
99
+ startup(): Promise<void>;
100
+ /**
101
+ * Shuts down the synchronization manager.
102
+ *
103
+ * This stops all channels, flushes pending operations, and releases resources.
104
+ * The shutdown status indicates whether the system was cleanly shut down.
105
+ *
106
+ * @returns Status object with shutdown information
107
+ */
108
+ shutdown(): ShutdownStatus;
109
+ /**
110
+ * Gets a remote by name.
111
+ *
112
+ * @param name - The name of the remote
113
+ * @returns The remote
114
+ * @throws Error if the remote does not exist
115
+ */
116
+ get(name: string): Remote;
117
+ /**
118
+ * Adds a new remote and starts its channel.
119
+ *
120
+ * The remote configuration is persisted to storage and a channel is created
121
+ * using the appropriate factory. The channel begins processing immediately.
122
+ *
123
+ * @param name - Unique name for the remote
124
+ * @param collectionId - Collection ID to synchronize
125
+ * @param channelConfig - Configuration for the channel type and parameters
126
+ * @param filter - Optional filter for operations (defaults to no filtering)
127
+ * @param options - Optional remote configuration options
128
+ * @returns Promise that resolves with the created remote
129
+ * @throws Error if a remote with this name already exists
130
+ */
131
+ add(name: string, collectionId: string, channelConfig: ChannelConfig, filter?: RemoteFilter, options?: RemoteOptions): Promise<Remote>;
132
+ /**
133
+ * Removes a remote and stops its channel.
134
+ *
135
+ * The remote configuration is removed from storage and the channel is shut down.
136
+ * Any pending sync operations in the channel's mailboxes will be processed before shutdown.
137
+ *
138
+ * @param name - The name of the remote to remove
139
+ * @returns Promise that resolves when the remote is removed
140
+ * @throws Error if the remote does not exist
141
+ */
142
+ remove(name: string): Promise<void>;
143
+ /**
144
+ * Lists all configured remotes.
145
+ *
146
+ * @returns Array of all remotes
147
+ */
148
+ list(): Remote[];
149
+ }
150
+ //# sourceMappingURL=interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../../src/sync/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAE9B;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAE/B;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAEnC;;OAEG;IACH,QAAQ,IAAI,IAAI,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,GAAG,QAAQ,CAAC;CAC9E;AAED;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,OAAO,EAAE,aAAa,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,QAAQ,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;OAOG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;;;;;OAOG;IACH,QAAQ,IAAI,cAAc,CAAC;IAE3B;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1B;;;;;;;;;;;;;OAaG;IACH,GAAG,CACD,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,aAAa,EAC5B,MAAM,CAAC,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;;;;;;;;OASG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC;;;;OAIG;IACH,IAAI,IAAI,MAAM,EAAE,CAAC;CAClB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/sync/interfaces.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ export type MailboxItem = {
2
+ id: string;
3
+ };
4
+ type MailboxCallback<T extends MailboxItem> = (item: T) => void;
5
+ export declare class MailboxAggregateError extends Error {
6
+ errors: Error[];
7
+ constructor(errors: Error[]);
8
+ }
9
+ export declare class Mailbox<T extends MailboxItem> {
10
+ private itemsMap;
11
+ private addedCallbacks;
12
+ private removedCallbacks;
13
+ get items(): ReadonlyArray<T>;
14
+ get(id: string): T | undefined;
15
+ add(item: T): void;
16
+ remove(item: T): void;
17
+ onAdded(callback: MailboxCallback<T>): void;
18
+ onRemoved(callback: MailboxCallback<T>): void;
19
+ }
20
+ export {};
21
+ //# sourceMappingURL=mailbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox.d.ts","sourceRoot":"","sources":["../../../src/sync/mailbox.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,KAAK,eAAe,CAAC,CAAC,SAAS,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;AAEhE,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,MAAM,EAAE,KAAK,EAAE,CAAC;gBAEJ,MAAM,EAAE,KAAK,EAAE;CAQ5B;AAED,qBAAa,OAAO,CAAC,CAAC,SAAS,WAAW;IACxC,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,gBAAgB,CAA4B;IAEpD,IAAI,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC,CAE5B;IAED,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAI9B,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAgBlB,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAgBrB,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI;IAI3C,SAAS,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI;CAG9C"}
@@ -0,0 +1,59 @@
1
+ export class MailboxAggregateError extends Error {
2
+ errors;
3
+ constructor(errors) {
4
+ const messages = errors.map((e) => e.message).join("; ");
5
+ super(`Mailbox callback failed with ${errors.length} error(s): ${messages}`);
6
+ this.name = "MailboxAggregateError";
7
+ this.errors = errors;
8
+ }
9
+ }
10
+ export class Mailbox {
11
+ itemsMap = new Map();
12
+ addedCallbacks = [];
13
+ removedCallbacks = [];
14
+ get items() {
15
+ return Array.from(this.itemsMap.values());
16
+ }
17
+ get(id) {
18
+ return this.itemsMap.get(id);
19
+ }
20
+ add(item) {
21
+ this.itemsMap.set(item.id, item);
22
+ const callbacks = [...this.addedCallbacks];
23
+ const errors = [];
24
+ for (const callback of callbacks) {
25
+ try {
26
+ callback(item);
27
+ }
28
+ catch (error) {
29
+ errors.push(error instanceof Error ? error : new Error(String(error)));
30
+ }
31
+ }
32
+ if (errors.length > 0) {
33
+ throw new MailboxAggregateError(errors);
34
+ }
35
+ }
36
+ remove(item) {
37
+ this.itemsMap.delete(item.id);
38
+ const callbacks = [...this.removedCallbacks];
39
+ const errors = [];
40
+ for (const callback of callbacks) {
41
+ try {
42
+ callback(item);
43
+ }
44
+ catch (error) {
45
+ errors.push(error instanceof Error ? error : new Error(String(error)));
46
+ }
47
+ }
48
+ if (errors.length > 0) {
49
+ throw new MailboxAggregateError(errors);
50
+ }
51
+ }
52
+ onAdded(callback) {
53
+ this.addedCallbacks.push(callback);
54
+ }
55
+ onRemoved(callback) {
56
+ this.removedCallbacks.push(callback);
57
+ }
58
+ }
59
+ //# sourceMappingURL=mailbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mailbox.js","sourceRoot":"","sources":["../../../src/sync/mailbox.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,MAAM,CAAU;IAEhB,YAAY,MAAe;QACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,KAAK,CACH,gCAAgC,MAAM,CAAC,MAAM,cAAc,QAAQ,EAAE,CACtE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,OAAO;IACV,QAAQ,GAAmB,IAAI,GAAG,EAAE,CAAC;IACrC,cAAc,GAAyB,EAAE,CAAC;IAC1C,gBAAgB,GAAyB,EAAE,CAAC;IAEpD,IAAI,KAAK;QACP,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,IAAO;QACT,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAO;QACZ,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,OAAO,CAAC,QAA4B;QAClC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,SAAS,CAAC,QAA4B;QACpC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ import type { Kysely } from "kysely";
2
+ import type { IOperationIndex } from "../cache/operation-index-types.js";
3
+ import type { IReactor } from "../core/types.js";
4
+ import type { IEventBus } from "../events/interfaces.js";
5
+ import type { ISyncCursorStorage, ISyncRemoteStorage } from "../storage/interfaces.js";
6
+ import type { Database } from "../storage/kysely/types.js";
7
+ import type { IChannelFactory, ISyncManager } from "./interfaces.js";
8
+ export declare class SyncBuilder {
9
+ private channelFactory?;
10
+ private remoteStorage?;
11
+ private cursorStorage?;
12
+ withChannelFactory(factory: IChannelFactory): this;
13
+ withRemoteStorage(storage: ISyncRemoteStorage): this;
14
+ withCursorStorage(storage: ISyncCursorStorage): this;
15
+ build(reactor: IReactor, operationIndex: IOperationIndex, eventBus: IEventBus, db: Kysely<Database>): ISyncManager;
16
+ }
17
+ //# sourceMappingURL=sync-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-builder.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGrE,qBAAa,WAAW;IACtB,OAAO,CAAC,cAAc,CAAC,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAC,CAAqB;IAC3C,OAAO,CAAC,aAAa,CAAC,CAAqB;IAE3C,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAKlD,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAKpD,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAKpD,KAAK,CACH,OAAO,EAAE,QAAQ,EACjB,cAAc,EAAE,eAAe,EAC/B,QAAQ,EAAE,SAAS,EACnB,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,GACnB,YAAY;CAiBhB"}
@@ -0,0 +1,29 @@
1
+ import { KyselySyncCursorStorage } from "../storage/kysely/sync-cursor-storage.js";
2
+ import { KyselySyncRemoteStorage } from "../storage/kysely/sync-remote-storage.js";
3
+ import { SyncManager } from "./sync-manager.js";
4
+ export class SyncBuilder {
5
+ channelFactory;
6
+ remoteStorage;
7
+ cursorStorage;
8
+ withChannelFactory(factory) {
9
+ this.channelFactory = factory;
10
+ return this;
11
+ }
12
+ withRemoteStorage(storage) {
13
+ this.remoteStorage = storage;
14
+ return this;
15
+ }
16
+ withCursorStorage(storage) {
17
+ this.cursorStorage = storage;
18
+ return this;
19
+ }
20
+ build(reactor, operationIndex, eventBus, db) {
21
+ if (!this.channelFactory) {
22
+ throw new Error("Channel factory is required");
23
+ }
24
+ const remoteStorage = this.remoteStorage ?? new KyselySyncRemoteStorage(db);
25
+ const cursorStorage = this.cursorStorage ?? new KyselySyncCursorStorage(db);
26
+ return new SyncManager(remoteStorage, cursorStorage, this.channelFactory, operationIndex, reactor, eventBus);
27
+ }
28
+ }
29
+ //# sourceMappingURL=sync-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-builder.js","sourceRoot":"","sources":["../../../src/sync/sync-builder.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAEnF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,OAAO,WAAW;IACd,cAAc,CAAmB;IACjC,aAAa,CAAsB;IACnC,aAAa,CAAsB;IAE3C,kBAAkB,CAAC,OAAwB;QACzC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB,CAAC,OAA2B;QAC3C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB,CAAC,OAA2B;QAC3C,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CACH,OAAiB,EACjB,cAA+B,EAC/B,QAAmB,EACnB,EAAoB;QAEpB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,uBAAuB,CAAC,EAAE,CAAC,CAAC;QAC5E,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,uBAAuB,CAAC,EAAE,CAAC,CAAC;QAE5E,OAAO,IAAI,WAAW,CACpB,aAAa,EACb,aAAa,EACb,IAAI,CAAC,cAAc,EACnB,cAAc,EACd,OAAO,EACP,QAAQ,CACT,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import type { IOperationIndex } from "../cache/operation-index-types.js";
2
+ import type { IReactor } from "../core/types.js";
3
+ import type { IEventBus } from "../events/interfaces.js";
4
+ import { type JobInfo, type ShutdownStatus } from "../shared/types.js";
5
+ import type { ISyncCursorStorage, ISyncRemoteStorage } from "../storage/interfaces.js";
6
+ import type { IChannelFactory, ISyncManager, Remote } from "./interfaces.js";
7
+ import type { ChannelConfig, RemoteFilter, RemoteOptions } from "./types.js";
8
+ export declare class SyncManager implements ISyncManager {
9
+ private readonly remoteStorage;
10
+ private readonly cursorStorage;
11
+ private readonly channelFactory;
12
+ private readonly _operationIndex;
13
+ private readonly reactor;
14
+ private readonly eventBus;
15
+ private readonly remotes;
16
+ private readonly awaiter;
17
+ private isShutdown;
18
+ private eventUnsubscribe?;
19
+ loadJobs: Map<string, JobInfo>;
20
+ constructor(remoteStorage: ISyncRemoteStorage, cursorStorage: ISyncCursorStorage, channelFactory: IChannelFactory, operationIndex: IOperationIndex, reactor: IReactor, eventBus: IEventBus);
21
+ startup(): Promise<void>;
22
+ shutdown(): ShutdownStatus;
23
+ get(name: string): Remote;
24
+ add(name: string, collectionId: string, channelConfig: ChannelConfig, filter?: RemoteFilter, options?: RemoteOptions): Promise<Remote>;
25
+ remove(name: string): Promise<void>;
26
+ list(): Remote[];
27
+ private wireChannelCallbacks;
28
+ private handleOperationWritten;
29
+ private handleInboxJob;
30
+ private handleOutboxJob;
31
+ private applyInboxJob;
32
+ }
33
+ //# sourceMappingURL=sync-manager.d.ts.map