Default to Subduction#34
Closed
expede wants to merge 8 commits into
Closed
Conversation
Subduction was previously opt-in via `--sub`. Make it the default sync backend and add `--legacy` to opt back into the classic WebSocket relay. Backend choice is persisted per-directory as a `protocol` field in a new versioned config; v0 configs are migrated to v1 in place (with a backup) and their backend inferred, so existing repos keep working unchanged. - `protocol: "subduction" | "legacy"` replaces the boolean `subduction` flag; `--sub` is removed. - `config_version` + `resolveProtocol()` + `migrateIfNeeded()` drive the v0->v1 upgrade and infer the backend for pre-existing configs. - `--sync-server`'s storage id is legacy-only; supplying one in the default Subduction mode is now a hard error rather than a silent no-op. - Replace the `sub-flag` integration test with `legacy-flag`; add config-migration and subduction-config coverage.
`src/index.ts` re-exported `./cli`, whose module top-level ran
`program.parseAsync()`. Importing the package therefore parsed the host
process's argv -- printing help and exiting, or even running a pushwork
command. Guard the CLI bootstrap behind `require.main === module` and stop
re-exporting it, so `require("pushwork")` has no side effects.
Curate the public surface to the high-level API (SyncEngine, ConfigManager,
SnapshotManager, createRepo, ...) instead of dumping every internal util,
and add a regression test that the package imports cleanly.
A binary file with no NUL byte in its first 8 KB was classified as text and read with `fs.readFile(path, "utf8")`, replacing invalid UTF-8 sequences with U+FFFD -- a 256-byte file came back as 461 bytes of garbage on clone. Classify content as text only when it is *losslessly* valid UTF-8 (a fatal streaming decode), and guard `readFileContent` to return a string only if the bytes survive a round-trip. Add a property-based round-trip test over arbitrary byte buffers plus the null-free-binary repro.
`checkout` opened a networked Repo via setupCommandContext but never shut it down or exited, so the open connection kept the process alive forever -- for a command that only prints "not implemented". Resolve the path, print the message, and exit non-zero without opening a repo. Hide the experimental `checkout`/`log` stubs from `--help` so the CLI stops advertising non-functional commands.
- `clone`/`track` only checked the `automerge:` prefix, so a typo'd URL produced a silent empty clone; validate the full document id with `isValidAutomergeUrl`. - `sync --gentle --nuclear` silently ran nuclear; reject the combination. - Render expected errors (e.g. "not initialized") as a clean one-line message and show the internal stack only under DEBUG. - Lower Subduction's Rust log level so WARN transport chatter stops leaking to stdout, and filter the benign negative-timeout warning emitted by automerge-repo's throttle.
- `ConfigManager.load()` silently fell back to defaults on an unreadable config; warn instead so corruption isn't invisible. - `url` crashed with a stack trace on a corrupt snapshot.json; tolerate it. - `init <file>` failed deep inside with a raw ENOTDIR; reject a non-directory path up front. - Fix README drift: drop the non-existent `--debug` flag, correct the `ls` flag / Node version / source tree, document `sync --gentle`/`--nuclear`.
Stand up the quality tooling the project lacked: - ESLint (flat config) with typescript-eslint and type-aware promise rules; fix what it found (floating/misused promises in `watch`, unnecessary assertions). The old `lint` script used a removed flag with no config. - GitHub Actions CI: build, typecheck, lint, package-validate, unit tests, plus a typos spell-check job. - `publint`/`attw` (`check:package`), which surfaced that the library shipped no `types`/`files` -- fix package.json `exports` accordingly. - `typos` config + Nix dev-shell entry; bump the flake to nixos-26.05 and drop the removed `nodePackages` attribute.
Several "tests" exercised Node's fs/timers or hand-written simulation loops rather than pushwork code: `sync-timing` (pure stdlib), `sync-convergence` (asserts on a hardcoded while-loop), and `deletion-behavior`/`sync-deletion` (never invoke the engine -- they `new` ChangeDetector and discard it). Delete them; the behavior is covered by `in-memory-sync` and `fuzzer`. Add direct coverage for the previously-untested core logic: MoveDetector (threshold, size guard, binary short-circuit, best-match) and text-diff's `spliceText` (a round-trip property over our cursor arithmetic, incl. unicode). Fix `sync-flow`'s corrupt-config test, which wrote snapshot.json but asserted on config.load(), passing for the wrong reason.
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #22
I started this back in London 🇬🇧
TL;DR
The Main Show
--subis gone (use--legacyif you want the old relay)Bug Fixes
require("pushwork")would actually run the CLI against your process'sargv"Other"
26.05stdlibor a hardcoded while loop and added coverage for the stuff that was actually untestedExample
v1Config