@powerhousedao/reactor-api 6.0.0-dev.52 → 6.0.0-dev.53
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/test/connect-switchboard-reshuffle-convergence.test.d.ts +2 -0
- package/dist/test/connect-switchboard-reshuffle-convergence.test.d.ts.map +1 -0
- package/dist/test/connect-switchboard-reshuffle-convergence.test.js +200 -0
- package/dist/test/connect-switchboard-reshuffle-convergence.test.js.map +1 -0
- package/dist/test/utils/gql-resolver-bridge.d.ts +4 -1
- package/dist/test/utils/gql-resolver-bridge.d.ts.map +1 -1
- package/dist/test/utils/gql-resolver-bridge.js +12 -5
- package/dist/test/utils/gql-resolver-bridge.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-switchboard-reshuffle-convergence.test.d.ts","sourceRoot":"","sources":["../../test/connect-switchboard-reshuffle-convergence.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { ConsoleLogger, EventBus, GqlRequestChannelFactory, GqlResponseChannelFactory, InMemoryQueue, JobStatus, ReactorBuilder, SyncBuilder, driveCollectionId, } from "@powerhousedao/reactor";
|
|
2
|
+
import { driveDocumentModelModule } from "document-drive";
|
|
3
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { createResolverBridge } from "./utils/gql-resolver-bridge.js";
|
|
5
|
+
const DOCUMENT_ID = "3af9b9e2-4b3f-45d4-87b3-5d345b1fb398";
|
|
6
|
+
const FIXED_TIMESTAMP = "2026-02-17T16:17:13.886Z";
|
|
7
|
+
const WAIT_STEP_MS = 50;
|
|
8
|
+
function createConnectModule(logger, eventBus, queue) {
|
|
9
|
+
return new ReactorBuilder()
|
|
10
|
+
.withEventBus(eventBus)
|
|
11
|
+
.withQueue(queue)
|
|
12
|
+
.withDocumentModels([
|
|
13
|
+
driveDocumentModelModule,
|
|
14
|
+
])
|
|
15
|
+
.withSync(new SyncBuilder().withChannelFactory(new GqlRequestChannelFactory(logger, undefined, queue)))
|
|
16
|
+
.buildModule();
|
|
17
|
+
}
|
|
18
|
+
function createSwitchboardModule(logger, eventBus, queue) {
|
|
19
|
+
return new ReactorBuilder()
|
|
20
|
+
.withEventBus(eventBus)
|
|
21
|
+
.withQueue(queue)
|
|
22
|
+
.withDocumentModels([
|
|
23
|
+
driveDocumentModelModule,
|
|
24
|
+
])
|
|
25
|
+
.withSync(new SyncBuilder().withChannelFactory(new GqlResponseChannelFactory(logger)))
|
|
26
|
+
.buildModule();
|
|
27
|
+
}
|
|
28
|
+
async function setup() {
|
|
29
|
+
const logger = new ConsoleLogger(["test"]);
|
|
30
|
+
const eventA = new EventBus();
|
|
31
|
+
const eventB = new EventBus();
|
|
32
|
+
const eventS = new EventBus();
|
|
33
|
+
const queueA = new InMemoryQueue(eventA);
|
|
34
|
+
const queueB = new InMemoryQueue(eventB);
|
|
35
|
+
const queueS = new InMemoryQueue(eventS);
|
|
36
|
+
const connectA = await createConnectModule(logger, eventA, queueA);
|
|
37
|
+
const connectB = await createConnectModule(logger, eventB, queueB);
|
|
38
|
+
const switchboard = await createSwitchboardModule(logger, eventS, queueS);
|
|
39
|
+
const syncManagerRegistry = new Map();
|
|
40
|
+
syncManagerRegistry.set("switchboard", switchboard.syncModule.syncManager);
|
|
41
|
+
const bridge = createResolverBridge(syncManagerRegistry, { log: false });
|
|
42
|
+
return { connectA, connectB, switchboard, bridge };
|
|
43
|
+
}
|
|
44
|
+
async function advanceAndFlush(ms) {
|
|
45
|
+
await vi.advanceTimersByTimeAsync(ms);
|
|
46
|
+
await Promise.resolve();
|
|
47
|
+
}
|
|
48
|
+
async function waitForJobCompletion(reactor, jobId, timeoutMs = 20000) {
|
|
49
|
+
let elapsedMs = 0;
|
|
50
|
+
while (elapsedMs <= timeoutMs) {
|
|
51
|
+
const status = await reactor.getJobStatus(jobId);
|
|
52
|
+
if (status.status === JobStatus.READ_READY) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (status.status === JobStatus.FAILED) {
|
|
56
|
+
throw new Error(`Job ${jobId} failed: ${status.error?.message ?? "unknown"}`);
|
|
57
|
+
}
|
|
58
|
+
await advanceAndFlush(WAIT_STEP_MS);
|
|
59
|
+
elapsedMs += WAIT_STEP_MS;
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Timed out waiting for job ${jobId}`);
|
|
62
|
+
}
|
|
63
|
+
async function waitForDocumentAvailable(reactor, documentId, timeoutMs = 20000) {
|
|
64
|
+
let elapsedMs = 0;
|
|
65
|
+
while (elapsedMs <= timeoutMs) {
|
|
66
|
+
try {
|
|
67
|
+
await reactor.get(documentId, { branch: "main" });
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Keep polling until available.
|
|
72
|
+
}
|
|
73
|
+
await advanceAndFlush(WAIT_STEP_MS);
|
|
74
|
+
elapsedMs += WAIT_STEP_MS;
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`Timed out waiting for document ${documentId}`);
|
|
77
|
+
}
|
|
78
|
+
function createDeterministicAddFolderAction(actionId, folderId) {
|
|
79
|
+
const action = driveDocumentModelModule.actions.addFolder({
|
|
80
|
+
id: folderId,
|
|
81
|
+
name: "same",
|
|
82
|
+
parentFolder: null,
|
|
83
|
+
});
|
|
84
|
+
action.id = actionId;
|
|
85
|
+
action.timestampUtcMs = FIXED_TIMESTAMP;
|
|
86
|
+
return action;
|
|
87
|
+
}
|
|
88
|
+
function gcGlobalEntries(entries) {
|
|
89
|
+
const sorted = entries.slice().sort((a, b) => a.index - b.index);
|
|
90
|
+
return sorted.filter((entry) => {
|
|
91
|
+
for (const later of sorted) {
|
|
92
|
+
if (later.index <= entry.index || later.skip <= 0) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const logicalIndex = later.index - later.skip;
|
|
96
|
+
if (logicalIndex <= entry.index) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function normalizeForComparison(entries) {
|
|
104
|
+
return entries.map((entry) => ({
|
|
105
|
+
actionId: entry.action.id,
|
|
106
|
+
actionType: entry.action.type,
|
|
107
|
+
operationId: entry.id,
|
|
108
|
+
timestampUtcMs: entry.timestampUtcMs,
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
describe("Connect-Switchboard reshuffle rebroadcast convergence", () => {
|
|
112
|
+
let connectA;
|
|
113
|
+
let connectB;
|
|
114
|
+
let switchboard;
|
|
115
|
+
afterEach(() => {
|
|
116
|
+
connectA?.reactor.kill();
|
|
117
|
+
connectB?.reactor.kill();
|
|
118
|
+
switchboard?.reactor.kill();
|
|
119
|
+
vi.useRealTimers();
|
|
120
|
+
});
|
|
121
|
+
it("should converge after reshuffle rebroadcast between two connect reactors", async () => {
|
|
122
|
+
vi.useFakeTimers();
|
|
123
|
+
vi.setSystemTime(new Date(FIXED_TIMESTAMP));
|
|
124
|
+
const setupResult = await setup();
|
|
125
|
+
connectA = setupResult.connectA;
|
|
126
|
+
connectB = setupResult.connectB;
|
|
127
|
+
switchboard = setupResult.switchboard;
|
|
128
|
+
const collectionId = driveCollectionId("main", DOCUMENT_ID);
|
|
129
|
+
await connectA.syncModule.syncManager.add(`switchboard-a-${DOCUMENT_ID}`, collectionId, {
|
|
130
|
+
type: "gql",
|
|
131
|
+
parameters: {
|
|
132
|
+
url: "http://switchboard/graphql",
|
|
133
|
+
pollIntervalMs: 25,
|
|
134
|
+
retryBaseDelayMs: 10,
|
|
135
|
+
retryMaxDelayMs: 200,
|
|
136
|
+
fetchFn: setupResult.bridge,
|
|
137
|
+
},
|
|
138
|
+
}, { documentId: [], scope: [], branch: "main" });
|
|
139
|
+
await connectB.syncModule.syncManager.add(`switchboard-b-${DOCUMENT_ID}`, collectionId, {
|
|
140
|
+
type: "gql",
|
|
141
|
+
parameters: {
|
|
142
|
+
url: "http://switchboard/graphql",
|
|
143
|
+
pollIntervalMs: 25,
|
|
144
|
+
retryBaseDelayMs: 10,
|
|
145
|
+
retryMaxDelayMs: 200,
|
|
146
|
+
fetchFn: setupResult.bridge,
|
|
147
|
+
},
|
|
148
|
+
}, { documentId: [], scope: [], branch: "main" });
|
|
149
|
+
const document = driveDocumentModelModule.utils.createDocument({
|
|
150
|
+
global: { name: "Repro", icon: null, nodes: [] },
|
|
151
|
+
});
|
|
152
|
+
document.header.id = DOCUMENT_ID;
|
|
153
|
+
const createJob = await connectA.reactor.create(document);
|
|
154
|
+
await waitForJobCompletion(connectA.reactor, createJob.id);
|
|
155
|
+
await Promise.all([
|
|
156
|
+
waitForDocumentAvailable(switchboard.reactor, DOCUMENT_ID),
|
|
157
|
+
waitForDocumentAvailable(connectB.reactor, DOCUMENT_ID),
|
|
158
|
+
]);
|
|
159
|
+
const actionA = createDeterministicAddFolderAction("action-A", "folder-A");
|
|
160
|
+
const actionB = createDeterministicAddFolderAction("action-B", "folder-B");
|
|
161
|
+
const [jobA, jobB] = await Promise.all([
|
|
162
|
+
connectA.reactor.execute(DOCUMENT_ID, "main", [actionA]),
|
|
163
|
+
connectB.reactor.execute(DOCUMENT_ID, "main", [actionB]),
|
|
164
|
+
]);
|
|
165
|
+
await waitForJobCompletion(connectA.reactor, jobA.id);
|
|
166
|
+
await waitForJobCompletion(connectB.reactor, jobB.id);
|
|
167
|
+
await advanceAndFlush(3000);
|
|
168
|
+
const [docA, docB, docS] = await Promise.all([
|
|
169
|
+
connectA.reactor.get(DOCUMENT_ID, { branch: "main" }),
|
|
170
|
+
connectB.reactor.get(DOCUMENT_ID, { branch: "main" }),
|
|
171
|
+
switchboard.reactor.get(DOCUMENT_ID, { branch: "main" }),
|
|
172
|
+
]);
|
|
173
|
+
const [indexA, indexB, indexS] = await Promise.all([
|
|
174
|
+
connectA.operationIndex.get(DOCUMENT_ID),
|
|
175
|
+
connectB.operationIndex.get(DOCUMENT_ID),
|
|
176
|
+
switchboard.operationIndex.get(DOCUMENT_ID),
|
|
177
|
+
]);
|
|
178
|
+
const globalEntries = [
|
|
179
|
+
...indexA.results,
|
|
180
|
+
...indexB.results,
|
|
181
|
+
...indexS.results,
|
|
182
|
+
].filter((entry) => entry.scope === "global");
|
|
183
|
+
expect(globalEntries.length).toBeGreaterThan(0);
|
|
184
|
+
expect(globalEntries.some((entry) => entry.skip > 0)).toBe(true);
|
|
185
|
+
const globalA = indexA.results.filter((entry) => entry.scope === "global");
|
|
186
|
+
const globalB = indexB.results.filter((entry) => entry.scope === "global");
|
|
187
|
+
const globalS = indexS.results.filter((entry) => entry.scope === "global");
|
|
188
|
+
const gcA = normalizeForComparison(gcGlobalEntries(globalA));
|
|
189
|
+
const gcB = normalizeForComparison(gcGlobalEntries(globalB));
|
|
190
|
+
const gcS = normalizeForComparison(gcGlobalEntries(globalS));
|
|
191
|
+
expect(gcA).toEqual(gcB);
|
|
192
|
+
expect(gcB).toEqual(gcS);
|
|
193
|
+
const stateA = docA.state;
|
|
194
|
+
const stateB = docB.state;
|
|
195
|
+
const stateS = docS.state;
|
|
196
|
+
expect(stateA).toEqual(stateB);
|
|
197
|
+
expect(stateB).toEqual(stateS);
|
|
198
|
+
}, 20000);
|
|
199
|
+
});
|
|
200
|
+
//# sourceMappingURL=connect-switchboard-reshuffle-convergence.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-switchboard-reshuffle-convergence.test.js","sourceRoot":"","sources":["../../test/connect-switchboard-reshuffle-convergence.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ISyncManager } from "@powerhousedao/reactor";
|
|
2
2
|
type SyncManagerRegistry = Map<string, ISyncManager>;
|
|
3
|
+
type ResolverBridgeOptions = {
|
|
4
|
+
log?: boolean;
|
|
5
|
+
};
|
|
3
6
|
/**
|
|
4
7
|
* Creates a mock fetch function that routes GraphQL sync operations
|
|
5
8
|
* directly to the resolver functions, bypassing the network.
|
|
@@ -7,6 +10,6 @@ type SyncManagerRegistry = Map<string, ISyncManager>;
|
|
|
7
10
|
* This enables integration testing of GqlChannel without running
|
|
8
11
|
* an actual GraphQL server.
|
|
9
12
|
*/
|
|
10
|
-
export declare function createResolverBridge(syncManagers: SyncManagerRegistry): typeof fetch;
|
|
13
|
+
export declare function createResolverBridge(syncManagers: SyncManagerRegistry, options?: ResolverBridgeOptions): typeof fetch;
|
|
11
14
|
export {};
|
|
12
15
|
//# sourceMappingURL=gql-resolver-bridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gql-resolver-bridge.d.ts","sourceRoot":"","sources":["../../../test/utils/gql-resolver-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAO3D,KAAK,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"gql-resolver-bridge.d.ts","sourceRoot":"","sources":["../../../test/utils/gql-resolver-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAO3D,KAAK,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAOrD,KAAK,qBAAqB,GAAG;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAyBF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,mBAAmB,EACjC,OAAO,GAAE,qBAA0B,GAClC,OAAO,KAAK,CAiId"}
|
|
@@ -22,7 +22,8 @@ function extractSyncManagerFromUrl(url, registry) {
|
|
|
22
22
|
* This enables integration testing of GqlChannel without running
|
|
23
23
|
* an actual GraphQL server.
|
|
24
24
|
*/
|
|
25
|
-
export function createResolverBridge(syncManagers) {
|
|
25
|
+
export function createResolverBridge(syncManagers, options = {}) {
|
|
26
|
+
const logEnabled = options.log ?? true;
|
|
26
27
|
return async (input, init) => {
|
|
27
28
|
let url;
|
|
28
29
|
if (typeof input === "string") {
|
|
@@ -42,7 +43,7 @@ export function createResolverBridge(syncManagers) {
|
|
|
42
43
|
if (body.query.includes("pollSyncEnvelopes")) {
|
|
43
44
|
const variables = body.variables;
|
|
44
45
|
const result = pollSyncEnvelopes(syncManager, variables);
|
|
45
|
-
if (result.envelopes.length > 0) {
|
|
46
|
+
if (logEnabled && result.envelopes.length > 0) {
|
|
46
47
|
console.log(`[BRIDGE] pollSyncEnvelopes: ${result.envelopes.length} envelopes for channel ${variables.channelId}`);
|
|
47
48
|
}
|
|
48
49
|
// Normalize envelopes for GqlRequestChannel compatibility:
|
|
@@ -65,15 +66,21 @@ export function createResolverBridge(syncManagers) {
|
|
|
65
66
|
if (body.query.includes("pushSyncEnvelopes")) {
|
|
66
67
|
const variables = body.variables;
|
|
67
68
|
const envelopeOps = variables.envelopes.flatMap((e) => (e.operations ?? []).map((op) => op.context.documentId));
|
|
68
|
-
|
|
69
|
+
if (logEnabled) {
|
|
70
|
+
console.log(`[BRIDGE] pushSyncEnvelopes: ${variables.envelopes.length} envelopes, docs: ${[...new Set(envelopeOps)].join(",")}`);
|
|
71
|
+
}
|
|
69
72
|
const result = await pushSyncEnvelopes(syncManager, variables);
|
|
70
73
|
return createMockResponse({ pushSyncEnvelopes: result });
|
|
71
74
|
}
|
|
72
75
|
if (body.query.includes("touchChannel")) {
|
|
73
76
|
const variables = body.variables;
|
|
74
|
-
|
|
77
|
+
if (logEnabled) {
|
|
78
|
+
console.log(`[BRIDGE] touchChannel: id=${variables.input.id} collection=${variables.input.collectionId}`);
|
|
79
|
+
}
|
|
75
80
|
const result = await touchChannel(syncManager, variables);
|
|
76
|
-
|
|
81
|
+
if (logEnabled) {
|
|
82
|
+
console.log(`[BRIDGE] touchChannel result: ${result}`);
|
|
83
|
+
}
|
|
77
84
|
return createMockResponse({ touchChannel: result });
|
|
78
85
|
}
|
|
79
86
|
throw new Error(`Unknown GraphQL operation in query: ${body.query}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gql-resolver-bridge.js","sourceRoot":"","sources":["../../../test/utils/gql-resolver-bridge.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"gql-resolver-bridge.js","sourceRoot":"","sources":["../../../test/utils/gql-resolver-bridge.ts"],"names":[],"mappings":"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"}
|