Skip to content

feat(runtime): ns:worker_threads builtin module with typed iOS worker options - #494

Open
edusperoni wants to merge 1 commit into
fix/worker-terminate-during-entryfrom
feat/ns-worker-module
Open

edusperoni wants to merge 1 commit into
fix/worker-terminate-during-entryfrom
feat/ns-worker-module

Conversation

@edusperoni

@edusperoni edusperoni commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #493 (base branch fix/worker-terminate-during-entry); only the last commit is this PR.

What

A new ns:worker_threads builtin exporting the runtime's own Worker constructor, plus type declarations for the iOS constructor options that #470 (ios.priority) and #471 (resourceLimits) added but never typed. The name pairs with the node:worker_threads shim the way ns:util/node:util and ns:module/node:module do, and the shim now takes its constructor from the module instead of reading globalThis.Worker.

import { Worker } from "ns:worker_threads";

const worker = new Worker("./heavy.js", {
  ios: { priority: "utility" },
  resourceLimits: { maxOldGenerationSizeMb: 64 },
});

Why a module

The options live on the global Worker, whose type comes from whichever lib a program includes. A specifier gives typed code one fixed place to name the constructor and its options. The binding takes the constructor from the template Worker::Init installed, which V8 instantiates once per context, so the module hands out the very function the global was created with even after an app reassigns globalThis.Worker.

The export set is Worker only for now. The channel half (MessageChannel, MessagePort, BroadcastChannel) can join later the way ns:util grew TextEncoder; the shim already hands out the global objects for those.

Types

types/ns-worker-threads.d.ts declares the module (Worker, WorkerOptions, WorkerIosOptions, WorkerResourceLimits, WorkerPriority, and the event shapes a standalone declaration needs). At script level it does what @types/node does for its own globals:

  • the two options merge into the global WorkerOptions, so new Worker(path, { ios }) on the DOM constructor type-checks;
  • declare var Worker uses the typeof globalThis extends { onmessage: any; Worker: infer T } probe, so a program with a DOM lib keeps the lib's own declaration (the two declare vars agree) and a program without one gets the module's constructor as the global.

Verified with tsc --strict against a DOM program and a non-DOM program: the DOM one is clean, including @ts-expect-error checks on a bad priority name and a string megabyte count; the non-DOM one reports only the pre-existing URL references in ns-module.d.ts.

Docs and tests

docs/ns-builtin-modules.md gains the module's reference section (marked experimental, iOS-only until Android ships it), the public-row count, and a corrected node:worker_threads row; docs/worker-threads.md points at it from "Worker options". NsWorkerThreadsTests.js pins the frozen export set, identity with the global, the per-realm singleton, distinctness from the shim's module object, construction with both options, and, through a worker fixture that reassigns globalThis.Worker before its first require("ns:worker_threads"), that the module still exports the original constructor.

Summary by CodeRabbit

  • New Features

    • Added the experimental, iOS-only ns:worker_threads module, exposing the runtime’s Worker constructor with support for iOS priority and resource limit options.
    • Added TypeScript declarations for the module, worker options, events, and global worker types.
  • Documentation

    • Documented the new builtin module and its relationship to the node:worker_threads bridge.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 31 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 75e55714-294c-4b39-8dc7-50c36ed64c8b
📥 Commits

Reviewing files that changed from the base of the PR and between 31753d7 and a38ff54.

📒 Files selected for processing (13)
  • NativeScript/runtime/NsBuiltinModules.cpp
  • NativeScript/runtime/Worker.h
  • NativeScript/runtime/Worker.mm
  • NativeScript/runtime/js/node-worker-threads.js
  • NativeScript/runtime/js/ns-worker-threads.js
  • TestRunner/app/tests/NsWorkerThreadsTests.js
  • TestRunner/app/tests/index.js
  • TestRunner/app/tests/nsWorkerThreadsIdentityWorker.js
  • docs/ns-builtin-modules.md
  • docs/worker-threads.md
  • tools/js2c-inputs.xcfilelist
  • types/index.d.ts
  • types/ns-worker-threads.d.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bd72e8dc-0539-41a3-b2ac-ede7d75086ca
📥 Commits

Reviewing files that changed from the base of the PR and between 6f54a44 and 31753d7.

