pushwork 1.0.5 → 1.0.11
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/README.md +87 -335
- package/babel.config.js +5 -0
- package/dist/cli/commands.d.ts +9 -15
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +37 -170
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/output.d.ts +11 -25
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +55 -61
- package/dist/cli/output.js.map +1 -1
- package/dist/cli.js +208 -213
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +51 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +799 -0
- package/dist/commands.js.map +1 -0
- package/dist/core/change-detection.d.ts +7 -23
- package/dist/core/change-detection.d.ts.map +1 -1
- package/dist/core/change-detection.js +108 -122
- package/dist/core/change-detection.js.map +1 -1
- package/dist/core/config.d.ts +81 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +296 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/move-detection.d.ts +4 -3
- package/dist/core/move-detection.d.ts.map +1 -1
- package/dist/core/move-detection.js +8 -7
- package/dist/core/move-detection.js.map +1 -1
- package/dist/core/snapshot.d.ts +0 -4
- package/dist/core/snapshot.d.ts.map +1 -1
- package/dist/core/snapshot.js +2 -11
- package/dist/core/snapshot.js.map +1 -1
- package/dist/core/sync-engine.d.ts +41 -12
- package/dist/core/sync-engine.d.ts.map +1 -1
- package/dist/core/sync-engine.js +522 -359
- package/dist/core/sync-engine.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -6
- package/dist/index.js.map +1 -1
- package/dist/types/config.d.ts +24 -88
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/documents.d.ts +15 -2
- package/dist/types/documents.d.ts.map +1 -1
- package/dist/types/documents.js.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +1 -1
- package/dist/types/snapshot.d.ts +0 -21
- package/dist/types/snapshot.d.ts.map +1 -1
- package/dist/types/snapshot.js +0 -14
- package/dist/types/snapshot.js.map +1 -1
- package/dist/utils/content.d.ts.map +1 -1
- package/dist/utils/content.js +2 -6
- package/dist/utils/content.js.map +1 -1
- package/dist/utils/directory.d.ts +24 -0
- package/dist/utils/directory.d.ts.map +1 -0
- package/dist/utils/directory.js +56 -0
- package/dist/utils/directory.js.map +1 -0
- package/dist/utils/fs.d.ts +15 -2
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +53 -20
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -3
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/keyhive.d.ts +9 -0
- package/dist/utils/keyhive.d.ts.map +1 -0
- package/dist/utils/keyhive.js +26 -0
- package/dist/utils/keyhive.js.map +1 -0
- package/dist/utils/mime-types.d.ts.map +1 -1
- package/dist/utils/mime-types.js +11 -4
- package/dist/utils/mime-types.js.map +1 -1
- package/dist/utils/network-sync.d.ts +16 -7
- package/dist/utils/network-sync.d.ts.map +1 -1
- package/dist/utils/network-sync.js +158 -99
- package/dist/utils/network-sync.js.map +1 -1
- package/dist/utils/output.d.ts +129 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +375 -0
- package/dist/utils/output.js.map +1 -0
- package/dist/utils/repo-factory.d.ts +2 -6
- package/dist/utils/repo-factory.d.ts.map +1 -1
- package/dist/utils/repo-factory.js +8 -31
- package/dist/utils/repo-factory.js.map +1 -1
- package/dist/utils/string-similarity.js +2 -2
- package/dist/utils/string-similarity.js.map +1 -1
- package/dist/utils/trace.d.ts +19 -0
- package/dist/utils/trace.d.ts.map +1 -0
- package/dist/utils/trace.js +68 -0
- package/dist/utils/trace.js.map +1 -0
- package/package.json +21 -11
- package/src/cli.ts +276 -308
- package/src/commands.ts +988 -0
- package/src/core/change-detection.ts +226 -246
- package/src/{config/index.ts → core/config.ts} +65 -82
- package/src/core/index.ts +1 -1
- package/src/core/move-detection.ts +10 -8
- package/src/core/snapshot.ts +2 -12
- package/src/core/sync-engine.ts +630 -478
- package/src/index.ts +0 -10
- package/src/types/config.ts +28 -93
- package/src/types/documents.ts +16 -2
- package/src/types/index.ts +0 -5
- package/src/types/snapshot.ts +0 -23
- package/src/utils/content.ts +2 -6
- package/src/utils/directory.ts +73 -0
- package/src/utils/fs.ts +57 -23
- package/src/utils/index.ts +1 -5
- package/src/utils/mime-types.ts +12 -4
- package/src/utils/network-sync.ts +216 -138
- package/src/utils/output.ts +450 -0
- package/src/utils/repo-factory.ts +13 -44
- package/src/utils/string-similarity.ts +2 -2
- package/src/utils/trace.ts +70 -0
- package/test/integration/exclude-patterns.test.ts +6 -15
- package/test/integration/fuzzer.test.ts +308 -391
- package/test/integration/in-memory-sync.test.ts +435 -0
- package/test/integration/init-sync.test.ts +89 -0
- package/test/integration/sync-deletion.test.ts +2 -61
- package/test/integration/sync-flow.test.ts +4 -24
- package/test/jest.setup.ts +34 -0
- package/test/unit/deletion-behavior.test.ts +3 -14
- package/test/unit/enhanced-mime-detection.test.ts +0 -22
- package/test/unit/snapshot.test.ts +2 -29
- package/test/unit/sync-convergence.test.ts +3 -198
- package/test/unit/sync-timing.test.ts +0 -44
- package/test/unit/utils.test.ts +0 -2
- package/tsconfig.json +3 -3
- package/bench/filesystem.bench.ts +0 -78
- package/bench/hashing.bench.ts +0 -60
- package/bench/move-detection.bench.ts +0 -130
- package/bench/runner.ts +0 -49
- package/dist/browser/browser-sync-engine.d.ts +0 -64
- package/dist/browser/browser-sync-engine.d.ts.map +0 -1
- package/dist/browser/browser-sync-engine.js +0 -303
- package/dist/browser/browser-sync-engine.js.map +0 -1
- package/dist/browser/filesystem-adapter.d.ts +0 -84
- package/dist/browser/filesystem-adapter.d.ts.map +0 -1
- package/dist/browser/filesystem-adapter.js +0 -413
- package/dist/browser/filesystem-adapter.js.map +0 -1
- package/dist/browser/index.d.ts +0 -36
- package/dist/browser/index.d.ts.map +0 -1
- package/dist/browser/index.js +0 -90
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/types.d.ts +0 -70
- package/dist/browser/types.d.ts.map +0 -1
- package/dist/browser/types.js +0 -6
- package/dist/browser/types.js.map +0 -1
- package/dist/config/remote-manager.d.ts +0 -65
- package/dist/config/remote-manager.d.ts.map +0 -1
- package/dist/config/remote-manager.js +0 -243
- package/dist/config/remote-manager.js.map +0 -1
- package/dist/core/isomorphic-snapshot.d.ts +0 -58
- package/dist/core/isomorphic-snapshot.d.ts.map +0 -1
- package/dist/core/isomorphic-snapshot.js +0 -204
- package/dist/core/isomorphic-snapshot.js.map +0 -1
- package/dist/platform/browser-filesystem.d.ts +0 -26
- package/dist/platform/browser-filesystem.d.ts.map +0 -1
- package/dist/platform/browser-filesystem.js +0 -91
- package/dist/platform/browser-filesystem.js.map +0 -1
- package/dist/platform/filesystem.d.ts +0 -29
- package/dist/platform/filesystem.d.ts.map +0 -1
- package/dist/platform/filesystem.js +0 -65
- package/dist/platform/filesystem.js.map +0 -1
- package/dist/platform/node-filesystem.d.ts +0 -21
- package/dist/platform/node-filesystem.d.ts.map +0 -1
- package/dist/platform/node-filesystem.js +0 -93
- package/dist/platform/node-filesystem.js.map +0 -1
- package/dist/utils/fs-browser.d.ts +0 -57
- package/dist/utils/fs-browser.d.ts.map +0 -1
- package/dist/utils/fs-browser.js +0 -311
- package/dist/utils/fs-browser.js.map +0 -1
- package/dist/utils/fs-node.d.ts +0 -53
- package/dist/utils/fs-node.d.ts.map +0 -1
- package/dist/utils/fs-node.js +0 -220
- package/dist/utils/fs-node.js.map +0 -1
- package/dist/utils/isomorphic.d.ts +0 -29
- package/dist/utils/isomorphic.d.ts.map +0 -1
- package/dist/utils/isomorphic.js +0 -139
- package/dist/utils/isomorphic.js.map +0 -1
- package/dist/utils/pure.d.ts +0 -25
- package/dist/utils/pure.d.ts.map +0 -1
- package/dist/utils/pure.js +0 -112
- package/dist/utils/pure.js.map +0 -1
- package/src/cli/commands.ts +0 -1030
- package/src/cli/index.ts +0 -2
- package/src/cli/output.ts +0 -244
- package/test/README-TESTING-GAPS.md +0 -174
|
@@ -1,169 +1,247 @@
|
|
|
1
|
-
import { DocHandle, StorageId } from "@automerge/automerge-repo";
|
|
1
|
+
import { DocHandle, StorageId, Repo, AutomergeUrl } from "@automerge/automerge-repo";
|
|
2
2
|
import * as A from "@automerge/automerge";
|
|
3
|
+
import { out } from "./output";
|
|
4
|
+
import { DirectoryDocument } from "../types";
|
|
5
|
+
import { getPlainUrl } from "./directory";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Wait for bidirectional sync to stabilize.
|
|
9
|
+
* This function waits until document heads stop changing, indicating that
|
|
10
|
+
* both outgoing and incoming sync has completed.
|
|
11
|
+
*
|
|
12
|
+
* @param repo - The Automerge repository
|
|
13
|
+
* @param rootDirectoryUrl - The root directory URL to start traversal from
|
|
14
|
+
* @param syncServerStorageId - The sync server storage ID
|
|
15
|
+
* @param options - Configuration options
|
|
16
|
+
*/
|
|
17
|
+
export async function waitForBidirectionalSync(
|
|
18
|
+
repo: Repo,
|
|
19
|
+
rootDirectoryUrl: AutomergeUrl | undefined,
|
|
20
|
+
syncServerStorageId: StorageId | undefined,
|
|
21
|
+
options: {
|
|
22
|
+
timeoutMs?: number;
|
|
23
|
+
pollIntervalMs?: number;
|
|
24
|
+
stableChecksRequired?: number;
|
|
25
|
+
} = {}
|
|
26
|
+
): Promise<void> {
|
|
27
|
+
const {
|
|
28
|
+
timeoutMs = 10000,
|
|
29
|
+
pollIntervalMs = 100,
|
|
30
|
+
stableChecksRequired = 3,
|
|
31
|
+
} = options;
|
|
32
|
+
|
|
33
|
+
if (!syncServerStorageId || !rootDirectoryUrl) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const startTime = Date.now();
|
|
38
|
+
let lastSeenHeads = new Map<string, string>();
|
|
39
|
+
let stableCount = 0;
|
|
40
|
+
|
|
41
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
42
|
+
// Get current heads for all documents in the directory hierarchy
|
|
43
|
+
const currentHeads = await getAllDocumentHeads(repo, rootDirectoryUrl);
|
|
44
|
+
|
|
45
|
+
// Check if heads are stable (no changes since last check)
|
|
46
|
+
const isStable = headsMapEqual(lastSeenHeads, currentHeads);
|
|
47
|
+
|
|
48
|
+
if (isStable) {
|
|
49
|
+
stableCount++;
|
|
50
|
+
if (stableCount >= stableChecksRequired) {
|
|
51
|
+
return; // Converged!
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
stableCount = 0;
|
|
55
|
+
lastSeenHeads = currentHeads;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
await new Promise((r) => setTimeout(r, pollIntervalMs));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Timeout - but don't throw, just log a warning
|
|
62
|
+
// The sync may still work, we just couldn't confirm stability
|
|
63
|
+
out.taskLine(`Sync stability check timed out after ${timeoutMs}ms`, true);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get all document heads in the directory hierarchy.
|
|
68
|
+
* Returns a map of document URL -> serialized heads.
|
|
69
|
+
* Uses plain URLs (without heads) to ensure we see current document state.
|
|
70
|
+
*/
|
|
71
|
+
async function getAllDocumentHeads(
|
|
72
|
+
repo: Repo,
|
|
73
|
+
rootDirectoryUrl: AutomergeUrl
|
|
74
|
+
): Promise<Map<string, string>> {
|
|
75
|
+
const heads = new Map<string, string>();
|
|
76
|
+
// Pass URL as-is; collectHeadsRecursive will strip heads
|
|
77
|
+
await collectHeadsRecursive(repo, rootDirectoryUrl, heads);
|
|
78
|
+
return heads;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Recursively collect document heads from the directory hierarchy.
|
|
83
|
+
* Uses getPlainUrl to strip heads and always see the CURRENT state of documents.
|
|
84
|
+
*/
|
|
85
|
+
async function collectHeadsRecursive(
|
|
86
|
+
repo: Repo,
|
|
87
|
+
directoryUrl: AutomergeUrl,
|
|
88
|
+
heads: Map<string, string>
|
|
89
|
+
): Promise<void> {
|
|
90
|
+
try {
|
|
91
|
+
const plainUrl = getPlainUrl(directoryUrl);
|
|
92
|
+
const handle = await repo.find<DirectoryDocument>(plainUrl);
|
|
93
|
+
const doc = await handle.doc();
|
|
94
|
+
|
|
95
|
+
// Record this directory's heads (use plain URL as key for consistency)
|
|
96
|
+
heads.set(plainUrl, JSON.stringify(handle.heads()));
|
|
97
|
+
|
|
98
|
+
if (!doc || !doc.docs) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Process all entries in the directory
|
|
103
|
+
for (const entry of doc.docs) {
|
|
104
|
+
if (entry.type === "folder") {
|
|
105
|
+
// Recurse into subdirectory (entry.url may have stale heads)
|
|
106
|
+
await collectHeadsRecursive(repo, entry.url, heads);
|
|
107
|
+
} else if (entry.type === "file") {
|
|
108
|
+
// Get file document heads (strip heads from entry.url)
|
|
109
|
+
try {
|
|
110
|
+
const fileUrl = getPlainUrl(entry.url);
|
|
111
|
+
const fileHandle = await repo.find(fileUrl);
|
|
112
|
+
heads.set(fileUrl, JSON.stringify(fileHandle.heads()));
|
|
113
|
+
} catch {
|
|
114
|
+
// File document may not exist yet
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
// Directory may not exist yet
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Compare two heads maps for equality.
|
|
125
|
+
*/
|
|
126
|
+
function headsMapEqual(
|
|
127
|
+
a: Map<string, string>,
|
|
128
|
+
b: Map<string, string>
|
|
129
|
+
): boolean {
|
|
130
|
+
if (a.size !== b.size) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
for (const [key, value] of a) {
|
|
134
|
+
if (b.get(key) !== value) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
3
140
|
|
|
4
141
|
/**
|
|
5
142
|
* Wait for documents to sync to the remote server
|
|
6
|
-
* Based on patchwork-cli implementation with timeout for debugging
|
|
7
143
|
*/
|
|
8
144
|
export async function waitForSync(
|
|
9
145
|
handlesToWaitOn: DocHandle<unknown>[],
|
|
10
146
|
syncServerStorageId?: StorageId,
|
|
11
|
-
timeoutMs: number = 60000
|
|
147
|
+
timeoutMs: number = 60000
|
|
12
148
|
): Promise<void> {
|
|
13
149
|
const startTime = Date.now();
|
|
14
150
|
|
|
15
151
|
if (!syncServerStorageId) {
|
|
16
|
-
|
|
17
|
-
"No sync server storage ID provided. Skipping network sync wait."
|
|
18
|
-
);
|
|
152
|
+
// No sync server storage ID - skip network sync
|
|
19
153
|
return;
|
|
20
154
|
}
|
|
21
155
|
|
|
22
156
|
if (handlesToWaitOn.length === 0) {
|
|
23
|
-
|
|
157
|
+
// No documents to sync
|
|
24
158
|
return;
|
|
25
159
|
}
|
|
26
160
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
handlesToWaitOn.forEach((handle, i) => {
|
|
37
|
-
const localHeads = handle.heads();
|
|
38
|
-
const syncInfo = handle.getSyncInfo(syncServerStorageId);
|
|
39
|
-
const remoteHeads = syncInfo?.lastHeads;
|
|
40
|
-
console.log(` 📄 Document ${i + 1}: ${handle.url}`);
|
|
41
|
-
console.log(` 🏠 Local heads: ${JSON.stringify(localHeads)}`);
|
|
42
|
-
console.log(` 🌐 Remote heads: ${JSON.stringify(remoteHeads)}`);
|
|
43
|
-
console.log(
|
|
44
|
-
` ✅ Already synced: ${A.equals(localHeads, remoteHeads)}`
|
|
45
|
-
);
|
|
46
|
-
});
|
|
47
|
-
}
|
|
161
|
+
let alreadySynced = 0;
|
|
162
|
+
|
|
163
|
+
const promises = handlesToWaitOn.map((handle) => {
|
|
164
|
+
// Check if already synced
|
|
165
|
+
const heads = handle.heads();
|
|
166
|
+
const syncInfo = handle.getSyncInfo(syncServerStorageId);
|
|
167
|
+
const remoteHeads = syncInfo?.lastHeads;
|
|
168
|
+
const wasAlreadySynced = A.equals(heads, remoteHeads);
|
|
48
169
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// Check if already synced
|
|
95
|
-
if (checkSync()) {
|
|
96
|
-
return;
|
|
170
|
+
if (wasAlreadySynced) {
|
|
171
|
+
alreadySynced++;
|
|
172
|
+
return Promise.resolve();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Wait for convergence
|
|
176
|
+
return new Promise<void>((resolve, reject) => {
|
|
177
|
+
// TODO: can we delete this polling?
|
|
178
|
+
let pollInterval: NodeJS.Timeout;
|
|
179
|
+
|
|
180
|
+
const cleanup = () => {
|
|
181
|
+
clearTimeout(timeout);
|
|
182
|
+
clearInterval(pollInterval);
|
|
183
|
+
handle.off("remote-heads", onRemoteHeads);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const onConverged = () => {
|
|
187
|
+
cleanup();
|
|
188
|
+
resolve();
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const timeout = setTimeout(() => {
|
|
192
|
+
cleanup();
|
|
193
|
+
reject(
|
|
194
|
+
new Error(
|
|
195
|
+
`Sync timeout after ${timeoutMs}ms for document ${handle.url}`
|
|
196
|
+
)
|
|
197
|
+
);
|
|
198
|
+
}, timeoutMs);
|
|
199
|
+
|
|
200
|
+
const isConverged = () => {
|
|
201
|
+
const localHeads = handle.heads();
|
|
202
|
+
const info = handle.getSyncInfo(syncServerStorageId);
|
|
203
|
+
return A.equals(localHeads, info?.lastHeads);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const onRemoteHeads = ({
|
|
207
|
+
storageId,
|
|
208
|
+
}: {
|
|
209
|
+
storageId: StorageId;
|
|
210
|
+
heads: any;
|
|
211
|
+
}) => {
|
|
212
|
+
if (storageId === syncServerStorageId && isConverged()) {
|
|
213
|
+
onConverged();
|
|
97
214
|
}
|
|
215
|
+
};
|
|
98
216
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
}, 100); // Check every 100ms for faster response
|
|
105
|
-
|
|
106
|
-
// Also wait for remote-heads event (faster when events work)
|
|
107
|
-
const onRemoteHeads = ({
|
|
108
|
-
storageId,
|
|
109
|
-
heads,
|
|
110
|
-
}: {
|
|
111
|
-
storageId: StorageId;
|
|
112
|
-
heads: any;
|
|
113
|
-
}) => {
|
|
114
|
-
if (verbose) {
|
|
115
|
-
console.log(`📡 Received remote heads event for ${handle.url}:`);
|
|
116
|
-
console.log(` Event storage ID: ${storageId}`);
|
|
117
|
-
console.log(` Expected storage ID: ${syncServerStorageId}`);
|
|
118
|
-
console.log(` Event heads: ${JSON.stringify(heads)}`);
|
|
119
|
-
console.log(
|
|
120
|
-
` Current local heads: ${JSON.stringify(handle.heads())}`
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (
|
|
125
|
-
storageId === syncServerStorageId &&
|
|
126
|
-
A.equals(handle.heads(), heads)
|
|
127
|
-
) {
|
|
128
|
-
if (verbose) {
|
|
129
|
-
console.log(
|
|
130
|
-
`✅ Document ${index + 1} synced via event: ${handle.url}`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
clearTimeout(timeout);
|
|
134
|
-
clearInterval(pollInterval);
|
|
135
|
-
handle.off("remote-heads", onRemoteHeads);
|
|
136
|
-
resolve();
|
|
137
|
-
} else if (verbose) {
|
|
138
|
-
console.log(`❌ Heads/storage mismatch for ${handle.url}`);
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
if (verbose) {
|
|
143
|
-
console.log(`👂 Listening for remote-heads events on ${handle.url}`);
|
|
217
|
+
const poll = () => {
|
|
218
|
+
if (isConverged()) {
|
|
219
|
+
onConverged();
|
|
220
|
+
return true;
|
|
144
221
|
}
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
222
|
+
return false;
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// Initial check
|
|
226
|
+
if (poll()) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Start polling and event listening
|
|
231
|
+
pollInterval = setInterval(() => {
|
|
232
|
+
poll();
|
|
233
|
+
}, 100);
|
|
234
|
+
|
|
235
|
+
handle.on("remote-heads", onRemoteHeads);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
148
238
|
|
|
149
239
|
try {
|
|
150
240
|
await Promise.all(promises);
|
|
151
|
-
const elapsed = Date.now() - startTime;
|
|
152
|
-
if (verbose) {
|
|
153
|
-
console.log(`✅ All documents synced to network (took ${elapsed}ms)`);
|
|
154
|
-
}
|
|
155
241
|
} catch (error) {
|
|
156
242
|
const elapsed = Date.now() - startTime;
|
|
157
|
-
|
|
243
|
+
out.errorBlock("FAILED", `after ${elapsed}ms`);
|
|
244
|
+
out.crash(error);
|
|
158
245
|
throw error;
|
|
159
246
|
}
|
|
160
247
|
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Get the storage ID for the sync server
|
|
164
|
-
* Using the same ID as patchwork-cli for consistency
|
|
165
|
-
*/
|
|
166
|
-
export function getSyncServerStorageId(customStorageId?: string): StorageId {
|
|
167
|
-
return (customStorageId ||
|
|
168
|
-
"3760df37-a4c6-4f66-9ecd-732039a9385d") as StorageId;
|
|
169
|
-
}
|