@log0u7/opencode-mesh 0.2.0 → 0.4.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/CHANGELOG.md +150 -0
- package/README.md +46 -13
- package/dist/lib/client.d.ts +2 -0
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +6 -1
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +26 -1
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/discovery.d.ts +3 -0
- package/dist/lib/discovery.d.ts.map +1 -1
- package/dist/lib/discovery.js +33 -7
- package/dist/lib/discovery.js.map +1 -1
- package/dist/lib/identity.d.ts +10 -8
- package/dist/lib/identity.d.ts.map +1 -1
- package/dist/lib/identity.js +132 -32
- package/dist/lib/identity.js.map +1 -1
- package/dist/lib/locks.d.ts.map +1 -1
- package/dist/lib/locks.js +20 -12
- package/dist/lib/locks.js.map +1 -1
- package/dist/lib/peers.d.ts +13 -1
- package/dist/lib/peers.d.ts.map +1 -1
- package/dist/lib/peers.js +114 -18
- package/dist/lib/peers.js.map +1 -1
- package/dist/lib/serve.d.ts +2 -0
- package/dist/lib/serve.d.ts.map +1 -1
- package/dist/lib/serve.js +62 -71
- package/dist/lib/serve.js.map +1 -1
- package/dist/lib/spawn.d.ts +14 -4
- package/dist/lib/spawn.d.ts.map +1 -1
- package/dist/lib/spawn.js +210 -21
- package/dist/lib/spawn.js.map +1 -1
- package/dist/lib/sqlite.d.ts.map +1 -1
- package/dist/lib/sqlite.js +15 -4
- package/dist/lib/sqlite.js.map +1 -1
- package/dist/lib/workers.d.ts +2 -0
- package/dist/lib/workers.d.ts.map +1 -1
- package/dist/lib/workers.js +45 -12
- package/dist/lib/workers.js.map +1 -1
- package/dist/lib/worktree.d.ts +22 -4
- package/dist/lib/worktree.d.ts.map +1 -1
- package/dist/lib/worktree.js +54 -6
- package/dist/lib/worktree.js.map +1 -1
- package/dist/plugin-v2.d.ts.map +1 -1
- package/dist/plugin-v2.js +65 -337
- package/dist/plugin-v2.js.map +1 -1
- package/dist/plugin.d.ts +2 -6
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +119 -265
- package/dist/plugin.js.map +1 -1
- package/dist/tools.d.ts +30 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +315 -0
- package/dist/tools.js.map +1 -0
- package/dist/types/peer.d.ts +2 -0
- package/dist/types/peer.d.ts.map +1 -1
- package/package.json +10 -8
package/dist/lib/serve.js
CHANGED
|
@@ -2,30 +2,43 @@ import { createServer } from "node:http";
|
|
|
2
2
|
import { authenticateToken } from "./peers.js";
|
|
3
3
|
import { receiveMessage, unreadCount } from "./mail.js";
|
|
4
4
|
const BODY_LIMIT = 64 * 1024;
|
|
5
|
+
// Loopback by default: the mesh HTTP API must not be reachable from the
|
|
6
|
+
// network unless the operator explicitly opted into a LAN pool.
|
|
7
|
+
const DEFAULT_BIND = "127.0.0.1";
|
|
5
8
|
// Bind the mesh HTTP server and resolve the actual port. When the requested
|
|
6
9
|
// port is taken (two mesh nodes on one machine, e.g. a spawned worker loading
|
|
7
10
|
// the same plugin), fall back to an ephemeral port instead of crashing.
|
|
8
11
|
export async function startMeshServer(options) {
|
|
12
|
+
const host = options.bind === "lan" ? "0.0.0.0" : DEFAULT_BIND;
|
|
9
13
|
const server = createServer((req, res) => {
|
|
10
14
|
void handle(options.db, req, res);
|
|
11
15
|
});
|
|
16
|
+
let onListen = () => { };
|
|
12
17
|
const port = await new Promise((resolve, reject) => {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
const attempt = (requested) => {
|
|
19
|
+
onListen = () => {
|
|
20
|
+
server.removeListener("error", onError);
|
|
21
|
+
resolve(serverAddressPort(server, requested));
|
|
22
|
+
};
|
|
23
|
+
server.once("listening", onListen);
|
|
24
|
+
server.once("error", onError);
|
|
25
|
+
server.listen(requested, host);
|
|
26
|
+
};
|
|
27
|
+
const onError = (err) => {
|
|
28
|
+
server.removeListener("listening", onListen);
|
|
29
|
+
if (err.code === "EADDRINUSE" && server.listening === false) {
|
|
30
|
+
attempt(0);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
reject(err);
|
|
25
34
|
};
|
|
26
|
-
|
|
35
|
+
attempt(options.port);
|
|
27
36
|
});
|
|
28
|
-
return { server, port };
|
|
37
|
+
return { server, port, address: host };
|
|
38
|
+
}
|
|
39
|
+
function serverAddressPort(server, fallback) {
|
|
40
|
+
const address = server.address();
|
|
41
|
+
return address !== null && typeof address !== "string" ? address.port : fallback;
|
|
29
42
|
}
|
|
30
43
|
async function handle(db, req, res) {
|
|
31
44
|
const url = new URL(req.url ?? "/", "http://localhost");
|
|
@@ -38,48 +51,36 @@ async function handle(db, req, res) {
|
|
|
38
51
|
json(res, 405, { error: "method not allowed" });
|
|
39
52
|
return;
|
|
40
53
|
}
|
|
41
|
-
if (req.method === "POST") {
|
|
54
|
+
if (req.method === "POST" && url.pathname === "/mail") {
|
|
42
55
|
const body = await readBody(req);
|
|
43
|
-
if (
|
|
44
|
-
|
|
56
|
+
if ("error" in body) {
|
|
57
|
+
// A body over the limit is 413; a read failure (client aborted mid-body)
|
|
58
|
+
// is a malformed request, not an oversized one.
|
|
59
|
+
json(res, body.error === "too_large" ? 413 : 400, {
|
|
60
|
+
error: body.error === "too_large" ? "body too large" : "malformed request body",
|
|
61
|
+
});
|
|
45
62
|
return;
|
|
46
63
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
json(res, 400, { error: "invalid mail body" });
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
// Authenticate with the claimed sender so pending pairing tokens bind
|
|
54
|
-
// to the node id in the message.
|
|
55
|
-
const mailPeer = authenticate(db, req, parsed.from);
|
|
56
|
-
if (!mailPeer) {
|
|
57
|
-
json(res, 401, { error: "unauthorized" });
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (parsed.from !== mailPeer.node_id) {
|
|
61
|
-
json(res, 401, { error: "from does not match token" });
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
receiveMessage(db, parsed);
|
|
65
|
-
json(res, 200, { ok: true, unread: unreadCount(db) });
|
|
64
|
+
const parsed = parseMail(body.body);
|
|
65
|
+
if (!parsed) {
|
|
66
|
+
json(res, 400, { error: "invalid mail body" });
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
// Authenticate with the claimed sender so a pending pairing token can only
|
|
70
|
+
// bind to a node this host already knows. The pairing proof (sender-signed
|
|
71
|
+
// over node_id+token) is what authorizes binding a pairing to that node.
|
|
72
|
+
const mailPeer = authenticate(db, req, parsed.from, parsed.proof);
|
|
73
|
+
if (!mailPeer) {
|
|
70
74
|
json(res, 401, { error: "unauthorized" });
|
|
71
75
|
return;
|
|
72
76
|
}
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
if (!parsed) {
|
|
76
|
-
json(res, 400, { error: "invalid announce body" });
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
touchAddress(db, peer.node_id, parsed.addresses);
|
|
80
|
-
json(res, 200, { ok: true });
|
|
77
|
+
if (parsed.from !== mailPeer.node_id) {
|
|
78
|
+
json(res, 401, { error: "from does not match token" });
|
|
81
79
|
return;
|
|
82
80
|
}
|
|
81
|
+
receiveMessage(db, parsed);
|
|
82
|
+
json(res, 200, { ok: true, unread: unreadCount(db) });
|
|
83
|
+
return;
|
|
83
84
|
}
|
|
84
85
|
if (req.method === "GET" && url.pathname === "/status") {
|
|
85
86
|
const peer = authenticate(db, req);
|
|
@@ -95,22 +96,15 @@ async function handle(db, req, res) {
|
|
|
95
96
|
}
|
|
96
97
|
json(res, 404, { error: "not found" });
|
|
97
98
|
}
|
|
98
|
-
function authenticate(db, req, from = null) {
|
|
99
|
+
function authenticate(db, req, from = null, proof) {
|
|
99
100
|
const header = req.headers.authorization ?? "";
|
|
100
101
|
const match = /^Bearer (.+)$/.exec(header);
|
|
101
102
|
if (!match?.[1]) {
|
|
102
103
|
return null;
|
|
103
104
|
}
|
|
104
|
-
const peer = authenticateToken(db, match[1], from);
|
|
105
|
+
const peer = authenticateToken(db, match[1], from, proof);
|
|
105
106
|
return peer ? { node_id: peer.node_id } : null;
|
|
106
107
|
}
|
|
107
|
-
function touchAddress(db, nodeId, addresses) {
|
|
108
|
-
db.conn.run("UPDATE peers SET addresses = ?, last_seen = ? WHERE node_id = ?", [
|
|
109
|
-
JSON.stringify(addresses),
|
|
110
|
-
Date.now(),
|
|
111
|
-
nodeId,
|
|
112
|
-
]);
|
|
113
|
-
}
|
|
114
108
|
function readBody(req) {
|
|
115
109
|
return new Promise((resolve) => {
|
|
116
110
|
const chunks = [];
|
|
@@ -127,8 +121,13 @@ function readBody(req) {
|
|
|
127
121
|
chunks.push(chunk);
|
|
128
122
|
}
|
|
129
123
|
});
|
|
130
|
-
req.on("end", () => resolve(limited ?
|
|
131
|
-
|
|
124
|
+
req.on("end", () => resolve(limited ? { error: "too_large" } : { body: Buffer.concat(chunks).toString("utf8") }));
|
|
125
|
+
// A socket error, an aborted request, or a bare close all end the read
|
|
126
|
+
// without `end`. `close` is the last-resort fallback; resolving twice is a
|
|
127
|
+
// no-op, so a normal request that already ended is unaffected.
|
|
128
|
+
req.on("error", () => resolve({ error: "read" }));
|
|
129
|
+
req.on("aborted", () => resolve({ error: "read" }));
|
|
130
|
+
req.on("close", () => resolve({ error: "read" }));
|
|
132
131
|
});
|
|
133
132
|
}
|
|
134
133
|
function parseMail(raw) {
|
|
@@ -139,20 +138,12 @@ function parseMail(raw) {
|
|
|
139
138
|
typeof parsed.body !== "string") {
|
|
140
139
|
return null;
|
|
141
140
|
}
|
|
142
|
-
return {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
function parseAnnounce(raw) {
|
|
149
|
-
try {
|
|
150
|
-
const parsed = JSON.parse(raw);
|
|
151
|
-
if (!Array.isArray(parsed.addresses)) {
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
const addresses = parsed.addresses.filter((a) => typeof a === "string");
|
|
155
|
-
return { addresses };
|
|
141
|
+
return {
|
|
142
|
+
from: parsed.from,
|
|
143
|
+
subject: parsed.subject,
|
|
144
|
+
body: parsed.body,
|
|
145
|
+
...(typeof parsed.proof === "string" ? { proof: parsed.proof } : {}),
|
|
146
|
+
};
|
|
156
147
|
}
|
|
157
148
|
catch {
|
|
158
149
|
return null;
|
package/dist/lib/serve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/lib/serve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/lib/serve.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/spawn.d.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import type { MeshDb } from "./db.js";
|
|
2
2
|
import { type Worker } from "./workers.js";
|
|
3
|
+
export type DataListener = (chunk: string) => void;
|
|
3
4
|
export type SpawnedProcess = {
|
|
4
5
|
pid: number;
|
|
5
6
|
stdout: {
|
|
6
|
-
on(event: "data", listener:
|
|
7
|
+
on(event: "data", listener: DataListener): void;
|
|
8
|
+
};
|
|
9
|
+
stderr: {
|
|
10
|
+
on(event: "data", listener: DataListener): void;
|
|
7
11
|
};
|
|
8
12
|
on(event: "exit", listener: (code: number | null) => void): void;
|
|
13
|
+
on(event: "error", listener: (error: Error) => void): void;
|
|
9
14
|
kill(signal?: string): void;
|
|
10
15
|
};
|
|
11
|
-
export type SpawnFn = (argv: string[]) => SpawnedProcess;
|
|
16
|
+
export type SpawnFn = (argv: string[], env?: Record<string, string>) => SpawnedProcess;
|
|
12
17
|
export type KillFn = (id: string, signal: string) => void;
|
|
13
|
-
export declare
|
|
18
|
+
export declare const CHILD_ENV: {
|
|
19
|
+
OPENCODE_MESH_CHILD: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function nodeSpawn(argv: string[], env?: Record<string, string>): SpawnedProcess;
|
|
14
22
|
export type RunWorkerInput = {
|
|
15
23
|
task: string;
|
|
16
24
|
worktree_path: string;
|
|
@@ -19,13 +27,15 @@ export type RunWorkerInput = {
|
|
|
19
27
|
agent?: string;
|
|
20
28
|
auto?: boolean;
|
|
21
29
|
spawnFn: SpawnFn;
|
|
22
|
-
killFn?: KillFn;
|
|
23
30
|
};
|
|
24
31
|
export type StopOptions = {
|
|
25
32
|
killFn?: KillFn;
|
|
33
|
+
graceMs?: number;
|
|
26
34
|
};
|
|
27
35
|
export declare function runWorker(db: MeshDb, dataDir: string, input: RunWorkerInput): Worker;
|
|
28
36
|
export declare function stopWorker(db: MeshDb, id: string, options?: StopOptions): boolean;
|
|
29
37
|
export declare function stopAllWorkers(db: MeshDb, options?: StopOptions): void;
|
|
30
38
|
export declare function liveWorkerIds(): string[];
|
|
39
|
+
export declare function removeWorkerLog(dataDir: string, id: string): void;
|
|
40
|
+
export declare function readLogTail(dataDir: string, id: string, limit: number): string;
|
|
31
41
|
//# sourceMappingURL=spawn.d.ts.map
|
package/dist/lib/spawn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/lib/spawn.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/lib/spawn.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAML,KAAK,MAAM,EAEZ,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAEnD,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;KAAE,CAAC;IAC5D,MAAM,EAAE;QAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;KAAE,CAAC;IAC5D,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3D,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,cAAc,CAAC;AACvF,MAAM,MAAM,MAAM,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAI1D,eAAO,MAAM,SAAS;IAAK,mBAAmB;CAAO,CAAC;AAItD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,cAAc,CA2CtF;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AASF,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CA8FpF;AAKD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CA4BrF;AAyBD,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI,CAQ1E;AAED,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAwDD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAIjE;AAQD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAoC9E"}
|
package/dist/lib/spawn.js
CHANGED
|
@@ -1,63 +1,157 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { appendFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { appendFileSync, closeSync, fstatSync, mkdirSync, openSync, readSync, renameSync, rmSync, statSync, } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { insertWorker, setWorkerSession, setWorkerStatus } from "./workers.js";
|
|
4
|
+
import { getWorker, insertWorker, setWorkerPid, setWorkerSession, setWorkerStatus, } from "./workers.js";
|
|
5
|
+
// A child must not boot its own mesh node: a pool of N workers would otherwise
|
|
6
|
+
// cost N servers, N mDNS advertisers and N databases.
|
|
7
|
+
export const CHILD_ENV = { OPENCODE_MESH_CHILD: "1" };
|
|
5
8
|
// Real adapter used by the plugin: node child_process wrapped to the minimal
|
|
6
9
|
// SpawnedProcess surface (works under Bun's node compat at runtime).
|
|
7
|
-
export function nodeSpawn(argv) {
|
|
10
|
+
export function nodeSpawn(argv, env) {
|
|
11
|
+
// Detached on POSIX: the worker becomes a process group leader, so a stop
|
|
12
|
+
// takes down its own children too instead of orphaning them.
|
|
13
|
+
const detached = process.platform !== "win32";
|
|
8
14
|
const child = spawn(argv[0] ?? "", argv.slice(1), {
|
|
9
15
|
stdio: ["ignore", "pipe", "pipe"],
|
|
16
|
+
...(detached ? { detached: true } : {}),
|
|
17
|
+
...(env !== undefined ? { env: { ...process.env, ...env } } : {}),
|
|
10
18
|
});
|
|
11
19
|
const pid = child.pid ?? -1;
|
|
12
20
|
return {
|
|
13
21
|
pid,
|
|
14
22
|
stdout: {
|
|
15
|
-
on: (
|
|
16
|
-
child.stdout?.on(
|
|
23
|
+
on: (_event, listener) => {
|
|
24
|
+
child.stdout?.on("data", (chunk) => listener(chunk.toString("utf8")));
|
|
17
25
|
},
|
|
18
26
|
},
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
stderr: {
|
|
28
|
+
on: (_event, listener) => {
|
|
29
|
+
child.stderr?.on("data", (chunk) => listener(chunk.toString("utf8")));
|
|
30
|
+
},
|
|
21
31
|
},
|
|
32
|
+
on: ((event, listener) => {
|
|
33
|
+
if (event === "error") {
|
|
34
|
+
child.on("error", listener);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
child.on("exit", listener);
|
|
38
|
+
}
|
|
39
|
+
}),
|
|
22
40
|
kill: (signal) => {
|
|
23
|
-
|
|
41
|
+
const sig = (signal ?? "SIGTERM");
|
|
42
|
+
if (detached && pid > 0) {
|
|
43
|
+
try {
|
|
44
|
+
// Negative pid targets the whole group: worker plus its children.
|
|
45
|
+
process.kill(-pid, sig);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Group already gone; fall through to the direct signal.
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
child.kill(sig);
|
|
24
53
|
},
|
|
25
54
|
};
|
|
26
55
|
}
|
|
27
56
|
const LIVE_PROCESSES = new Map();
|
|
57
|
+
const PENDING_KILLS = new Map();
|
|
58
|
+
const DEFAULT_KILL_GRACE_MS = 3000;
|
|
59
|
+
// Session-id line-buffer cap: session lines are short, 64 KiB is generous.
|
|
60
|
+
const PENDING_MAX_CHARS = 64 * 1024;
|
|
28
61
|
// Headless worker: one prompt in an isolated worktree, tracked by pid and log.
|
|
29
62
|
export function runWorker(db, dataDir, input) {
|
|
30
|
-
const argv = buildArgv(input);
|
|
31
|
-
const proc = input.spawnFn(argv);
|
|
32
63
|
mkdirSync(join(dataDir, "workers"), { recursive: true });
|
|
64
|
+
// Insert first: a process spawned before the row exists would be untracked if
|
|
65
|
+
// the insert threw, and the pid is only known after spawnFn returns.
|
|
33
66
|
const worker = insertWorker(db, {
|
|
34
67
|
task: input.task,
|
|
35
68
|
worktree_path: input.worktree_path,
|
|
36
69
|
branch: input.branch,
|
|
37
|
-
pid:
|
|
70
|
+
pid: null,
|
|
38
71
|
});
|
|
72
|
+
let proc;
|
|
73
|
+
try {
|
|
74
|
+
proc = input.spawnFn(buildArgv(input), CHILD_ENV);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
finalize(db, worker.id, "failed", null);
|
|
78
|
+
return { ...worker, status: "failed", finished_at: Date.now() };
|
|
79
|
+
}
|
|
80
|
+
// A failed spawn reports pid -1 (child.pid undefined): never persist it.
|
|
81
|
+
if (proc.pid > 0) {
|
|
82
|
+
setWorkerPid(db, worker.id, proc.pid);
|
|
83
|
+
worker.pid = proc.pid;
|
|
84
|
+
}
|
|
39
85
|
let sawSessionId = false;
|
|
86
|
+
let pending = "";
|
|
87
|
+
const captureSession = (text) => {
|
|
88
|
+
if (sawSessionId) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const sessionId = parseSessionId(text);
|
|
92
|
+
if (sessionId) {
|
|
93
|
+
sawSessionId = true;
|
|
94
|
+
setWorkerSession(db, worker.id, sessionId);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
40
97
|
proc.stdout.on("data", (chunk) => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
98
|
+
appendLog(dataDir, worker.id, chunk);
|
|
99
|
+
// Buffer across chunks: a JSON line split between two reads must still be
|
|
100
|
+
// parsed once, not dropped as two invalid halves. Cap host memory: a
|
|
101
|
+
// newline-free chatty stream would otherwise accumulate forever.
|
|
102
|
+
pending += chunk;
|
|
103
|
+
if (pending.length > PENDING_MAX_CHARS) {
|
|
104
|
+
pending = pending.slice(-PENDING_MAX_CHARS);
|
|
105
|
+
}
|
|
106
|
+
const lastBreak = pending.lastIndexOf("\n");
|
|
107
|
+
if (lastBreak === -1) {
|
|
108
|
+
return;
|
|
48
109
|
}
|
|
110
|
+
const complete = pending.slice(0, lastBreak);
|
|
111
|
+
pending = pending.slice(lastBreak + 1);
|
|
112
|
+
captureSession(complete);
|
|
113
|
+
});
|
|
114
|
+
// stderr is piped: someone must drain it or the child blocks once the pipe
|
|
115
|
+
// fills (~64 KB). Fold it into the same log so diagnostics survive.
|
|
116
|
+
proc.stderr.on("data", (chunk) => {
|
|
117
|
+
appendLog(dataDir, worker.id, chunk);
|
|
118
|
+
});
|
|
119
|
+
// A spawn failure (binary not on PATH) emits 'error' and never 'exit': without
|
|
120
|
+
// this the row stays 'running' forever and the live entry leaks.
|
|
121
|
+
proc.on("error", () => {
|
|
122
|
+
LIVE_PROCESSES.delete(worker.id);
|
|
123
|
+
clearPendingKill(worker.id);
|
|
124
|
+
finalize(db, worker.id, "failed", null);
|
|
49
125
|
});
|
|
50
126
|
proc.on("exit", (code) => {
|
|
51
127
|
LIVE_PROCESSES.delete(worker.id);
|
|
128
|
+
clearPendingKill(worker.id);
|
|
129
|
+
captureSession(pending);
|
|
130
|
+
// A deliberate stopWorker already recorded a terminal state; the OS-level
|
|
131
|
+
// exit event that follows must not fight it.
|
|
132
|
+
const current = getWorker(db, worker.id);
|
|
133
|
+
if (current === null || current.status !== "running") {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
52
136
|
setWorkerStatus(db, worker.id, code === 0 ? "completed" : "failed", { exit_code: code });
|
|
53
137
|
});
|
|
138
|
+
// A pid <= 0 means the child never spawned (a real ENOENT reports pid -1
|
|
139
|
+
// synchronously and delivers 'error' a tick later). Finalize now so the tool
|
|
140
|
+
// reports the failure; the later 'error' event finds a terminal row and is a
|
|
141
|
+
// no-op. Listeners stay attached so an unhandled 'error' cannot crash the host.
|
|
142
|
+
if (proc.pid <= 0) {
|
|
143
|
+
finalize(db, worker.id, "failed", null);
|
|
144
|
+
return { ...worker, status: "failed", finished_at: Date.now() };
|
|
145
|
+
}
|
|
54
146
|
LIVE_PROCESSES.set(worker.id, proc);
|
|
55
147
|
return worker;
|
|
56
148
|
}
|
|
57
|
-
// Stop a running worker. The default kill sends SIGTERM to the recorded pid
|
|
58
|
-
//
|
|
149
|
+
// Stop a running worker. The default kill sends SIGTERM to the recorded pid and
|
|
150
|
+
// escalates to SIGKILL after graceMs if the process ignores it; killFn is an
|
|
151
|
+
// injection seam for tests (and disables escalation).
|
|
59
152
|
export function stopWorker(db, id, options = {}) {
|
|
60
|
-
|
|
153
|
+
const proc = LIVE_PROCESSES.get(id);
|
|
154
|
+
if (proc === undefined) {
|
|
61
155
|
throw new Error(`worker ${id} is not running`);
|
|
62
156
|
}
|
|
63
157
|
const kill = options.killFn ?? defaultKill;
|
|
@@ -66,8 +160,37 @@ export function stopWorker(db, id, options = {}) {
|
|
|
66
160
|
// time to reap the process (or a test fake ignores the signal).
|
|
67
161
|
LIVE_PROCESSES.delete(id);
|
|
68
162
|
setWorkerStatus(db, id, "stopped", { exit_code: null });
|
|
163
|
+
const graceMs = options.graceMs ?? DEFAULT_KILL_GRACE_MS;
|
|
164
|
+
if (options.killFn === undefined && proc.pid > 0 && graceMs > 0) {
|
|
165
|
+
clearPendingKill(id);
|
|
166
|
+
const timer = setTimeout(() => {
|
|
167
|
+
PENDING_KILLS.delete(id);
|
|
168
|
+
try {
|
|
169
|
+
proc.kill("SIGKILL");
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Process group already gone.
|
|
173
|
+
}
|
|
174
|
+
}, graceMs);
|
|
175
|
+
timer.unref?.();
|
|
176
|
+
PENDING_KILLS.set(id, timer);
|
|
177
|
+
}
|
|
69
178
|
return true;
|
|
70
179
|
}
|
|
180
|
+
function clearPendingKill(id) {
|
|
181
|
+
const timer = PENDING_KILLS.get(id);
|
|
182
|
+
if (timer !== undefined) {
|
|
183
|
+
clearTimeout(timer);
|
|
184
|
+
PENDING_KILLS.delete(id);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function finalize(db, id, status, exitCode) {
|
|
188
|
+
const current = getWorker(db, id);
|
|
189
|
+
if (current === null || current.status !== "running") {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
setWorkerStatus(db, id, status, { exit_code: exitCode });
|
|
193
|
+
}
|
|
71
194
|
function defaultKill(id, signal) {
|
|
72
195
|
const proc = LIVE_PROCESSES.get(id);
|
|
73
196
|
proc?.kill(signal);
|
|
@@ -121,4 +244,70 @@ function parseSessionId(chunk) {
|
|
|
121
244
|
function logPath(dataDir, id) {
|
|
122
245
|
return join(dataDir, "workers", `${id}.log`);
|
|
123
246
|
}
|
|
247
|
+
// Bound one worker's log to ~LOG_MAX_BYTES: rotate to `.1` (overwritten) once it
|
|
248
|
+
// grows past the cap, so a chatty worker cannot fill the disk. The tail reader
|
|
249
|
+
// only ever needs the last LOG_WINDOW_BYTES anyway.
|
|
250
|
+
const LOG_MAX_BYTES = 512 * 1024;
|
|
251
|
+
function appendLog(dataDir, id, chunk) {
|
|
252
|
+
const path = logPath(dataDir, id);
|
|
253
|
+
try {
|
|
254
|
+
if (statSync(path).size > LOG_MAX_BYTES) {
|
|
255
|
+
renameSync(path, `${path}.1`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
// No log yet: nothing to rotate.
|
|
260
|
+
}
|
|
261
|
+
appendFileSync(path, chunk);
|
|
262
|
+
}
|
|
263
|
+
// Remove a worker's captured log, including the rotated generation.
|
|
264
|
+
export function removeWorkerLog(dataDir, id) {
|
|
265
|
+
const path = logPath(dataDir, id);
|
|
266
|
+
rmSync(path, { force: true });
|
|
267
|
+
rmSync(`${path}.1`, { force: true });
|
|
268
|
+
}
|
|
269
|
+
// Bounded tail read: a chatty worker can produce tens of MB, and the host's
|
|
270
|
+
// event loop must not pay for a full readFileSync on every mesh_worker_logs
|
|
271
|
+
// call. Reads at most LOG_WINDOW bytes from the end, then keeps the last
|
|
272
|
+
// `limit` complete lines.
|
|
273
|
+
const LOG_WINDOW_BYTES = 256 * 1024;
|
|
274
|
+
export function readLogTail(dataDir, id, limit) {
|
|
275
|
+
const count = Number.isFinite(limit) ? Math.max(0, Math.floor(limit)) : 50;
|
|
276
|
+
if (count === 0) {
|
|
277
|
+
return "";
|
|
278
|
+
}
|
|
279
|
+
let fd;
|
|
280
|
+
try {
|
|
281
|
+
fd = openSync(logPath(dataDir, id), "r");
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
return "";
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
const size = fstatSync(fd).size;
|
|
288
|
+
const start = Math.max(0, size - LOG_WINDOW_BYTES);
|
|
289
|
+
const chunk = Buffer.alloc(size - start);
|
|
290
|
+
// readSync may return a short count (pipes, signals): loop until filled.
|
|
291
|
+
let read = 0;
|
|
292
|
+
while (read < chunk.length) {
|
|
293
|
+
const n = readSync(fd, chunk, read, chunk.length - read, start + read);
|
|
294
|
+
if (n <= 0) {
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
read += n;
|
|
298
|
+
}
|
|
299
|
+
const lines = chunk.subarray(0, read).toString("utf8").split("\n");
|
|
300
|
+
if (lines.at(-1) === "") {
|
|
301
|
+
lines.pop();
|
|
302
|
+
}
|
|
303
|
+
if (start > 0 && lines.length > 0) {
|
|
304
|
+
// The window may begin mid-line: drop the partial line.
|
|
305
|
+
lines.shift();
|
|
306
|
+
}
|
|
307
|
+
return lines.slice(-count).join("\n");
|
|
308
|
+
}
|
|
309
|
+
finally {
|
|
310
|
+
closeSync(fd);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
124
313
|
//# sourceMappingURL=spawn.js.map
|
package/dist/lib/spawn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/lib/spawn.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/lib/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EACL,cAAc,EACd,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,MAAM,EACN,QAAQ,GACT,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EACL,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,eAAe,GAGhB,MAAM,cAAc,CAAC;AAgBtB,+EAA+E;AAC/E,sDAAsD;AACtD,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC;AAEtD,6EAA6E;AAC7E,qEAAqE;AACrE,MAAM,UAAU,SAAS,CAAC,IAAc,EAAE,GAA4B;IACpE,0EAA0E;IAC1E,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QAChD,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;QACjC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClE,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC5B,OAAO;QACL,GAAG;QACH,MAAM,EAAE;YACN,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;gBACvB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAChF,CAAC;SACF;QACD,MAAM,EAAE;YACN,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;gBACvB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAChF,CAAC;SACF;QACD,EAAE,EAAE,CAAC,CAAC,KAAuB,EAAE,QAA8B,EAAE,EAAE;YAC/D,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;gBACtB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,QAAkC,CAAC,CAAC;YACxD,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,QAAyC,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC,CAAyB;QAC1B,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE;YACf,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,SAAS,CAAmB,CAAC;YACpD,IAAI,QAAQ,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACH,kEAAkE;oBAClE,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;oBACxB,OAAO;gBACT,CAAC;gBAAC,MAAM,CAAC;oBACP,yDAAyD;gBAC3D,CAAC;YACH,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC;AAiBD,MAAM,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;AACzD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAyC,CAAC;AACvE,MAAM,qBAAqB,GAAG,IAAI,CAAC;AACnC,2EAA2E;AAC3E,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEpC,+EAA+E;AAC/E,MAAM,UAAU,SAAS,CAAC,EAAU,EAAE,OAAe,EAAE,KAAqB;IAC1E,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,8EAA8E;IAC9E,qEAAqE;IACrE,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,EAAE;QAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,EAAE,IAAI;KACV,CAAC,CAAC;IAEH,IAAI,IAAoB,CAAC;IACzB,IAAI,CAAC;QACH,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAClE,CAAC;IAED,yEAAyE;IACzE,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;QACjB,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;IACxB,CAAC;IAED,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;QAC5C,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,SAAS,EAAE,CAAC;YACd,YAAY,GAAG,IAAI,CAAC;YACpB,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAC/B,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACrC,0EAA0E;QAC1E,qEAAqE;QACrE,iEAAiE;QACjE,OAAO,IAAI,KAAK,CAAC;QACjB,IAAI,OAAO,CAAC,MAAM,GAAG,iBAAiB,EAAE,CAAC;YACvC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC7C,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QACvC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,2EAA2E;IAC3E,oEAAoE;IACpE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAC/B,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,+EAA+E;IAC/E,iEAAiE;IACjE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACpB,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACvB,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5B,cAAc,CAAC,OAAO,CAAC,CAAC;QACxB,0EAA0E;QAC1E,6CAA6C;QAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACrD,OAAO;QACT,CAAC;QACD,eAAe,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,yEAAyE;IACzE,6EAA6E;IAC7E,6EAA6E;IAC7E,gFAAgF;IAChF,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAClE,CAAC;IAED,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,6EAA6E;AAC7E,sDAAsD;AACtD,MAAM,UAAU,UAAU,CAAC,EAAU,EAAE,EAAU,EAAE,OAAO,GAAgB,EAAE;IAC1E,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC;IAC3C,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACpB,2EAA2E;IAC3E,gEAAgE;IAChE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1B,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,qBAAqB,CAAC;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChE,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACrB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACzB,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,8BAA8B;YAChC,CAAC;QACH,CAAC,EAAE,OAAO,CAAC,CAAC;QACZ,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAChB,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB,CAAC,EAAU;IAClC,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,EAAU,EAAE,EAAU,EAAE,MAAoB,EAAE,QAAuB;IACrF,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAClC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACrD,OAAO;IACT,CAAC;IACD,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,EAAU,EAAE,MAAc;IAC7C,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,yEAAyE;AACzE,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,EAAU,EAAE,OAAO,GAAgB,EAAE;IAClE,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,CAAC,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,SAAS,CAAC,KAAqB;IACtC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,aAAa,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACnF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,qEAAqE;IACrE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrD,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;YAC9D,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxE,OAAO,MAAM,CAAC,SAAS,CAAC;YAC1B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,8CAA8C;QAChD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,OAAO,CAAC,OAAe,EAAE,EAAU;IAC1C,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,iFAAiF;AACjF,+EAA+E;AAC/E,oDAAoD;AACpD,MAAM,aAAa,GAAG,GAAG,GAAG,IAAI,CAAC;AAEjC,SAAS,SAAS,CAAC,OAAe,EAAE,EAAU,EAAE,KAAa;IAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAClC,IAAI,CAAC;QACH,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,aAAa,EAAE,CAAC;YACxC,UAAU,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;IACD,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,EAAU;IACzD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAClC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,4EAA4E;AAC5E,4EAA4E;AAC5E,yEAAyE;AACzE,0BAA0B;AAC1B,MAAM,gBAAgB,GAAG,GAAG,GAAG,IAAI,CAAC;AAEpC,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,EAAU,EAAE,KAAa;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,EAAU,CAAC;IACf,IAAI,CAAC;QACH,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,gBAAgB,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QACzC,yEAAyE;QACzE,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,OAAO,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;YACvE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACX,MAAM;YACR,CAAC;YACD,IAAI,IAAI,CAAC,CAAC;QACZ,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;QACD,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,wDAAwD;YACxD,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;YAAS,CAAC;QACT,SAAS,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;AACH,CAAC"}
|
package/dist/lib/sqlite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/lib/sqlite.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IACvD,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC5D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/lib/sqlite.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IACvD,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC5D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;CACf;AA6FD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAmBnD"}
|
package/dist/lib/sqlite.js
CHANGED
|
@@ -47,6 +47,15 @@ try {
|
|
|
47
47
|
catch {
|
|
48
48
|
BunSqliteEngine = null;
|
|
49
49
|
}
|
|
50
|
+
let NodeSqliteEngine = null;
|
|
51
|
+
try {
|
|
52
|
+
NodeSqliteEngine =
|
|
53
|
+
(await import("node:sqlite")).default ??
|
|
54
|
+
(await import("node:sqlite"));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
NodeSqliteEngine = null;
|
|
58
|
+
}
|
|
50
59
|
export function openSqlite(path) {
|
|
51
60
|
const globalRuntime = globalThis;
|
|
52
61
|
if (globalRuntime.Bun?.sqlite?.Database) {
|
|
@@ -55,9 +64,11 @@ export function openSqlite(path) {
|
|
|
55
64
|
if (BunSqliteEngine) {
|
|
56
65
|
return createBunConn(new BunSqliteEngine.Database(path));
|
|
57
66
|
}
|
|
58
|
-
// node:sqlite ships with Node >= 22.5;
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
// node:sqlite ships with Node >= 22.5; a failed import leaves the engine
|
|
68
|
+
// null, so tests get a clear error instead of a hidden require() ReferenceError.
|
|
69
|
+
if (!NodeSqliteEngine) {
|
|
70
|
+
throw new Error("no sqlite engine available: expected bun:sqlite or node:sqlite");
|
|
71
|
+
}
|
|
72
|
+
return createPreparedConn(new NodeSqliteEngine.DatabaseSync(path));
|
|
62
73
|
}
|
|
63
74
|
//# sourceMappingURL=sqlite.js.map
|