githolon 0.12.0 → 0.14.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/dist/cli.mjs +98 -6
- package/package.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -476,7 +476,14 @@ function call(ex, mode, fields, STDERR) {
|
|
|
476
476
|
const reqPtr = ex.git_holon_alloc(req.length);
|
|
477
477
|
try {
|
|
478
478
|
new Uint8Array(ex.memory.buffer, reqPtr, req.length).set(req);
|
|
479
|
-
|
|
479
|
+
let packed;
|
|
480
|
+
try {
|
|
481
|
+
packed = ex.git_holon_call(reqPtr, req.length);
|
|
482
|
+
} catch (e) {
|
|
483
|
+
const tail = STDERR.length ? ` | stderr: ${STDERR.slice(-8).join(" / ")}` : "";
|
|
484
|
+
throw new Error(`${String(e && e.stack || e)}${tail}`);
|
|
485
|
+
}
|
|
486
|
+
const { ptr, len } = unpack(packed);
|
|
480
487
|
try {
|
|
481
488
|
const e = JSON.parse(dec2.decode(new Uint8Array(ex.memory.buffer, ptr, len).slice()));
|
|
482
489
|
if (!e.ok) throw new Error((e.error || "holon error") + (STDERR.length ? ` | ${STDERR.slice(-4).join(" / ")}` : ""));
|
|
@@ -543,28 +550,48 @@ function setManifests(eng, strings) {
|
|
|
543
550
|
if (wsDir) seedManifests(wsDir.contents, strings);
|
|
544
551
|
}
|
|
545
552
|
}
|
|
546
|
-
|
|
547
|
-
if (eng.mounted.has(ws)) return eng.mounted.get(ws);
|
|
553
|
+
function stageWorkspaceDir(eng, ws) {
|
|
548
554
|
const wsContents = /* @__PURE__ */ new Map();
|
|
549
555
|
seedManifests(wsContents, eng.manifestStrings);
|
|
550
556
|
eng.preopen.dir.contents.get("ws").contents.set(ws, new Directory(wsContents));
|
|
557
|
+
}
|
|
558
|
+
async function mountWorkspace(eng, ws, ledger) {
|
|
559
|
+
if (eng.mounted.has(ws)) return eng.mounted.get(ws);
|
|
560
|
+
stageWorkspaceDir(eng, ws);
|
|
551
561
|
const gitdir = gitdirOf(ws);
|
|
552
|
-
let restored = false, remoteMain = null, restoreError = null;
|
|
562
|
+
let restored = false, remoteMain = null, restoreError = null, checkpoint = null;
|
|
553
563
|
try {
|
|
554
564
|
const info = await git.getRemoteInfo({ http, url: ledger.remote, headers: ledger.headers });
|
|
555
565
|
remoteMain = info.refs && info.refs.heads && info.refs.heads.main || null;
|
|
556
566
|
if (remoteMain) {
|
|
557
567
|
await git.init({ fs: eng.fs, gitdir, bare: true, defaultBranch: "main" });
|
|
558
568
|
await git.addRemote({ fs: eng.fs, gitdir, remote: "origin", url: ledger.remote, force: true });
|
|
559
|
-
|
|
569
|
+
const ckpt = await discoverCheckpointFromCustody(ledger).catch(() => null);
|
|
570
|
+
let shallowOk = false;
|
|
571
|
+
if (ckpt?.cursor && ckpt.frontier) {
|
|
572
|
+
const steps = [32, 96, 256, 1024];
|
|
573
|
+
for (let i = 0; i < steps.length; i++) {
|
|
574
|
+
const depth = steps[i], relative = i > 0;
|
|
575
|
+
await git.fetch({ fs: eng.fs, http, gitdir, remote: "origin", ref: "main", singleBranch: true, depth, relative, headers: ledger.headers });
|
|
576
|
+
if (await git.readCommit({ fs: eng.fs, gitdir, oid: ckpt.cursor }).then(() => true, () => false)) {
|
|
577
|
+
shallowOk = true;
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
if (!shallowOk) await git.fetch({ fs: eng.fs, http, gitdir, remote: "origin", ref: "main", singleBranch: true, headers: ledger.headers });
|
|
560
583
|
await git.writeRef({ fs: eng.fs, gitdir, ref: "refs/heads/main", value: remoteMain, force: true });
|
|
561
584
|
await git.writeRef({ fs: eng.fs, gitdir, ref: "HEAD", value: "ref: refs/heads/main", force: true, symbolic: true });
|
|
585
|
+
if (shallowOk && ckpt?.blob) {
|
|
586
|
+
const r = importCheckpoint(eng, ws, ckpt.blob, ckpt.frontier);
|
|
587
|
+
checkpoint = { restored: !!(r && r.restored), frontierSeeded: !!(r && r.frontierSeeded), cursor: r && r.cursor ? r.cursor : ckpt.cursor, ref: ckpt.ref };
|
|
588
|
+
}
|
|
562
589
|
restored = true;
|
|
563
590
|
}
|
|
564
591
|
} catch (e) {
|
|
565
592
|
restoreError = String(e && e.stack || e).split("\n").slice(0, 5).join(" | ");
|
|
566
593
|
}
|
|
567
|
-
const m = { restored, remoteMain, restoreError };
|
|
594
|
+
const m = { restored, remoteMain, restoreError, checkpoint };
|
|
568
595
|
eng.mounted.set(ws, m);
|
|
569
596
|
return m;
|
|
570
597
|
}
|
|
@@ -591,6 +618,71 @@ function author(eng, ws, domain, directiveId, payload, controllerHash, opts = {}
|
|
|
591
618
|
if (defer && res.ok) (eng.pendingProjection ??= /* @__PURE__ */ new Set()).add(ws);
|
|
592
619
|
return res;
|
|
593
620
|
}
|
|
621
|
+
function importCheckpoint(eng, ws, blobB64, frontierB64) {
|
|
622
|
+
return JSON.parse(call(eng.ex, "checkpoint_import", { repoArg: repoArgOf(ws), workspace: ws, branch: BRANCH, blob: blobB64, ...frontierB64 ? { frontier: frontierB64 } : {} }, eng.STDERR));
|
|
623
|
+
}
|
|
624
|
+
async function streamAll(stream) {
|
|
625
|
+
const chunks = [];
|
|
626
|
+
const reader = stream.getReader();
|
|
627
|
+
for (; ; ) {
|
|
628
|
+
const { done, value } = await reader.read();
|
|
629
|
+
if (done) break;
|
|
630
|
+
chunks.push(value);
|
|
631
|
+
}
|
|
632
|
+
let len = 0;
|
|
633
|
+
for (const c of chunks) len += c.length;
|
|
634
|
+
const out10 = new Uint8Array(len);
|
|
635
|
+
let at = 0;
|
|
636
|
+
for (const c of chunks) {
|
|
637
|
+
out10.set(c, at);
|
|
638
|
+
at += c.length;
|
|
639
|
+
}
|
|
640
|
+
return out10;
|
|
641
|
+
}
|
|
642
|
+
async function gunzip(bytes) {
|
|
643
|
+
const ds = new DecompressionStream("gzip");
|
|
644
|
+
return streamAll(new Response(bytes).body.pipeThrough(ds));
|
|
645
|
+
}
|
|
646
|
+
async function discoverCheckpointFromCustody(ledger) {
|
|
647
|
+
const freshHeaders = () => ({ ...ledger.headers || {} });
|
|
648
|
+
const refs = (await git.listServerRefs({ http, url: ledger.remote, headers: freshHeaders(), prefix: "refs/meta/checkpoint/", protocolVersion: 2 }) || []).filter((r) => r.ref && r.ref.startsWith("refs/meta/checkpoint/") && r.oid);
|
|
649
|
+
if (!refs.length) return null;
|
|
650
|
+
const root = /* @__PURE__ */ new Map();
|
|
651
|
+
root.set("ckpt", new Directory(/* @__PURE__ */ new Map()));
|
|
652
|
+
const preopen = new PreopenDirectory("/work", root);
|
|
653
|
+
const fs = makeGitFs(preopen, "/work", { File, Directory });
|
|
654
|
+
const gitdir = "/work/ckpt/nomos.git";
|
|
655
|
+
await git.init({ fs, gitdir, bare: true, defaultBranch: BRANCH });
|
|
656
|
+
await git.addRemote({ fs, gitdir, remote: "origin", url: ledger.remote, force: true });
|
|
657
|
+
const readFile = async (oid, filepath) => {
|
|
658
|
+
try {
|
|
659
|
+
return (await git.readBlob({ fs, gitdir, oid, filepath })).blob;
|
|
660
|
+
} catch {
|
|
661
|
+
return null;
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
for (let i = refs.length - 1; i >= 0 && i >= refs.length - 3; i--) {
|
|
665
|
+
const { ref, oid } = refs[i];
|
|
666
|
+
try {
|
|
667
|
+
await git.fetch({ fs, http, gitdir, remote: "origin", ref, singleBranch: true, depth: 1, headers: freshHeaders() });
|
|
668
|
+
const gz = await readFile(oid, "checkpoint");
|
|
669
|
+
if (!gz) continue;
|
|
670
|
+
let meta = {};
|
|
671
|
+
try {
|
|
672
|
+
const mb = await readFile(oid, "meta");
|
|
673
|
+
if (mb) meta = JSON.parse(dec2.decode(mb));
|
|
674
|
+
} catch {
|
|
675
|
+
}
|
|
676
|
+
const codec = meta.codec ?? "gzip";
|
|
677
|
+
const blob = dec2.decode(codec === "gzip" ? await gunzip(gz) : gz);
|
|
678
|
+
const fgz = await readFile(oid, "frontier");
|
|
679
|
+
const frontier = fgz ? dec2.decode(codec === "gzip" ? await gunzip(fgz) : fgz) : null;
|
|
680
|
+
return { ref, oid, cursor: meta.cursor || null, blob, frontier };
|
|
681
|
+
} catch {
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
return null;
|
|
685
|
+
}
|
|
594
686
|
function applyIntentBytes(eng, ws, bytes) {
|
|
595
687
|
const name = `intent-in-${eng.seq++}.json`;
|
|
596
688
|
writeWork(eng, name, bytes);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "githolon",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "githolon — the Nomos developer CLI: Rails-style generators for @githolon/dsl domains + the package compiler. Kernel-independent.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@bjorn3/browser_wasi_shim": "0.4.2",
|
|
30
|
-
"@githolon/dsl": "^0.
|
|
30
|
+
"@githolon/dsl": "^0.14.0",
|
|
31
31
|
"isomorphic-git": "^1.38.4"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|