@ricsam/r5d-worker 0.0.107 → 0.0.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/main.cjs +431 -145
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/plan-lint.cjs +165 -0
- package/dist/cjs/plan-parser.cjs +127 -0
- package/dist/cjs/plan-paths.cjs +53 -0
- package/dist/cjs/recovery-output-window.cjs +77 -0
- package/dist/cjs/recovery-protocol.cjs +31 -0
- package/dist/cjs/recovery-store.cjs +229 -0
- package/dist/cjs/supervisor.cjs +11 -4
- package/dist/mjs/main.mjs +433 -144
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/plan-lint.mjs +129 -0
- package/dist/mjs/plan-parser.mjs +94 -0
- package/dist/mjs/plan-paths.mjs +25 -0
- package/dist/mjs/recovery-output-window.mjs +53 -0
- package/dist/mjs/recovery-protocol.mjs +6 -0
- package/dist/mjs/recovery-store.mjs +194 -0
- package/dist/mjs/supervisor.mjs +10 -4
- package/dist/types/main.d.ts +49 -3
- package/dist/types/plan-lint.d.ts +16 -0
- package/dist/types/plan-parser.d.ts +38 -0
- package/dist/types/plan-paths.d.ts +36 -0
- package/dist/types/recovery-output-window.d.ts +19 -0
- package/dist/types/recovery-protocol.d.ts +59 -0
- package/dist/types/recovery-store.d.ts +38 -0
- package/dist/types/supervisor.d.ts +2 -1
- package/package.json +3 -2
package/dist/cjs/package.json
CHANGED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var plan_lint_exports = {};
|
|
30
|
+
__export(plan_lint_exports, {
|
|
31
|
+
formatPlanLintErrors: () => formatPlanLintErrors,
|
|
32
|
+
lintPlanContent: () => lintPlanContent,
|
|
33
|
+
lintPlans: () => lintPlans
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(plan_lint_exports);
|
|
36
|
+
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
37
|
+
var import_node_path = __toESM(require("node:path"), 1);
|
|
38
|
+
var import_picomatch = __toESM(require("picomatch"), 1);
|
|
39
|
+
var import_plan_parser = require("./plan-parser.cjs");
|
|
40
|
+
var import_plan_paths = require("./plan-paths.cjs");
|
|
41
|
+
var import_plan_parser2 = require("./plan-parser.cjs");
|
|
42
|
+
const LEGACY_SCHEMA_FIELD_REGEX = /^\s*(type|status|parent|phase|discovered_problem)\s*:/m;
|
|
43
|
+
function lintPlanContent(planId, content) {
|
|
44
|
+
const errors = [];
|
|
45
|
+
const lines = content.split(/\r?\n/);
|
|
46
|
+
if (/^---(?:\r?\n|$)/.test(content)) {
|
|
47
|
+
errors.push({
|
|
48
|
+
planId,
|
|
49
|
+
severity: "error",
|
|
50
|
+
message: "YAML frontmatter is not supported. Use plain Markdown with a ## Tasks checklist.",
|
|
51
|
+
line: 1
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (LEGACY_SCHEMA_FIELD_REGEX.test(content)) {
|
|
55
|
+
errors.push({
|
|
56
|
+
planId,
|
|
57
|
+
severity: "error",
|
|
58
|
+
message: "Legacy plan schema fields are not supported. Remove type/status/parent/phase/discovered_problem metadata."
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const titleLineIndex = lines.findIndex((line) => /^# .+\S\s*$/.test(line));
|
|
62
|
+
if (titleLineIndex === -1) {
|
|
63
|
+
errors.push({
|
|
64
|
+
planId,
|
|
65
|
+
severity: "error",
|
|
66
|
+
message: "Plan must start with or contain an H1 title, for example '# Implementation Plan'."
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const range = (0, import_plan_parser.getTasksSectionRange)(content);
|
|
70
|
+
if (!range) {
|
|
71
|
+
errors.push({
|
|
72
|
+
planId,
|
|
73
|
+
severity: "error",
|
|
74
|
+
message: "Plan is missing a ## Tasks section."
|
|
75
|
+
});
|
|
76
|
+
return errors;
|
|
77
|
+
}
|
|
78
|
+
const taskIds = /* @__PURE__ */ new Set();
|
|
79
|
+
let taskCount = 0;
|
|
80
|
+
for (let index = range.startIndex + 1; index < range.endIndex; index += 1) {
|
|
81
|
+
const line = lines[index] ?? "";
|
|
82
|
+
if (line.trim() === "") continue;
|
|
83
|
+
const match = line.match(import_plan_parser.PLAN_TASK_LINE_REGEX);
|
|
84
|
+
if (!match || !match[3].trim()) {
|
|
85
|
+
errors.push({
|
|
86
|
+
planId,
|
|
87
|
+
severity: "error",
|
|
88
|
+
line: index + 1,
|
|
89
|
+
message: 'Malformed task line. Use "- [ ] task-id: Description" or "- [x] task-id: Description".'
|
|
90
|
+
});
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
taskCount += 1;
|
|
94
|
+
const taskId = match[2];
|
|
95
|
+
if (taskIds.has(taskId)) {
|
|
96
|
+
errors.push({
|
|
97
|
+
planId,
|
|
98
|
+
severity: "error",
|
|
99
|
+
line: index + 1,
|
|
100
|
+
message: `Duplicate task id "${taskId}".`
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
taskIds.add(taskId);
|
|
104
|
+
}
|
|
105
|
+
if (taskCount === 0) {
|
|
106
|
+
errors.push({
|
|
107
|
+
planId,
|
|
108
|
+
severity: "error",
|
|
109
|
+
message: "Plan must include at least one task in the ## Tasks section.",
|
|
110
|
+
line: range.startIndex + 1
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return errors;
|
|
114
|
+
}
|
|
115
|
+
async function lintPlans(plansDir, glob) {
|
|
116
|
+
const errors = [];
|
|
117
|
+
let entries;
|
|
118
|
+
try {
|
|
119
|
+
entries = await import_promises.default.readdir(plansDir, { withFileTypes: true });
|
|
120
|
+
} catch (error) {
|
|
121
|
+
if (error.code !== "ENOENT") throw error;
|
|
122
|
+
entries = [];
|
|
123
|
+
}
|
|
124
|
+
const matches = glob ? (0, import_picomatch.default)(glob) : null;
|
|
125
|
+
let lintedPlanCount = 0;
|
|
126
|
+
for (const entry of entries) {
|
|
127
|
+
if (!entry.isFile() || !entry.name.endsWith(import_plan_paths.PLAN_EXTENSION)) continue;
|
|
128
|
+
const planId = entry.name.slice(0, -import_plan_paths.PLAN_EXTENSION.length);
|
|
129
|
+
if (!import_plan_parser2.PLAN_TASK_ID_REGEX.test(planId) || matches && !matches(entry.name) && !matches(planId)) continue;
|
|
130
|
+
const content = await import_promises.default.readFile(import_node_path.default.join(plansDir, entry.name), "utf8");
|
|
131
|
+
lintedPlanCount += 1;
|
|
132
|
+
errors.push(...lintPlanContent(planId, content));
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
type: "plan_lint",
|
|
136
|
+
errors,
|
|
137
|
+
errorCount: errors.filter((error) => error.severity === "error").length,
|
|
138
|
+
warningCount: errors.filter((error) => error.severity === "warning").length,
|
|
139
|
+
lintedPlanCount
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function formatPlanLintErrors(errors) {
|
|
143
|
+
if (errors.length === 0) return "";
|
|
144
|
+
const lines = ["## Plan Lint Errors", ""];
|
|
145
|
+
const byPlan = /* @__PURE__ */ new Map();
|
|
146
|
+
for (const error of errors) {
|
|
147
|
+
byPlan.set(error.planId, [...byPlan.get(error.planId) ?? [], error]);
|
|
148
|
+
}
|
|
149
|
+
for (const [planId, planErrors] of byPlan) {
|
|
150
|
+
lines.push(`### ${planId}.plan.md`);
|
|
151
|
+
for (const error of planErrors) {
|
|
152
|
+
const location = error.line ? ` line ${error.line}` : "";
|
|
153
|
+
lines.push(`- ${error.severity.toUpperCase()}${location}: ${error.message}`);
|
|
154
|
+
}
|
|
155
|
+
lines.push("");
|
|
156
|
+
}
|
|
157
|
+
lines.push("Fix these issues by editing the Markdown plan file.");
|
|
158
|
+
return lines.join("\n");
|
|
159
|
+
}
|
|
160
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
161
|
+
0 && (module.exports = {
|
|
162
|
+
formatPlanLintErrors,
|
|
163
|
+
lintPlanContent,
|
|
164
|
+
lintPlans
|
|
165
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var plan_parser_exports = {};
|
|
20
|
+
__export(plan_parser_exports, {
|
|
21
|
+
PLAN_TASKS_HEADING_REGEX: () => PLAN_TASKS_HEADING_REGEX,
|
|
22
|
+
PLAN_TASK_ID_REGEX: () => PLAN_TASK_ID_REGEX,
|
|
23
|
+
PLAN_TASK_LINE_REGEX: () => PLAN_TASK_LINE_REGEX,
|
|
24
|
+
createPlanMarkdown: () => createPlanMarkdown,
|
|
25
|
+
formatPlanTitle: () => formatPlanTitle,
|
|
26
|
+
getPlanMetadata: () => getPlanMetadata,
|
|
27
|
+
getTasksSectionRange: () => getTasksSectionRange,
|
|
28
|
+
parseMarkdownPlan: () => parseMarkdownPlan,
|
|
29
|
+
parsePlan: () => parsePlan,
|
|
30
|
+
updateTaskCheckbox: () => updateTaskCheckbox
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(plan_parser_exports);
|
|
33
|
+
const PLAN_TASK_ID_REGEX = /^[a-z0-9][a-z0-9-]*$/;
|
|
34
|
+
const PLAN_TASK_LINE_REGEX = /^- \[( |x)\] ([a-z0-9][a-z0-9-]*): (.+)$/;
|
|
35
|
+
const PLAN_TASKS_HEADING_REGEX = /^## Tasks\s*$/;
|
|
36
|
+
function getPlanMetadata(content) {
|
|
37
|
+
const title = content.split(/\r?\n/).map((line) => line.match(/^# (.+)$/)?.[1]?.trim()).find((value) => Boolean(value));
|
|
38
|
+
return { title: title || "Untitled Plan" };
|
|
39
|
+
}
|
|
40
|
+
function getTasksSectionRange(content) {
|
|
41
|
+
const lines = content.split(/\r?\n/);
|
|
42
|
+
const startIndex = lines.findIndex((line) => PLAN_TASKS_HEADING_REGEX.test(line));
|
|
43
|
+
if (startIndex === -1) return null;
|
|
44
|
+
let endIndex = lines.length;
|
|
45
|
+
for (let index = startIndex + 1; index < lines.length; index += 1) {
|
|
46
|
+
if (/^##\s+/.test(lines[index] ?? "")) {
|
|
47
|
+
endIndex = index;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { startIndex, endIndex };
|
|
52
|
+
}
|
|
53
|
+
function parseMarkdownPlan(content, planId) {
|
|
54
|
+
const lines = content.split(/\r?\n/);
|
|
55
|
+
const { title } = getPlanMetadata(content);
|
|
56
|
+
const range = getTasksSectionRange(content);
|
|
57
|
+
const tasks = [];
|
|
58
|
+
if (range) {
|
|
59
|
+
for (let index = range.startIndex + 1; index < range.endIndex; index += 1) {
|
|
60
|
+
const line = lines[index] ?? "";
|
|
61
|
+
const match = line.match(PLAN_TASK_LINE_REGEX);
|
|
62
|
+
if (!match) continue;
|
|
63
|
+
const description = match[3].trim();
|
|
64
|
+
if (!description) continue;
|
|
65
|
+
tasks.push({
|
|
66
|
+
id: match[2],
|
|
67
|
+
description,
|
|
68
|
+
checked: match[1] === "x",
|
|
69
|
+
lineNumber: index + 1
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const currentTask = tasks.find((task) => !task.checked) ?? null;
|
|
74
|
+
return {
|
|
75
|
+
id: planId,
|
|
76
|
+
title,
|
|
77
|
+
content,
|
|
78
|
+
tasks,
|
|
79
|
+
currentTask,
|
|
80
|
+
complete: tasks.length > 0 && tasks.every((task) => task.checked),
|
|
81
|
+
tasksStartLine: range ? range.startIndex + 1 : null,
|
|
82
|
+
tasksEndLine: range ? range.endIndex : null
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const parsePlan = parseMarkdownPlan;
|
|
86
|
+
function createPlanMarkdown(planId, title = formatPlanTitle(planId)) {
|
|
87
|
+
return `# ${title}
|
|
88
|
+
|
|
89
|
+
Brief implementation notes.
|
|
90
|
+
|
|
91
|
+
## Tasks
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
function updateTaskCheckbox(content, taskId, checked) {
|
|
95
|
+
if (!PLAN_TASK_ID_REGEX.test(taskId)) {
|
|
96
|
+
throw new Error(`Invalid task id: ${taskId}`);
|
|
97
|
+
}
|
|
98
|
+
const lines = content.split(/\r?\n/);
|
|
99
|
+
const range = getTasksSectionRange(content);
|
|
100
|
+
if (!range) {
|
|
101
|
+
throw new Error("Plan is missing a ## Tasks section.");
|
|
102
|
+
}
|
|
103
|
+
for (let index = range.startIndex + 1; index < range.endIndex; index += 1) {
|
|
104
|
+
const line = lines[index] ?? "";
|
|
105
|
+
const match = line.match(PLAN_TASK_LINE_REGEX);
|
|
106
|
+
if (!match || match[2] !== taskId) continue;
|
|
107
|
+
lines[index] = `- [${checked ? "x" : " "}] ${match[2]}: ${match[3].trim()}`;
|
|
108
|
+
return lines.join("\n");
|
|
109
|
+
}
|
|
110
|
+
throw new Error(`Task not found in plan: ${taskId}`);
|
|
111
|
+
}
|
|
112
|
+
function formatPlanTitle(planId) {
|
|
113
|
+
return planId.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
114
|
+
}
|
|
115
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
116
|
+
0 && (module.exports = {
|
|
117
|
+
PLAN_TASKS_HEADING_REGEX,
|
|
118
|
+
PLAN_TASK_ID_REGEX,
|
|
119
|
+
PLAN_TASK_LINE_REGEX,
|
|
120
|
+
createPlanMarkdown,
|
|
121
|
+
formatPlanTitle,
|
|
122
|
+
getPlanMetadata,
|
|
123
|
+
getTasksSectionRange,
|
|
124
|
+
parseMarkdownPlan,
|
|
125
|
+
parsePlan,
|
|
126
|
+
updateTaskCheckbox
|
|
127
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var plan_paths_exports = {};
|
|
20
|
+
__export(plan_paths_exports, {
|
|
21
|
+
PLAN_EXTENSION: () => PLAN_EXTENSION,
|
|
22
|
+
assertPlanTarget: () => assertPlanTarget,
|
|
23
|
+
getWorkerPlanPath: () => getWorkerPlanPath,
|
|
24
|
+
getWorkerPlansPath: () => getWorkerPlansPath,
|
|
25
|
+
validatePlanId: () => validatePlanId
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(plan_paths_exports);
|
|
28
|
+
var import_plan_parser = require("./plan-parser.cjs");
|
|
29
|
+
const PLAN_EXTENSION = ".plan.md";
|
|
30
|
+
function validatePlanId(planId) {
|
|
31
|
+
if (!import_plan_parser.PLAN_TASK_ID_REGEX.test(planId)) throw new Error(`Invalid plan id: ${planId}`);
|
|
32
|
+
}
|
|
33
|
+
function assertPlanTarget(target) {
|
|
34
|
+
if (target.type === "workspace" && target.rootProfile !== "visible_projects") {
|
|
35
|
+
throw new Error("Ordinary plans are unavailable in canonical synchronization sessions");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function getWorkerPlansPath(target) {
|
|
39
|
+
assertPlanTarget(target);
|
|
40
|
+
return target.type === "project" ? "$R5D_ROOT/plans/$R5D_PROJECT_ID/$R5D_BRANCH_NAME" : "$R5D_ROOT/plans/workspace";
|
|
41
|
+
}
|
|
42
|
+
function getWorkerPlanPath(target, planId) {
|
|
43
|
+
validatePlanId(planId);
|
|
44
|
+
return `${getWorkerPlansPath(target)}/${planId}${PLAN_EXTENSION}`;
|
|
45
|
+
}
|
|
46
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
47
|
+
0 && (module.exports = {
|
|
48
|
+
PLAN_EXTENSION,
|
|
49
|
+
assertPlanTarget,
|
|
50
|
+
getWorkerPlanPath,
|
|
51
|
+
getWorkerPlansPath,
|
|
52
|
+
validatePlanId
|
|
53
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var recovery_output_window_exports = {};
|
|
20
|
+
__export(recovery_output_window_exports, {
|
|
21
|
+
WorkerOutputWindow: () => WorkerOutputWindow
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(recovery_output_window_exports);
|
|
24
|
+
const keyOf = (runId, stream) => `${runId}:${stream}`;
|
|
25
|
+
class WorkerOutputWindow {
|
|
26
|
+
constructor(windowBytes = 1024 * 1024) {
|
|
27
|
+
this.windowBytes = windowBytes;
|
|
28
|
+
}
|
|
29
|
+
windowBytes;
|
|
30
|
+
sent = /* @__PURE__ */ new Map();
|
|
31
|
+
acknowledged = /* @__PURE__ */ new Map();
|
|
32
|
+
outstanding = 0;
|
|
33
|
+
reset(cursors) {
|
|
34
|
+
this.sent.clear();
|
|
35
|
+
this.acknowledged.clear();
|
|
36
|
+
this.outstanding = 0;
|
|
37
|
+
for (const cursor of cursors) {
|
|
38
|
+
for (const stream of ["stdout", "stderr"]) {
|
|
39
|
+
const offset = stream === "stdout" ? cursor.stdoutBytes : cursor.stderrBytes;
|
|
40
|
+
this.sent.set(keyOf(cursor.runId, stream), offset);
|
|
41
|
+
this.acknowledged.set(keyOf(cursor.runId, stream), offset);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
send(frame, send, bufferedAmount = 0) {
|
|
46
|
+
const key = keyOf(frame.runId, frame.stream);
|
|
47
|
+
const sent = this.sent.get(key) ?? 0;
|
|
48
|
+
const bytes = Buffer.from(frame.data, "utf8");
|
|
49
|
+
const end = frame.offset + bytes.length;
|
|
50
|
+
if (end <= sent) return true;
|
|
51
|
+
if (frame.offset > sent) return false;
|
|
52
|
+
let cursor = sent;
|
|
53
|
+
while (cursor < end) {
|
|
54
|
+
let count = Math.min(end - cursor, 64 * 1024, this.windowBytes - this.outstanding);
|
|
55
|
+
while (count > 0 && ((bytes[cursor - frame.offset + count] ?? 0) & 192) === 128) count -= 1;
|
|
56
|
+
if (count <= 0 || bufferedAmount >= this.windowBytes) return false;
|
|
57
|
+
const data = bytes.subarray(cursor - frame.offset, cursor - frame.offset + count).toString("utf8");
|
|
58
|
+
if (!send({ ...frame, offset: cursor, data })) return false;
|
|
59
|
+
cursor += count;
|
|
60
|
+
this.sent.set(key, cursor);
|
|
61
|
+
this.outstanding += count;
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
acknowledge(runId, stream, offset) {
|
|
66
|
+
if (!Number.isSafeInteger(offset) || offset < 0) return;
|
|
67
|
+
const key = keyOf(runId, stream);
|
|
68
|
+
const previous = this.acknowledged.get(key) ?? 0;
|
|
69
|
+
const next = Math.max(previous, Math.min(this.sent.get(key) ?? 0, offset));
|
|
70
|
+
this.acknowledged.set(key, next);
|
|
71
|
+
this.outstanding = Math.max(0, this.outstanding - (next - previous));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
75
|
+
0 && (module.exports = {
|
|
76
|
+
WorkerOutputWindow
|
|
77
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var recovery_protocol_exports = {};
|
|
20
|
+
__export(recovery_protocol_exports, {
|
|
21
|
+
WORKER_RECOVERY_TIMEOUT_MS: () => WORKER_RECOVERY_TIMEOUT_MS,
|
|
22
|
+
WORKER_RESUMABLE_PROTOCOL: () => WORKER_RESUMABLE_PROTOCOL
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(recovery_protocol_exports);
|
|
25
|
+
const WORKER_RESUMABLE_PROTOCOL = 1;
|
|
26
|
+
const WORKER_RECOVERY_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
27
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
28
|
+
0 && (module.exports = {
|
|
29
|
+
WORKER_RECOVERY_TIMEOUT_MS,
|
|
30
|
+
WORKER_RESUMABLE_PROTOCOL
|
|
31
|
+
});
|