midsummer-sol 0.3.2 → 0.3.6
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/package.json +1 -1
- package/sol-mcp.js +122 -39
- package/sol.js +122 -39
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "midsummer-sol",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Sol — agent-native version control (a new git). CLI, MCP server, and no-filesystem SDK.",
|
|
5
5
|
"bin": { "sol": "./sol.js", "sol-mcp": "./sol-mcp.js", "sol-secret-mcp": "./sol-secret-mcp.js" },
|
|
6
6
|
"main": "./index.js",
|
package/sol-mcp.js
CHANGED
|
@@ -4156,11 +4156,11 @@ var init_lib = __esm(() => {
|
|
|
4156
4156
|
var exports_remote = {};
|
|
4157
4157
|
__export(exports_remote, {
|
|
4158
4158
|
writeBundle: () => writeBundle,
|
|
4159
|
+
splitLeafPacks: () => splitLeafPacks,
|
|
4159
4160
|
saveRemote: () => saveRemote,
|
|
4160
4161
|
remoteRefs: () => remoteRefs,
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
remotePushBatch: () => remotePushBatch,
|
|
4162
|
+
remotePushPack: () => remotePushPack,
|
|
4163
|
+
remotePushBlobs: () => remotePushBlobs,
|
|
4164
4164
|
remotePush: () => remotePush,
|
|
4165
4165
|
remotePromote: () => remotePromote,
|
|
4166
4166
|
remoteHead: () => remoteHead,
|
|
@@ -4184,12 +4184,13 @@ __export(exports_remote, {
|
|
|
4184
4184
|
loadRemote: () => loadRemote,
|
|
4185
4185
|
forksList: () => forksList,
|
|
4186
4186
|
forkMeta: () => forkMeta,
|
|
4187
|
+
classifyNodes: () => classifyNodes,
|
|
4187
4188
|
accessSet: () => accessSet,
|
|
4188
4189
|
accessGet: () => accessGet
|
|
4189
4190
|
});
|
|
4190
4191
|
import { appendFileSync as appendFileSync4, existsSync as existsSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync6 } from "node:fs";
|
|
4191
4192
|
import { join as join6 } from "node:path";
|
|
4192
|
-
import { gzipSync as gzipSync3 } from "node:zlib";
|
|
4193
|
+
import { gunzipSync as gunzipSync3, gzipSync as gzipSync3 } from "node:zlib";
|
|
4193
4194
|
async function call(cfg, token, path, init) {
|
|
4194
4195
|
const res = await fetch(endpoint(cfg, path), {
|
|
4195
4196
|
...init,
|
|
@@ -4199,44 +4200,125 @@ async function call(cfg, token, path, init) {
|
|
|
4199
4200
|
throw new Error(`remote ${path} -> ${res.status}: ${(await res.text().catch(() => "")).slice(0, 200)}`);
|
|
4200
4201
|
return res.json();
|
|
4201
4202
|
}
|
|
4202
|
-
function
|
|
4203
|
-
const
|
|
4203
|
+
function decodePackLine(line) {
|
|
4204
|
+
const map = JSON.parse(gunzipSync3(Buffer.from(line, "base64")).toString("utf8"));
|
|
4205
|
+
return Object.values(map);
|
|
4206
|
+
}
|
|
4207
|
+
async function exportStreaming(cfg, token) {
|
|
4208
|
+
const res = await fetch(endpoint(cfg, "/export?stream=1"), {
|
|
4209
|
+
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" }
|
|
4210
|
+
});
|
|
4211
|
+
if (!res.ok)
|
|
4212
|
+
throw new Error(`remote /export -> ${res.status}: ${(await res.text().catch(() => "")).slice(0, 200)}`);
|
|
4213
|
+
if (!res.body)
|
|
4214
|
+
return res.json();
|
|
4215
|
+
const reader = res.body.getReader();
|
|
4216
|
+
const td = new TextDecoder;
|
|
4217
|
+
let buf = "";
|
|
4218
|
+
let header;
|
|
4219
|
+
const nodes = [];
|
|
4220
|
+
const consumeLine = (line) => {
|
|
4221
|
+
if (line === "")
|
|
4222
|
+
return;
|
|
4223
|
+
if (!header) {
|
|
4224
|
+
header = JSON.parse(line);
|
|
4225
|
+
if (Array.isArray(header.nodes))
|
|
4226
|
+
for (const n of header.nodes)
|
|
4227
|
+
nodes.push(n);
|
|
4228
|
+
return;
|
|
4229
|
+
}
|
|
4230
|
+
for (const n of decodePackLine(line))
|
|
4231
|
+
nodes.push(n);
|
|
4232
|
+
};
|
|
4233
|
+
for (;; ) {
|
|
4234
|
+
const { done, value } = await reader.read();
|
|
4235
|
+
if (value)
|
|
4236
|
+
buf += td.decode(value, { stream: true });
|
|
4237
|
+
let nl;
|
|
4238
|
+
while ((nl = buf.indexOf(`
|
|
4239
|
+
`)) >= 0) {
|
|
4240
|
+
consumeLine(buf.slice(0, nl));
|
|
4241
|
+
buf = buf.slice(nl + 1);
|
|
4242
|
+
}
|
|
4243
|
+
if (done)
|
|
4244
|
+
break;
|
|
4245
|
+
}
|
|
4246
|
+
buf += td.decode();
|
|
4247
|
+
if (buf.length)
|
|
4248
|
+
consumeLine(buf);
|
|
4249
|
+
if (!header)
|
|
4250
|
+
throw new Error("remote /export returned an empty stream");
|
|
4251
|
+
return { ...header, nodes };
|
|
4252
|
+
}
|
|
4253
|
+
function classifyNodes(nodes) {
|
|
4254
|
+
const trees = [];
|
|
4255
|
+
const leaves = [];
|
|
4256
|
+
let total = 0;
|
|
4257
|
+
for (const n of nodes) {
|
|
4258
|
+
total += nodeBytes(n);
|
|
4259
|
+
(n.kind === "tree" ? trees : leaves).push(n);
|
|
4260
|
+
}
|
|
4261
|
+
return { trees, leaves, total };
|
|
4262
|
+
}
|
|
4263
|
+
function splitLeafPacks(leaves, maxBytes) {
|
|
4264
|
+
const packs = [];
|
|
4204
4265
|
let cur = [];
|
|
4205
|
-
let
|
|
4206
|
-
for (const
|
|
4207
|
-
const
|
|
4208
|
-
if (cur.length &&
|
|
4209
|
-
|
|
4266
|
+
let size = 0;
|
|
4267
|
+
for (const n of leaves) {
|
|
4268
|
+
const b = nodeBytes(n);
|
|
4269
|
+
if (cur.length && size + b > maxBytes) {
|
|
4270
|
+
packs.push(cur);
|
|
4210
4271
|
cur = [];
|
|
4211
|
-
|
|
4272
|
+
size = 0;
|
|
4212
4273
|
}
|
|
4213
|
-
cur.push(
|
|
4214
|
-
|
|
4274
|
+
cur.push(n);
|
|
4275
|
+
size += b;
|
|
4215
4276
|
}
|
|
4216
4277
|
if (cur.length)
|
|
4217
|
-
|
|
4218
|
-
return
|
|
4219
|
-
}
|
|
4220
|
-
async function
|
|
4221
|
-
const
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
batchIds.push(`${stamp}-${i}`);
|
|
4230
|
-
try {
|
|
4231
|
-
for (let w = 0;w < nodeBatches.length; w += CONC) {
|
|
4232
|
-
await Promise.all(nodeBatches.slice(w, w + CONC).map((nodes, j) => remotePushBatch(cfg, token, batchIds[w + j], nodes, w + j === 0 ? body.ops : [], w + j)));
|
|
4278
|
+
packs.push(cur);
|
|
4279
|
+
return packs;
|
|
4280
|
+
}
|
|
4281
|
+
async function pool(tasks, limit) {
|
|
4282
|
+
const out = new Array(tasks.length);
|
|
4283
|
+
let next = 0;
|
|
4284
|
+
const worker = async () => {
|
|
4285
|
+
for (;; ) {
|
|
4286
|
+
const i = next++;
|
|
4287
|
+
if (i >= tasks.length)
|
|
4288
|
+
return;
|
|
4289
|
+
out[i] = await tasks[i]();
|
|
4233
4290
|
}
|
|
4234
|
-
}
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4291
|
+
};
|
|
4292
|
+
await Promise.all(Array.from({ length: Math.min(limit, tasks.length) }, worker));
|
|
4293
|
+
return out;
|
|
4294
|
+
}
|
|
4295
|
+
async function retryTransient(fn, attempts = 5) {
|
|
4296
|
+
let last;
|
|
4297
|
+
for (let i = 0;i < attempts; i++) {
|
|
4298
|
+
try {
|
|
4299
|
+
return await fn();
|
|
4300
|
+
} catch (e) {
|
|
4301
|
+
last = e;
|
|
4302
|
+
const m = e instanceof Error ? e.message : String(e);
|
|
4303
|
+
if (!/-> 5dd|reset|fetch failed|network|ECONN|terminated|timeout/i.test(m))
|
|
4304
|
+
throw e;
|
|
4305
|
+
await new Promise((r) => setTimeout(r, 400 * (i + 1)));
|
|
4306
|
+
}
|
|
4307
|
+
}
|
|
4308
|
+
throw last;
|
|
4309
|
+
}
|
|
4310
|
+
async function remotePushPack(cfg, token, body) {
|
|
4311
|
+
const { trees, leaves, total } = classifyNodes(body.nodes);
|
|
4312
|
+
if (total <= SMALL_PUSH_BYTES) {
|
|
4313
|
+
return retryTransient(() => call(cfg, token, "/push/pack", { method: "POST", body: gzipSync3(JSON.stringify(body)), headers: { "content-encoding": "gzip" } }));
|
|
4314
|
+
}
|
|
4315
|
+
const blobPacks = splitLeafPacks(leaves, BLOB_PACK_BYTES);
|
|
4316
|
+
await pool(blobPacks.map((pack) => () => remotePushBlobs(cfg, token, pack)), BLOB_PACK_CONCURRENCY);
|
|
4317
|
+
return retryTransient(() => call(cfg, token, "/push/pack", {
|
|
4318
|
+
method: "POST",
|
|
4319
|
+
body: gzipSync3(JSON.stringify({ ...body, nodes: trees })),
|
|
4320
|
+
headers: { "content-encoding": "gzip" }
|
|
4321
|
+
}));
|
|
4240
4322
|
}
|
|
4241
4323
|
function loadRemote(solDir2) {
|
|
4242
4324
|
const p = join6(solDir2, "remote.json");
|
|
@@ -4258,10 +4340,11 @@ async function writeBundle(solDir2, bundle, from = 0) {
|
|
|
4258
4340
|
writeFileSync6(join6(solDir2, "HEAD"), JSON.stringify({ head: bundle.head, seq: bundle.seq, logTip: bundle.tip }));
|
|
4259
4341
|
return fresh.length;
|
|
4260
4342
|
}
|
|
4261
|
-
var endpoint = (cfg, path) => `${cfg.url.replace(/\/+$/, "")}${path}${path.includes("?") ? "&" : "?"}repo=${encodeURIComponent(cfg.repo)}`, remoteHead = (cfg, token) => call(cfg, token, "/head"), remoteGate = (cfg, token, branch) => call(cfg, token, `/head?gateState=true${branch ? `&branch=${encodeURIComponent(branch)}` : ""}`), remoteExport = (cfg, token) =>
|
|
4343
|
+
var endpoint = (cfg, path) => `${cfg.url.replace(/\/+$/, "")}${path}${path.includes("?") ? "&" : "?"}repo=${encodeURIComponent(cfg.repo)}`, remoteHead = (cfg, token) => call(cfg, token, "/head"), remoteGate = (cfg, token, branch) => call(cfg, token, `/head?gateState=true${branch ? `&branch=${encodeURIComponent(branch)}` : ""}`), remoteExport = (cfg, token) => exportStreaming(cfg, token), remoteRefs = (cfg, token) => call(cfg, token, "/refs"), remotePush = (cfg, token, body) => call(cfg, token, "/push", { method: "POST", body: JSON.stringify(body) }), remotePromote = (cfg, token, branch) => call(cfg, token, "/promote", { method: "POST", body: JSON.stringify({ branch }) }), SMALL_PUSH_BYTES, BLOB_PACK_BYTES, BLOB_PACK_CONCURRENCY = 1, nodeBytes = (n) => JSON.stringify(n).length, remotePushBlobs = (cfg, token, nodes) => retryTransient(() => call(cfg, token, "/push/blobs", { method: "POST", body: gzipSync3(JSON.stringify({ nodes })), headers: { "content-encoding": "gzip" } })), mrOpen = (cfg, token, body) => call(cfg, token, "/mr", { method: "POST", body: JSON.stringify(body) }), mrList = (cfg, token) => call(cfg, token, "/mrs"), mrDiff = (cfg, token, id) => call(cfg, token, `/mr/diff?id=${id}`), mrGet = (cfg, token, id) => call(cfg, token, `/mr?id=${id}`), mrAction = (cfg, token, action, body) => call(cfg, token, `/mr/${action}`, { method: "POST", body: JSON.stringify(body) }), accessGet = (cfg, token) => call(cfg, token, "/access"), ownerSet = (cfg, token, ownerHandle) => call(cfg, token, "/owner", { method: "POST", body: JSON.stringify({ ownerHandle }) }), accessSet = (cfg, token, body) => call(cfg, token, "/access", { method: "POST", body: JSON.stringify(body) }), policyCheck = (cfg, token, paths) => call(cfg, token, "/policy/check", { method: "POST", body: JSON.stringify({ paths }) }), policyGet = (cfg, token) => call(cfg, token, "/policy"), policyUpsert = (cfg, token, rule) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "upsert", rule }) }), policyRemove = (cfg, token, pattern) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "remove", pattern }) }), recipientsForPath = (cfg, token, path) => call(cfg, token, `/recipients?path=${encodeURIComponent(path)}`), recipientsForAudience = (cfg, token, audience, recovery) => call(cfg, token, `/recipients?audience=${encodeURIComponent(JSON.stringify(audience))}${recovery?.length ? `&recovery=${encodeURIComponent(recovery.join(","))}` : ""}`), remoteEnvPush = (cfg, token, bundle) => call(cfg, token, "/env/push", { method: "POST", body: JSON.stringify(bundle) }), remoteEnvAnchor = (cfg, token) => call(cfg, token, "/env/anchor"), remoteEnvPull = (cfg, token) => call(cfg, token, "/env/pull"), forkMeta = (cfg, token, parent) => call(cfg, token, "/fork-meta", { method: "POST", body: JSON.stringify({ parent }) }), forksList = (cfg, token) => call(cfg, token, "/forks"), saveRemote = (solDir2, cfg) => writeFileSync6(join6(solDir2, "remote.json"), JSON.stringify(cfg, null, 2));
|
|
4262
4344
|
var init_remote = __esm(() => {
|
|
4263
4345
|
init_file_store2();
|
|
4264
|
-
|
|
4346
|
+
SMALL_PUSH_BYTES = 24 * 1024 * 1024;
|
|
4347
|
+
BLOB_PACK_BYTES = 16 * 1024 * 1024;
|
|
4265
4348
|
});
|
|
4266
4349
|
|
|
4267
4350
|
// src/bin/test-gate.ts
|
|
@@ -12550,7 +12633,7 @@ WARNING: "${path}" was committed as PLAINTEXT before this seal — the pre-seal
|
|
|
12550
12633
|
const forkBase = localRefs?.branches[branch]?.remote;
|
|
12551
12634
|
const baseOp = forkBase ? ops.find((o) => o.rootAfter === forkBase) : undefined;
|
|
12552
12635
|
const fromSeq = baseOp ? baseOp.seq : rh.seq;
|
|
12553
|
-
const res = await
|
|
12636
|
+
const res = await remotePushPack(cfg, token, {
|
|
12554
12637
|
nodes: allLocalNodes(),
|
|
12555
12638
|
ops: ops.filter((o) => o.seq > fromSeq),
|
|
12556
12639
|
branch,
|
package/sol.js
CHANGED
|
@@ -3389,11 +3389,11 @@ var init_lib = __esm(() => {
|
|
|
3389
3389
|
var exports_remote = {};
|
|
3390
3390
|
__export(exports_remote, {
|
|
3391
3391
|
writeBundle: () => writeBundle,
|
|
3392
|
+
splitLeafPacks: () => splitLeafPacks,
|
|
3392
3393
|
saveRemote: () => saveRemote,
|
|
3393
3394
|
remoteRefs: () => remoteRefs,
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
remotePushBatch: () => remotePushBatch,
|
|
3395
|
+
remotePushPack: () => remotePushPack,
|
|
3396
|
+
remotePushBlobs: () => remotePushBlobs,
|
|
3397
3397
|
remotePush: () => remotePush,
|
|
3398
3398
|
remotePromote: () => remotePromote,
|
|
3399
3399
|
remoteHead: () => remoteHead,
|
|
@@ -3417,12 +3417,13 @@ __export(exports_remote, {
|
|
|
3417
3417
|
loadRemote: () => loadRemote,
|
|
3418
3418
|
forksList: () => forksList,
|
|
3419
3419
|
forkMeta: () => forkMeta,
|
|
3420
|
+
classifyNodes: () => classifyNodes,
|
|
3420
3421
|
accessSet: () => accessSet,
|
|
3421
3422
|
accessGet: () => accessGet
|
|
3422
3423
|
});
|
|
3423
3424
|
import { appendFileSync as appendFileSync3, existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
3424
3425
|
import { join as join5 } from "node:path";
|
|
3425
|
-
import { gzipSync as gzipSync2 } from "node:zlib";
|
|
3426
|
+
import { gunzipSync as gunzipSync2, gzipSync as gzipSync2 } from "node:zlib";
|
|
3426
3427
|
async function call(cfg, token, path, init) {
|
|
3427
3428
|
const res = await fetch(endpoint(cfg, path), {
|
|
3428
3429
|
...init,
|
|
@@ -3432,44 +3433,125 @@ async function call(cfg, token, path, init) {
|
|
|
3432
3433
|
throw new Error(`remote ${path} -> ${res.status}: ${(await res.text().catch(() => "")).slice(0, 200)}`);
|
|
3433
3434
|
return res.json();
|
|
3434
3435
|
}
|
|
3435
|
-
function
|
|
3436
|
-
const
|
|
3436
|
+
function decodePackLine(line) {
|
|
3437
|
+
const map = JSON.parse(gunzipSync2(Buffer.from(line, "base64")).toString("utf8"));
|
|
3438
|
+
return Object.values(map);
|
|
3439
|
+
}
|
|
3440
|
+
async function exportStreaming(cfg, token) {
|
|
3441
|
+
const res = await fetch(endpoint(cfg, "/export?stream=1"), {
|
|
3442
|
+
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" }
|
|
3443
|
+
});
|
|
3444
|
+
if (!res.ok)
|
|
3445
|
+
throw new Error(`remote /export -> ${res.status}: ${(await res.text().catch(() => "")).slice(0, 200)}`);
|
|
3446
|
+
if (!res.body)
|
|
3447
|
+
return res.json();
|
|
3448
|
+
const reader = res.body.getReader();
|
|
3449
|
+
const td = new TextDecoder;
|
|
3450
|
+
let buf = "";
|
|
3451
|
+
let header;
|
|
3452
|
+
const nodes = [];
|
|
3453
|
+
const consumeLine = (line) => {
|
|
3454
|
+
if (line === "")
|
|
3455
|
+
return;
|
|
3456
|
+
if (!header) {
|
|
3457
|
+
header = JSON.parse(line);
|
|
3458
|
+
if (Array.isArray(header.nodes))
|
|
3459
|
+
for (const n of header.nodes)
|
|
3460
|
+
nodes.push(n);
|
|
3461
|
+
return;
|
|
3462
|
+
}
|
|
3463
|
+
for (const n of decodePackLine(line))
|
|
3464
|
+
nodes.push(n);
|
|
3465
|
+
};
|
|
3466
|
+
for (;; ) {
|
|
3467
|
+
const { done, value } = await reader.read();
|
|
3468
|
+
if (value)
|
|
3469
|
+
buf += td.decode(value, { stream: true });
|
|
3470
|
+
let nl;
|
|
3471
|
+
while ((nl = buf.indexOf(`
|
|
3472
|
+
`)) >= 0) {
|
|
3473
|
+
consumeLine(buf.slice(0, nl));
|
|
3474
|
+
buf = buf.slice(nl + 1);
|
|
3475
|
+
}
|
|
3476
|
+
if (done)
|
|
3477
|
+
break;
|
|
3478
|
+
}
|
|
3479
|
+
buf += td.decode();
|
|
3480
|
+
if (buf.length)
|
|
3481
|
+
consumeLine(buf);
|
|
3482
|
+
if (!header)
|
|
3483
|
+
throw new Error("remote /export returned an empty stream");
|
|
3484
|
+
return { ...header, nodes };
|
|
3485
|
+
}
|
|
3486
|
+
function classifyNodes(nodes) {
|
|
3487
|
+
const trees = [];
|
|
3488
|
+
const leaves = [];
|
|
3489
|
+
let total = 0;
|
|
3490
|
+
for (const n of nodes) {
|
|
3491
|
+
total += nodeBytes(n);
|
|
3492
|
+
(n.kind === "tree" ? trees : leaves).push(n);
|
|
3493
|
+
}
|
|
3494
|
+
return { trees, leaves, total };
|
|
3495
|
+
}
|
|
3496
|
+
function splitLeafPacks(leaves, maxBytes) {
|
|
3497
|
+
const packs = [];
|
|
3437
3498
|
let cur = [];
|
|
3438
|
-
let
|
|
3439
|
-
for (const
|
|
3440
|
-
const
|
|
3441
|
-
if (cur.length &&
|
|
3442
|
-
|
|
3499
|
+
let size = 0;
|
|
3500
|
+
for (const n of leaves) {
|
|
3501
|
+
const b = nodeBytes(n);
|
|
3502
|
+
if (cur.length && size + b > maxBytes) {
|
|
3503
|
+
packs.push(cur);
|
|
3443
3504
|
cur = [];
|
|
3444
|
-
|
|
3505
|
+
size = 0;
|
|
3445
3506
|
}
|
|
3446
|
-
cur.push(
|
|
3447
|
-
|
|
3507
|
+
cur.push(n);
|
|
3508
|
+
size += b;
|
|
3448
3509
|
}
|
|
3449
3510
|
if (cur.length)
|
|
3450
|
-
|
|
3451
|
-
return
|
|
3452
|
-
}
|
|
3453
|
-
async function
|
|
3454
|
-
const
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3511
|
+
packs.push(cur);
|
|
3512
|
+
return packs;
|
|
3513
|
+
}
|
|
3514
|
+
async function pool(tasks, limit) {
|
|
3515
|
+
const out = new Array(tasks.length);
|
|
3516
|
+
let next = 0;
|
|
3517
|
+
const worker = async () => {
|
|
3518
|
+
for (;; ) {
|
|
3519
|
+
const i = next++;
|
|
3520
|
+
if (i >= tasks.length)
|
|
3521
|
+
return;
|
|
3522
|
+
out[i] = await tasks[i]();
|
|
3523
|
+
}
|
|
3524
|
+
};
|
|
3525
|
+
await Promise.all(Array.from({ length: Math.min(limit, tasks.length) }, worker));
|
|
3526
|
+
return out;
|
|
3527
|
+
}
|
|
3528
|
+
async function retryTransient(fn, attempts = 5) {
|
|
3529
|
+
let last;
|
|
3530
|
+
for (let i = 0;i < attempts; i++) {
|
|
3531
|
+
try {
|
|
3532
|
+
return await fn();
|
|
3533
|
+
} catch (e) {
|
|
3534
|
+
last = e;
|
|
3535
|
+
const m = e instanceof Error ? e.message : String(e);
|
|
3536
|
+
if (!/-> 5dd|reset|fetch failed|network|ECONN|terminated|timeout/i.test(m))
|
|
3537
|
+
throw e;
|
|
3538
|
+
await new Promise((r) => setTimeout(r, 400 * (i + 1)));
|
|
3466
3539
|
}
|
|
3467
|
-
} catch (e) {
|
|
3468
|
-
if (e instanceof Error && /-> 404/.test(e.message))
|
|
3469
|
-
return remotePush(cfg, token, body);
|
|
3470
|
-
throw e;
|
|
3471
3540
|
}
|
|
3472
|
-
|
|
3541
|
+
throw last;
|
|
3542
|
+
}
|
|
3543
|
+
async function remotePushPack(cfg, token, body) {
|
|
3544
|
+
const { trees, leaves, total } = classifyNodes(body.nodes);
|
|
3545
|
+
if (total <= SMALL_PUSH_BYTES) {
|
|
3546
|
+
return retryTransient(() => call(cfg, token, "/push/pack", { method: "POST", body: gzipSync2(JSON.stringify(body)), headers: { "content-encoding": "gzip" } }));
|
|
3547
|
+
}
|
|
3548
|
+
const blobPacks = splitLeafPacks(leaves, BLOB_PACK_BYTES);
|
|
3549
|
+
await pool(blobPacks.map((pack) => () => remotePushBlobs(cfg, token, pack)), BLOB_PACK_CONCURRENCY);
|
|
3550
|
+
return retryTransient(() => call(cfg, token, "/push/pack", {
|
|
3551
|
+
method: "POST",
|
|
3552
|
+
body: gzipSync2(JSON.stringify({ ...body, nodes: trees })),
|
|
3553
|
+
headers: { "content-encoding": "gzip" }
|
|
3554
|
+
}));
|
|
3473
3555
|
}
|
|
3474
3556
|
function loadRemote(solDir2) {
|
|
3475
3557
|
const p = join5(solDir2, "remote.json");
|
|
@@ -3491,10 +3573,11 @@ async function writeBundle(solDir2, bundle, from = 0) {
|
|
|
3491
3573
|
writeFileSync5(join5(solDir2, "HEAD"), JSON.stringify({ head: bundle.head, seq: bundle.seq, logTip: bundle.tip }));
|
|
3492
3574
|
return fresh.length;
|
|
3493
3575
|
}
|
|
3494
|
-
var endpoint = (cfg, path) => `${cfg.url.replace(/\/+$/, "")}${path}${path.includes("?") ? "&" : "?"}repo=${encodeURIComponent(cfg.repo)}`, remoteHead = (cfg, token) => call(cfg, token, "/head"), remoteGate = (cfg, token, branch) => call(cfg, token, `/head?gateState=true${branch ? `&branch=${encodeURIComponent(branch)}` : ""}`), remoteExport = (cfg, token) =>
|
|
3576
|
+
var endpoint = (cfg, path) => `${cfg.url.replace(/\/+$/, "")}${path}${path.includes("?") ? "&" : "?"}repo=${encodeURIComponent(cfg.repo)}`, remoteHead = (cfg, token) => call(cfg, token, "/head"), remoteGate = (cfg, token, branch) => call(cfg, token, `/head?gateState=true${branch ? `&branch=${encodeURIComponent(branch)}` : ""}`), remoteExport = (cfg, token) => exportStreaming(cfg, token), remoteRefs = (cfg, token) => call(cfg, token, "/refs"), remotePush = (cfg, token, body) => call(cfg, token, "/push", { method: "POST", body: JSON.stringify(body) }), remotePromote = (cfg, token, branch) => call(cfg, token, "/promote", { method: "POST", body: JSON.stringify({ branch }) }), SMALL_PUSH_BYTES, BLOB_PACK_BYTES, BLOB_PACK_CONCURRENCY = 1, nodeBytes = (n) => JSON.stringify(n).length, remotePushBlobs = (cfg, token, nodes) => retryTransient(() => call(cfg, token, "/push/blobs", { method: "POST", body: gzipSync2(JSON.stringify({ nodes })), headers: { "content-encoding": "gzip" } })), mrOpen = (cfg, token, body) => call(cfg, token, "/mr", { method: "POST", body: JSON.stringify(body) }), mrList = (cfg, token) => call(cfg, token, "/mrs"), mrDiff = (cfg, token, id) => call(cfg, token, `/mr/diff?id=${id}`), mrGet = (cfg, token, id) => call(cfg, token, `/mr?id=${id}`), mrAction = (cfg, token, action, body) => call(cfg, token, `/mr/${action}`, { method: "POST", body: JSON.stringify(body) }), accessGet = (cfg, token) => call(cfg, token, "/access"), ownerSet = (cfg, token, ownerHandle) => call(cfg, token, "/owner", { method: "POST", body: JSON.stringify({ ownerHandle }) }), accessSet = (cfg, token, body) => call(cfg, token, "/access", { method: "POST", body: JSON.stringify(body) }), policyCheck = (cfg, token, paths) => call(cfg, token, "/policy/check", { method: "POST", body: JSON.stringify({ paths }) }), policyGet = (cfg, token) => call(cfg, token, "/policy"), policyUpsert = (cfg, token, rule) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "upsert", rule }) }), policyRemove = (cfg, token, pattern) => call(cfg, token, "/policy?write=1", { method: "POST", body: JSON.stringify({ op: "remove", pattern }) }), recipientsForPath = (cfg, token, path) => call(cfg, token, `/recipients?path=${encodeURIComponent(path)}`), recipientsForAudience = (cfg, token, audience, recovery) => call(cfg, token, `/recipients?audience=${encodeURIComponent(JSON.stringify(audience))}${recovery?.length ? `&recovery=${encodeURIComponent(recovery.join(","))}` : ""}`), remoteEnvPush = (cfg, token, bundle) => call(cfg, token, "/env/push", { method: "POST", body: JSON.stringify(bundle) }), remoteEnvAnchor = (cfg, token) => call(cfg, token, "/env/anchor"), remoteEnvPull = (cfg, token) => call(cfg, token, "/env/pull"), forkMeta = (cfg, token, parent) => call(cfg, token, "/fork-meta", { method: "POST", body: JSON.stringify({ parent }) }), forksList = (cfg, token) => call(cfg, token, "/forks"), saveRemote = (solDir2, cfg) => writeFileSync5(join5(solDir2, "remote.json"), JSON.stringify(cfg, null, 2));
|
|
3495
3577
|
var init_remote = __esm(() => {
|
|
3496
3578
|
init_file_store();
|
|
3497
|
-
|
|
3579
|
+
SMALL_PUSH_BYTES = 24 * 1024 * 1024;
|
|
3580
|
+
BLOB_PACK_BYTES = 16 * 1024 * 1024;
|
|
3498
3581
|
});
|
|
3499
3582
|
|
|
3500
3583
|
// src/bin/test-gate.ts
|
|
@@ -12318,7 +12401,7 @@ WARNING: "${path}" was committed as PLAINTEXT before this seal — the pre-seal
|
|
|
12318
12401
|
const forkBase = localRefs?.branches[branch]?.remote;
|
|
12319
12402
|
const baseOp = forkBase ? ops.find((o) => o.rootAfter === forkBase) : undefined;
|
|
12320
12403
|
const fromSeq = baseOp ? baseOp.seq : rh.seq;
|
|
12321
|
-
const res = await
|
|
12404
|
+
const res = await remotePushPack(cfg, token, {
|
|
12322
12405
|
nodes: allLocalNodes(),
|
|
12323
12406
|
ops: ops.filter((o) => o.seq > fromSeq),
|
|
12324
12407
|
branch,
|
|
@@ -16602,7 +16685,7 @@ WARNING: "${path}" was committed as PLAINTEXT before this seal — the pre-seal
|
|
|
16602
16685
|
const forkBase = localRefs?.branches[branch]?.remote;
|
|
16603
16686
|
const baseOp = forkBase ? ops.find((o) => o.rootAfter === forkBase) : undefined;
|
|
16604
16687
|
const fromSeq = baseOp ? baseOp.seq : rh.seq;
|
|
16605
|
-
const res = await
|
|
16688
|
+
const res = await remotePushPack(cfg, token, {
|
|
16606
16689
|
nodes: allLocalNodes(),
|
|
16607
16690
|
ops: ops.filter((o) => o.seq > fromSeq),
|
|
16608
16691
|
branch,
|