From 2ba00a96175ea422cbfcc9529257af2969880772 Mon Sep 17 00:00:00 2001 From: webbureaucrat Date: Sun, 29 Jun 2025 17:09:32 -0500 Subject: [PATCH 1/7] reproduce issue generating SharedWorker. --- .../TypeScript-DOM-lib-generator/src/build.ts | 12 ++++++------ .../src/build/emitter.ts | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/tools/TypeScript-DOM-lib-generator/src/build.ts b/tools/TypeScript-DOM-lib-generator/src/build.ts index 4d73eb8..8bd730b 100644 --- a/tools/TypeScript-DOM-lib-generator/src/build.ts +++ b/tools/TypeScript-DOM-lib-generator/src/build.ts @@ -320,12 +320,12 @@ async function emitDom() { // outputFolder, // useIteratorObject, // }); - // emitFlavor(webidl, new Set(knownTypes.Worker), { - // name: "sharedworker", - // global: ["SharedWorker", "Worker"], - // outputFolder, - // useIteratorObject, - // }); + emitFlavor(webidl, new Set(knownTypes.Worker), { + name: "sharedworker", + global: ["SharedWorker", "Worker"], + outputFolder, + useIteratorObject, + }); // emitFlavor(webidl, new Set(knownTypes.Worker), { // name: "serviceworker", // global: ["ServiceWorker", "Worker"], diff --git a/tools/TypeScript-DOM-lib-generator/src/build/emitter.ts b/tools/TypeScript-DOM-lib-generator/src/build/emitter.ts index e19af0e..0c6f6b7 100644 --- a/tools/TypeScript-DOM-lib-generator/src/build/emitter.ts +++ b/tools/TypeScript-DOM-lib-generator/src/build/emitter.ts @@ -1567,7 +1567,7 @@ export async function emitRescriptBindings(webidl: Browser.WebIdl) { } printer.endLine(); - const windowInterface = allInterfaces.find((i) => i.name === "Window"); + const windowInterface = allInterfaces.find((i) => i.name === "WindowOrWorkerGlobalScope"); if (!windowInterface) throw new Error("Window interface not found"); const allProperties: Browser.Property[] = @@ -2823,11 +2823,12 @@ export async function emitRescriptBindings(webidl: Browser.WebIdl) { interfaceHierarchy = [ { name: "Temp", - entries: [ - enums(["WebGLPowerPreference"]), - dictionaries(["ImageBitmapRenderingContextSettings", "WebGLContextAttributes"]), + entries: [ + enums(["WorkerType"]), + individualInterfaces(["SharedWorker"]), + dictionaries(["WorkerOptions"]) ], - opens: [], + opens: [ "EventAPI", "ChannelMessagingAPI"], } ] @@ -2938,5 +2939,10 @@ export async function emitRescriptBindings(webidl: Browser.WebIdl) { // emitIndividualInterfaces(remainers); } - await emit(); + await emit(); + + await fs.writeFile( + path.join(outputFolder, "sharedworker.json"), + JSON.stringify(webidl, null, 2), + ); } From bba4378649a5669d98592c7c5dc3cbc9e645118f Mon Sep 17 00:00:00 2001 From: webbureaucrat Date: Mon, 21 Jul 2025 19:51:35 -0500 Subject: [PATCH 2/7] write bindings for the SharedWorker API. --- .gitignore | 3 +- src/WebWorkersAPI.res | 29 ++++++++ src/WebWorkersAPI/SharedWorker.res | 69 +++++++++++++++++++ src/WebWorkersAPI/SharedWorkerGlobalScope.res | 32 +++++++++ src/WebWorkersAPI/WorkerGlobalScope.res | 1 + .../SharedWorkerGlobalScope__test.res | 7 ++ tests/WebWorkersAPI/SharedWorker__test.res | 18 +++++ 7 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/WebWorkersAPI/SharedWorker.res create mode 100644 src/WebWorkersAPI/SharedWorkerGlobalScope.res create mode 100644 tests/WebWorkersAPI/SharedWorkerGlobalScope__test.res create mode 100644 tests/WebWorkersAPI/SharedWorker__test.res diff --git a/.gitignore b/.gitignore index 0bb699c..5d4fe94 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ .astro dist/ tmp/ -docs/public/llm.txt \ No newline at end of file +docs/public/llm.txt +*~ \ No newline at end of file diff --git a/src/WebWorkersAPI.res b/src/WebWorkersAPI.res index e7fb89c..6677015 100644 --- a/src/WebWorkersAPI.res +++ b/src/WebWorkersAPI.res @@ -1,4 +1,5 @@ open EventAPI +open FetchAPI /** Provides a storage mechanism for Request / Response object pairs that are cached, for example as part of the ServiceWorker life cycle. Note that the Cache interface is exposed to windowed scopes as well as workers. You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec. @@ -25,6 +26,8 @@ type multiCacheQueryOptions = { mutable cacheName?: string, } +type sharedWorker + /** The WorkerGlobalScope interface of the Web Workers API is an interface representing the scope of any worker. Workers have no browsing context; this scope contains the information usually conveyed by Window objects — @@ -44,3 +47,29 @@ type workerGlobalScope = { */ crossOriginIsolated: bool, } + +type workerType = + | @as("classic") Classic + | @as("module") Module + + +/** An object containing option properties that can set when creating the +object instance. */ +type workerOptions = { + @as("type") mutable type_?: workerType, + mutable credentials?: requestCredentials, + mutable name?: string, +} + +/** +The `SharedWorkerGlobalScope` object (the `SharedWorker` global scope) is +accessible through the self keyword. Some additional global functions, +namespaces objects, and constructors, not typically associated with the worker +global scope, but available on it, are listed in the JavaScript Reference. See +the complete list of functions available to workers. +*/ +@editor.completeFrom(SharedWorkerGlobalScope) +type sharedWorkerGlobalScope = { + ...workerGlobalScope, + name: option +} diff --git a/src/WebWorkersAPI/SharedWorker.res b/src/WebWorkersAPI/SharedWorker.res new file mode 100644 index 0000000..6084c41 --- /dev/null +++ b/src/WebWorkersAPI/SharedWorker.res @@ -0,0 +1,69 @@ +open ChannelMessagingAPI +open WebWorkersAPI + +include EventTarget.Impl({ + type t = sharedWorker +}) + +/** +`make(string)` + +The SharedWorker() constructor creates a SharedWorker object that executes the +script at the specified URL. This script must obey the same-origin policy. + +```res +let shared: sharedWorker = SharedWorker.make("sharedworker.js") +``` + +[Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/) +*/ +@new +external make: string => sharedWorker = "SharedWorker" + +/** +`make_withName(string, string)` + +The SharedWorker() constructor creates a SharedWorker object that executes the +script at the specified URL. This script must obey the same-origin policy. + +```res +let shared: sharedWorker = SharedWorker.make("sharedworker.js", "name") +``` + +[Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/) +*/ +@new +external make_withName: (string, string) => sharedWorker = "SharedWorker" + +/** +`make_withOptions(string, workerOptions)` + +The SharedWorker() constructor creates a SharedWorker object that executes the +script at the specified URL. This script must obey the same-origin policy. + +```res +let shared3: sharedWorker = SharedWorker.make_withOptions("sharedworker.js", { + name: "workerName", + type_: Module +}) +``` + +[Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/) +*/ +@new +external make_withOptions: (string, workerOptions) => sharedWorker = "SharedWorker" + +/** +`port(sharedWorker)` + +The port property of the SharedWorker interface returns a MessagePort object +used to communicate and control the shared worker. + +```res +let port: WebAPI.ChannelMessagingAPI.messagePort = SharedWorker.port(myWorker) +``` + +[Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/port) +*/ +@get +external port: sharedWorker => messagePort = "port" diff --git a/src/WebWorkersAPI/SharedWorkerGlobalScope.res b/src/WebWorkersAPI/SharedWorkerGlobalScope.res new file mode 100644 index 0000000..bd603c1 --- /dev/null +++ b/src/WebWorkersAPI/SharedWorkerGlobalScope.res @@ -0,0 +1,32 @@ +open WebWorkersAPI + +module Impl = ( + T: { + type t + }, +) => { + include WorkerGlobalScope.Impl({ + type t = T.t + }) + + /** +`close(sharedWorkerGlobalScope)` + +The close() method of the SharedWorkerGlobalScope interface discards any tasks +queued in the SharedWorkerGlobalScope's event loop, effectively closing this +particular scope. + +```res +self -> SharedWorkerGlobalScope.close +``` + +[Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorkerGlobalScope/close) +*/ + @send + external close: T.t => unit = "close" +} + +include Impl({ + type t = sharedWorkerGlobalScope +}) + diff --git a/src/WebWorkersAPI/WorkerGlobalScope.res b/src/WebWorkersAPI/WorkerGlobalScope.res index fc76c75..bc18614 100644 --- a/src/WebWorkersAPI/WorkerGlobalScope.res +++ b/src/WebWorkersAPI/WorkerGlobalScope.res @@ -38,6 +38,7 @@ let response = await self->WorkerGlobalScope.fetch(myRequest) [Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/fetch) */ external fetch_withRequest: (T.t, request, ~init: requestInit=?) => promise = "fetch" + external self: T.t = "self" } include Impl({ diff --git a/tests/WebWorkersAPI/SharedWorkerGlobalScope__test.res b/tests/WebWorkersAPI/SharedWorkerGlobalScope__test.res new file mode 100644 index 0000000..34c3bbf --- /dev/null +++ b/tests/WebWorkersAPI/SharedWorkerGlobalScope__test.res @@ -0,0 +1,7 @@ +open WebAPI.WebWorkersAPI + +external getSelf: () => sharedWorkerGlobalScope = "self" + +let self = getSelf() + +self -> SharedWorkerGlobalScope.close diff --git a/tests/WebWorkersAPI/SharedWorker__test.res b/tests/WebWorkersAPI/SharedWorker__test.res new file mode 100644 index 0000000..8bd96a3 --- /dev/null +++ b/tests/WebWorkersAPI/SharedWorker__test.res @@ -0,0 +1,18 @@ +open WebAPI.WebWorkersAPI + +let shared1: sharedWorker = SharedWorker.make("sharedworker.js") + +let shared2: sharedWorker = SharedWorker.make_withName("sharedworker.js", "name") + +let shared3: sharedWorker = SharedWorker.make_withOptions("sharedworker.js", { + name: "workerName", + type_: Module +}) + +let port: WebAPI.ChannelMessagingAPI.messagePort = SharedWorker.port(shared1) + +external getSelf: () => sharedWorkerGlobalScope = "self" + +let self = getSelf() + +self -> SharedWorkerGlobalScope.close From b43d65d6cd877d1cb4998d66ad6aafe060d9ca92 Mon Sep 17 00:00:00 2001 From: webbureaucrat Date: Sat, 26 Jul 2025 13:53:51 -0500 Subject: [PATCH 3/7] add missing JavaScript compiled files. --- src/WebWorkersAPI/SharedWorker.js | 7 +++++++ src/WebWorkersAPI/SharedWorkerGlobalScope.js | 15 +++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/WebWorkersAPI/SharedWorker.js create mode 100644 src/WebWorkersAPI/SharedWorkerGlobalScope.js diff --git a/src/WebWorkersAPI/SharedWorker.js b/src/WebWorkersAPI/SharedWorker.js new file mode 100644 index 0000000..dbf8d92 --- /dev/null +++ b/src/WebWorkersAPI/SharedWorker.js @@ -0,0 +1,7 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as EventTarget$WebAPI from "../EventAPI/EventTarget.js"; + +EventTarget$WebAPI.Impl({}); + +/* Not a pure module */ diff --git a/src/WebWorkersAPI/SharedWorkerGlobalScope.js b/src/WebWorkersAPI/SharedWorkerGlobalScope.js new file mode 100644 index 0000000..e33fbad --- /dev/null +++ b/src/WebWorkersAPI/SharedWorkerGlobalScope.js @@ -0,0 +1,15 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as WorkerGlobalScope$WebAPI from "./WorkerGlobalScope.js"; + +function Impl(T) { + WorkerGlobalScope$WebAPI.Impl({}); + return {}; +} + +WorkerGlobalScope$WebAPI.Impl({}); + +export { + Impl, +} +/* Not a pure module */ From 5d002a754214bb166d7cd01d310f0869c87778a0 Mon Sep 17 00:00:00 2001 From: webbureaucrat Date: Sat, 26 Jul 2025 14:02:54 -0500 Subject: [PATCH 4/7] add missing test files. --- .../SharedWorkerGlobalScope__test.js | 11 ++++++++ tests/WebWorkersAPI/SharedWorker__test.js | 26 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 tests/WebWorkersAPI/SharedWorkerGlobalScope__test.js create mode 100644 tests/WebWorkersAPI/SharedWorker__test.js diff --git a/tests/WebWorkersAPI/SharedWorkerGlobalScope__test.js b/tests/WebWorkersAPI/SharedWorkerGlobalScope__test.js new file mode 100644 index 0000000..12dd312 --- /dev/null +++ b/tests/WebWorkersAPI/SharedWorkerGlobalScope__test.js @@ -0,0 +1,11 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +let self = self(); + +self.close(); + +export { + self, +} +/* self Not a pure module */ diff --git a/tests/WebWorkersAPI/SharedWorker__test.js b/tests/WebWorkersAPI/SharedWorker__test.js new file mode 100644 index 0000000..44fee58 --- /dev/null +++ b/tests/WebWorkersAPI/SharedWorker__test.js @@ -0,0 +1,26 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +let shared1 = new SharedWorker("sharedworker.js"); + +let shared2 = new SharedWorker("sharedworker.js", "name"); + +let shared3 = new SharedWorker("sharedworker.js", { + type: "module", + name: "workerName" +}); + +let port = shared1.port; + +let self = self(); + +self.close(); + +export { + shared1, + shared2, + shared3, + port, + self, +} +/* shared1 Not a pure module */ From 9ba8ac1f19be9b675080754e5fa0d6e85504f3db Mon Sep 17 00:00:00 2001 From: webbureaucrat Date: Sat, 26 Jul 2025 14:26:28 -0500 Subject: [PATCH 5/7] revert accidentally committed files. --- .../TypeScript-DOM-lib-generator/src/build.ts | 12 ++++++------ .../src/build/emitter.ts | 18 ++++++------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/tools/TypeScript-DOM-lib-generator/src/build.ts b/tools/TypeScript-DOM-lib-generator/src/build.ts index 8bd730b..4d73eb8 100644 --- a/tools/TypeScript-DOM-lib-generator/src/build.ts +++ b/tools/TypeScript-DOM-lib-generator/src/build.ts @@ -320,12 +320,12 @@ async function emitDom() { // outputFolder, // useIteratorObject, // }); - emitFlavor(webidl, new Set(knownTypes.Worker), { - name: "sharedworker", - global: ["SharedWorker", "Worker"], - outputFolder, - useIteratorObject, - }); + // emitFlavor(webidl, new Set(knownTypes.Worker), { + // name: "sharedworker", + // global: ["SharedWorker", "Worker"], + // outputFolder, + // useIteratorObject, + // }); // emitFlavor(webidl, new Set(knownTypes.Worker), { // name: "serviceworker", // global: ["ServiceWorker", "Worker"], diff --git a/tools/TypeScript-DOM-lib-generator/src/build/emitter.ts b/tools/TypeScript-DOM-lib-generator/src/build/emitter.ts index 0c6f6b7..e19af0e 100644 --- a/tools/TypeScript-DOM-lib-generator/src/build/emitter.ts +++ b/tools/TypeScript-DOM-lib-generator/src/build/emitter.ts @@ -1567,7 +1567,7 @@ export async function emitRescriptBindings(webidl: Browser.WebIdl) { } printer.endLine(); - const windowInterface = allInterfaces.find((i) => i.name === "WindowOrWorkerGlobalScope"); + const windowInterface = allInterfaces.find((i) => i.name === "Window"); if (!windowInterface) throw new Error("Window interface not found"); const allProperties: Browser.Property[] = @@ -2823,12 +2823,11 @@ export async function emitRescriptBindings(webidl: Browser.WebIdl) { interfaceHierarchy = [ { name: "Temp", - entries: [ - enums(["WorkerType"]), - individualInterfaces(["SharedWorker"]), - dictionaries(["WorkerOptions"]) + entries: [ + enums(["WebGLPowerPreference"]), + dictionaries(["ImageBitmapRenderingContextSettings", "WebGLContextAttributes"]), ], - opens: [ "EventAPI", "ChannelMessagingAPI"], + opens: [], } ] @@ -2939,10 +2938,5 @@ export async function emitRescriptBindings(webidl: Browser.WebIdl) { // emitIndividualInterfaces(remainers); } - await emit(); - - await fs.writeFile( - path.join(outputFolder, "sharedworker.json"), - JSON.stringify(webidl, null, 2), - ); + await emit(); } From 047274d36c371675a619bdef504f0b405784dccc Mon Sep 17 00:00:00 2001 From: webbureaucrat Date: Sun, 27 Jul 2025 14:43:34 -0500 Subject: [PATCH 6/7] add trailing newline to .gitignore. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5d4fe94..f4fca42 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ dist/ tmp/ docs/public/llm.txt -*~ \ No newline at end of file +*~ From d3e3f128f1cb9ee0771e5aafd0b6aa51e3e43989 Mon Sep 17 00:00:00 2001 From: webbureaucrat Date: Sun, 27 Jul 2025 14:48:40 -0500 Subject: [PATCH 7/7] comply with new naming convention by removing underscores. --- src/WebWorkersAPI/SharedWorker.res | 10 +++++----- tests/WebWorkersAPI/SharedWorker__test.res | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/WebWorkersAPI/SharedWorker.res b/src/WebWorkersAPI/SharedWorker.res index 6084c41..105e44a 100644 --- a/src/WebWorkersAPI/SharedWorker.res +++ b/src/WebWorkersAPI/SharedWorker.res @@ -21,7 +21,7 @@ let shared: sharedWorker = SharedWorker.make("sharedworker.js") external make: string => sharedWorker = "SharedWorker" /** -`make_withName(string, string)` +`makeWithName(string, string)` The SharedWorker() constructor creates a SharedWorker object that executes the script at the specified URL. This script must obey the same-origin policy. @@ -33,16 +33,16 @@ let shared: sharedWorker = SharedWorker.make("sharedworker.js", "name") [Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/) */ @new -external make_withName: (string, string) => sharedWorker = "SharedWorker" +external makeWithName: (string, string) => sharedWorker = "SharedWorker" /** -`make_withOptions(string, workerOptions)` +`makeWithOptions(string, workerOptions)` The SharedWorker() constructor creates a SharedWorker object that executes the script at the specified URL. This script must obey the same-origin policy. ```res -let shared3: sharedWorker = SharedWorker.make_withOptions("sharedworker.js", { +let shared: sharedWorker = SharedWorker.makeWithOptions("sharedworker.js", { name: "workerName", type_: Module }) @@ -51,7 +51,7 @@ let shared3: sharedWorker = SharedWorker.make_withOptions("sharedworker.js", { [Read more on MDN](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/) */ @new -external make_withOptions: (string, workerOptions) => sharedWorker = "SharedWorker" +external makeWithOptions: (string, workerOptions) => sharedWorker = "SharedWorker" /** `port(sharedWorker)` diff --git a/tests/WebWorkersAPI/SharedWorker__test.res b/tests/WebWorkersAPI/SharedWorker__test.res index 8bd96a3..e8bd388 100644 --- a/tests/WebWorkersAPI/SharedWorker__test.res +++ b/tests/WebWorkersAPI/SharedWorker__test.res @@ -2,9 +2,9 @@ open WebAPI.WebWorkersAPI let shared1: sharedWorker = SharedWorker.make("sharedworker.js") -let shared2: sharedWorker = SharedWorker.make_withName("sharedworker.js", "name") +let shared2: sharedWorker = SharedWorker.makeWithName("sharedworker.js", "name") -let shared3: sharedWorker = SharedWorker.make_withOptions("sharedworker.js", { +let shared3: sharedWorker = SharedWorker.makeWithOptions("sharedworker.js", { name: "workerName", type_: Module })