@elpapi42/pi-fleet 0.1.0-beta.1 → 0.1.0-beta.2
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 +27 -0
- package/README.md +6 -3
- package/dist/cli-meta.json +8 -8
- package/dist/cli.mjs +137 -13
- package/dist/cli.mjs.map +3 -3
- package/dist/installer-meta.json +4 -4
- package/dist/installer.mjs +116 -11
- package/dist/installer.mjs.map +3 -3
- package/dist/runtime-manifest.json +24 -24
- package/dist/runtime-meta.json +12 -12
- package/dist/runtime.mjs +149 -46
- package/dist/runtime.mjs.map +2 -2
- package/dist/sqlite-worker-meta.json +4 -4
- package/dist/sqlite-worker.mjs +45 -38
- package/dist/sqlite-worker.mjs.map +2 -2
- package/package.json +4 -1
package/dist/runtime.mjs
CHANGED
|
@@ -64,7 +64,7 @@ var PiProcess = class _PiProcess {
|
|
|
64
64
|
#responses = /* @__PURE__ */ new Map();
|
|
65
65
|
#listeners = /* @__PURE__ */ new Set();
|
|
66
66
|
#exitListeners = /* @__PURE__ */ new Set();
|
|
67
|
-
#stdoutBuffer =
|
|
67
|
+
#stdoutBuffer = Buffer.alloc(0);
|
|
68
68
|
#stderr = "";
|
|
69
69
|
#stopping = false;
|
|
70
70
|
#maxStdoutFrameBytes;
|
|
@@ -80,7 +80,6 @@ var PiProcess = class _PiProcess {
|
|
|
80
80
|
stdio: ["pipe", "pipe", "pipe"]
|
|
81
81
|
}
|
|
82
82
|
);
|
|
83
|
-
this.#child.stdout.setEncoding("utf8");
|
|
84
83
|
this.#child.stderr.setEncoding("utf8");
|
|
85
84
|
this.#child.stdout.on("data", (chunk) => this.#consumeStdout(chunk));
|
|
86
85
|
this.#child.stderr.on("data", (chunk) => {
|
|
@@ -136,11 +135,20 @@ var PiProcess = class _PiProcess {
|
|
|
136
135
|
const response = new Promise((resolveResponse, rejectResponse) => {
|
|
137
136
|
const timer = setTimeout(() => {
|
|
138
137
|
this.#responses.delete(id);
|
|
139
|
-
rejectResponse(new Error(
|
|
138
|
+
rejectResponse(new Error("Pi RPC request timed out"));
|
|
140
139
|
}, timeoutMs);
|
|
141
140
|
this.#responses.set(id, { resolve: resolveResponse, reject: rejectResponse, timer });
|
|
142
141
|
});
|
|
143
|
-
|
|
142
|
+
try {
|
|
143
|
+
await this.#write({ ...command, id });
|
|
144
|
+
} catch (error) {
|
|
145
|
+
const waiter = this.#responses.get(id);
|
|
146
|
+
if (waiter !== void 0) {
|
|
147
|
+
clearTimeout(waiter.timer);
|
|
148
|
+
this.#responses.delete(id);
|
|
149
|
+
waiter.reject(error instanceof Error ? error : new Error("Pi RPC write failed"));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
144
152
|
const frame = await response;
|
|
145
153
|
if (frame.success !== true)
|
|
146
154
|
throw new Error(frame.error ?? `Pi rejected ${String(command.type)}`);
|
|
@@ -169,27 +177,29 @@ var PiProcess = class _PiProcess {
|
|
|
169
177
|
await once(this.#child.stdin, "drain");
|
|
170
178
|
}
|
|
171
179
|
#consumeStdout(chunk) {
|
|
172
|
-
this.#stdoutBuffer
|
|
180
|
+
this.#stdoutBuffer = Buffer.concat([this.#stdoutBuffer, chunk]);
|
|
173
181
|
while (true) {
|
|
174
|
-
const newline = this.#stdoutBuffer.indexOf(
|
|
182
|
+
const newline = this.#stdoutBuffer.indexOf(10);
|
|
175
183
|
if (newline < 0) {
|
|
176
|
-
if (
|
|
184
|
+
if (this.#stdoutBuffer.length > this.#maxStdoutFrameBytes) {
|
|
177
185
|
signalProcessTree(this.pid, "SIGTERM");
|
|
178
186
|
}
|
|
179
187
|
return;
|
|
180
188
|
}
|
|
181
|
-
if (
|
|
189
|
+
if (newline > this.#maxStdoutFrameBytes) {
|
|
182
190
|
signalProcessTree(this.pid, "SIGTERM");
|
|
183
191
|
return;
|
|
184
192
|
}
|
|
185
|
-
|
|
186
|
-
this.#stdoutBuffer = this.#stdoutBuffer.
|
|
187
|
-
if (
|
|
193
|
+
let lineBytes = this.#stdoutBuffer.subarray(0, newline);
|
|
194
|
+
this.#stdoutBuffer = this.#stdoutBuffer.subarray(newline + 1);
|
|
195
|
+
if (lineBytes.at(-1) === 13) lineBytes = lineBytes.subarray(0, -1);
|
|
196
|
+
if (lineBytes.length === 0) continue;
|
|
188
197
|
let frame;
|
|
189
198
|
try {
|
|
199
|
+
const line = new TextDecoder("utf-8", { fatal: true }).decode(lineBytes);
|
|
190
200
|
frame = JSON.parse(line);
|
|
191
201
|
} catch {
|
|
192
|
-
this
|
|
202
|
+
signalProcessTree(this.pid, "SIGTERM");
|
|
193
203
|
return;
|
|
194
204
|
}
|
|
195
205
|
if (frame.type === "extension_ui_request" && typeof frame.id === "string" && ["select", "confirm", "input", "editor"].includes(String(frame.method))) {
|
|
@@ -6533,12 +6543,12 @@ function handleConnection(socket, service, maxFrameBytes) {
|
|
|
6533
6543
|
stopReading();
|
|
6534
6544
|
void service.then((readyService) => dispatch(value, readyService, socket, abort.signal, maxFrameBytes)).catch((error) => {
|
|
6535
6545
|
if (socket.destroyed) return;
|
|
6536
|
-
const
|
|
6546
|
+
const invalidRequest = error instanceof InvalidRequestError;
|
|
6537
6547
|
writeJsonLine(socket, {
|
|
6538
6548
|
v: PROTOCOL_VERSION,
|
|
6539
6549
|
requestId: requestIdFrom(value),
|
|
6540
6550
|
ok: false,
|
|
6541
|
-
error: { code: "invalid_request", message }
|
|
6551
|
+
error: invalidRequest ? { code: "invalid_request", message: error.message } : { code: "internal_error", message: "Pi Fleet encountered an internal error." }
|
|
6542
6552
|
});
|
|
6543
6553
|
socket.end();
|
|
6544
6554
|
});
|
|
@@ -6556,7 +6566,14 @@ function handleConnection(socket, service, maxFrameBytes) {
|
|
|
6556
6566
|
);
|
|
6557
6567
|
}
|
|
6558
6568
|
async function dispatch(value, service, socket, connectionSignal, maxFrameBytes) {
|
|
6559
|
-
|
|
6569
|
+
let request;
|
|
6570
|
+
try {
|
|
6571
|
+
request = parseProtocolRequest(value);
|
|
6572
|
+
} catch (error) {
|
|
6573
|
+
throw new InvalidRequestError(
|
|
6574
|
+
error instanceof Error ? error.message : "Invalid protocol request"
|
|
6575
|
+
);
|
|
6576
|
+
}
|
|
6560
6577
|
const operationId = request.operation?.operationId;
|
|
6561
6578
|
let result;
|
|
6562
6579
|
switch (request.method) {
|
|
@@ -6616,7 +6633,7 @@ async function dispatch(value, service, socket, connectionSignal, maxFrameBytes)
|
|
|
6616
6633
|
});
|
|
6617
6634
|
socket.end();
|
|
6618
6635
|
}
|
|
6619
|
-
} catch
|
|
6636
|
+
} catch {
|
|
6620
6637
|
if (!socket.destroyed) {
|
|
6621
6638
|
writeJsonLine(socket, {
|
|
6622
6639
|
v: PROTOCOL_VERSION,
|
|
@@ -6624,7 +6641,7 @@ async function dispatch(value, service, socket, connectionSignal, maxFrameBytes)
|
|
|
6624
6641
|
stream: "error",
|
|
6625
6642
|
error: {
|
|
6626
6643
|
code: "session_changed",
|
|
6627
|
-
message:
|
|
6644
|
+
message: "Pi session changed while watching."
|
|
6628
6645
|
}
|
|
6629
6646
|
});
|
|
6630
6647
|
socket.end();
|
|
@@ -6648,10 +6665,10 @@ function asCreateInput(params) {
|
|
|
6648
6665
|
const instructions = params.instructions;
|
|
6649
6666
|
const piArgv = params.piArgv;
|
|
6650
6667
|
if (instructions !== void 0 && typeof instructions !== "string") {
|
|
6651
|
-
throw new
|
|
6668
|
+
throw new InvalidRequestError("instructions must be a string");
|
|
6652
6669
|
}
|
|
6653
6670
|
if (!Array.isArray(piArgv) || !piArgv.every((token) => typeof token === "string")) {
|
|
6654
|
-
throw new
|
|
6671
|
+
throw new InvalidRequestError("piArgv must be an array of strings");
|
|
6655
6672
|
}
|
|
6656
6673
|
return { name, cwd, piArgv, ...instructions === void 0 ? {} : { instructions } };
|
|
6657
6674
|
}
|
|
@@ -6663,13 +6680,17 @@ function asNamedInput(params) {
|
|
|
6663
6680
|
}
|
|
6664
6681
|
async function receiveWithTimeout(service, input, timeoutMs, connectionSignal) {
|
|
6665
6682
|
const abort = new AbortController();
|
|
6683
|
+
let timedOut = false;
|
|
6666
6684
|
const onConnectionAbort = () => abort.abort();
|
|
6667
6685
|
connectionSignal.addEventListener("abort", onConnectionAbort, { once: true });
|
|
6668
|
-
const timer = timeoutMs === void 0 ? void 0 : setTimeout(() =>
|
|
6686
|
+
const timer = timeoutMs === void 0 ? void 0 : setTimeout(() => {
|
|
6687
|
+
timedOut = true;
|
|
6688
|
+
abort.abort();
|
|
6689
|
+
}, timeoutMs);
|
|
6669
6690
|
try {
|
|
6670
6691
|
return await service.receive(input, abort.signal);
|
|
6671
6692
|
} catch (error) {
|
|
6672
|
-
if (
|
|
6693
|
+
if (timedOut) {
|
|
6673
6694
|
return err({ code: "timeout", message: "Agent did not become idle before timeout." });
|
|
6674
6695
|
}
|
|
6675
6696
|
throw error;
|
|
@@ -6682,19 +6703,23 @@ function numberParam(params, key) {
|
|
|
6682
6703
|
const value = params[key];
|
|
6683
6704
|
if (value === void 0) return void 0;
|
|
6684
6705
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
6685
|
-
throw new
|
|
6706
|
+
throw new InvalidRequestError(`${key} must be a non-negative number`);
|
|
6686
6707
|
}
|
|
6687
6708
|
return value;
|
|
6688
6709
|
}
|
|
6689
6710
|
function stringParam(params, key) {
|
|
6690
6711
|
const value = params[key];
|
|
6691
|
-
if (typeof value !== "string") throw new
|
|
6712
|
+
if (typeof value !== "string") throw new InvalidRequestError(`${key} must be a string`);
|
|
6692
6713
|
return value;
|
|
6693
6714
|
}
|
|
6694
6715
|
function requireOperation(operationId) {
|
|
6695
|
-
if (operationId === void 0)
|
|
6716
|
+
if (operationId === void 0)
|
|
6717
|
+
throw new InvalidRequestError("Mutation requires operation identity");
|
|
6696
6718
|
return operationId;
|
|
6697
6719
|
}
|
|
6720
|
+
var InvalidRequestError = class extends Error {
|
|
6721
|
+
name = "InvalidRequestError";
|
|
6722
|
+
};
|
|
6698
6723
|
function requestIdFrom(value) {
|
|
6699
6724
|
if (typeof value !== "object" || value === null || !("requestId" in value)) return "unknown";
|
|
6700
6725
|
return typeof value.requestId === "string" ? value.requestId : "unknown";
|
|
@@ -6918,16 +6943,17 @@ var AgentCoordinator = class {
|
|
|
6918
6943
|
this.now = now;
|
|
6919
6944
|
this.onProcessExit = onProcessExit;
|
|
6920
6945
|
this.#unsubscribeFrame = process2.onFrame((frame) => {
|
|
6921
|
-
if (frame.type === "agent_start")
|
|
6922
|
-
if (frame.type === "agent_settled")
|
|
6946
|
+
if (frame.type === "agent_start") this.#queueEvent(() => this.#markWorking());
|
|
6947
|
+
if (frame.type === "agent_settled") this.#queueEvent(() => this.#markIdle());
|
|
6923
6948
|
});
|
|
6924
6949
|
this.#unsubscribeExit = process2.onExit((error) => {
|
|
6925
|
-
|
|
6950
|
+
this.#queueEvent(() => this.#handleProcessExit(error));
|
|
6926
6951
|
});
|
|
6927
6952
|
}
|
|
6928
6953
|
#idleWaiters = /* @__PURE__ */ new Set();
|
|
6929
6954
|
#lane = Promise.resolve();
|
|
6930
6955
|
#stopReason = null;
|
|
6956
|
+
#handlingFailure = false;
|
|
6931
6957
|
#unsubscribeFrame;
|
|
6932
6958
|
#unsubscribeExit;
|
|
6933
6959
|
get storedAgent() {
|
|
@@ -7101,6 +7127,17 @@ var AgentCoordinator = class {
|
|
|
7101
7127
|
}
|
|
7102
7128
|
this.#idleWaiters.clear();
|
|
7103
7129
|
}
|
|
7130
|
+
#queueEvent(operation) {
|
|
7131
|
+
void this.#enqueue(operation).catch((error) => this.#handleEventFailure(error));
|
|
7132
|
+
}
|
|
7133
|
+
async #handleEventFailure(error) {
|
|
7134
|
+
if (this.#handlingFailure) return;
|
|
7135
|
+
this.#handlingFailure = true;
|
|
7136
|
+
const failure = error instanceof Error ? error : new Error("Agent coordinator failed");
|
|
7137
|
+
this.#rejectIdleWaiters(failure);
|
|
7138
|
+
await this.process.stop().catch(() => void 0);
|
|
7139
|
+
this.onProcessExit(failure);
|
|
7140
|
+
}
|
|
7104
7141
|
#enqueue(operation) {
|
|
7105
7142
|
const result = this.#lane.then(operation, operation);
|
|
7106
7143
|
this.#lane = result.then(
|
|
@@ -7253,6 +7290,7 @@ var FleetService = class {
|
|
|
7253
7290
|
#coordinators = /* @__PURE__ */ new Map();
|
|
7254
7291
|
#watchers = /* @__PURE__ */ new Map();
|
|
7255
7292
|
#processSlots = /* @__PURE__ */ new Set();
|
|
7293
|
+
#agentLanes = /* @__PURE__ */ new Map();
|
|
7256
7294
|
#sendLanes = /* @__PURE__ */ new Map();
|
|
7257
7295
|
#launcher;
|
|
7258
7296
|
#now;
|
|
@@ -7262,7 +7300,7 @@ var FleetService = class {
|
|
|
7262
7300
|
operationId,
|
|
7263
7301
|
"create",
|
|
7264
7302
|
input,
|
|
7265
|
-
() => this.#createImpl(input, operationId)
|
|
7303
|
+
() => this.#enqueueAgent(input.name, () => this.#createImpl(input, operationId))
|
|
7266
7304
|
);
|
|
7267
7305
|
}
|
|
7268
7306
|
async #createImpl(input, operationId) {
|
|
@@ -7462,14 +7500,19 @@ var FleetService = class {
|
|
|
7462
7500
|
const code = cleanupUncertain ? "incarnation_cleanup_uncertain" : deliveryAmbiguous ? "delivery_uncertain" : "pi_start_failed";
|
|
7463
7501
|
const result = err({
|
|
7464
7502
|
code,
|
|
7465
|
-
message:
|
|
7503
|
+
message: code === "delivery_uncertain" ? "Pi may have accepted the initial instructions; Fleet will not replay them automatically." : code === "incarnation_cleanup_uncertain" ? "Fleet could not prove the Pi process group was removed." : "Pi failed to start."
|
|
7466
7504
|
});
|
|
7467
7505
|
await this.#remember(operationId, "create", input, result);
|
|
7468
7506
|
return result;
|
|
7469
7507
|
}
|
|
7470
7508
|
}
|
|
7471
7509
|
send(input, operationId) {
|
|
7472
|
-
return this.#runOperation(
|
|
7510
|
+
return this.#runOperation(
|
|
7511
|
+
operationId,
|
|
7512
|
+
"send",
|
|
7513
|
+
input,
|
|
7514
|
+
() => this.#enqueueAgent(input.name, () => this.#sendImpl(input, operationId))
|
|
7515
|
+
);
|
|
7473
7516
|
}
|
|
7474
7517
|
async #sendImpl(input, operationId) {
|
|
7475
7518
|
const replay = await this.#operation(operationId, "send", input);
|
|
@@ -7569,7 +7612,22 @@ var FleetService = class {
|
|
|
7569
7612
|
}
|
|
7570
7613
|
async receive(input, signal) {
|
|
7571
7614
|
const coordinator = this.#coordinators.get(input.name);
|
|
7572
|
-
|
|
7615
|
+
let agent;
|
|
7616
|
+
try {
|
|
7617
|
+
agent = coordinator === void 0 ? await this.store.getAgent(input.name) : await coordinator.waitForIdle(signal);
|
|
7618
|
+
} catch (error) {
|
|
7619
|
+
if (signal?.aborted === true) throw error;
|
|
7620
|
+
if (error instanceof Error && error.message === "Agent destroyed") {
|
|
7621
|
+
return err({ code: "agent_destroyed", message: `Agent ${input.name} was destroyed.` });
|
|
7622
|
+
}
|
|
7623
|
+
if (error instanceof Error && error.message === "Pi work was interrupted") {
|
|
7624
|
+
return err({
|
|
7625
|
+
code: "runtime_interrupted",
|
|
7626
|
+
message: `Agent ${input.name} was interrupted before becoming idle.`
|
|
7627
|
+
});
|
|
7628
|
+
}
|
|
7629
|
+
throw error;
|
|
7630
|
+
}
|
|
7573
7631
|
if (agent === null) return this.#notFound(input.name);
|
|
7574
7632
|
if (agent.latestAssistantText === null || agent.responseObservedAt === null) {
|
|
7575
7633
|
return err({
|
|
@@ -7634,7 +7692,7 @@ var FleetService = class {
|
|
|
7634
7692
|
operationId,
|
|
7635
7693
|
"destroy",
|
|
7636
7694
|
input,
|
|
7637
|
-
() => this.#destroyImpl(input, operationId)
|
|
7695
|
+
() => this.#enqueueAgent(input.name, () => this.#destroyImpl(input, operationId))
|
|
7638
7696
|
);
|
|
7639
7697
|
}
|
|
7640
7698
|
async #destroyImpl(input, operationId) {
|
|
@@ -7781,7 +7839,7 @@ var FleetService = class {
|
|
|
7781
7839
|
agent: { id: agent.summary.id, name: agent.summary.name },
|
|
7782
7840
|
acceptedAt
|
|
7783
7841
|
});
|
|
7784
|
-
} catch
|
|
7842
|
+
} catch {
|
|
7785
7843
|
if (!this.#coordinators.has(input.name)) this.#releaseProcessSlot(input.name);
|
|
7786
7844
|
if (incarnationId !== null && !this.#coordinators.has(input.name)) {
|
|
7787
7845
|
await this.store.putIncarnation({
|
|
@@ -7801,7 +7859,7 @@ var FleetService = class {
|
|
|
7801
7859
|
});
|
|
7802
7860
|
return err({
|
|
7803
7861
|
code: "delivery_uncertain",
|
|
7804
|
-
message:
|
|
7862
|
+
message: "Pi may have accepted the message; Fleet will not replay it automatically."
|
|
7805
7863
|
});
|
|
7806
7864
|
}
|
|
7807
7865
|
}
|
|
@@ -7830,6 +7888,9 @@ var FleetService = class {
|
|
|
7830
7888
|
this.#coordinators.set(agent.summary.name, coordinator);
|
|
7831
7889
|
return coordinator;
|
|
7832
7890
|
}
|
|
7891
|
+
#enqueueAgent(name, operation) {
|
|
7892
|
+
return enqueueNamed(this.#agentLanes, name, operation);
|
|
7893
|
+
}
|
|
7833
7894
|
#enqueueSend(name, operation) {
|
|
7834
7895
|
const previous = this.#sendLanes.get(name) ?? Promise.resolve();
|
|
7835
7896
|
const result = previous.then(operation, operation);
|
|
@@ -7955,6 +8016,18 @@ var FleetService = class {
|
|
|
7955
8016
|
}
|
|
7956
8017
|
return null;
|
|
7957
8018
|
} else {
|
|
8019
|
+
const send = await this.store.getSend(operationId);
|
|
8020
|
+
if (send === null) {
|
|
8021
|
+
await this.store.deleteOperation(operationId);
|
|
8022
|
+
await this.store.putOperation({
|
|
8023
|
+
operationId,
|
|
8024
|
+
method,
|
|
8025
|
+
fingerprint,
|
|
8026
|
+
state: "pending",
|
|
8027
|
+
result: null
|
|
8028
|
+
});
|
|
8029
|
+
return null;
|
|
8030
|
+
}
|
|
7958
8031
|
return err({
|
|
7959
8032
|
code: "operation_in_progress",
|
|
7960
8033
|
message: `Operation ${operationId} is still pending.`
|
|
@@ -7998,6 +8071,19 @@ var FleetService = class {
|
|
|
7998
8071
|
});
|
|
7999
8072
|
}
|
|
8000
8073
|
};
|
|
8074
|
+
function enqueueNamed(lanes, name, operation) {
|
|
8075
|
+
const previous = lanes.get(name) ?? Promise.resolve();
|
|
8076
|
+
const result = previous.then(operation, operation);
|
|
8077
|
+
const settled = result.then(
|
|
8078
|
+
() => void 0,
|
|
8079
|
+
() => void 0
|
|
8080
|
+
);
|
|
8081
|
+
lanes.set(name, settled);
|
|
8082
|
+
void settled.finally(() => {
|
|
8083
|
+
if (lanes.get(name) === settled) lanes.delete(name);
|
|
8084
|
+
});
|
|
8085
|
+
return result;
|
|
8086
|
+
}
|
|
8001
8087
|
async function* watchWithCleanup(subscription, cleanup) {
|
|
8002
8088
|
try {
|
|
8003
8089
|
yield* subscription;
|
|
@@ -8013,19 +8099,24 @@ var WorkerFleetStore = class {
|
|
|
8013
8099
|
#worker;
|
|
8014
8100
|
#pending = /* @__PURE__ */ new Map();
|
|
8015
8101
|
#closed = false;
|
|
8102
|
+
#failure = null;
|
|
8016
8103
|
constructor(path, workerUrl = new URL("./sqlite-worker.mjs", import.meta.url)) {
|
|
8017
8104
|
this.#worker = new Worker(workerUrl, { workerData: { path } });
|
|
8018
|
-
this.#worker.on("message", (
|
|
8019
|
-
|
|
8105
|
+
this.#worker.on("message", (value) => {
|
|
8106
|
+
if (!isWorkerResponse(value)) {
|
|
8107
|
+
this.#fail(new Error("SQLite worker returned a malformed response"));
|
|
8108
|
+
void this.#worker.terminate();
|
|
8109
|
+
return;
|
|
8110
|
+
}
|
|
8111
|
+
const pending = this.#pending.get(value.id);
|
|
8020
8112
|
if (pending === void 0) return;
|
|
8021
|
-
this.#pending.delete(
|
|
8022
|
-
if (
|
|
8023
|
-
else pending.reject(new Error(
|
|
8113
|
+
this.#pending.delete(value.id);
|
|
8114
|
+
if (value.ok) pending.resolve(value.value);
|
|
8115
|
+
else pending.reject(new Error(value.error ?? "SQLite worker failed"));
|
|
8024
8116
|
});
|
|
8025
|
-
this.#worker.on("error", (error) => this.#
|
|
8117
|
+
this.#worker.on("error", (error) => this.#fail(error));
|
|
8026
8118
|
this.#worker.on("exit", (code) => {
|
|
8027
|
-
if (!this.#closed)
|
|
8028
|
-
this.#rejectAll(new Error(`SQLite worker exited unexpectedly with ${code}`));
|
|
8119
|
+
if (!this.#closed) this.#fail(new Error(`SQLite worker exited unexpectedly with ${code}`));
|
|
8029
8120
|
});
|
|
8030
8121
|
}
|
|
8031
8122
|
createAgent(agent) {
|
|
@@ -8075,12 +8166,13 @@ var WorkerFleetStore = class {
|
|
|
8075
8166
|
}
|
|
8076
8167
|
async close(cleanShutdown = true) {
|
|
8077
8168
|
if (this.#closed) return;
|
|
8078
|
-
await this.#call("close", [cleanShutdown]);
|
|
8169
|
+
if (this.#failure === null) await this.#call("close", [cleanShutdown]);
|
|
8079
8170
|
this.#closed = true;
|
|
8080
8171
|
await this.#worker.terminate();
|
|
8081
8172
|
}
|
|
8082
8173
|
#call(method, args) {
|
|
8083
8174
|
if (this.#closed) return Promise.reject(new Error("Fleet store is closed"));
|
|
8175
|
+
if (this.#failure !== null) return Promise.reject(this.#failure);
|
|
8084
8176
|
const id = randomUUID3();
|
|
8085
8177
|
const result = new Promise((resolveCall, rejectCall) => {
|
|
8086
8178
|
this.#pending.set(id, {
|
|
@@ -8088,14 +8180,25 @@ var WorkerFleetStore = class {
|
|
|
8088
8180
|
reject: rejectCall
|
|
8089
8181
|
});
|
|
8090
8182
|
});
|
|
8091
|
-
|
|
8183
|
+
try {
|
|
8184
|
+
this.#worker.postMessage({ id, method, args });
|
|
8185
|
+
} catch (error) {
|
|
8186
|
+
const failure = error instanceof Error ? error : new Error("SQLite worker request failed");
|
|
8187
|
+
this.#fail(failure);
|
|
8188
|
+
}
|
|
8092
8189
|
return result;
|
|
8093
8190
|
}
|
|
8094
|
-
#
|
|
8095
|
-
|
|
8191
|
+
#fail(error) {
|
|
8192
|
+
this.#failure ??= error;
|
|
8193
|
+
for (const pending of this.#pending.values()) pending.reject(this.#failure);
|
|
8096
8194
|
this.#pending.clear();
|
|
8097
8195
|
}
|
|
8098
8196
|
};
|
|
8197
|
+
function isWorkerResponse(value) {
|
|
8198
|
+
if (typeof value !== "object" || value === null) return false;
|
|
8199
|
+
const response = value;
|
|
8200
|
+
return typeof response.id === "string" && typeof response.ok === "boolean" && (response.error === void 0 || typeof response.error === "string");
|
|
8201
|
+
}
|
|
8099
8202
|
|
|
8100
8203
|
// src/entry/runtime.ts
|
|
8101
8204
|
async function runRuntime() {
|