@davideasden/pi-undo 0.2.4 → 0.2.5
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 +15 -4
- package/package.json +1 -1
- package/src/snapshot-store.ts +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Each completed agent run creates a checkpoint that captures both the Pi session
|
|
|
15
15
|
- **External concurrency detection** — file fingerprint and inode checks detect external modification. Conflicting changes are never silently overwritten; the system fails closed or enters `recovery required`.
|
|
16
16
|
- **No Git workflow** — snapshots use a private object database. No `git commit`, `git stash`, `git reset`, branches, or forges are required.
|
|
17
17
|
- **Nested repositories** and **initialized submodules** are handled as independent roots. Their `.git` metadata is never modified.
|
|
18
|
-
- **Performance** — batch WAL operations (up to 1,024 files per batch), scoped safety snapshots, prebuilt durable transaction packs, and
|
|
18
|
+
- **Performance** — batch WAL operations (up to 1,024 files per batch), scoped safety snapshots, prebuilt durable transaction packs, native Rust no-clobber file helper for macOS arm64, indexed WAL record and conflict lookups, and parallel manifest blob reads keep restore fast at scale. Unsupported platforms and failed integrity checks automatically use the TypeScript path.
|
|
19
19
|
|
|
20
20
|
## Requirements
|
|
21
21
|
|
|
@@ -115,12 +115,18 @@ Real-world measurements from a 104-file undo operation before optimizations:
|
|
|
115
115
|
ok files:104 total:8797ms apply:8591ms capture:89ms journal:64ms commit:27ms plan:11ms
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
-
After batch WAL, scoped safety snapshots, parallel restore I/O,
|
|
118
|
+
After batch WAL, scoped safety snapshots, parallel restore I/O, batch file deletes, and prebuilt durable transaction packs:
|
|
119
119
|
|
|
120
120
|
```text
|
|
121
121
|
ok files:104 total:~1050ms apply:~850ms capture:~90ms journal:~65ms
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
+
After native Rust helper, durable pack caching, parallel durable finalization, batch validated blob reads, and indexed mutation/path lookups:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
ok files:104 total:~850ms apply:~650ms capture:~90ms journal:~65ms plan:~10ms
|
|
128
|
+
```
|
|
129
|
+
|
|
124
130
|
Performance gains come from:
|
|
125
131
|
|
|
126
132
|
- **Batch WAL durability** — write-once, fsync-once per batch of up to 1,024 entries instead of per-file.
|
|
@@ -132,6 +138,11 @@ Performance gains come from:
|
|
|
132
138
|
- **Concurrent request preparation** — blob reads, live-state checks, and fingerprint computation run at 32-wide concurrency.
|
|
133
139
|
- **Batch file deletes** — delete operations share the same WAL batch and directory fsync merging.
|
|
134
140
|
- **Directory fsync merging** — barriers are applied once per unique directory per phase, not once per file.
|
|
141
|
+
- **Native Rust no-clobber helper** — packaged macOS arm64 binary uses platform renameat2 with EEXIST guard for regular-file batches; missing binaries or platform mismatch fall back to the TypeScript path before mutation.
|
|
142
|
+
- **Durable pack caching** — completed agent runs build and cache reverse/forward durable packs; the undo/redo hot path reuses the cached pack with manifest pin, avoiding redundant snapshot reads.
|
|
143
|
+
- **Indexed WAL record lookups** — mutation records are indexed by ordinal for O(1) direct access instead of linear scan.
|
|
144
|
+
- **Indexed path conflict resolution** — `exactExclusions` are stored as a Set for O(1) membership checks instead of O(n) `Array.includes`.
|
|
145
|
+
- **Batch validated manifest blob reads** — durable pack reads coalesce blob fetches into a single batch per manifest with combined Git validation.
|
|
135
146
|
|
|
136
147
|
## How It Works
|
|
137
148
|
|
|
@@ -259,7 +270,7 @@ test/ Unit, integration, recovery, and fault-injection te
|
|
|
259
270
|
### Testing
|
|
260
271
|
|
|
261
272
|
```bash
|
|
262
|
-
npm test # Full test suite (
|
|
273
|
+
npm test # Full test suite (425+ tests)
|
|
263
274
|
npm run test:native # Rust helper and durable-pack recovery tests
|
|
264
275
|
npm run test:watch # Watch mode
|
|
265
276
|
npm run test:integration # Pi runtime and extension integration tests
|
|
@@ -279,7 +290,7 @@ Benchmark tests assert Git call counts and WAL record counts, not wall-clock thr
|
|
|
279
290
|
| 100-file restore (delete) — batch deletes | ≤12 | 600 | ~0.6s |
|
|
280
291
|
| 4,000-file rollback snapshot — batch Git | ≤24 (4 x `mktree`, 4 x `commit-tree`) | — | ~7s |
|
|
281
292
|
|
|
282
|
-
The 104-file standalone apply probe (10 warmup iterations + 10 measured) completes in approximately 3.9s post-optimization
|
|
293
|
+
The 104-file standalone apply probe (10 warmup iterations + 10 measured) completes in approximately 3.9s post-optimization on the TypeScript path (down from 14.3s before batching), and approximately 2.8s on the native Rust path with durable pack caching and indexed blob reads.
|
|
283
294
|
|
|
284
295
|
## License
|
|
285
296
|
|
package/package.json
CHANGED
package/src/snapshot-store.ts
CHANGED
|
@@ -41,7 +41,7 @@ const INDEX_BATCH_MAX_ENTRIES = 4_096;
|
|
|
41
41
|
const INDEX_BATCH_MAX_BYTES = 8 * 1024 * 1024;
|
|
42
42
|
const BLOB_CACHE_MAX_BYTES = 128 * 1024 * 1024;
|
|
43
43
|
const BLOB_BATCH_MAX_BYTES = 16 * 1024 * 1024;
|
|
44
|
-
const BLOB_BATCH_MAX_ENTRIES = 256;
|
|
44
|
+
const BLOB_BATCH_MAX_ENTRIES = process.platform === "win32" ? 256 : 2_048;
|
|
45
45
|
|
|
46
46
|
interface PinRecord {
|
|
47
47
|
readonly schemaVersion: 1;
|