alchemy 0.53.0 → 0.54.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/bin/alchemy.js +196353 -0
- package/bin/alchemy.ts +2 -2
- package/bin/commands/init.ts +1190 -0
- package/bin/constants.ts +18 -0
- package/bin/services/execute-alchemy.ts +7 -2
- package/bin/services/package-manager.ts +1 -1
- package/bin/types.ts +14 -5
- package/lib/cloudflare/astro.d.ts.map +1 -1
- package/lib/cloudflare/astro.js +4 -3
- package/lib/cloudflare/astro.js.map +1 -1
- package/lib/cloudflare/bundle/externals.d.ts +3 -0
- package/lib/cloudflare/bundle/externals.d.ts.map +1 -0
- package/lib/cloudflare/bundle/externals.js +35 -0
- package/lib/cloudflare/bundle/externals.js.map +1 -0
- package/lib/cloudflare/bundle/internal-worker-bundle.d.ts +8 -1
- package/lib/cloudflare/bundle/internal-worker-bundle.d.ts.map +1 -1
- package/lib/cloudflare/bundle/internal-worker-bundle.js +11 -4
- package/lib/cloudflare/bundle/internal-worker-bundle.js.map +1 -1
- package/lib/cloudflare/bundle/plugin-hot-reload.d.ts +4 -1
- package/lib/cloudflare/bundle/plugin-hot-reload.d.ts.map +1 -1
- package/lib/cloudflare/bundle/plugin-hot-reload.js +27 -11
- package/lib/cloudflare/bundle/plugin-hot-reload.js.map +1 -1
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js +5 -1
- package/lib/cloudflare/bundle/plugin-hybrid-node-compat.js.map +1 -1
- package/lib/cloudflare/bundle/plugin-wasm.d.ts +6 -2
- package/lib/cloudflare/bundle/plugin-wasm.d.ts.map +1 -1
- package/lib/cloudflare/bundle/plugin-wasm.js +21 -47
- package/lib/cloudflare/bundle/plugin-wasm.js.map +1 -1
- package/lib/cloudflare/bundle/validate-node-compat.d.ts +2 -1
- package/lib/cloudflare/bundle/validate-node-compat.d.ts.map +1 -1
- package/lib/cloudflare/bundle/validate-node-compat.js +5 -4
- package/lib/cloudflare/bundle/validate-node-compat.js.map +1 -1
- package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
- package/lib/cloudflare/compatibility-date.gen.js +1 -1
- package/lib/cloudflare/d1-database.js +1 -1
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
- package/lib/cloudflare/d1-migrations.js +8 -10
- package/lib/cloudflare/d1-migrations.js.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-options.d.ts +3 -3
- package/lib/cloudflare/miniflare/miniflare-worker-options.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-options.js +23 -6
- package/lib/cloudflare/miniflare/miniflare-worker-options.js.map +1 -1
- package/lib/cloudflare/miniflare/miniflare.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare.js +2 -4
- package/lib/cloudflare/miniflare/miniflare.js.map +1 -1
- package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/remote-binding-proxy.js +4 -6
- package/lib/cloudflare/miniflare/remote-binding-proxy.js.map +1 -1
- package/lib/cloudflare/react-router.d.ts +4 -0
- package/lib/cloudflare/react-router.d.ts.map +1 -1
- package/lib/cloudflare/react-router.js +8 -5
- package/lib/cloudflare/react-router.js.map +1 -1
- package/lib/cloudflare/worker-bundle.d.ts +80 -0
- package/lib/cloudflare/worker-bundle.d.ts.map +1 -0
- package/lib/cloudflare/worker-bundle.js +266 -0
- package/lib/cloudflare/worker-bundle.js.map +1 -0
- package/lib/cloudflare/worker.d.ts +1 -1
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +81 -195
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/esbuild/bundle.d.ts +1 -0
- package/lib/esbuild/bundle.d.ts.map +1 -1
- package/lib/state/cloudflare-state-store.js +1 -5
- package/lib/state/cloudflare-state-store.js.map +1 -1
- package/lib/state/dofs-state-store/store.d.ts.map +1 -1
- package/lib/state/dofs-state-store/store.js +4 -4
- package/lib/state/dofs-state-store/store.js.map +1 -1
- package/package.json +10 -5
- package/src/cloudflare/astro.ts +4 -3
- package/src/cloudflare/bundle/externals.ts +36 -0
- package/src/cloudflare/bundle/internal-worker-bundle.ts +12 -3
- package/src/cloudflare/bundle/plugin-hot-reload.ts +32 -12
- package/src/cloudflare/bundle/plugin-hybrid-node-compat.ts +6 -1
- package/src/cloudflare/bundle/plugin-wasm.ts +26 -54
- package/src/cloudflare/bundle/validate-node-compat.ts +6 -5
- package/src/cloudflare/compatibility-date.gen.ts +1 -1
- package/src/cloudflare/d1-database.ts +1 -1
- package/src/cloudflare/d1-migrations.ts +19 -18
- package/src/cloudflare/miniflare/miniflare-worker-options.ts +27 -13
- package/src/cloudflare/miniflare/miniflare.ts +2 -4
- package/src/cloudflare/miniflare/remote-binding-proxy.ts +5 -7
- package/src/cloudflare/react-router.ts +14 -6
- package/src/cloudflare/worker-bundle.ts +364 -0
- package/src/cloudflare/worker.ts +104 -241
- package/src/state/cloudflare-state-store.ts +1 -5
- package/src/state/dofs-state-store/store.ts +4 -4
- package/templates/nuxt/package.json +1 -1
- package/templates/nuxt/types/env.d.ts +11 -0
- package/templates/react-router/workers/app.ts +2 -2
- package/templates/rwsdk/.cursor/rules/alchemy_cloudflare.mdc +385 -0
- package/templates/rwsdk/wrangler.jsonc +10 -7
- package/templates/typescript/tsconfig.json +1 -2
- package/bin/alchemy.mjs +0 -51766
- package/lib/cloudflare/bundle/esbuild.d.ts +0 -16
- package/lib/cloudflare/bundle/esbuild.d.ts.map +0 -1
- package/lib/cloudflare/bundle/esbuild.js +0 -159
- package/lib/cloudflare/bundle/esbuild.js.map +0 -1
- package/lib/cloudflare/bundle/fs.d.ts +0 -18
- package/lib/cloudflare/bundle/fs.d.ts.map +0 -1
- package/lib/cloudflare/bundle/fs.js +0 -78
- package/lib/cloudflare/bundle/fs.js.map +0 -1
- package/lib/cloudflare/bundle/index.d.ts +0 -3
- package/lib/cloudflare/bundle/index.d.ts.map +0 -1
- package/lib/cloudflare/bundle/index.js +0 -2
- package/lib/cloudflare/bundle/index.js.map +0 -1
- package/lib/cloudflare/bundle/inline.d.ts +0 -12
- package/lib/cloudflare/bundle/inline.d.ts.map +0 -1
- package/lib/cloudflare/bundle/inline.js +0 -32
- package/lib/cloudflare/bundle/inline.js.map +0 -1
- package/lib/cloudflare/bundle/normalize.d.ts +0 -21
- package/lib/cloudflare/bundle/normalize.d.ts.map +0 -1
- package/lib/cloudflare/bundle/normalize.js +0 -49
- package/lib/cloudflare/bundle/normalize.js.map +0 -1
- package/lib/cloudflare/bundle/shared.d.ts +0 -30
- package/lib/cloudflare/bundle/shared.d.ts.map +0 -1
- package/lib/cloudflare/bundle/shared.js +0 -34
- package/lib/cloudflare/bundle/shared.js.map +0 -1
- package/src/cloudflare/bundle/esbuild.ts +0 -194
- package/src/cloudflare/bundle/fs.ts +0 -103
- package/src/cloudflare/bundle/index.ts +0 -6
- package/src/cloudflare/bundle/inline.ts +0 -42
- package/src/cloudflare/bundle/normalize.ts +0 -76
- package/src/cloudflare/bundle/shared.ts +0 -73
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import esbuild from "esbuild";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
|
-
import path from "pathe";
|
|
4
|
-
import { esbuildPluginCompatWarning } from "./plugin-compat-warning.ts";
|
|
5
|
-
import { esbuildPluginHotReload } from "./plugin-hot-reload.ts";
|
|
6
|
-
import { esbuildPluginHybridNodeCompat } from "./plugin-hybrid-node-compat.ts";
|
|
7
|
-
import { esbuildPluginWasm } from "./plugin-wasm.ts";
|
|
8
|
-
import type {
|
|
9
|
-
WorkerBundle,
|
|
10
|
-
WorkerBundleBaseProps,
|
|
11
|
-
WorkerBundleChunk,
|
|
12
|
-
WorkerBundleProvider,
|
|
13
|
-
} from "./shared.ts";
|
|
14
|
-
import { parseFiles } from "./shared.ts";
|
|
15
|
-
|
|
16
|
-
interface ESBuildBundleProps
|
|
17
|
-
extends WorkerBundleBaseProps,
|
|
18
|
-
Omit<
|
|
19
|
-
esbuild.BuildOptions,
|
|
20
|
-
"entryPoints" | "format" | "absWorkingDir" | "outdir"
|
|
21
|
-
> {
|
|
22
|
-
entrypoint: string;
|
|
23
|
-
cwd: string;
|
|
24
|
-
outdir: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export class ESBuildBundleProvider implements WorkerBundleProvider {
|
|
28
|
-
constructor(private props: ESBuildBundleProps) {
|
|
29
|
-
// Normalize paths to ensure consistency between esbuild inputs and outputs:
|
|
30
|
-
// - the `cwd` is absolute
|
|
31
|
-
// - the `entrypoint` and `outdir` are relative to the `cwd`
|
|
32
|
-
// This is so we can identify the entrypoint from the metafile.
|
|
33
|
-
this.props.cwd = path.resolve(this.props.cwd);
|
|
34
|
-
this.props.entrypoint = path.isAbsolute(props.entrypoint)
|
|
35
|
-
? path.relative(this.props.cwd, props.entrypoint)
|
|
36
|
-
: path.normalize(props.entrypoint);
|
|
37
|
-
this.props.outdir = path.isAbsolute(props.outdir)
|
|
38
|
-
? path.relative(this.props.cwd, props.outdir)
|
|
39
|
-
: path.normalize(props.outdir);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async create(): Promise<WorkerBundle> {
|
|
43
|
-
const options = buildOptions(this.props);
|
|
44
|
-
const result = await esbuild.build(options);
|
|
45
|
-
return resolveOutputs(result.metafile, this.props);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async watch(signal: AbortSignal): Promise<ReadableStream<WorkerBundleChunk>> {
|
|
49
|
-
const options = buildOptions(this.props);
|
|
50
|
-
|
|
51
|
-
return new ReadableStream<WorkerBundleChunk>({
|
|
52
|
-
start: async (controller) => {
|
|
53
|
-
const context = await esbuild.context({
|
|
54
|
-
...options,
|
|
55
|
-
plugins: [
|
|
56
|
-
...(options.plugins ?? []),
|
|
57
|
-
esbuildPluginHotReload({
|
|
58
|
-
onBuildStart: () => {
|
|
59
|
-
controller.enqueue({ type: "start" });
|
|
60
|
-
},
|
|
61
|
-
onBuildError: (errors) => {
|
|
62
|
-
controller.enqueue({ type: "error", errors });
|
|
63
|
-
},
|
|
64
|
-
onBuildEnd: async (result) => {
|
|
65
|
-
controller.enqueue({
|
|
66
|
-
type: "end",
|
|
67
|
-
result: await resolveOutputs(result.metafile!, this.props),
|
|
68
|
-
});
|
|
69
|
-
},
|
|
70
|
-
}),
|
|
71
|
-
],
|
|
72
|
-
});
|
|
73
|
-
await context.watch();
|
|
74
|
-
signal.addEventListener("abort", async () => {
|
|
75
|
-
await context.dispose();
|
|
76
|
-
controller.close();
|
|
77
|
-
});
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async delete(): Promise<void> {
|
|
83
|
-
await fs.rm(path.join(this.props.cwd, this.props.outdir), {
|
|
84
|
-
recursive: true,
|
|
85
|
-
force: true,
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function buildOptions({
|
|
90
|
-
entrypoint,
|
|
91
|
-
nodeCompat,
|
|
92
|
-
cwd,
|
|
93
|
-
...props
|
|
94
|
-
}: ESBuildBundleProps) {
|
|
95
|
-
return {
|
|
96
|
-
...props,
|
|
97
|
-
entryPoints: [entrypoint],
|
|
98
|
-
absWorkingDir: cwd,
|
|
99
|
-
format: props.format,
|
|
100
|
-
target: "esnext",
|
|
101
|
-
platform: "node",
|
|
102
|
-
metafile: true,
|
|
103
|
-
write: true,
|
|
104
|
-
bundle: true,
|
|
105
|
-
conditions: ["workerd", "worker", "import", "module", "browser"],
|
|
106
|
-
mainFields: ["module", "main"],
|
|
107
|
-
loader: {
|
|
108
|
-
".sql": "text",
|
|
109
|
-
".json": "json",
|
|
110
|
-
...props.loader,
|
|
111
|
-
},
|
|
112
|
-
plugins: [
|
|
113
|
-
esbuildPluginWasm(),
|
|
114
|
-
nodeCompat === "v2"
|
|
115
|
-
? esbuildPluginHybridNodeCompat()
|
|
116
|
-
: esbuildPluginCompatWarning(nodeCompat ?? null),
|
|
117
|
-
...(props.plugins ?? []),
|
|
118
|
-
],
|
|
119
|
-
alias: props.alias,
|
|
120
|
-
external: [
|
|
121
|
-
...(nodeCompat === "als" ? external_als : external),
|
|
122
|
-
...(props.external ?? []),
|
|
123
|
-
],
|
|
124
|
-
} satisfies esbuild.BuildOptions;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async function resolveOutputs(
|
|
128
|
-
metafile: esbuild.Metafile,
|
|
129
|
-
props: ESBuildBundleProps,
|
|
130
|
-
): Promise<WorkerBundle> {
|
|
131
|
-
const outdir = path.resolve(props.cwd, props.outdir);
|
|
132
|
-
const paths: string[] = [];
|
|
133
|
-
let entrypoint: string | undefined;
|
|
134
|
-
for (const [key, value] of Object.entries(metafile.outputs)) {
|
|
135
|
-
const name = path.relative(outdir, path.resolve(props.cwd, key));
|
|
136
|
-
paths.push(name);
|
|
137
|
-
if (value.entryPoint === props.entrypoint) {
|
|
138
|
-
entrypoint = name;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if (!entrypoint) {
|
|
142
|
-
throw new Error(
|
|
143
|
-
`Failed to find entrypoint in metafile - expected ${props.entrypoint} but found ${Object.values(
|
|
144
|
-
metafile.outputs,
|
|
145
|
-
)
|
|
146
|
-
.map((v) => v.entryPoint)
|
|
147
|
-
.filter((v) => v !== undefined)
|
|
148
|
-
.join(", ")}`,
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
const { files, hash } = await parseFiles(outdir, paths, props.format);
|
|
152
|
-
return {
|
|
153
|
-
entrypoint,
|
|
154
|
-
files,
|
|
155
|
-
hash,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// https://developers.cloudflare.com/workers/runtime-apis/nodejs/#supported-nodejs-apis
|
|
160
|
-
const nodejs_compat = [
|
|
161
|
-
"node:async_hooks",
|
|
162
|
-
"node:assert",
|
|
163
|
-
"node:buffer",
|
|
164
|
-
"node:console",
|
|
165
|
-
"node:crypto",
|
|
166
|
-
"node:debug",
|
|
167
|
-
"node:diagnostics_channel",
|
|
168
|
-
"node:dns",
|
|
169
|
-
"node:events",
|
|
170
|
-
"node:inspector",
|
|
171
|
-
"node:net",
|
|
172
|
-
"node:path",
|
|
173
|
-
"node:perf_hooks", // partially supported
|
|
174
|
-
"node:process",
|
|
175
|
-
"node:querystring",
|
|
176
|
-
"node:stream",
|
|
177
|
-
"node:string_decoder",
|
|
178
|
-
"node:timers",
|
|
179
|
-
"node:tls", // partially supported
|
|
180
|
-
"node:url",
|
|
181
|
-
"node:util",
|
|
182
|
-
"node:zlib",
|
|
183
|
-
// "node:*",
|
|
184
|
-
];
|
|
185
|
-
|
|
186
|
-
const external = [
|
|
187
|
-
...nodejs_compat,
|
|
188
|
-
...nodejs_compat.map((p) => p.split(":")[1]),
|
|
189
|
-
"cloudflare:workers",
|
|
190
|
-
"cloudflare:workflows",
|
|
191
|
-
"cloudflare:*",
|
|
192
|
-
];
|
|
193
|
-
|
|
194
|
-
const external_als = ["node:async_hooks", "async_hooks", "cloudflare:*"];
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import kleur from "kleur";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
|
-
import path from "pathe";
|
|
4
|
-
import { logger } from "../../util/logger.ts";
|
|
5
|
-
import type {
|
|
6
|
-
WorkerBundle,
|
|
7
|
-
WorkerBundleBaseProps,
|
|
8
|
-
WorkerBundleChunk,
|
|
9
|
-
WorkerBundleProvider,
|
|
10
|
-
} from "./shared.ts";
|
|
11
|
-
import { parseFiles } from "./shared.ts";
|
|
12
|
-
|
|
13
|
-
interface FSBundleProps extends WorkerBundleBaseProps {
|
|
14
|
-
entrypoint: string;
|
|
15
|
-
globs: string[] | undefined;
|
|
16
|
-
cwd: string;
|
|
17
|
-
sourcemaps: boolean;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export class FSBundleProvider implements WorkerBundleProvider {
|
|
21
|
-
private root: string;
|
|
22
|
-
private entrypoint: string;
|
|
23
|
-
private globs: string[];
|
|
24
|
-
private format: "esm" | "cjs";
|
|
25
|
-
|
|
26
|
-
constructor(props: FSBundleProps) {
|
|
27
|
-
const entrypoint = path.resolve(props.cwd, props.entrypoint);
|
|
28
|
-
this.root = path.dirname(entrypoint);
|
|
29
|
-
this.entrypoint = path.relative(this.root, entrypoint);
|
|
30
|
-
this.globs = props.globs ?? [
|
|
31
|
-
"**/*.js",
|
|
32
|
-
"**/*.mjs",
|
|
33
|
-
"**/*.wasm",
|
|
34
|
-
...(props.sourcemaps ? ["**/*.js.map"] : []),
|
|
35
|
-
];
|
|
36
|
-
this.format = props.format;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async create(log = true): Promise<WorkerBundle> {
|
|
40
|
-
const fileNames = new Set<string>();
|
|
41
|
-
await Promise.all(
|
|
42
|
-
this.globs.map(async (glob) => {
|
|
43
|
-
for await (const file of fs.glob(glob, { cwd: this.root })) {
|
|
44
|
-
fileNames.add(file);
|
|
45
|
-
}
|
|
46
|
-
}),
|
|
47
|
-
);
|
|
48
|
-
if (fileNames.size === 0) {
|
|
49
|
-
throw new Error(
|
|
50
|
-
`No files found matching ${this.globs.join(", ")} in ${this.root}`,
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
const { files, hash } = await parseFiles(
|
|
54
|
-
this.root,
|
|
55
|
-
Array.from(fileNames),
|
|
56
|
-
this.format,
|
|
57
|
-
);
|
|
58
|
-
if (log) {
|
|
59
|
-
logger.log(`${kleur.gray("worker:")} ${kleur.blue(this.entrypoint)}`);
|
|
60
|
-
logger.log(`${kleur.gray("main:")} ${kleur.blue(this.entrypoint)}`);
|
|
61
|
-
logger.log(
|
|
62
|
-
`${kleur.gray("dist:")} ${kleur.blue(path.relative(process.cwd(), this.root))}:`,
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
return {
|
|
66
|
-
entrypoint: this.entrypoint,
|
|
67
|
-
files,
|
|
68
|
-
hash,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async watch(signal: AbortSignal): Promise<ReadableStream<WorkerBundleChunk>> {
|
|
73
|
-
let result = await this.create();
|
|
74
|
-
const watcher = fs.watch(this.root, {
|
|
75
|
-
recursive: true,
|
|
76
|
-
signal,
|
|
77
|
-
});
|
|
78
|
-
const iterator = watcher[Symbol.asyncIterator]();
|
|
79
|
-
return new ReadableStream({
|
|
80
|
-
start: async (controller) => {
|
|
81
|
-
controller.enqueue({ type: "end", result });
|
|
82
|
-
},
|
|
83
|
-
pull: async (controller) => {
|
|
84
|
-
const next = await iterator.next().catch((err) => {
|
|
85
|
-
if (err instanceof DOMException && err.name === "AbortError") {
|
|
86
|
-
return { done: true };
|
|
87
|
-
}
|
|
88
|
-
throw err;
|
|
89
|
-
});
|
|
90
|
-
if (next.done) {
|
|
91
|
-
controller.close();
|
|
92
|
-
} else {
|
|
93
|
-
controller.enqueue({ type: "start" });
|
|
94
|
-
const update = await this.create(false);
|
|
95
|
-
if (update.hash !== result.hash) {
|
|
96
|
-
result = update;
|
|
97
|
-
controller.enqueue({ type: "end", result });
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import type {
|
|
3
|
-
WorkerBundle,
|
|
4
|
-
WorkerBundleBaseProps,
|
|
5
|
-
WorkerBundleChunk,
|
|
6
|
-
WorkerBundleProvider,
|
|
7
|
-
} from "./shared.ts";
|
|
8
|
-
|
|
9
|
-
interface InlineBundleProps extends WorkerBundleBaseProps {
|
|
10
|
-
content: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class InlineBundleProvider implements WorkerBundleProvider {
|
|
14
|
-
constructor(private props: InlineBundleProps) {}
|
|
15
|
-
|
|
16
|
-
async create(): Promise<WorkerBundle> {
|
|
17
|
-
return {
|
|
18
|
-
entrypoint: "worker.js",
|
|
19
|
-
files: [
|
|
20
|
-
new File([this.props.content], "worker.js", {
|
|
21
|
-
type:
|
|
22
|
-
this.props.format === "cjs"
|
|
23
|
-
? "application/javascript"
|
|
24
|
-
: "application/javascript+module",
|
|
25
|
-
}),
|
|
26
|
-
],
|
|
27
|
-
hash: crypto
|
|
28
|
-
.createHash("sha256")
|
|
29
|
-
.update(this.props.content)
|
|
30
|
-
.digest("hex"),
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async watch(): Promise<ReadableStream<WorkerBundleChunk>> {
|
|
35
|
-
return new ReadableStream<WorkerBundleChunk>({
|
|
36
|
-
start: async (controller) => {
|
|
37
|
-
controller.enqueue({ type: "end", result: await this.create() });
|
|
38
|
-
controller.close();
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import type esbuild from "esbuild";
|
|
2
|
-
import { ESBuildBundleProvider } from "./esbuild.ts";
|
|
3
|
-
import { FSBundleProvider } from "./fs.ts";
|
|
4
|
-
import { InlineBundleProvider } from "./inline.ts";
|
|
5
|
-
import type { WorkerBundleProvider } from "./shared.ts";
|
|
6
|
-
import { validateNodeCompat } from "./validate-node-compat.ts";
|
|
7
|
-
|
|
8
|
-
interface NormalizeWorkerBundleProps {
|
|
9
|
-
script: string | undefined;
|
|
10
|
-
entrypoint: string | undefined;
|
|
11
|
-
noBundle: boolean | undefined;
|
|
12
|
-
format: "cjs" | "esm" | undefined;
|
|
13
|
-
compatibilityDate: string;
|
|
14
|
-
compatibilityFlags: string[];
|
|
15
|
-
rules:
|
|
16
|
-
| {
|
|
17
|
-
globs: string[];
|
|
18
|
-
}[]
|
|
19
|
-
| undefined;
|
|
20
|
-
bundle?: Omit<
|
|
21
|
-
esbuild.BuildOptions,
|
|
22
|
-
"entryPoints" | "format" | "absWorkingDir"
|
|
23
|
-
>;
|
|
24
|
-
cwd: string;
|
|
25
|
-
outdir: string;
|
|
26
|
-
sourceMap: boolean | undefined;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function wrap<T>(fn: () => T): [T, null] | [null, Error] {
|
|
30
|
-
try {
|
|
31
|
-
return [fn(), null];
|
|
32
|
-
} catch (e) {
|
|
33
|
-
return [null, e instanceof Error ? e : new Error(String(e))];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function normalizeWorkerBundle(
|
|
38
|
-
props: NormalizeWorkerBundleProps,
|
|
39
|
-
): WorkerBundleProvider {
|
|
40
|
-
const nodeCompat = validateNodeCompat({
|
|
41
|
-
compatibilityDate: props.compatibilityDate,
|
|
42
|
-
compatibilityFlags: props.compatibilityFlags,
|
|
43
|
-
noBundle: props.noBundle ?? false,
|
|
44
|
-
});
|
|
45
|
-
if (props.script) {
|
|
46
|
-
return new InlineBundleProvider({
|
|
47
|
-
content: props.script,
|
|
48
|
-
format: props.format ?? "esm",
|
|
49
|
-
nodeCompat,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
if (!props.entrypoint) {
|
|
53
|
-
throw new Error(
|
|
54
|
-
"Either `script` or `entrypoint` must be provided for workers",
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
if (props.noBundle) {
|
|
58
|
-
return new FSBundleProvider({
|
|
59
|
-
entrypoint: props.entrypoint,
|
|
60
|
-
format: props.format ?? "esm",
|
|
61
|
-
nodeCompat,
|
|
62
|
-
cwd: props.cwd,
|
|
63
|
-
globs: props.rules?.flatMap((rule) => rule.globs),
|
|
64
|
-
sourcemaps: props.sourceMap !== false,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return new ESBuildBundleProvider({
|
|
68
|
-
entrypoint: props.entrypoint,
|
|
69
|
-
format: props.format ?? "esm",
|
|
70
|
-
nodeCompat,
|
|
71
|
-
cwd: props.cwd,
|
|
72
|
-
outdir: props.outdir,
|
|
73
|
-
sourcemap: props.sourceMap !== false ? "inline" : undefined,
|
|
74
|
-
...props.bundle,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import type esbuild from "esbuild";
|
|
2
|
-
import crypto from "node:crypto";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { getContentType } from "../../util/content-type.ts";
|
|
6
|
-
|
|
7
|
-
export interface WorkerBundleBaseProps {
|
|
8
|
-
format: "cjs" | "esm";
|
|
9
|
-
nodeCompat: "als" | "v2" | null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface WorkerBundle {
|
|
13
|
-
entrypoint: string;
|
|
14
|
-
files: File[];
|
|
15
|
-
hash: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type WorkerBundleChunk =
|
|
19
|
-
| {
|
|
20
|
-
type: "start";
|
|
21
|
-
}
|
|
22
|
-
| {
|
|
23
|
-
type: "end";
|
|
24
|
-
result: WorkerBundle;
|
|
25
|
-
}
|
|
26
|
-
| {
|
|
27
|
-
type: "error";
|
|
28
|
-
errors: esbuild.Message[];
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export interface WorkerBundleProvider {
|
|
32
|
-
create(): Promise<WorkerBundle>;
|
|
33
|
-
watch(signal: AbortSignal): Promise<ReadableStream<WorkerBundleChunk>>;
|
|
34
|
-
delete?(): Promise<void>;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const normalizeFileType = (file: string, format: "cjs" | "esm") => {
|
|
38
|
-
if (path.extname(file) === ".js" && format === "esm") {
|
|
39
|
-
return "application/javascript+module";
|
|
40
|
-
}
|
|
41
|
-
return getContentType(file);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export const parseFiles = async (
|
|
45
|
-
root: string,
|
|
46
|
-
paths: string[],
|
|
47
|
-
format: "esm" | "cjs",
|
|
48
|
-
) => {
|
|
49
|
-
const outputs = await Promise.all(
|
|
50
|
-
paths.map(async (file) => {
|
|
51
|
-
const content = await fs.readFile(path.join(root, file));
|
|
52
|
-
return {
|
|
53
|
-
file: new File([content], file, {
|
|
54
|
-
type: normalizeFileType(file, format),
|
|
55
|
-
}),
|
|
56
|
-
hash: crypto.createHash("sha256").update(content).digest("hex"),
|
|
57
|
-
};
|
|
58
|
-
}),
|
|
59
|
-
);
|
|
60
|
-
return {
|
|
61
|
-
files: outputs.map(({ file }) => file),
|
|
62
|
-
hash: combineFileHashes(outputs),
|
|
63
|
-
};
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const combineFileHashes = (files: { file: File; hash: string }[]) => {
|
|
67
|
-
const sorted = files.sort((a, b) => a.file.name.localeCompare(b.file.name));
|
|
68
|
-
const finalHash = crypto.createHash("sha256");
|
|
69
|
-
for (const { hash } of sorted) {
|
|
70
|
-
finalHash.update(hash);
|
|
71
|
-
}
|
|
72
|
-
return finalHash.digest("hex");
|
|
73
|
-
};
|