pushwork 1.0.4 → 1.0.7
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 -328
- package/dist/.pushwork/automerge/3P/Dm3ekE2pmjGnWvDaG3vSR7ww98/snapshot/aa2349c94955ea561f698720142f9d884a6872d9f82dc332d578c216beb0df0e +0 -0
- package/dist/.pushwork/automerge/st/orage-adapter-id +1 -0
- package/dist/.pushwork/config.json +15 -0
- package/dist/.pushwork/snapshot.json +7 -0
- package/dist/cli.js +231 -170
- 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 +6 -19
- package/dist/core/change-detection.d.ts.map +1 -1
- package/dist/core/change-detection.js +101 -80
- package/dist/core/change-detection.js.map +1 -1
- package/dist/{config/index.d.ts → core/config.d.ts} +13 -3
- package/dist/core/config.d.ts.map +1 -0
- package/dist/{config/index.js → core/config.js} +55 -73
- 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 +12 -50
- package/dist/core/move-detection.d.ts.map +1 -1
- package/dist/core/move-detection.js +58 -139
- 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 +5 -11
- package/dist/core/sync-engine.d.ts.map +1 -1
- package/dist/core/sync-engine.js +220 -362
- 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 +43 -67
- 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 -3
- 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 +3 -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 +10 -0
- package/dist/utils/directory.d.ts.map +1 -0
- package/dist/utils/directory.js +37 -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 +63 -53
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -4
- package/dist/utils/index.js.map +1 -1
- 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 +0 -6
- package/dist/utils/network-sync.d.ts.map +1 -1
- package/dist/utils/network-sync.js +55 -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 -22
- package/dist/utils/repo-factory.js.map +1 -1
- package/dist/utils/string-similarity.d.ts +14 -0
- package/dist/utils/string-similarity.d.ts.map +1 -0
- package/dist/utils/string-similarity.js +43 -0
- package/dist/utils/string-similarity.js.map +1 -0
- 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 +17 -12
- package/src/cli.ts +326 -252
- package/src/commands.ts +988 -0
- package/src/core/change-detection.ts +199 -162
- package/src/{config/index.ts → core/config.ts} +65 -82
- package/src/core/index.ts +1 -1
- package/src/core/move-detection.ts +74 -180
- package/src/core/snapshot.ts +2 -12
- package/src/core/sync-engine.ts +248 -499
- package/src/index.ts +0 -10
- package/src/types/config.ts +50 -72
- package/src/types/documents.ts +16 -3
- package/src/types/index.ts +0 -5
- package/src/types/snapshot.ts +1 -23
- package/src/utils/content.ts +2 -6
- package/src/utils/directory.ts +50 -0
- package/src/utils/fs.ts +67 -56
- package/src/utils/index.ts +1 -6
- package/src/utils/mime-types.ts +12 -4
- package/src/utils/network-sync.ts +79 -137
- package/src/utils/output.ts +450 -0
- package/src/utils/repo-factory.ts +13 -31
- package/src/utils/string-similarity.ts +54 -0
- 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/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/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/cli/commands.d.ts +0 -77
- package/dist/cli/commands.d.ts.map +0 -1
- package/dist/cli/commands.js +0 -904
- package/dist/cli/commands.js.map +0 -1
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -19
- package/dist/cli/index.js.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.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/content-similarity.d.ts +0 -53
- package/dist/utils/content-similarity.d.ts.map +0 -1
- package/dist/utils/content-similarity.js +0 -155
- package/dist/utils/content-similarity.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 -1207
- package/src/cli/index.ts +0 -2
- package/src/utils/content-similarity.ts +0 -194
- package/test/README-TESTING-GAPS.md +0 -174
- package/test/unit/content-similarity.test.ts +0 -236
|
@@ -2,56 +2,38 @@ import { Repo, StorageId } from "@automerge/automerge-repo";
|
|
|
2
2
|
import { NodeFSStorageAdapter } from "@automerge/automerge-repo-storage-nodefs";
|
|
3
3
|
import { BrowserWebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket";
|
|
4
4
|
import * as path from "path";
|
|
5
|
-
import
|
|
6
|
-
import { ConfigManager } from "../config";
|
|
7
|
-
|
|
8
|
-
export interface RepoFactoryOptions {
|
|
9
|
-
enableNetwork?: boolean;
|
|
10
|
-
syncServer?: string;
|
|
11
|
-
syncServerStorageId?: string;
|
|
12
|
-
}
|
|
5
|
+
import { DirectoryConfig } from "../types";
|
|
13
6
|
|
|
14
7
|
/**
|
|
15
8
|
* Create an Automerge repository with configuration-based setup
|
|
16
9
|
*/
|
|
17
10
|
export async function createRepo(
|
|
18
11
|
workingDir: string,
|
|
19
|
-
|
|
12
|
+
config: DirectoryConfig
|
|
20
13
|
): Promise<Repo> {
|
|
21
|
-
const configManager = new ConfigManager(workingDir);
|
|
22
|
-
const config = await configManager.getMerged();
|
|
23
|
-
|
|
24
14
|
const syncToolDir = path.join(workingDir, ".pushwork");
|
|
25
15
|
const storage = new NodeFSStorageAdapter(path.join(syncToolDir, "automerge"));
|
|
26
16
|
|
|
27
17
|
const repoConfig: any = { storage };
|
|
28
18
|
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// Add network adapter only if explicitly enabled and sync server is configured
|
|
36
|
-
if (enableNetwork && syncServer) {
|
|
37
|
-
const networkAdapter = new BrowserWebSocketClientAdapter(syncServer);
|
|
19
|
+
// Add network adapter only if sync is enabled and server is configured
|
|
20
|
+
if (config.sync_enabled && config.sync_server) {
|
|
21
|
+
const networkAdapter = new BrowserWebSocketClientAdapter(
|
|
22
|
+
config.sync_server
|
|
23
|
+
);
|
|
38
24
|
repoConfig.network = [networkAdapter];
|
|
39
25
|
repoConfig.enableRemoteHeadsGossiping = true;
|
|
40
|
-
console.log(chalk.gray(` ✓ Network sync enabled: ${syncServer}`));
|
|
41
|
-
} else {
|
|
42
|
-
console.log(chalk.gray(" ✓ Local-only mode (network sync disabled)"));
|
|
43
26
|
}
|
|
44
27
|
|
|
45
28
|
const repo = new Repo(repoConfig);
|
|
46
29
|
|
|
47
30
|
// Subscribe to the sync server storage for network sync
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
);
|
|
31
|
+
if (
|
|
32
|
+
config.sync_enabled &&
|
|
33
|
+
config.sync_server &&
|
|
34
|
+
config.sync_server_storage_id
|
|
35
|
+
) {
|
|
36
|
+
repo.subscribeToRemotes([config.sync_server_storage_id as StorageId]);
|
|
55
37
|
}
|
|
56
38
|
|
|
57
39
|
return repo;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/* Based on the Sørensen–Dice coefficient, code from https://github.com/stephenjjbrown/string-similarity-js */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
|
|
5
|
+
* Calculate similarity between two strings
|
|
6
|
+
|
|
7
|
+
* @param {string} str1 First string to match
|
|
8
|
+
* @param {string} str2 Second string to match
|
|
9
|
+
* @param {number} [substringLength=2] Optional. Length of substring to be used in calculating similarity. Default 2.
|
|
10
|
+
* @param {boolean} [caseSensitive=false] Optional. Whether you want to consider case in string matching. Default false;
|
|
11
|
+
|
|
12
|
+
* @returns Number between 0 and 1, with 0 being a low match score.
|
|
13
|
+
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const stringSimilarity = (
|
|
17
|
+
str1: string,
|
|
18
|
+
str2: string,
|
|
19
|
+
substringLength: number = 2,
|
|
20
|
+
caseSensitive: boolean = false
|
|
21
|
+
) => {
|
|
22
|
+
if (str1 === str2) return 1;
|
|
23
|
+
if (!caseSensitive) {
|
|
24
|
+
str1 = str1.toLowerCase();
|
|
25
|
+
|
|
26
|
+
str2 = str2.toLowerCase();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (str1.length < substringLength || str2.length < substringLength) return 0;
|
|
30
|
+
|
|
31
|
+
const map = new Map();
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < str1.length - (substringLength - 1); i++) {
|
|
34
|
+
const substr1 = str1.substring(i, i + substringLength);
|
|
35
|
+
|
|
36
|
+
map.set(substr1, map.has(substr1) ? map.get(substr1) + 1 : 1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let match = 0;
|
|
40
|
+
|
|
41
|
+
for (let j = 0; j < str2.length - (substringLength - 1); j++) {
|
|
42
|
+
const substr2 = str2.substring(j, j + substringLength);
|
|
43
|
+
|
|
44
|
+
const count = map.has(substr2) ? map.get(substr2) : 0;
|
|
45
|
+
|
|
46
|
+
if (count > 0) {
|
|
47
|
+
map.set(substr2, count - 1);
|
|
48
|
+
|
|
49
|
+
match++;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (match * 2) / (str1.length + str2.length - (substringLength - 1) * 2);
|
|
54
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { out } from "./output";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Global tracing state
|
|
5
|
+
*/
|
|
6
|
+
let tracingEnabled = false;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Enable or disable tracing
|
|
10
|
+
*/
|
|
11
|
+
export function setTracingEnabled(enabled: boolean): void {
|
|
12
|
+
tracingEnabled = enabled;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if tracing is enabled
|
|
17
|
+
*/
|
|
18
|
+
export function isTracingEnabled(): boolean {
|
|
19
|
+
return tracingEnabled;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Trace a span of work by outputting to console
|
|
24
|
+
* Works for both sync and async functions
|
|
25
|
+
* Only outputs if tracing is enabled
|
|
26
|
+
*
|
|
27
|
+
* Usage:
|
|
28
|
+
* await span("operation", async () => { ... })
|
|
29
|
+
* span("operation", () => { ... })
|
|
30
|
+
*/
|
|
31
|
+
export function span<T>(
|
|
32
|
+
name: string,
|
|
33
|
+
fn: () => T | Promise<T>
|
|
34
|
+
): T | Promise<T> {
|
|
35
|
+
if (!tracingEnabled) {
|
|
36
|
+
return fn();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const start = performance.now();
|
|
40
|
+
const result = fn();
|
|
41
|
+
|
|
42
|
+
// Check if it's a promise (async)
|
|
43
|
+
if (result instanceof Promise) {
|
|
44
|
+
return result.then((value) => {
|
|
45
|
+
const duration = performance.now() - start;
|
|
46
|
+
out.taskLine(`${name} (${formatDuration(duration)})`, true);
|
|
47
|
+
return value;
|
|
48
|
+
}) as T;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Sync case
|
|
52
|
+
const duration = performance.now() - start;
|
|
53
|
+
out.taskLine(`${name} (${formatDuration(duration)})`, true);
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Format duration for display
|
|
59
|
+
*/
|
|
60
|
+
function formatDuration(ms: number): string {
|
|
61
|
+
if (ms < 1) {
|
|
62
|
+
return `${ms.toFixed(2)}ms`;
|
|
63
|
+
} else if (ms < 1000) {
|
|
64
|
+
return `${Math.round(ms)}ms`;
|
|
65
|
+
} else if (ms < 2000) {
|
|
66
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
67
|
+
} else {
|
|
68
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
2
|
import * as fs from "fs/promises";
|
|
3
3
|
import { tmpdir } from "os";
|
|
4
|
-
import { ConfigManager } from "../../src/
|
|
4
|
+
import { ConfigManager } from "../../src/core";
|
|
5
5
|
import { DirectoryConfig } from "../../src/types";
|
|
6
6
|
import {
|
|
7
7
|
ensureDirectoryExists,
|
|
@@ -105,18 +105,9 @@ describe("Exclude Patterns", () => {
|
|
|
105
105
|
const localConfig: DirectoryConfig = {
|
|
106
106
|
sync_server: "wss://test.server.com",
|
|
107
107
|
sync_enabled: true,
|
|
108
|
-
|
|
109
|
-
exclude_patterns: [".git", "*.tmp", ".pushwork", "*.env"],
|
|
110
|
-
large_file_threshold: "100MB",
|
|
111
|
-
},
|
|
112
|
-
diff: {
|
|
113
|
-
show_binary: false,
|
|
114
|
-
},
|
|
108
|
+
exclude_patterns: [".git", "*.tmp", ".pushwork", "*.env"],
|
|
115
109
|
sync: {
|
|
116
110
|
move_detection_threshold: 0.8,
|
|
117
|
-
prompt_threshold: 0.5,
|
|
118
|
-
auto_sync: false,
|
|
119
|
-
parallel_operations: 4,
|
|
120
111
|
},
|
|
121
112
|
};
|
|
122
113
|
await configManager.save(localConfig);
|
|
@@ -125,9 +116,9 @@ describe("Exclude Patterns", () => {
|
|
|
125
116
|
const mergedConfig = await configManager.getMerged();
|
|
126
117
|
|
|
127
118
|
// Verify .pushwork is in the exclude patterns
|
|
128
|
-
expect(mergedConfig.
|
|
129
|
-
expect(mergedConfig.
|
|
130
|
-
expect(mergedConfig.
|
|
119
|
+
expect(mergedConfig.exclude_patterns).toContain(".pushwork");
|
|
120
|
+
expect(mergedConfig.exclude_patterns).toContain("*.env");
|
|
121
|
+
expect(mergedConfig.exclude_patterns).toContain(".git");
|
|
131
122
|
|
|
132
123
|
// Create test files
|
|
133
124
|
await writeFileContent(path.join(tmpDir, "include.txt"), "include me");
|
|
@@ -141,7 +132,7 @@ describe("Exclude Patterns", () => {
|
|
|
141
132
|
const entries = await listDirectory(
|
|
142
133
|
tmpDir,
|
|
143
134
|
true,
|
|
144
|
-
mergedConfig.
|
|
135
|
+
mergedConfig.exclude_patterns
|
|
145
136
|
);
|
|
146
137
|
const filePaths = entries.map((entry) => path.relative(tmpDir, entry.path));
|
|
147
138
|
|