diff --git a/.gitignore b/.gitignore index 2fb37cb48..232ea1145 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ xcuserdata/ .vscode Examples/*/Bundle Examples/*/package-lock.json -/Package.resolved +Package.resolved diff --git a/Examples/ActorOnWebWorker/index.html b/Examples/ActorOnWebWorker/index.html index 2797702e1..4a16f16a0 100644 --- a/Examples/ActorOnWebWorker/index.html +++ b/Examples/ActorOnWebWorker/index.html @@ -8,7 +8,7 @@ <body> <script type="module"> import { init } from "./Bundle/index.js" - init(fetch(new URL("./Bundle/main.wasm", import.meta.url))); + init(); </script> <h1>Full-text Search with Actor on Web Worker</h1> diff --git a/Examples/Basic/.gitignore b/Examples/Basic/.gitignore deleted file mode 100644 index 95c432091..000000000 --- a/Examples/Basic/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.DS_Store -/.build -/Packages -/*.xcodeproj -xcuserdata/ diff --git a/Examples/Basic/index.html b/Examples/Basic/index.html index a674baca1..93868214d 100644 --- a/Examples/Basic/index.html +++ b/Examples/Basic/index.html @@ -8,7 +8,7 @@ <body> <script type="module"> import { init } from "./.build/plugins/PackageToJS/outputs/Package/index.js"; - await init(fetch("./.build/plugins/PackageToJS/outputs/Package/main.wasm")); + init(); </script> </body> diff --git a/Examples/Embedded/.gitignore b/Examples/Embedded/.gitignore deleted file mode 100644 index 31492b35d..000000000 --- a/Examples/Embedded/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.DS_Store -/.build -/Packages -/*.xcodeproj -xcuserdata/ -Package.resolved \ No newline at end of file diff --git a/Examples/Embedded/index.html b/Examples/Embedded/index.html index a674baca1..93868214d 100644 --- a/Examples/Embedded/index.html +++ b/Examples/Embedded/index.html @@ -8,7 +8,7 @@ <body> <script type="module"> import { init } from "./.build/plugins/PackageToJS/outputs/Package/index.js"; - await init(fetch("./.build/plugins/PackageToJS/outputs/Package/main.wasm")); + init(); </script> </body> diff --git a/Examples/Multithreading/.gitignore b/Examples/Multithreading/.gitignore deleted file mode 100644 index 0023a5340..000000000 --- a/Examples/Multithreading/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/Examples/Multithreading/index.html b/Examples/Multithreading/index.html index 74ba8cfed..20696d83a 100644 --- a/Examples/Multithreading/index.html +++ b/Examples/Multithreading/index.html @@ -29,7 +29,7 @@ <body> <script type="module"> import { init } from "./Bundle/index.js" - init(fetch(new URL("./Bundle/main.wasm", import.meta.url))); + init(); </script> <h1>Threading Example</h1> <p> diff --git a/Examples/OffscrenCanvas/.gitignore b/Examples/OffscrenCanvas/.gitignore deleted file mode 100644 index 0023a5340..000000000 --- a/Examples/OffscrenCanvas/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/Examples/OffscrenCanvas/index.html b/Examples/OffscrenCanvas/index.html index 1202807a0..dd101b765 100644 --- a/Examples/OffscrenCanvas/index.html +++ b/Examples/OffscrenCanvas/index.html @@ -70,7 +70,7 @@ <body> <script type="module"> import { init } from "./Bundle/index.js" - init(fetch(new URL("./Bundle/main.wasm", import.meta.url))); + init(); </script> <h1>OffscreenCanvas Example</h1> <p> diff --git a/Plugins/PackageToJS/Sources/PackageToJS.swift b/Plugins/PackageToJS/Sources/PackageToJS.swift index cc0c02182..c766995d2 100644 --- a/Plugins/PackageToJS/Sources/PackageToJS.swift +++ b/Plugins/PackageToJS/Sources/PackageToJS.swift @@ -357,7 +357,7 @@ struct PackagingPlanner { /// The directory for intermediate files let intermediatesDir: BuildPath /// The filename of the .wasm file - let wasmFilename = "main.wasm" + let wasmFilename: String /// The path to the .wasm product artifact let wasmProductArtifact: BuildPath /// The build configuration @@ -374,6 +374,7 @@ struct PackagingPlanner { selfPackageDir: BuildPath, outputDir: BuildPath, wasmProductArtifact: BuildPath, + wasmFilename: String, configuration: String, triple: String, selfPath: BuildPath = BuildPath(absolute: #filePath), @@ -384,6 +385,7 @@ struct PackagingPlanner { self.selfPackageDir = selfPackageDir self.outputDir = outputDir self.intermediatesDir = intermediatesDir + self.wasmFilename = wasmFilename self.selfPath = selfPath self.wasmProductArtifact = wasmProductArtifact self.configuration = configuration diff --git a/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift b/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift index 4bf6a1106..2844d52ec 100644 --- a/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift +++ b/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift @@ -119,7 +119,9 @@ struct PackageToJSPlugin: CommandPlugin { ) let planner = PackagingPlanner( options: buildOptions.packageOptions, context: context, selfPackage: selfPackage, - outputDir: outputDir, wasmProductArtifact: productArtifact) + outputDir: outputDir, wasmProductArtifact: productArtifact, + wasmFilename: productArtifact.lastPathComponent + ) let rootTask = try planner.planBuild( make: &make, buildOptions: buildOptions) cleanIfBuildGraphChanged(root: rootTask, make: make, context: context) @@ -193,7 +195,14 @@ struct PackageToJSPlugin: CommandPlugin { ) let planner = PackagingPlanner( options: testOptions.packageOptions, context: context, selfPackage: selfPackage, - outputDir: outputDir, wasmProductArtifact: productArtifact) + outputDir: outputDir, wasmProductArtifact: productArtifact, + // If the product artifact doesn't have a .wasm extension, add it + // to deliver it with the correct MIME type when serving the test + // files for browser tests. + wasmFilename: productArtifact.lastPathComponent.hasSuffix(".wasm") + ? productArtifact.lastPathComponent + : productArtifact.lastPathComponent + ".wasm" + ) let (rootTask, binDir) = try planner.planTestBuild( make: &make) cleanIfBuildGraphChanged(root: rootTask, make: make, context: context) @@ -486,7 +495,8 @@ extension PackagingPlanner { context: PluginContext, selfPackage: Package, outputDir: URL, - wasmProductArtifact: URL + wasmProductArtifact: URL, + wasmFilename: String ) { let outputBaseName = outputDir.lastPathComponent let (configuration, triple) = PackageToJS.deriveBuildConfiguration(wasmProductArtifact: wasmProductArtifact) @@ -498,6 +508,7 @@ extension PackagingPlanner { selfPackageDir: BuildPath(absolute: selfPackage.directoryURL.path), outputDir: BuildPath(absolute: outputDir.path), wasmProductArtifact: BuildPath(absolute: wasmProductArtifact.path), + wasmFilename: wasmFilename, configuration: configuration, triple: triple, system: system diff --git a/Plugins/PackageToJS/Templates/index.d.ts b/Plugins/PackageToJS/Templates/index.d.ts index 4a1074c14..11d5908c2 100644 --- a/Plugins/PackageToJS/Templates/index.d.ts +++ b/Plugins/PackageToJS/Templates/index.d.ts @@ -1,29 +1,21 @@ -import type { Import, Export } from './instantiate.js' +import type { Export, ModuleSource } from './instantiate.js' export type Options = { /** - * The CLI arguments to pass to the WebAssembly module + * The WebAssembly module to instantiate + * + * If not provided, the module will be fetched from the default path. */ - args?: string[] -/* #if USE_SHARED_MEMORY */ - /** - * The WebAssembly memory to use (must be 'shared') - */ - memory: WebAssembly.Memory -/* #endif */ + module?: ModuleSource } /** - * Initialize the given WebAssembly module + * Instantiate and initialize the module * - * This is a convenience function that creates an instantiator and instantiates the module. - * @param moduleSource - The WebAssembly module to instantiate - * @param imports - The imports to add - * @param options - The options + * This is a convenience function for browser environments. + * If you need a more flexible API, see `instantiate`. */ -export declare function init( - moduleSource: WebAssembly.Module | ArrayBufferView | ArrayBuffer | Response | PromiseLike<Response> -): Promise<{ +export declare function init(options?: Options): Promise<{ instance: WebAssembly.Instance, exports: Export }> diff --git a/Plugins/PackageToJS/Templates/index.js b/Plugins/PackageToJS/Templates/index.js index d0d28569f..4b8d90f6b 100644 --- a/Plugins/PackageToJS/Templates/index.js +++ b/Plugins/PackageToJS/Templates/index.js @@ -3,12 +3,16 @@ import { instantiate } from './instantiate.js'; import { defaultBrowserSetup /* #if USE_SHARED_MEMORY */, createDefaultWorkerFactory /* #endif */} from './platforms/browser.js'; /** @type {import('./index.d').init} */ -export async function init(moduleSource) { - const options = await defaultBrowserSetup({ - module: moduleSource, +export async function init(options = {}) { + let module = options.module; + if (!module) { + module = fetch(new URL("@PACKAGE_TO_JS_MODULE_PATH@", import.meta.url)) + } + const instantiateOptions = await defaultBrowserSetup({ + module, /* #if USE_SHARED_MEMORY */ spawnWorker: createDefaultWorkerFactory() /* #endif */ }) - return await instantiate(options); + return await instantiate(instantiateOptions); } diff --git a/Plugins/PackageToJS/Templates/test.browser.html b/Plugins/PackageToJS/Templates/test.browser.html index 27bfd25fc..35a37c943 100644 --- a/Plugins/PackageToJS/Templates/test.browser.html +++ b/Plugins/PackageToJS/Templates/test.browser.html @@ -4,6 +4,7 @@ <body> <script type="module"> import { testBrowserInPage } from "./test.js"; + import { MODULE_PATH } from "./instantiate.js"; import { defaultBrowserSetup /* #if USE_SHARED_MEMORY */, createDefaultWorkerFactory /* #endif */} from './platforms/browser.js'; const logElement = document.createElement("pre"); @@ -11,7 +12,7 @@ const processInfo = await fetch("/process-info.json").then((response) => response.json()); const options = await defaultBrowserSetup({ - module: await fetch("./main.wasm"), + module: await fetch(new URL(MODULE_PATH, import.meta.url)), args: processInfo.args, onStdoutLine: (line) => { console.log(line); diff --git a/Plugins/PackageToJS/Tests/ExampleTests.swift b/Plugins/PackageToJS/Tests/ExampleTests.swift index 90a20e5a4..508062297 100644 --- a/Plugins/PackageToJS/Tests/ExampleTests.swift +++ b/Plugins/PackageToJS/Tests/ExampleTests.swift @@ -182,7 +182,7 @@ extension Trait where Self == ConditionTrait { let process = Process() process.executableURL = llvmCov let profdata = packageDir.appending(path: ".build/plugins/PackageToJS/outputs/PackageTests/default.profdata") - let wasm = packageDir.appending(path: ".build/plugins/PackageToJS/outputs/PackageTests/main.wasm") + let wasm = packageDir.appending(path: ".build/plugins/PackageToJS/outputs/PackageTests/TestingPackageTests.wasm") process.arguments = ["report", "-instr-profile", profdata.path, wasm.path] process.standardOutput = FileHandle.nullDevice try process.run() diff --git a/Plugins/PackageToJS/Tests/PackagingPlannerTests.swift b/Plugins/PackageToJS/Tests/PackagingPlannerTests.swift index 1b1eb1abf..6392ca664 100644 --- a/Plugins/PackageToJS/Tests/PackagingPlannerTests.swift +++ b/Plugins/PackageToJS/Tests/PackagingPlannerTests.swift @@ -53,6 +53,7 @@ import Testing selfPackageDir: BuildPath(prefix: "SELF_PACKAGE"), outputDir: BuildPath(prefix: "OUTPUT"), wasmProductArtifact: BuildPath(prefix: "WASM_PRODUCT_ARTIFACT"), + wasmFilename: "main.wasm", configuration: configuration, triple: "wasm32-unknown-wasi", selfPath: BuildPath(prefix: "PLANNER_SOURCE_PATH"), @@ -81,6 +82,7 @@ import Testing selfPackageDir: BuildPath(prefix: "SELF_PACKAGE"), outputDir: BuildPath(prefix: "OUTPUT"), wasmProductArtifact: BuildPath(prefix: "WASM_PRODUCT_ARTIFACT"), + wasmFilename: "main.wasm", configuration: "debug", triple: "wasm32-unknown-wasi", selfPath: BuildPath(prefix: "PLANNER_SOURCE_PATH"), diff --git a/Sources/JavaScriptKit/Documentation.docc/Tutorials/Hello-World/Resources/hello-world-2-2-index-html.html b/Sources/JavaScriptKit/Documentation.docc/Tutorials/Hello-World/Resources/hello-world-2-2-index-html.html index 84a3aa15e..c75dd927a 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Tutorials/Hello-World/Resources/hello-world-2-2-index-html.html +++ b/Sources/JavaScriptKit/Documentation.docc/Tutorials/Hello-World/Resources/hello-world-2-2-index-html.html @@ -5,7 +5,7 @@ <title>Swift Web App</title> <script type="module"> import { init } from "./.build/plugins/PackageToJS/outputs/Package/index.js"; - await init(fetch("./.build/plugins/PackageToJS/outputs/Package/main.wasm")); + init(); </script> </head> <body>