📒 Files selected for processing (13)
  • NativeScript/runtime/NsBuiltinModules.cpp
  • NativeScript/runtime/Worker.h
  • NativeScript/runtime/Worker.mm
  • NativeScript/runtime/js/node-worker-threads.js
  • NativeScript/runtime/js/ns-worker-threads.js
  • TestRunner/app/tests/NsWorkerThreadsTests.js
  • TestRunner/app/tests/index.js
  • TestRunner/app/tests/nsWorkerThreadsIdentityWorker.js
  • docs/ns-builtin-modules.md
  • docs/worker-threads.md
  • tools/js2c-inputs.xcfilelist
  • types/index.d.ts
  • types/ns-worker-threads.d.ts

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The runtime adds the ns:worker_threads builtin and exports its Worker constructor. The node:worker_threads shim imports that constructor. The changes also add TypeScript declarations, documentation, and tests.

Changes

Worker threads builtin

Layer / File(s) Summary
Expose the runtime Worker constructor
NativeScript/runtime/Worker.h, NativeScript/runtime/Worker.mm, NativeScript/runtime/NsBuiltinModules.cpp
Worker stores its constructor template per isolate and exposes the constructor for a context. The builtin registry registers ns:worker_threads, whose binding exports that constructor.
Wire the JavaScript builtin and shim
NativeScript/runtime/js/ns-worker-threads.js, NativeScript/runtime/js/node-worker-threads.js, tools/js2c-inputs.xcfilelist
The new builtin exports and freezes its Worker export. The node:worker_threads shim imports NativeWorker from the builtin. The new JavaScript module is added to the js2c inputs.
Describe the builtin API
types/ns-worker-threads.d.ts, types/index.d.ts, docs/ns-builtin-modules.md, docs/worker-threads.md
The declarations describe worker options, events, and constructor types, including global Worker types. Documentation describes the experimental iOS builtin, its options, and its relationship to the shim.
Validate module identity and worker options
TestRunner/app/tests/NsWorkerThreadsTests.js, TestRunner/app/tests/nsWorkerThreadsIdentityWorker.js, TestRunner/app/tests/index.js
Tests check module freezing and constructor identity, worker construction with iOS priority and resource limits, and constructor identity in a worker realm.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant WorkerInit
  participant NsWorkerThreadsBinding
  participant NsWorkerThreadsModule
  participant NodeWorkerThreadsShim
  WorkerInit->>NsWorkerThreadsBinding: store and retrieve context Worker constructor
  NsWorkerThreadsBinding->>NsWorkerThreadsModule: provide binding.Worker
  NsWorkerThreadsModule->>NodeWorkerThreadsShim: export Worker for shim import
Loading

Suggested reviewers: nathanwalker

Merge Risk: ⚪ Minimal · up to 31753

This PR adds the experimental ns:worker_threads module and typed worker options. No concrete defect was found in the supplied context, so it is low risk to merge after the usual iOS build and test run.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 9 files. (4 skipped: 4… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main changes: adding the ns:worker_threads runtime builtin and typed iOS worker options.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 9 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit finds a Worker bright,
It hops through modules, swift and light.
The frozen exports hold their ground,
While typed options gather round.
A worker starts, then sends a note,
And bunnies cheer the message’s route.

Comment @coderabbitai help to get the list of available commands.

@edusperoni
edusperoni added this pull request to stack #495 October 7, 2026 20:04
@edusperoni
edusperoni marked this pull request as ready for review October 7, 2026 20:05
@edusperoni
edusperoni force-pushed the feat/ns-worker-module branch from 31753d7 to a858caf Compare October 7, 2026 20:23
… options

Adds `ns:worker_threads`, exporting the runtime's own Worker constructor, so
typed code can name the constructor and its iOS options (`ios.priority`,
Node's `resourceLimits`) by specifier instead of through whatever
`globalThis.Worker` resolves to in the program's type environment. The name
pairs with the `node:worker_threads` shim the way `ns:util`/`node:util` and
`ns:module`/`node:module` do, and the shim now takes the constructor from the
module. The binding takes it from the template Worker::Init installed, which
V8 instantiates once per context, so the module hands out the very function
the global was created with even after an app reassigns the global.

types/ns-worker-threads.d.ts declares the module and, at script level,
merges the two options into the global WorkerOptions and declares the global
Worker the way @types/node declares its own globals: a program with a DOM lib
keeps the lib's declaration, so `new Worker(path, { ios })` type-checks
either way without a conflicting redeclaration. Verified with tsc against a
DOM and a non-DOM program.

Experimental, iOS-only until the Android runtime ships the module.
@edusperoni
edusperoni force-pushed the feat/ns-worker-module branch from a858caf to a38ff54 Compare October 8, 2026 19:38

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant