import assert from "node:assert";
import crypto from "node:crypto";
import fs from "node:fs/promises";
import { createRequire } from "node:module";
import path from "pathe";
export function createWasmPlugin() {
    const modules = new Map();
    const plugin = {
        name: "alchemy-wasm",
        setup(build) {
            build.onStart(() => {
                modules.clear();
            });
            // Handle imports like `import "./foo.wasm"` and `import "./foo.wasm?module"`
            // TODO(john): Figure out why this suddenly became necessary
            build.onResolve({ filter: /\.wasm(\?.*)?$/ }, async (args) => {
                const resolved = modules.get(args.path);
                if (resolved) {
                    return { path: resolved.path, external: true };
                }
                // Resolve path to source file, excluding the `?module` suffix
                const normalizedPath = path.normalize(args.path).replace(/\?.*$/, "");
                // Determine the source file: use Node module resolution for bare specifiers (npm packages),
                // otherwise resolve relative to the importing file's directory
                let copyFrom;
                if (/^[./]/.test(normalizedPath)) {
                    copyFrom = path.resolve(args.resolveDir, normalizedPath);
                }
                else {
                    try {
                        // createRequire needs a file path to anchor node_modules resolution from.
                        // The filename is a dummy — only the directory matters.
                        const esmRequire = createRequire(path.join(args.resolveDir, "noop.js"));
                        copyFrom = esmRequire.resolve(normalizedPath);
                    }
                    catch {
                        // Fall back to the original behavior if require.resolve fails
                        copyFrom = path.resolve(args.resolveDir, normalizedPath);
                    }
                }
                // Resolve path to outdir (required for monorepos if the workdir is not the same as process.cwd())
                assert(build.initialOptions.absWorkingDir && build.initialOptions.outdir, "Missing absWorkingDir or outdir from esbuild options");
                const outdir = path.resolve(build.initialOptions.absWorkingDir, build.initialOptions.outdir);
                // Use path hash as module specifier for portability (note: the `?module` suffix is not needed in workerd)
                const hash = crypto.createHash("sha256").update(copyFrom).digest("hex");
                const specifier = `${hash}.wasm`;
                // Copy to outdir so it's included in the upload
                const copyTo = path.join(outdir, specifier);
                await fs.mkdir(path.dirname(copyTo), { recursive: true });
                await fs.copyFile(copyFrom, copyTo);
                modules.set(args.path, {
                    type: "wasm",
                    path: specifier,
                });
                return { path: specifier, external: true };
            });
        },
    };
    return { plugin, modules };
}
//# sourceMappingURL=plugin-wasm.js.map