xit-wasm 0.1.0
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 +156 -0
- package/dist/archive.d.ts +118 -0
- package/dist/archive.d.ts.map +1 -0
- package/dist/archive.js +363 -0
- package/dist/archive.js.map +1 -0
- package/dist/host-memory.d.ts +109 -0
- package/dist/host-memory.d.ts.map +1 -0
- package/dist/host-memory.js +432 -0
- package/dist/host-memory.js.map +1 -0
- package/dist/host-node.d.ts +102 -0
- package/dist/host-node.d.ts.map +1 -0
- package/dist/host-node.js +376 -0
- package/dist/host-node.js.map +1 -0
- package/dist/host.d.ts +160 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +164 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/package.json +36 -0
- package/src/archive.ts +515 -0
- package/src/host-memory.ts +458 -0
- package/src/host-node.ts +388 -0
- package/src/host.ts +262 -0
- package/src/index.ts +100 -0
- package/xit.wasm +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# xit-wasm
|
|
2
|
+
|
|
3
|
+
Versioned in-memory archives for TypeScript, backed by the **xit** version
|
|
4
|
+
control system compiled to WebAssembly. Pure in-memory by default, so it runs
|
|
5
|
+
identically in Node, Bun, Deno, and the browser.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { Archive } from "xit-wasm";
|
|
9
|
+
|
|
10
|
+
const a = await Archive.open(); // fresh repo
|
|
11
|
+
await a.write("manifest.json", encode({ v: 1 }));
|
|
12
|
+
await a.write("data/foo.json", encode({ x: 1 }));
|
|
13
|
+
await a.commit("initial");
|
|
14
|
+
|
|
15
|
+
await a.branch("feature");
|
|
16
|
+
await a.checkout("feature");
|
|
17
|
+
await a.write("data/foo.json", encode({ x: 2 }));
|
|
18
|
+
await a.commit("bump x");
|
|
19
|
+
|
|
20
|
+
await a.checkout("master");
|
|
21
|
+
await a.merge("feature"); // fast-forward
|
|
22
|
+
|
|
23
|
+
const bytes = await a.toBytes(); // serialize to a zip
|
|
24
|
+
// …round-trip…
|
|
25
|
+
const b = await Archive.open(bytes);
|
|
26
|
+
console.log(await b.log()); // CommitInfo[]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## What this is
|
|
30
|
+
|
|
31
|
+
A thin TypeScript surface over a slimmed-down build of [`xit`][xit] (Zig)
|
|
32
|
+
compiled to `wasm32-wasi`. Networking, the TUI, and the CLI are stripped; what
|
|
33
|
+
remains is the git/xit object model, the index/tree/pack/chunk machinery, and
|
|
34
|
+
the merge engine. We provide a pure in-memory `Host` that backs the wasm
|
|
35
|
+
filesystem with a JS map, so the public API has no `dirCreateFile` /
|
|
36
|
+
file-handle / wasm concept anywhere — just `archive.write(path, bytes)`,
|
|
37
|
+
`archive.commit(message)`, etc.
|
|
38
|
+
|
|
39
|
+
The on-disk shape inside an archive's zip stream is a real xit working
|
|
40
|
+
directory, including a `.xit/` subtree (single-file xitdb + content chunks).
|
|
41
|
+
Power users can unzip a `.甲` and find a fully-formed repo.
|
|
42
|
+
|
|
43
|
+
## Credit and provenance
|
|
44
|
+
|
|
45
|
+
This package wraps **xit**, a brand-new version control system written in Zig
|
|
46
|
+
by **radarroark**. xit aims to be a worthy successor to git and is well worth
|
|
47
|
+
exploring on its own:
|
|
48
|
+
|
|
49
|
+
- **xit on GitHub**: <https://github.com/xit-vcs/xit>
|
|
50
|
+
- **radarroark on YouTube** (where most of xit's development is recorded
|
|
51
|
+
live): <https://www.youtube.com/@xeuxeuxeuxeu>
|
|
52
|
+
|
|
53
|
+
This package is a downstream WebAssembly binding maintained by
|
|
54
|
+
[rheophile10][me]. None of the version-control engine is original work here —
|
|
55
|
+
the Zig source we compile lives at <https://github.com/rheophile10/xit/tree/wasm-spike>,
|
|
56
|
+
a fork that strips the parts wasm doesn't need (networking, TUI, CLI) and
|
|
57
|
+
adds the C ABI exports the bindings call into. Any improvements to the
|
|
58
|
+
underlying engine should go upstream to <https://github.com/xit-vcs/xit>.
|
|
59
|
+
|
|
60
|
+
## API
|
|
61
|
+
|
|
62
|
+
The headline class is `Archive`. Construction:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const fresh = await Archive.open(); // new repo on `master`
|
|
66
|
+
const opened = await Archive.open(zipBytes); // existing repo from a .甲
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Content (no wasm round-trip — pure in-memory writes):
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
await archive.write(path, content);
|
|
73
|
+
const bytes = await archive.read(path);
|
|
74
|
+
const paths = await archive.list();
|
|
75
|
+
await archive.remove(path);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Version control (each call goes through wasm):
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
const oid = await archive.commit(message, { author? });
|
|
82
|
+
const history = await archive.log({ limit? }); // CommitInfo[]
|
|
83
|
+
await archive.branch(name);
|
|
84
|
+
const { branches, current } = await archive.listBranches();
|
|
85
|
+
const name = await archive.currentBranch(); // string | null
|
|
86
|
+
await archive.checkout(branch);
|
|
87
|
+
const result = await archive.merge(branch, { message?, author? });
|
|
88
|
+
// MergeResult: { kind: "success", oid } | "fast_forward" | "nothing" | "conflict"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Persistence:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const bytes = await archive.toBytes(); // zip the working tree
|
|
95
|
+
await archive.close(); // release the wasm handle
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Loading the wasm module
|
|
99
|
+
|
|
100
|
+
The package ships `xit.wasm` next to its entry module. By default
|
|
101
|
+
`Archive.open()` resolves it via `new URL("../xit.wasm", import.meta.url)`,
|
|
102
|
+
which Just Works in Node and most modern bundlers. For environments where
|
|
103
|
+
that doesn't (some bundlers strip `import.meta.url`, browser deployments
|
|
104
|
+
fetching from a CDN, etc.) configure the source explicitly:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import { setDefaultWasmSource } from "xit-wasm";
|
|
108
|
+
|
|
109
|
+
setDefaultWasmSource(new URL("https://cdn.example.com/xit.wasm"));
|
|
110
|
+
// or
|
|
111
|
+
setDefaultWasmSource(preloadedBytes);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Or pass per-call:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
await Archive.open(bytes, { wasm: customSource });
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Filesystem interop
|
|
121
|
+
|
|
122
|
+
xit-wasm is intentionally fs-free. If you want to drive xit against a real
|
|
123
|
+
filesystem (CLI tools, tests against an unzipped tree), import the Node host:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { NodeHost } from "xit-wasm/node";
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
This exists primarily for the smoke tests under `example/`; most consumers
|
|
130
|
+
should reach for `Archive` and let MemoryHost back it.
|
|
131
|
+
|
|
132
|
+
## Status
|
|
133
|
+
|
|
134
|
+
Alpha. The headline ops (init / open / write / commit / log / branch /
|
|
135
|
+
checkout / merge / toBytes) work and are validated end-to-end against
|
|
136
|
+
native `git` for the `.git` repo kind. The default `.xit` repo kind round-
|
|
137
|
+
trips through xitdb. There is no networking; conflict resolution beyond
|
|
138
|
+
"detect and report" is not yet wired into the JS surface; performance has
|
|
139
|
+
not been profiled.
|
|
140
|
+
|
|
141
|
+
## Building from source
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
# 1. build the wasm (requires zig 0.16)
|
|
145
|
+
cd ../xit && zig build wasm
|
|
146
|
+
|
|
147
|
+
# 2. build the TS package + copy xit.wasm into place
|
|
148
|
+
cd ../xit-wasm-ts && npm install && npm run build
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## License
|
|
152
|
+
|
|
153
|
+
MIT.
|
|
154
|
+
|
|
155
|
+
[xit]: https://github.com/xit-vcs/xit
|
|
156
|
+
[me]: https://github.com/rheophile10
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archive — the headline API for xit-wasm-ts.
|
|
3
|
+
*
|
|
4
|
+
* - Pure in-memory by default (uses MemoryHost as the wasm fs backend).
|
|
5
|
+
* - Hides every host/file/wasm concept from consumers.
|
|
6
|
+
* - Persists via toBytes() → zip / open(zipBytes) → unzip.
|
|
7
|
+
*
|
|
8
|
+
* The "pleasant surprise" version control methods (commit, log, branch,
|
|
9
|
+
* merge, etc.) sit on the same Archive instance so any consumer who
|
|
10
|
+
* receives an opened archive finds them in their IDE without asking.
|
|
11
|
+
*/
|
|
12
|
+
export interface CommitOptions {
|
|
13
|
+
/** Author/committer string in the conventional `Name <email>` form.
|
|
14
|
+
* Defaults to `"plastron <plastron@local>"` if not given. */
|
|
15
|
+
author?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface LoadOptions {
|
|
18
|
+
/** Override how the wasm module is sourced. Useful in browsers (pass a
|
|
19
|
+
* URL or already-fetched Uint8Array). Defaults to a relative path
|
|
20
|
+
* resolved against the dev tree — set this in any non-dev environment. */
|
|
21
|
+
wasm?: WasmSource;
|
|
22
|
+
}
|
|
23
|
+
export type WasmSource = Uint8Array | URL | string | ArrayBuffer;
|
|
24
|
+
export interface CommitInfo {
|
|
25
|
+
oid: string;
|
|
26
|
+
parents: string[];
|
|
27
|
+
/** Unix timestamp in seconds — taken from the commit metadata. May be 0
|
|
28
|
+
* if the commit was created without an explicit timestamp. */
|
|
29
|
+
timestamp: number;
|
|
30
|
+
author: string;
|
|
31
|
+
message: string;
|
|
32
|
+
}
|
|
33
|
+
export interface BranchListing {
|
|
34
|
+
branches: string[];
|
|
35
|
+
/** Index into `branches` of the currently checked-out branch, or null if
|
|
36
|
+
* HEAD is detached or not on any of the listed refs. */
|
|
37
|
+
current: number | null;
|
|
38
|
+
}
|
|
39
|
+
export interface MergeOptions {
|
|
40
|
+
message?: string;
|
|
41
|
+
author?: string;
|
|
42
|
+
}
|
|
43
|
+
export type MergeResult = {
|
|
44
|
+
kind: "success";
|
|
45
|
+
oid: string;
|
|
46
|
+
} | {
|
|
47
|
+
kind: "fast_forward";
|
|
48
|
+
} | {
|
|
49
|
+
kind: "nothing";
|
|
50
|
+
} | {
|
|
51
|
+
kind: "conflict";
|
|
52
|
+
};
|
|
53
|
+
export interface SwitchResult {
|
|
54
|
+
kind: "success" | "conflict";
|
|
55
|
+
}
|
|
56
|
+
/** Configure where the wasm module is loaded from for any subsequent
|
|
57
|
+
* Archive.open() call that doesn't pass `opts.wasm`. Most consumers don't
|
|
58
|
+
* need this — the package ships its `xit.wasm` next to the entry module
|
|
59
|
+
* and the loader auto-resolves it via `import.meta.url`. Useful when:
|
|
60
|
+
*
|
|
61
|
+
* - You want to load from a CDN (`new URL("https://...")`).
|
|
62
|
+
* - You want to use a different wasm artifact (e.g. dev build).
|
|
63
|
+
* - Your bundler doesn't preserve `import.meta.url` and you need to
|
|
64
|
+
* fall back to a hand-supplied URL or pre-fetched bytes. */
|
|
65
|
+
export declare function setDefaultWasmSource(source: WasmSource): void;
|
|
66
|
+
export declare class Archive {
|
|
67
|
+
private host;
|
|
68
|
+
private memory;
|
|
69
|
+
private exports;
|
|
70
|
+
private repoHandle;
|
|
71
|
+
private dirtyAdded;
|
|
72
|
+
private dirtyRemoved;
|
|
73
|
+
/** Files prefixed with `.xit/` are repo internals — Archive content
|
|
74
|
+
* reads/writes never touch them. */
|
|
75
|
+
private static readonly INTERNAL_PREFIX;
|
|
76
|
+
private constructor();
|
|
77
|
+
/** Open an archive. With no `bytes`, creates a fresh in-memory repo
|
|
78
|
+
* (master branch, no commits). With `bytes`, unzips into memory and
|
|
79
|
+
* opens the existing repo. */
|
|
80
|
+
static open(bytes?: Uint8Array, opts?: LoadOptions): Promise<Archive>;
|
|
81
|
+
/** Write a file into the archive's working tree. Triggers no commit. */
|
|
82
|
+
write(path: string, content: Uint8Array): Promise<void>;
|
|
83
|
+
read(path: string): Promise<Uint8Array | null>;
|
|
84
|
+
/** List all content paths (excluding repo internals). */
|
|
85
|
+
list(): Promise<string[]>;
|
|
86
|
+
remove(path: string): Promise<void>;
|
|
87
|
+
/** Stage every dirty path and commit. Returns the new commit OID (hex). */
|
|
88
|
+
commit(message: string, opts?: CommitOptions): Promise<string>;
|
|
89
|
+
/** Walk commit history reachable from HEAD. Newest first. */
|
|
90
|
+
log(opts?: {
|
|
91
|
+
limit?: number;
|
|
92
|
+
}): Promise<CommitInfo[]>;
|
|
93
|
+
/** Create a new branch off the current HEAD. */
|
|
94
|
+
branch(name: string): Promise<void>;
|
|
95
|
+
/** Returns every branch name plus an index identifying the currently
|
|
96
|
+
* checked-out one (or null when HEAD is detached). */
|
|
97
|
+
listBranches(): Promise<BranchListing>;
|
|
98
|
+
/** Convenience: just the currently checked-out branch name, or null. */
|
|
99
|
+
currentBranch(): Promise<string | null>;
|
|
100
|
+
/** Switch the working tree to the named branch. */
|
|
101
|
+
checkout(branch: string): Promise<SwitchResult>;
|
|
102
|
+
/** Merge the named branch into the current HEAD. */
|
|
103
|
+
merge(branch: string, opts?: MergeOptions): Promise<MergeResult>;
|
|
104
|
+
/** Serialize the entire working tree (including repo internals) as a
|
|
105
|
+
* fflate zip. The result IS the .甲 byte stream. */
|
|
106
|
+
toBytes(): Promise<Uint8Array>;
|
|
107
|
+
/** Release the wasm-side repo handle. Subsequent calls fail. The host's
|
|
108
|
+
* in-memory tree is dropped. */
|
|
109
|
+
close(): Promise<void>;
|
|
110
|
+
/** Pattern shared by log/branch_list/merge: wasm allocates a result buffer,
|
|
111
|
+
* writes the size to a u32 out-parameter, returns the pointer. We copy
|
|
112
|
+
* the bytes out, free both, and hand them to a decoder. */
|
|
113
|
+
private callBufReturn;
|
|
114
|
+
private withBytes;
|
|
115
|
+
private callPathsBuf;
|
|
116
|
+
private callCommit;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=archive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"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"}
|
package/dist/archive.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Archive — the headline API for xit-wasm-ts.
|
|
3
|
+
*
|
|
4
|
+
* - Pure in-memory by default (uses MemoryHost as the wasm fs backend).
|
|
5
|
+
* - Hides every host/file/wasm concept from consumers.
|
|
6
|
+
* - Persists via toBytes() → zip / open(zipBytes) → unzip.
|
|
7
|
+
*
|
|
8
|
+
* The "pleasant surprise" version control methods (commit, log, branch,
|
|
9
|
+
* merge, etc.) sit on the same Archive instance so any consumer who
|
|
10
|
+
* receives an opened archive finds them in their IDE without asking.
|
|
11
|
+
*/
|
|
12
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
13
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
14
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
15
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return path;
|
|
19
|
+
};
|
|
20
|
+
import { unzipSync, zipSync } from "fflate";
|
|
21
|
+
import { MemoryHost } from "./host-memory.js";
|
|
22
|
+
import { hostImports } from "./host.js";
|
|
23
|
+
/** Where the in-memory repo lives inside the wasm fs. Keep this stable —
|
|
24
|
+
* changing it would invalidate any existing .甲 archive. */
|
|
25
|
+
const REPO_PATH = "/";
|
|
26
|
+
/** Hex SHA-1 oid length. */
|
|
27
|
+
const OID_HEX = 40;
|
|
28
|
+
let defaultWasmSource;
|
|
29
|
+
/** Configure where the wasm module is loaded from for any subsequent
|
|
30
|
+
* Archive.open() call that doesn't pass `opts.wasm`. Most consumers don't
|
|
31
|
+
* need this — the package ships its `xit.wasm` next to the entry module
|
|
32
|
+
* and the loader auto-resolves it via `import.meta.url`. Useful when:
|
|
33
|
+
*
|
|
34
|
+
* - You want to load from a CDN (`new URL("https://...")`).
|
|
35
|
+
* - You want to use a different wasm artifact (e.g. dev build).
|
|
36
|
+
* - Your bundler doesn't preserve `import.meta.url` and you need to
|
|
37
|
+
* fall back to a hand-supplied URL or pre-fetched bytes. */
|
|
38
|
+
export function setDefaultWasmSource(source) {
|
|
39
|
+
defaultWasmSource = source;
|
|
40
|
+
}
|
|
41
|
+
/** Default location of `xit.wasm` shipped with the package. Resolves
|
|
42
|
+
* consistently from src (during dev) and from dist (after build) because
|
|
43
|
+
* the file lives at the package root, one level up from either entry. */
|
|
44
|
+
function bundledWasmUrl() {
|
|
45
|
+
return new URL("../xit.wasm", import.meta.url);
|
|
46
|
+
}
|
|
47
|
+
async function resolveWasmBytes(source) {
|
|
48
|
+
if (source instanceof Uint8Array)
|
|
49
|
+
return source;
|
|
50
|
+
if (source instanceof ArrayBuffer)
|
|
51
|
+
return new Uint8Array(source);
|
|
52
|
+
const ref = source instanceof URL ? source.toString() : source;
|
|
53
|
+
// Prefer fetch for http(s) and blob URLs (browser, Bun, modern Node);
|
|
54
|
+
// file:// and bare paths go through the Node fs path so we don't take a
|
|
55
|
+
// dependency on fetch supporting file URLs (Node only added that recently).
|
|
56
|
+
if (typeof globalThis.fetch === "function" && /^https?:|^blob:/.test(ref)) {
|
|
57
|
+
const r = await fetch(ref);
|
|
58
|
+
return new Uint8Array(await r.arrayBuffer());
|
|
59
|
+
}
|
|
60
|
+
// Fall back to Node fs only when actually running on Node. Browser
|
|
61
|
+
// bundlers that statically analyze a bare `import("node:fs/promises")`
|
|
62
|
+
// would emit it as a stub and warn even when this branch is
|
|
63
|
+
// unreachable; routing through a runtime-built specifier keeps the
|
|
64
|
+
// browser build clean. The Node-default `bundledWasmUrl()` uses
|
|
65
|
+
// `import.meta.url`, which resolves to an http(s) URL after Vite asset
|
|
66
|
+
// emission — so browsers take the fetch branch above and never reach
|
|
67
|
+
// this fallback.
|
|
68
|
+
const isNode = typeof globalThis.process !== "undefined"
|
|
69
|
+
&& globalThis.process.versions != null
|
|
70
|
+
&& typeof globalThis.process.versions.node === "string";
|
|
71
|
+
if (!isNode) {
|
|
72
|
+
throw new Error(`xit-wasm: cannot resolve wasm source "${ref}" — fetch is unavailable ` +
|
|
73
|
+
`and no Node fs is present. Pass opts.wasm as a Uint8Array, ArrayBuffer, ` +
|
|
74
|
+
`or http(s)/blob URL.`);
|
|
75
|
+
}
|
|
76
|
+
const nodeFsSpecifier = "node:fs/promises";
|
|
77
|
+
const fs = await import(__rewriteRelativeImportExtension(/* @vite-ignore */ nodeFsSpecifier));
|
|
78
|
+
if (ref.startsWith("file:")) {
|
|
79
|
+
return new Uint8Array(await fs.readFile(new URL(ref)));
|
|
80
|
+
}
|
|
81
|
+
return new Uint8Array(await fs.readFile(ref));
|
|
82
|
+
}
|
|
83
|
+
export class Archive {
|
|
84
|
+
host;
|
|
85
|
+
memory;
|
|
86
|
+
exports;
|
|
87
|
+
repoHandle;
|
|
88
|
+
dirtyAdded = new Set();
|
|
89
|
+
dirtyRemoved = new Set();
|
|
90
|
+
/** Files prefixed with `.xit/` are repo internals — Archive content
|
|
91
|
+
* reads/writes never touch them. */
|
|
92
|
+
static INTERNAL_PREFIX = ".xit/";
|
|
93
|
+
constructor(host, memory, exports, repoHandle) {
|
|
94
|
+
this.host = host;
|
|
95
|
+
this.memory = memory;
|
|
96
|
+
this.exports = exports;
|
|
97
|
+
this.repoHandle = repoHandle;
|
|
98
|
+
}
|
|
99
|
+
/** Open an archive. With no `bytes`, creates a fresh in-memory repo
|
|
100
|
+
* (master branch, no commits). With `bytes`, unzips into memory and
|
|
101
|
+
* opens the existing repo. */
|
|
102
|
+
static async open(bytes, opts = {}) {
|
|
103
|
+
const wasmSource = opts.wasm ?? defaultWasmSource ?? bundledWasmUrl();
|
|
104
|
+
const wasmBytes = await resolveWasmBytes(wasmSource);
|
|
105
|
+
// WebAssembly.compile expects a BufferSource over a non-shared ArrayBuffer.
|
|
106
|
+
// Make a fresh copy with a plain ArrayBuffer to satisfy strict typings.
|
|
107
|
+
const wasmCopy = new Uint8Array(wasmBytes.byteLength);
|
|
108
|
+
wasmCopy.set(wasmBytes);
|
|
109
|
+
const mod = await WebAssembly.compile(wasmCopy);
|
|
110
|
+
const host = new MemoryHost();
|
|
111
|
+
if (bytes) {
|
|
112
|
+
const tree = unzipSync(bytes);
|
|
113
|
+
const map = new Map();
|
|
114
|
+
for (const [name, content] of Object.entries(tree)) {
|
|
115
|
+
if (content.length === 0 && name.endsWith("/"))
|
|
116
|
+
continue; // skip dir markers
|
|
117
|
+
map.set(name, content);
|
|
118
|
+
}
|
|
119
|
+
host.bulkLoad(map);
|
|
120
|
+
}
|
|
121
|
+
let memory;
|
|
122
|
+
const inst = await WebAssembly.instantiate(mod, hostImports(host, () => memory));
|
|
123
|
+
const exports = inst.exports;
|
|
124
|
+
memory = exports.memory;
|
|
125
|
+
const enc = new TextEncoder();
|
|
126
|
+
const pathBytes = enc.encode(REPO_PATH);
|
|
127
|
+
const pathPtr = exports.xit_alloc(pathBytes.length);
|
|
128
|
+
if (pathPtr === 0)
|
|
129
|
+
throw new Error("xit-wasm: alloc failed for repo path");
|
|
130
|
+
new Uint8Array(memory.buffer, pathPtr, pathBytes.length).set(pathBytes);
|
|
131
|
+
const handle = bytes
|
|
132
|
+
? exports.xit_repo_open(pathPtr, pathBytes.length)
|
|
133
|
+
: exports.xit_repo_init(pathPtr, pathBytes.length);
|
|
134
|
+
exports.xit_free(pathPtr, pathBytes.length);
|
|
135
|
+
if (handle < 0) {
|
|
136
|
+
throw new Error(`xit-wasm: ${bytes ? "xit_repo_open" : "xit_repo_init"} failed with code ${handle}`);
|
|
137
|
+
}
|
|
138
|
+
return new Archive(host, memory, exports, handle);
|
|
139
|
+
}
|
|
140
|
+
// ---- content ops (no wasm involvement) ----
|
|
141
|
+
/** Write a file into the archive's working tree. Triggers no commit. */
|
|
142
|
+
async write(path, content) {
|
|
143
|
+
if (path.startsWith(Archive.INTERNAL_PREFIX) || path.startsWith("/" + Archive.INTERNAL_PREFIX)) {
|
|
144
|
+
throw new Error(`Archive.write: path "${path}" is reserved for repo internals`);
|
|
145
|
+
}
|
|
146
|
+
this.host.putFile(path, content);
|
|
147
|
+
this.dirtyAdded.add(stripLeading(path));
|
|
148
|
+
this.dirtyRemoved.delete(stripLeading(path));
|
|
149
|
+
}
|
|
150
|
+
async read(path) {
|
|
151
|
+
return this.host.getFile(path);
|
|
152
|
+
}
|
|
153
|
+
/** List all content paths (excluding repo internals). */
|
|
154
|
+
async list() {
|
|
155
|
+
return this.host
|
|
156
|
+
.listFiles()
|
|
157
|
+
.filter((p) => !p.startsWith(Archive.INTERNAL_PREFIX));
|
|
158
|
+
}
|
|
159
|
+
async remove(path) {
|
|
160
|
+
const removed = this.host.removeFile(path);
|
|
161
|
+
if (!removed)
|
|
162
|
+
return;
|
|
163
|
+
const stripped = stripLeading(path);
|
|
164
|
+
this.dirtyRemoved.add(stripped);
|
|
165
|
+
this.dirtyAdded.delete(stripped);
|
|
166
|
+
}
|
|
167
|
+
// ---- version control ----
|
|
168
|
+
/** Stage every dirty path and commit. Returns the new commit OID (hex). */
|
|
169
|
+
async commit(message, opts = {}) {
|
|
170
|
+
const author = opts.author ?? "plastron <plastron@local>";
|
|
171
|
+
if (this.dirtyAdded.size > 0) {
|
|
172
|
+
this.callPathsBuf("xit_repo_add", Array.from(this.dirtyAdded));
|
|
173
|
+
}
|
|
174
|
+
if (this.dirtyRemoved.size > 0) {
|
|
175
|
+
this.callPathsBuf("xit_repo_remove", Array.from(this.dirtyRemoved));
|
|
176
|
+
}
|
|
177
|
+
const oid = this.callCommit(message, author);
|
|
178
|
+
this.dirtyAdded.clear();
|
|
179
|
+
this.dirtyRemoved.clear();
|
|
180
|
+
return oid;
|
|
181
|
+
}
|
|
182
|
+
/** Walk commit history reachable from HEAD. Newest first. */
|
|
183
|
+
async log(opts = {}) {
|
|
184
|
+
return this.callBufReturn((outSizePtr) => this.exports.xit_repo_log(this.repoHandle, opts.limit ?? 0, outSizePtr), (bytes) => decodeLog(bytes));
|
|
185
|
+
}
|
|
186
|
+
/** Create a new branch off the current HEAD. */
|
|
187
|
+
async branch(name) {
|
|
188
|
+
const enc = new TextEncoder();
|
|
189
|
+
const code = this.withBytes(enc.encode(name), (ptr, len) => this.exports.xit_repo_branch_add(this.repoHandle, ptr, len));
|
|
190
|
+
if (code < 0)
|
|
191
|
+
throw new Error(`xit-wasm: xit_repo_branch_add failed with code ${code}`);
|
|
192
|
+
}
|
|
193
|
+
/** Returns every branch name plus an index identifying the currently
|
|
194
|
+
* checked-out one (or null when HEAD is detached). */
|
|
195
|
+
async listBranches() {
|
|
196
|
+
return this.callBufReturn((outSizePtr) => this.exports.xit_repo_branch_list(this.repoHandle, outSizePtr), (bytes) => decodeBranches(bytes));
|
|
197
|
+
}
|
|
198
|
+
/** Convenience: just the currently checked-out branch name, or null. */
|
|
199
|
+
async currentBranch() {
|
|
200
|
+
const { branches, current } = await this.listBranches();
|
|
201
|
+
return current === null ? null : branches[current] ?? null;
|
|
202
|
+
}
|
|
203
|
+
/** Switch the working tree to the named branch. */
|
|
204
|
+
async checkout(branch) {
|
|
205
|
+
const enc = new TextEncoder();
|
|
206
|
+
const code = this.withBytes(enc.encode(branch), (ptr, len) => this.exports.xit_repo_switch(this.repoHandle, ptr, len));
|
|
207
|
+
if (code < 0)
|
|
208
|
+
throw new Error(`xit-wasm: xit_repo_switch failed with code ${code}`);
|
|
209
|
+
return { kind: code === 0 ? "success" : "conflict" };
|
|
210
|
+
}
|
|
211
|
+
/** Merge the named branch into the current HEAD. */
|
|
212
|
+
async merge(branch, opts = {}) {
|
|
213
|
+
const enc = new TextEncoder();
|
|
214
|
+
const message = opts.message ?? `merge ${branch}`;
|
|
215
|
+
const author = opts.author ?? "plastron <plastron@local>";
|
|
216
|
+
return this.callBufReturn((outSizePtr) => this.withBytes(enc.encode(branch), (bp, bl) => this.withBytes(enc.encode(message), (mp, ml) => this.withBytes(enc.encode(author), (ap, al) => this.exports.xit_repo_merge(this.repoHandle, bp, bl, mp, ml, ap, al, outSizePtr)))), (bytes) => decodeMergeResult(bytes));
|
|
217
|
+
}
|
|
218
|
+
/** Serialize the entire working tree (including repo internals) as a
|
|
219
|
+
* fflate zip. The result IS the .甲 byte stream. */
|
|
220
|
+
async toBytes() {
|
|
221
|
+
const tree = this.host.snapshot();
|
|
222
|
+
const files = {};
|
|
223
|
+
for (const [path, content] of tree)
|
|
224
|
+
files[path] = content;
|
|
225
|
+
return zipSync(files);
|
|
226
|
+
}
|
|
227
|
+
/** Release the wasm-side repo handle. Subsequent calls fail. The host's
|
|
228
|
+
* in-memory tree is dropped. */
|
|
229
|
+
async close() {
|
|
230
|
+
this.exports.xit_repo_close(this.repoHandle);
|
|
231
|
+
this.repoHandle = -1;
|
|
232
|
+
}
|
|
233
|
+
// ---- internal: marshalling helpers ----
|
|
234
|
+
/** Pattern shared by log/branch_list/merge: wasm allocates a result buffer,
|
|
235
|
+
* writes the size to a u32 out-parameter, returns the pointer. We copy
|
|
236
|
+
* the bytes out, free both, and hand them to a decoder. */
|
|
237
|
+
callBufReturn(call, decode) {
|
|
238
|
+
const outSizePtr = this.exports.xit_alloc(4);
|
|
239
|
+
if (outSizePtr === 0)
|
|
240
|
+
throw new Error("xit-wasm: alloc failed for out_size");
|
|
241
|
+
let dataPtr = 0;
|
|
242
|
+
let size = 0;
|
|
243
|
+
try {
|
|
244
|
+
dataPtr = call(outSizePtr);
|
|
245
|
+
if (dataPtr === 0)
|
|
246
|
+
throw new Error("xit-wasm: returned null buffer");
|
|
247
|
+
size = new DataView(this.memory.buffer, outSizePtr, 4).getUint32(0, true);
|
|
248
|
+
const copy = new Uint8Array(this.memory.buffer, dataPtr, size).slice();
|
|
249
|
+
return decode(copy);
|
|
250
|
+
}
|
|
251
|
+
finally {
|
|
252
|
+
if (dataPtr !== 0)
|
|
253
|
+
this.exports.xit_free(dataPtr, size);
|
|
254
|
+
this.exports.xit_free(outSizePtr, 4);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
withBytes(bytes, fn) {
|
|
258
|
+
const ptr = this.exports.xit_alloc(bytes.length);
|
|
259
|
+
if (ptr === 0)
|
|
260
|
+
throw new Error("xit-wasm: alloc failed");
|
|
261
|
+
new Uint8Array(this.memory.buffer, ptr, bytes.length).set(bytes);
|
|
262
|
+
try {
|
|
263
|
+
return fn(ptr, bytes.length);
|
|
264
|
+
}
|
|
265
|
+
finally {
|
|
266
|
+
this.exports.xit_free(ptr, bytes.length);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
callPathsBuf(fn, paths) {
|
|
270
|
+
const enc = new TextEncoder();
|
|
271
|
+
const buf = enc.encode(paths.join("\n"));
|
|
272
|
+
const code = this.withBytes(buf, (ptr, len) => this.exports[fn](this.repoHandle, ptr, len));
|
|
273
|
+
if (code < 0) {
|
|
274
|
+
throw new Error(`xit-wasm: ${fn} failed with code ${code}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
callCommit(message, author) {
|
|
278
|
+
const enc = new TextEncoder();
|
|
279
|
+
const msgBytes = enc.encode(message);
|
|
280
|
+
const authorBytes = enc.encode(author);
|
|
281
|
+
const oidPtr = this.exports.xit_alloc(OID_HEX);
|
|
282
|
+
if (oidPtr === 0)
|
|
283
|
+
throw new Error("xit-wasm: alloc failed for oid");
|
|
284
|
+
try {
|
|
285
|
+
return this.withBytes(msgBytes, (mp, ml) => this.withBytes(authorBytes, (ap, al) => {
|
|
286
|
+
const code = this.exports.xit_repo_commit(this.repoHandle, mp, ml, ap, al, oidPtr, OID_HEX);
|
|
287
|
+
if (code < 0) {
|
|
288
|
+
throw new Error(`xit-wasm: xit_repo_commit failed with code ${code}`);
|
|
289
|
+
}
|
|
290
|
+
const oidBytes = new Uint8Array(this.memory.buffer, oidPtr, OID_HEX);
|
|
291
|
+
return new TextDecoder().decode(oidBytes);
|
|
292
|
+
}));
|
|
293
|
+
}
|
|
294
|
+
finally {
|
|
295
|
+
this.exports.xit_free(oidPtr, OID_HEX);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function stripLeading(p) {
|
|
300
|
+
return p.startsWith("/") ? p.slice(1) : p;
|
|
301
|
+
}
|
|
302
|
+
// =========================================================================
|
|
303
|
+
// Wire decoders (mirror the formats documented in xit/src/lib.zig).
|
|
304
|
+
// =========================================================================
|
|
305
|
+
const dec = new TextDecoder();
|
|
306
|
+
function decodeLog(buf) {
|
|
307
|
+
const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
308
|
+
let p = 0;
|
|
309
|
+
const count = dv.getUint32(p, true);
|
|
310
|
+
p += 4;
|
|
311
|
+
const out = [];
|
|
312
|
+
for (let i = 0; i < count; i++) {
|
|
313
|
+
const oid = dec.decode(buf.subarray(p, p + OID_HEX));
|
|
314
|
+
p += OID_HEX;
|
|
315
|
+
const parentCount = dv.getUint32(p, true);
|
|
316
|
+
p += 4;
|
|
317
|
+
const parents = [];
|
|
318
|
+
for (let j = 0; j < parentCount; j++) {
|
|
319
|
+
parents.push(dec.decode(buf.subarray(p, p + OID_HEX)));
|
|
320
|
+
p += OID_HEX;
|
|
321
|
+
}
|
|
322
|
+
const timestamp = Number(dv.getBigUint64(p, true));
|
|
323
|
+
p += 8;
|
|
324
|
+
const authorLen = dv.getUint32(p, true);
|
|
325
|
+
p += 4;
|
|
326
|
+
const author = dec.decode(buf.subarray(p, p + authorLen));
|
|
327
|
+
p += authorLen;
|
|
328
|
+
const messageLen = dv.getUint32(p, true);
|
|
329
|
+
p += 4;
|
|
330
|
+
const message = dec.decode(buf.subarray(p, p + messageLen));
|
|
331
|
+
p += messageLen;
|
|
332
|
+
out.push({ oid, parents, timestamp, author, message });
|
|
333
|
+
}
|
|
334
|
+
return out;
|
|
335
|
+
}
|
|
336
|
+
function decodeBranches(buf) {
|
|
337
|
+
const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
338
|
+
let p = 0;
|
|
339
|
+
const count = dv.getUint32(p, true);
|
|
340
|
+
p += 4;
|
|
341
|
+
const currentRaw = dv.getInt32(p, true);
|
|
342
|
+
p += 4;
|
|
343
|
+
const branches = [];
|
|
344
|
+
for (let i = 0; i < count; i++) {
|
|
345
|
+
const nameLen = dv.getUint32(p, true);
|
|
346
|
+
p += 4;
|
|
347
|
+
branches.push(dec.decode(buf.subarray(p, p + nameLen)));
|
|
348
|
+
p += nameLen;
|
|
349
|
+
}
|
|
350
|
+
return { branches, current: currentRaw < 0 ? null : currentRaw };
|
|
351
|
+
}
|
|
352
|
+
function decodeMergeResult(buf) {
|
|
353
|
+
const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
354
|
+
const kind = dv.getUint32(0, true);
|
|
355
|
+
switch (kind) {
|
|
356
|
+
case 0: return { kind: "success", oid: dec.decode(buf.subarray(4, 4 + OID_HEX)) };
|
|
357
|
+
case 1: return { kind: "fast_forward" };
|
|
358
|
+
case 2: return { kind: "nothing" };
|
|
359
|
+
case 3: return { kind: "conflict" };
|
|
360
|
+
default: throw new Error(`xit-wasm: unexpected merge result kind ${kind}`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"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"}
|