lopata 0.0.1
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 +15 -0
- package/package.json +51 -0
- package/runtime/bindings/ai.ts +132 -0
- package/runtime/bindings/analytics-engine.ts +96 -0
- package/runtime/bindings/browser.ts +64 -0
- package/runtime/bindings/cache.ts +179 -0
- package/runtime/bindings/cf-streams.ts +56 -0
- package/runtime/bindings/container-docker.ts +225 -0
- package/runtime/bindings/container.ts +662 -0
- package/runtime/bindings/crypto-extras.ts +89 -0
- package/runtime/bindings/d1.ts +315 -0
- package/runtime/bindings/do-executor-inprocess.ts +140 -0
- package/runtime/bindings/do-executor-worker.ts +368 -0
- package/runtime/bindings/do-executor.ts +45 -0
- package/runtime/bindings/do-websocket-bridge.ts +70 -0
- package/runtime/bindings/do-worker-entry.ts +220 -0
- package/runtime/bindings/do-worker-env.ts +74 -0
- package/runtime/bindings/durable-object.ts +992 -0
- package/runtime/bindings/email.ts +180 -0
- package/runtime/bindings/html-rewriter.ts +84 -0
- package/runtime/bindings/hyperdrive.ts +130 -0
- package/runtime/bindings/images.ts +381 -0
- package/runtime/bindings/kv.ts +359 -0
- package/runtime/bindings/queue.ts +507 -0
- package/runtime/bindings/r2.ts +759 -0
- package/runtime/bindings/rpc-stub.ts +267 -0
- package/runtime/bindings/scheduled.ts +172 -0
- package/runtime/bindings/service-binding.ts +217 -0
- package/runtime/bindings/static-assets.ts +481 -0
- package/runtime/bindings/websocket-pair.ts +182 -0
- package/runtime/bindings/workflow.ts +858 -0
- package/runtime/bunflare-config.ts +56 -0
- package/runtime/cli/cache.ts +39 -0
- package/runtime/cli/context.ts +105 -0
- package/runtime/cli/d1.ts +163 -0
- package/runtime/cli/dev.ts +392 -0
- package/runtime/cli/kv.ts +84 -0
- package/runtime/cli/queues.ts +109 -0
- package/runtime/cli/r2.ts +140 -0
- package/runtime/cli/traces.ts +251 -0
- package/runtime/cli.ts +102 -0
- package/runtime/config.ts +148 -0
- package/runtime/d1-migrate.ts +37 -0
- package/runtime/dashboard/api.ts +174 -0
- package/runtime/dashboard/app.tsx +220 -0
- package/runtime/dashboard/components/breadcrumb.tsx +16 -0
- package/runtime/dashboard/components/buttons.tsx +13 -0
- package/runtime/dashboard/components/code-block.tsx +5 -0
- package/runtime/dashboard/components/detail-field.tsx +8 -0
- package/runtime/dashboard/components/empty-state.tsx +8 -0
- package/runtime/dashboard/components/filter-input.tsx +11 -0
- package/runtime/dashboard/components/index.ts +16 -0
- package/runtime/dashboard/components/key-value-table.tsx +23 -0
- package/runtime/dashboard/components/modal.tsx +23 -0
- package/runtime/dashboard/components/page-header.tsx +11 -0
- package/runtime/dashboard/components/pill-button.tsx +14 -0
- package/runtime/dashboard/components/refresh-button.tsx +7 -0
- package/runtime/dashboard/components/service-info.tsx +45 -0
- package/runtime/dashboard/components/status-badge.tsx +7 -0
- package/runtime/dashboard/components/table-link.tsx +5 -0
- package/runtime/dashboard/components/table.tsx +26 -0
- package/runtime/dashboard/components.tsx +19 -0
- package/runtime/dashboard/index.html +23 -0
- package/runtime/dashboard/lib.ts +45 -0
- package/runtime/dashboard/rpc/client.ts +20 -0
- package/runtime/dashboard/rpc/handlers/ai.ts +71 -0
- package/runtime/dashboard/rpc/handlers/analytics-engine.ts +53 -0
- package/runtime/dashboard/rpc/handlers/cache.ts +24 -0
- package/runtime/dashboard/rpc/handlers/config.ts +137 -0
- package/runtime/dashboard/rpc/handlers/containers.ts +194 -0
- package/runtime/dashboard/rpc/handlers/d1.ts +84 -0
- package/runtime/dashboard/rpc/handlers/do.ts +117 -0
- package/runtime/dashboard/rpc/handlers/email.ts +82 -0
- package/runtime/dashboard/rpc/handlers/errors.ts +32 -0
- package/runtime/dashboard/rpc/handlers/generations.ts +60 -0
- package/runtime/dashboard/rpc/handlers/kv.ts +76 -0
- package/runtime/dashboard/rpc/handlers/overview.ts +94 -0
- package/runtime/dashboard/rpc/handlers/queue.ts +79 -0
- package/runtime/dashboard/rpc/handlers/r2.ts +72 -0
- package/runtime/dashboard/rpc/handlers/scheduled.ts +91 -0
- package/runtime/dashboard/rpc/handlers/traces.ts +64 -0
- package/runtime/dashboard/rpc/handlers/workers.ts +65 -0
- package/runtime/dashboard/rpc/handlers/workflows.ts +171 -0
- package/runtime/dashboard/rpc/hooks.ts +132 -0
- package/runtime/dashboard/rpc/server.ts +70 -0
- package/runtime/dashboard/rpc/types.ts +396 -0
- package/runtime/dashboard/sql-browser/data-browser-tab.tsx +122 -0
- package/runtime/dashboard/sql-browser/editable-cell.tsx +117 -0
- package/runtime/dashboard/sql-browser/filter-row.tsx +99 -0
- package/runtime/dashboard/sql-browser/history-panels.tsx +110 -0
- package/runtime/dashboard/sql-browser/hooks.ts +137 -0
- package/runtime/dashboard/sql-browser/index.ts +4 -0
- package/runtime/dashboard/sql-browser/insert-row-form.tsx +85 -0
- package/runtime/dashboard/sql-browser/modals.tsx +116 -0
- package/runtime/dashboard/sql-browser/schema-browser-tab.tsx +67 -0
- package/runtime/dashboard/sql-browser/sql-browser.tsx +52 -0
- package/runtime/dashboard/sql-browser/sql-console-tab.tsx +124 -0
- package/runtime/dashboard/sql-browser/table-data-view.tsx +566 -0
- package/runtime/dashboard/sql-browser/table-sidebar.tsx +38 -0
- package/runtime/dashboard/sql-browser/types.ts +61 -0
- package/runtime/dashboard/sql-browser/utils.ts +167 -0
- package/runtime/dashboard/style.css +177 -0
- package/runtime/dashboard/views/ai.tsx +152 -0
- package/runtime/dashboard/views/analytics-engine.tsx +169 -0
- package/runtime/dashboard/views/cache.tsx +93 -0
- package/runtime/dashboard/views/containers.tsx +197 -0
- package/runtime/dashboard/views/d1.tsx +81 -0
- package/runtime/dashboard/views/do.tsx +168 -0
- package/runtime/dashboard/views/email.tsx +235 -0
- package/runtime/dashboard/views/errors.tsx +558 -0
- package/runtime/dashboard/views/home.tsx +287 -0
- package/runtime/dashboard/views/kv.tsx +273 -0
- package/runtime/dashboard/views/queue.tsx +193 -0
- package/runtime/dashboard/views/r2.tsx +202 -0
- package/runtime/dashboard/views/scheduled.tsx +89 -0
- package/runtime/dashboard/views/trace-waterfall.tsx +410 -0
- package/runtime/dashboard/views/traces.tsx +768 -0
- package/runtime/dashboard/views/workers.tsx +55 -0
- package/runtime/dashboard/views/workflows.tsx +473 -0
- package/runtime/db.ts +258 -0
- package/runtime/env.ts +362 -0
- package/runtime/error-page/app.tsx +394 -0
- package/runtime/error-page/build.ts +269 -0
- package/runtime/error-page/index.html +16 -0
- package/runtime/error-page/style.css +31 -0
- package/runtime/execution-context.ts +18 -0
- package/runtime/file-watcher.ts +57 -0
- package/runtime/generation-manager.ts +230 -0
- package/runtime/generation.ts +411 -0
- package/runtime/plugin.ts +292 -0
- package/runtime/request-cf.ts +28 -0
- package/runtime/rpc-validate.ts +154 -0
- package/runtime/tracing/context.ts +40 -0
- package/runtime/tracing/db.ts +73 -0
- package/runtime/tracing/frames.ts +75 -0
- package/runtime/tracing/instrument.ts +186 -0
- package/runtime/tracing/span.ts +138 -0
- package/runtime/tracing/store.ts +499 -0
- package/runtime/tracing/types.ts +47 -0
- package/runtime/vite-plugin/config-plugin.ts +68 -0
- package/runtime/vite-plugin/dev-server-plugin.ts +493 -0
- package/runtime/vite-plugin/dist/index.mjs +52333 -0
- package/runtime/vite-plugin/globals-plugin.ts +94 -0
- package/runtime/vite-plugin/index.ts +43 -0
- package/runtime/vite-plugin/modules-plugin.ts +88 -0
- package/runtime/vite-plugin/react-router-plugin.ts +95 -0
- package/runtime/worker-registry.ts +52 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { $ } from "bun";
|
|
2
|
+
|
|
3
|
+
export interface DockerRunOptions {
|
|
4
|
+
image: string;
|
|
5
|
+
name: string;
|
|
6
|
+
ports: Map<number, number>; // containerPort -> hostPort
|
|
7
|
+
envVars?: Record<string, string>;
|
|
8
|
+
entrypoint?: string[];
|
|
9
|
+
enableInternet?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface DockerContainerInfo {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
state: string; // "running", "exited", "created", etc.
|
|
16
|
+
exitCode: number | null;
|
|
17
|
+
ports: Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Track active containers for cleanup on process exit
|
|
21
|
+
const activeContainers = new Set<string>();
|
|
22
|
+
let cleanupRegistered = false;
|
|
23
|
+
|
|
24
|
+
function registerCleanup() {
|
|
25
|
+
if (cleanupRegistered) return;
|
|
26
|
+
cleanupRegistered = true;
|
|
27
|
+
|
|
28
|
+
const cleanup = () => {
|
|
29
|
+
for (const name of activeContainers) {
|
|
30
|
+
try {
|
|
31
|
+
Bun.spawnSync(["docker", "rm", "-f", name]);
|
|
32
|
+
} catch {
|
|
33
|
+
// best-effort cleanup
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
activeContainers.clear();
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
process.on("SIGINT", () => {
|
|
40
|
+
cleanup();
|
|
41
|
+
process.exit(130);
|
|
42
|
+
});
|
|
43
|
+
process.on("SIGTERM", () => {
|
|
44
|
+
cleanup();
|
|
45
|
+
process.exit(143);
|
|
46
|
+
});
|
|
47
|
+
process.on("exit", cleanup);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Image build cache: tag -> { mtime }
|
|
51
|
+
const imageCache = new Map<string, { mtime: number }>();
|
|
52
|
+
|
|
53
|
+
const DOCKER_JSON_FORMAT = "{{json .}}";
|
|
54
|
+
|
|
55
|
+
export class DockerManager {
|
|
56
|
+
/**
|
|
57
|
+
* Build an image from a Dockerfile, with lazy mtime-based caching.
|
|
58
|
+
* Skips rebuild if the Dockerfile hasn't changed since last build.
|
|
59
|
+
*/
|
|
60
|
+
async buildImage(dockerfilePath: string, tag: string, context?: string): Promise<void> {
|
|
61
|
+
const file = Bun.file(dockerfilePath);
|
|
62
|
+
if (!(await file.exists())) {
|
|
63
|
+
throw new Error(`Dockerfile not found: ${dockerfilePath}`);
|
|
64
|
+
}
|
|
65
|
+
const mtime = file.lastModified;
|
|
66
|
+
const cached = imageCache.get(tag);
|
|
67
|
+
if (cached && cached.mtime === mtime) {
|
|
68
|
+
return; // Image already built and Dockerfile unchanged
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const buildContext = context ?? (dockerfilePath.substring(0, dockerfilePath.lastIndexOf("/")) || ".");
|
|
72
|
+
const result = await $`docker build -t ${tag} -f ${dockerfilePath} ${buildContext}`.quiet().nothrow();
|
|
73
|
+
if (result.exitCode !== 0) {
|
|
74
|
+
throw new Error(`Docker build failed (exit ${result.exitCode}): ${result.stderr.toString()}`);
|
|
75
|
+
}
|
|
76
|
+
imageCache.set(tag, { mtime });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Run a container and return its container ID.
|
|
81
|
+
*/
|
|
82
|
+
async run(options: DockerRunOptions): Promise<string> {
|
|
83
|
+
registerCleanup();
|
|
84
|
+
|
|
85
|
+
const args: string[] = ["docker", "run", "-d", "--name", options.name];
|
|
86
|
+
|
|
87
|
+
// Port mappings
|
|
88
|
+
for (const [containerPort, hostPort] of options.ports) {
|
|
89
|
+
args.push("-p", `${hostPort}:${containerPort}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Environment variables
|
|
93
|
+
if (options.envVars) {
|
|
94
|
+
for (const [key, value] of Object.entries(options.envVars)) {
|
|
95
|
+
args.push("-e", `${key}=${value}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Network isolation
|
|
100
|
+
if (options.enableInternet === false) {
|
|
101
|
+
args.push("--network", "none");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Entrypoint override
|
|
105
|
+
if (options.entrypoint && options.entrypoint.length > 0) {
|
|
106
|
+
args.push("--entrypoint", options.entrypoint[0]!);
|
|
107
|
+
// Additional entrypoint args go after the image
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
args.push(options.image);
|
|
111
|
+
|
|
112
|
+
// Entrypoint additional args
|
|
113
|
+
if (options.entrypoint && options.entrypoint.length > 1) {
|
|
114
|
+
args.push(...options.entrypoint.slice(1));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const result = await $`${args}`.quiet().nothrow();
|
|
118
|
+
if (result.exitCode !== 0) {
|
|
119
|
+
throw new Error(`Docker run failed (exit ${result.exitCode}): ${result.stderr.toString()}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const containerId = result.stdout.toString().trim();
|
|
123
|
+
activeContainers.add(options.name);
|
|
124
|
+
return containerId;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Stop a running container gracefully.
|
|
129
|
+
*/
|
|
130
|
+
async stop(name: string, timeoutSec?: number): Promise<void> {
|
|
131
|
+
const args = ["docker", "stop"];
|
|
132
|
+
if (timeoutSec !== undefined) {
|
|
133
|
+
args.push("-t", String(timeoutSec));
|
|
134
|
+
}
|
|
135
|
+
args.push(name);
|
|
136
|
+
await $`${args}`.quiet().nothrow();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Kill a container immediately.
|
|
141
|
+
*/
|
|
142
|
+
async kill(name: string): Promise<void> {
|
|
143
|
+
await $`docker kill ${name}`.quiet().nothrow();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Send a signal to a container.
|
|
148
|
+
*/
|
|
149
|
+
async signal(name: string, sig: number): Promise<void> {
|
|
150
|
+
await $`docker kill --signal ${sig} ${name}`.quiet().nothrow();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Inspect a container and return its info, or null if not found.
|
|
155
|
+
*/
|
|
156
|
+
async inspect(name: string): Promise<DockerContainerInfo | null> {
|
|
157
|
+
const result = await $`docker inspect ${name} --format=${DOCKER_JSON_FORMAT}`.quiet().nothrow();
|
|
158
|
+
if (result.exitCode !== 0) return null;
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
const data = JSON.parse(result.stdout.toString());
|
|
162
|
+
|
|
163
|
+
// Flatten NetworkSettings.Ports from { "80/tcp": [{"HostIp":"0.0.0.0","HostPort":"32768"}] }
|
|
164
|
+
// into { "80/tcp": "0.0.0.0:32768" }
|
|
165
|
+
const rawPorts = data.NetworkSettings?.Ports ?? {};
|
|
166
|
+
const ports: Record<string, string> = {};
|
|
167
|
+
for (const [containerPort, bindings] of Object.entries(rawPorts)) {
|
|
168
|
+
if (Array.isArray(bindings) && bindings.length > 0) {
|
|
169
|
+
const b = bindings[0] as { HostIp?: string; HostPort?: string };
|
|
170
|
+
ports[containerPort] = `${b.HostIp || "0.0.0.0"}:${b.HostPort || "?"}`;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const state = data.State?.Status ?? "unknown";
|
|
175
|
+
return {
|
|
176
|
+
id: data.Id ?? "",
|
|
177
|
+
name: (data.Name ?? "").replace(/^\//, ""),
|
|
178
|
+
state,
|
|
179
|
+
exitCode: state === "running" ? null : (data.State?.ExitCode ?? null),
|
|
180
|
+
ports,
|
|
181
|
+
};
|
|
182
|
+
} catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Get logs from a container.
|
|
189
|
+
*/
|
|
190
|
+
async logs(name: string, tail?: number): Promise<string> {
|
|
191
|
+
const args = ["docker", "logs"];
|
|
192
|
+
if (tail) args.push("--tail", String(tail));
|
|
193
|
+
args.push(name);
|
|
194
|
+
const result = await $`${args}`.quiet().nothrow();
|
|
195
|
+
if (result.exitCode !== 0) return "";
|
|
196
|
+
// docker logs outputs to both stdout and stderr
|
|
197
|
+
return result.stdout.toString() + result.stderr.toString();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Remove a container (force).
|
|
202
|
+
*/
|
|
203
|
+
async remove(name: string): Promise<void> {
|
|
204
|
+
await $`docker rm -f ${name}`.quiet().nothrow();
|
|
205
|
+
activeContainers.delete(name);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Allocate a random available port by binding to port 0.
|
|
210
|
+
*/
|
|
211
|
+
static async allocatePort(): Promise<number> {
|
|
212
|
+
const server = Bun.serve({
|
|
213
|
+
port: 0,
|
|
214
|
+
fetch() {
|
|
215
|
+
return new Response();
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
const port = server.port;
|
|
219
|
+
server.stop(true);
|
|
220
|
+
if (!port || port <= 0) {
|
|
221
|
+
throw new Error("Failed to allocate port");
|
|
222
|
+
}
|
|
223
|
+
return port;
|
|
224
|
+
}
|
|
225
|
+
}
|