[node] add module with fixed imports

Change-Id: I5e73c691a67de1f63217b45d8d9edbadada2d887
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/143540
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: snek <snek@chromium.org>
diff --git a/src/dawn/node/CMakeLists.txt b/src/dawn/node/CMakeLists.txt
index ee701ae..18edfa1 100644
--- a/src/dawn/node/CMakeLists.txt
+++ b/src/dawn/node/CMakeLists.txt
@@ -135,3 +135,14 @@
     file(GENERATE OUTPUT "${NAPI_SYMBOLS_H}" CONTENT "${NAPI_SYMBOLS}")
     target_sources(dawn_node PRIVATE "NapiSymbols.cpp")
 endif()
+
+macro(javascript file)
+    add_custom_command(
+        TARGET dawn_node POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E copy_if_different
+            "${CMAKE_SOURCE_DIR}/src/dawn/node/${file}"
+            "${Dawn_BINARY_DIR}/${file}")
+endmacro()
+
+javascript("index.js")
+javascript("cts.js")
diff --git a/src/dawn/node/Module.cpp b/src/dawn/node/Module.cpp
index 731cc95..ddeb529 100644
--- a/src/dawn/node/Module.cpp
+++ b/src/dawn/node/Module.cpp
@@ -32,6 +32,7 @@
 #endif  // DAWN_EMIT_COVERAGE
 
 namespace {
+
 Napi::Value CreateGPU(const Napi::CallbackInfo& info) {
     const auto& env = info.Env();
 
@@ -95,7 +96,7 @@
     dawnProcSetProcs(&dawn::native::GetProcs());
 
     // Register all the interop types
-    wgpu::interop::Initialize(env);
+    exports.Set(Napi::String::New(env, "globals"), wgpu::interop::Initialize(env));
 
     // Export function that creates and returns the wgpu::interop::GPU interface
     exports.Set(Napi::String::New(env, "create"), Napi::Function::New<CreateGPU>(env));
diff --git a/src/dawn/node/README.md b/src/dawn/node/README.md
index 5a8c972..9d7f4ab 100644
--- a/src/dawn/node/README.md
+++ b/src/dawn/node/README.md
@@ -59,13 +59,13 @@
 Now you can run CTS:
 
 ```sh
-./tools/run run-cts --dawn-node=<path-to-dawn.node> [WebGPU CTS query]
+./tools/run run-cts --dawn-node=<path-to-cts.js> [WebGPU CTS query]
 ```
 
 Or if you checked out your own CTS repo:
 
 ```sh
-./tools/run run-cts --dawn-node=<path-to-dawn.node> --cts=<path-to-cts> [WebGPU CTS query]
+./tools/run run-cts --dawn-node=<path-to-cts.js> --cts=<path-to-cts> [WebGPU CTS query]
 ```
 
 If this fails with the error message `TypeError: expander is not a function or its return value is not iterable`, try appending `--build=false` to the start of the `run-cts` command line flags.
@@ -73,7 +73,7 @@
 To test against SwiftShader instead of the default Vulkan device, prefix `./tools/run run-cts` with `VK_ICD_FILENAMES=<swiftshader-cmake-build>/Linux/vk_swiftshader_icd.json`. For example:
 
 ```sh
-VK_ICD_FILENAMES=<swiftshader-cmake-build>/Linux/vk_swiftshader_icd.json ./tools/run run-cts --dawn-node=<path-to-dawn.node> [WebGPU CTS query]
+VK_ICD_FILENAMES=<swiftshader-cmake-build>/Linux/vk_swiftshader_icd.json ./tools/run run-cts --dawn-node=<path-to-cts.js> [WebGPU CTS query]
 ```
 
 The `--flag` parameter must be passed in multiple times, once for each flag begin set. Here are some common arguments:
@@ -87,7 +87,7 @@
 For example, on Windows, to use the d3dcompiler_47.dll from a Chromium checkout, and to dump shader output, we could run the following using Git Bash:
 
 ```sh
-./tools/run run-cts --verbose --dawn-node=/c/src/dawn/build/Debug/dawn.node --cts=/c/src/webgpu-cts --flag=dlldir="C:\src\chromium\src\out\Release" --flag=enable-dawn-features=dump_shaders 'webgpu:shader,execution,builtin,abs:integer_builtin_functions,abs_unsigned:storageClass="storage";storageMode="read_write";containerType="vector";isAtomic=false;baseType="u32";type="vec2%3Cu32%3E"'
+./tools/run run-cts --verbose --dawn-node=/c/src/dawn/node/cts.js --cts=/c/src/webgpu-cts --flag=dlldir="C:\src\chromium\src\out\Release" --flag=enable-dawn-features=dump_shaders 'webgpu:shader,execution,builtin,abs:integer_builtin_functions,abs_unsigned:storageClass="storage";storageMode="read_write";containerType="vector";isAtomic=false;baseType="u32";type="vec2%3Cu32%3E"'
 ```
 
 Note that we pass `--verbose` above so that all test output, including the dumped shader, is written to stdout.
@@ -157,7 +157,7 @@
         "--",
         "placeholder-arg",
         "--gpu-provider",
-        "[path-to-dawn.node]", // REPLACE: [path-to-dawn.node]
+        "[path-to-cts.js]", // REPLACE: [path-to-cts.js]
         "[test-query]" // REPLACE: [test-query]
       ],
       "cwd": "[cts-root]" // REPLACE: [cts-root]
@@ -169,7 +169,7 @@
 Replacing:
 
 - `[cts-root]` with the path to the CTS root directory. If you are editing the `.vscode/launch.json` from within the CTS workspace, then you may use `${workspaceFolder}`.
-- `[path-to-dawn.node]` this the path to the `dawn.node` module built by the [build step](#Build)
+- `[cts.js]` this is the path to the `cts.js` module copied by the [build step](#Build)
 - `test-query` with the test query string. Example: `webgpu:shader,execution,builtin,abs:*`
 
 ## Debugging dawn-node issues in gdb/lldb
@@ -182,7 +182,7 @@
     -e "require('./src/common/tools/setup-ts-in-node.js');require('./src/common/runtime/cmdline.ts');" \
     -- \
     placeholder-arg \
-    --gpu-provider [path to dawn.node] \
+    --gpu-provider [path to cts.js] \
     [test-query]
 ```
 
diff --git a/src/dawn/node/binding/Converter.cpp b/src/dawn/node/binding/Converter.cpp
index a10d802..03b1177 100644
--- a/src/dawn/node/binding/Converter.cpp
+++ b/src/dawn/node/binding/Converter.cpp
@@ -1674,6 +1674,8 @@
         case wgpu::FeatureName::MSAARenderToSingleSampled:
         case wgpu::FeatureName::PixelLocalStorageCoherent:
         case wgpu::FeatureName::PixelLocalStorageNonCoherent:
+        case wgpu::FeatureName::DualSourceBlending:
+        case wgpu::FeatureName::D3D11MultithreadProtected:
         case wgpu::FeatureName::Undefined:
             return false;
     }
diff --git a/src/dawn/node/binding/GPUAdapter.cpp b/src/dawn/node/binding/GPUAdapter.cpp
index 303ca38..c2921bb 100644
--- a/src/dawn/node/binding/GPUAdapter.cpp
+++ b/src/dawn/node/binding/GPUAdapter.cpp
@@ -125,6 +125,10 @@
 
         requiredFeatures.emplace_back(feature);
     }
+    if (!conv(desc.label, descriptor.label)) {
+        Napi::Error::New(env, "invalid value for label").ThrowAsJavaScriptException();
+        return promise;
+    }
 
     wgpu::RequiredLimits limits;
 #define COPY_LIMIT(LIMIT)                                        \
diff --git a/src/dawn/node/cts.js b/src/dawn/node/cts.js
new file mode 100644
index 0000000..47111cb
--- /dev/null
+++ b/src/dawn/node/cts.js
@@ -0,0 +1,7 @@
+'use strict';
+
+const { create, globals } = require('./dawn.node');
+
+Object.assign(globalThis, globals);
+
+module.exports = { create };
diff --git a/src/dawn/node/index.js b/src/dawn/node/index.js
new file mode 100644
index 0000000..b70e421
--- /dev/null
+++ b/src/dawn/node/index.js
@@ -0,0 +1,8 @@
+'use strict';
+
+const { create, globals } = require('./dawn.node');
+
+module.exports = {
+  ...globals,
+  gpu: create(process.env.DAWN_FLAGS?.split(',') || []),
+};
diff --git a/src/dawn/node/interop/WebGPU.cpp.tmpl b/src/dawn/node/interop/WebGPU.cpp.tmpl
index 491a2f9..3072645 100644
--- a/src/dawn/node/interop/WebGPU.cpp.tmpl
+++ b/src/dawn/node/interop/WebGPU.cpp.tmpl
@@ -53,16 +53,17 @@
 {{- end}}
 
 
-void Initialize(Napi::Env env) {
+Napi::Object Initialize(Napi::Env env) {
   auto* wrapper = Wrappers::Init(env);
-  auto global = env.Global();
+  auto exports = Napi::Object::New(env);
 {{- range $ := .Declarations}}
 {{-   if IsInterfaceOrNamespace $}}
 {{-     if not (HasAnnotation $ "LegacyNoInterfaceObject")}}
-  global.Set(Napi::String::New(env, "{{$.Name}}"), wrapper->{{$.Name}}_ctor.Value());
+  exports.Set(Napi::String::New(env, "{{$.Name}}"), wrapper->{{$.Name}}_ctor.Value());
 {{-     end}}
 {{-   end}}
 {{- end}}
+  return exports;
 }
 
 }  // namespace interop
diff --git a/src/dawn/node/interop/WebGPU.h.tmpl b/src/dawn/node/interop/WebGPU.h.tmpl
index 6025bdd..eb0c8b2 100644
--- a/src/dawn/node/interop/WebGPU.h.tmpl
+++ b/src/dawn/node/interop/WebGPU.h.tmpl
@@ -38,8 +38,9 @@
 namespace wgpu {
 namespace interop {
 
-// Initialize() registers the WebGPU types with the Napi environment.
-void Initialize(Napi::Env env);
+// Initialize() registers the WebGPU types with the Napi environment
+// and returns an object containing their JavaScript interfaces.
+Napi::Object Initialize(Napi::Env env);
 
 {{  range $ := .Declarations}}
 {{-        if IsDictionary $}}{{template "Dictionary" $}}