Commit Graph
68 Commits
Author SHA1 Message Date
Chris Tate eb8a148605 Merge main 2026-10-20 21:01:40 -05:00
Malte UblandClaude Opus 5.5 fec779abbb Use the events module and EventEmitter as untyped constructor values
In JavaScript, `ReleaseEmitter = EventEmitter` over `const EventEmitter =
require("events")` was refused with SC1090 ("a runtime-provided class value
as an untyped value"), and `class Channel extends require("events")` failed
on the require call as a value. Bundled npm code does both, for example a
small semaphore that aliases EventEmitter and constructs its release channel
through the alias.

- The events module binding and the EventEmitter or stream class itself
  turn untyped as the runtime's untyped constructor that constructor
  functions already use (scr_dyn_builtin_class.c). `new` through it builds
  an emitter object with Node's listener API, and `===` against the class
  compares identity.
- `x instanceof EventEmitter` on an untyped value also recognizes a boxed
  compiled emitter (an instance of a program class extending EventEmitter),
  which the prototype test alone answered false for. The same holds through
  an untyped binding narrowed to the class.
- `class X extends require("events")` extends the runtime emitter, as
  through a require binding.
- A typed array of the class built from such values (`[EventEmitter]`) is
  refused with SC1090 rather than failing its class check at run time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 12:41:53 -07:00
Malte UblandClaude Opus 5.5 bebc0946bc Point bundled copies of shimmed packages at the shim; guard every shim
A bundle that embeds fs-extra (build-utils does) compiled the package's
own JavaScript, whose computed export table and graceful-fs internals the
static model cannot follow. A __commonJS chunk whose key names a shimmed
package's main file at a supported version now requires the shim
instead, through a forwarder declaration beside the bundle: the checker
follows it to the shim (a package's JavaScript cannot load TypeScript
sources directly), and module resolution answers the shim for its path.
The package's other chunks are no longer reached. Calls through such a
require of a TypeScript module lower when the export never reads `this`
(require() answers the module's namespace).

package-shim-guard.test.ts compiles every registered shim module under
both type worlds and fails on any lowering diagnostic or fence inside the
shims, reached or not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 01:21:06 -07:00
Malte UblandClaude Opus 5.5 5b53ce7144 Hoist lazily defined classes over global constructors
A bundled package's error class defined inside an __esm initializer
(`NowBuildError = class extends Error { … }`) now hoists to a declaration
like the classes over builtin module members, so a program class can
extend it and `new` and `instanceof` work against both. Reading a standard
global constructor the bundle never rebinds runs no code. References in
esbuild's `0 && (module.exports = { … })` annotation for Node's CommonJS
lexer never run and no longer block the move.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:51:07 -07:00
Malte UblandClaude Opus 5.5 1a17bd3405 Merge branch 'opt/npm-polyfill-shims' into opt/npm-esm-class-hoist
Renumbers this branch's npm case 2572 to 2588, after the renumbered
polyfill cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 21:44:23 -07:00
Malte UblandClaude Opus 5.5 1b282f9c80 Merge branch 'opt/npm-cjs-exports' into opt/npm-polyfill-shims
Renumbers this branch's npm cases 2569-2571 to 2585-2587: #1411 now uses
2571.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 21:44:08 -07:00
Malte UblandClaude Opus 5.5 dde27c7e21 Merge branch 'opt/npm-lazy-loaders' into opt/npm-cjs-exports
Renumbers this branch's npm cases 2567-2568 to 2583-2584: #1422 now uses
2567.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 21:43:36 -07:00
Malte UblandClaude Opus 5.5 6fc85e848d Merge branch 'opt/npm-esm-wrappers' into opt/npm-lazy-loaders
Renumbers this branch's npm cases 2564-2566 to 2580-2582: #1411 now uses
2564-2566.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 21:42:59 -07:00
Malte UblandClaude Opus 5.5 3d8c7259a0 Hoist lazily initialized ES module classes and follow on-demand workspace imports
A class a bundled ES module's __esm initializer stores into a module
binding (`Multi = class extends import_stream.Readable { … }`) becomes a
class declaration at the same text position: the initializer's body splits
around it into run-once pieces, so a class over a runtime-provided base no
longer has to exist as a stored class value. Only definitions whose
evaluation runs no code (no static fields, static blocks or computed names;
heritage absent, a builtin module member, or a hoisted class), declared
once, assigned only there and read only inside functions after the
assignment move.

npm selection now also scans the program modules a literal import()
reaches, with their static graphs: a workspace package loaded on demand
had its npm dependencies refused as "not part of the compiled module
graph".

`new import_x.C()` respelled `new require("x").C()`, which constructs the
require call; the interop binding now becomes `(require("x"))` there.

util.inherits onto a runtime-provided class (stream.Readable, the from2
and multistream shape) fences where it is written instead of failing in
Node's argument validation at run time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 20:33:19 -07:00
Chris Tate d07188d250 Merge base 2026-10-19 22:00:59 -05:00
Malte UblandClaude Opus 5.5 f80e4c1a09 Compile polyfill packages that are Node builtins as the builtins
isarray, safe-buffer, process-nextick-args, inherits and util-deprecate
evaluate to a Node builtin on Node 24 at their checked major versions, so
a require of one compiles as that builtin expression at the require's
position: from an opted-in package's files (the installed version where
Node's resolution finds it), from the program's own CommonJS files, and
through an esbuild __commonJS chunk whose pnpm path key names the package
and its version. The package's files never join the program.

readable-stream 2.x and 4.x compile as node:stream, the package's own
READABLE_STREAM=disable behavior (a documented divergence). A use of the
entry's export picks the builtin module (member reads of the carried
classes) or stream.Readable (value uses); a mixture keeps the package.
3.x stays as is: its disable branch throws on Node 24.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:52:05 -07:00
Malte UblandClaude Opus 5.5 5670bc182e Respell members of a function export object; name conditional exports
A CommonJS module whose export object is one of its own top-level
functions (semver 5/6's `exports = module.exports = SemVer`) reaches
its members through that function after the statement: member reads
and writes through module.exports (and, after the rebinding, every
`exports` reference) become members of the function, the expando form
both resolvers model, and the rebinding itself drops. Constructor
functions exported whole with members attached afterwards no longer
lose those members at runtime.

Replacing module.exports or rebinding exports inside a branch (an
environment-dependent export object, readable-stream 2.x) now names the
construct instead of the generic assignment fence, and a required
builtin module object is truthy in the LLVM backend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:21:52 -07:00
Chris Tate 4f7539103c Keep a lowered ES module namespace unobservable through calls that pass it as this
A call through a bundled ES module's namespace (`ns.fn()`, `(ns.fn)()`,
a tagged template) passes the namespace as `this`. Node's namespace is
the __toCommonJS object (`__esModule` first and non-enumerable,
non-configurable getters); the lowered object of getters differs. The
namespace lowers only when every such call targets a top-level function,
never reassigned, that reads no `this` (an arrow inside it included);
otherwise the package stays refused.
2026-10-19 19:10:11 -05:00
Malte UblandClaude Opus 5.5 02dba55958 Record order baselines for the new cases and corpus programs; format
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:55:55 -07:00
Malte UblandClaude Opus 5.5 bc32d97339 Compile build-utils' bundled code: star re-exports, aliases, three lowering fixes
- A star re-export of a lazily initialized module into the bundle's
  exports (__reExport(main, (init_x(), __toCommonJS(x_exports))))
  initializes the module at the statement and adds its names to the
  export table after the explicit ones, without default.
- The rewrite keeps the original's lexer answer whenever its export
  table holds accessors (Node's lexer stops at the first one).
- An npm alias directory of a selected package ("x-updated":
  "npm:x@6.3.0") resolves to that package's JavaScript in both resolvers.
- "use strict" code may read arguments in functions with parameters.
- A comma expression ending in null/undefined coerces its result.
- A void conditional return lowers as control flow.
- A detached method of a local class drops its empty capture list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:52:01 -07:00
Malte UblandClaude Opus 5.5 f7f239ad53 Lower memoized lazy loaders of bundled ES-module namespaces
A loader `L = () => M ??= NS` over a lazily initialized module's
namespace (optionally through __toESM) is respelled at every `L().name`
as the module's initializer call followed by the export's live read;
loaders whose result escapes as a value stay refused. The canonical
export table keeps a getter it cannot chase as a live accessor, so a
lazy re-export still initializes its module at the first read. An
ES-module importer copies those accessors once when it links the
CommonJS module, in the lexer's order, exactly like Node's loader;
require() keeps reading them live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 15:55:37 -07:00
Malte UblandClaude Opus 5.5 0d9a6da8c9 Select untyped dependencies and @types twins by identity
An untyped package another package's JavaScript imports is selected
whether resolution answers no declarations or its JavaScript. A
DefinitelyTyped twin qualifies by identity (@types/<mangled name>):
the declarations only check the program, and the JavaScript compiles
with its inferred surface, so a twin that disagrees with the shipped
JavaScript fails the build at the use rather than compiling against it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:19:07 -07:00
Malte UblandClaude Opus 5.5 f42fd146d9 Lower esbuild's lazy ES modules; select @types-typed packages by default
An __esm initializer becomes a run-once closure over its body in the
bundle's own scope. Interop bindings it assigns once from require()
become that require at the assignment, with their member reads respelled
as reads of the required module; a namespace read only through members
becomes an object literal of getters over the module's live bindings.
Asynchronous initializers, initializer results, and namespaces kept as
values (a memoized lazy loader) stay refused with a message naming them.

The default selection now also compiles a package typed by a
DefinitelyTyped twin that describes its installed release (same major,
or major.minor below 1.0), and untyped dependencies of compiled
packages. A twin for another release is refused with both versions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:00:32 -07:00
Malte UblandClaude Opus 5.5 405f643742 Judge bundled packages by the files their imports can load
Interop the rewrite cannot finish now refuses its package only when the
compiled program can load that file: the module order closed over every
literal require() and import() and, in package JavaScript, every import
and export declaration (a computed specifier keeps every file loadable).
A package reached through a leaf subpath and types from its main entry
stays static. Auto mode also no longer refuses a whitespace/syntax
minified bundle whose interop helpers keep their names: the recognizers
judge it instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:31:48 -07:00
Malte UblandClaude Opus 5.5 22edb6deb0 Test bundled chunks, cycles and refusals
Unit tests run each split bundle against its original under Node and
pin the refusal reasons; npm-static tests compile the new cases and
compare them with Node byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:20:28 -07:00
Chris Tate 961d27802f Make selected npm packages join the type-checked program (#1331) 2026-10-18 16:57:35 -05:00
Malte UblandClaude Opus 5.5 e90c77d36a Make selected npm packages join the type-checked program
scriptc's resolver and tsgo must answer one runtime file for every
opted-in npm edge; four disagreements left the file outside tsgo's
program (SC2013 "did not join the type-checked program") for express,
axios, body-parser, execa, fast-glob, globby, knex, uuid and tldts:

- uuid: the node-condition hoist re-added the inner "types" key after
  the claims were deleted; tsgo then took the browser build. Delete the
  claims after the hoist.
- tldts: tsgo's TypeScript-first lookup took the shipped root index.ts
  over "main". The fs shadow hides installed TypeScript sources of
  opted-in packages that have no same-stem runtime JavaScript.
- express: tsgo redirected same-version duplicate installs to one copy,
  either dropping a copy or merging two Node module instances into one.
  The shadow serves opted-in package.json files without "version".
- deep chains (get-intrinsic, dunder-proto, run-parallel, reusify,
  supports-color): maxNodeModuleJsDepth charges every node_modules hop.
  The program-root fixpoint also roots opted-in bare edges' runtime
  files that the program is missing.

All changes are gated on --npm-static being active.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:40:18 -07:00
Malte UblandClaude Opus 5.5 8597a364f6 Merge origin/main into opt/npm-small-fixes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 11:45:47 -07:00
Malte Ubl 8255315883 Merge origin/main into opt/cjs-interop 2026-10-18 06:46:23 -07:00
Malte UblandClaude Opus 5.5 ae91df908e Admit require cycles whose modules settle their exports first
A require cycle was always refused (SC1016). Node answers a require of a
module that is still evaluating with its exports as they stand, while the
compiled bindings alias the final declarations; the two agree when every
module of the cycle assigns all of its exports before its first statement
that can run another module's code, every other use of its export object
is a plain member read, and no module's top-level code can reach its
binding of another member. Each module then initializes exactly as it
would outside the cycle. This admits semver's comparator/range cycle
("hoisted class for cyclic dependency"); other cycles keep SC1016 with a
reason naming the offending statement.

The require reachability scan no longer treats a declaration's own name
as a read (esbuild's `var X = class {...}` before its requires), treats a
plain write of an export member as running only a setter published for it
(on-finished's `module.exports.isFinished = isFinished`), and keeps the
conservative scan for writes of __proto__, __esModule and members of a
replaced export object.

Evidence: corpus 6145 (the cycle), 6142 gains the esbuild layout; the
npm-static harness compiles the published fs.realpath@1.0.0,
on-finished@2.4.1 (with ee-first@1.1.1) and statuses@2.0.1 statically;
program.test.ts pins the TDZ analysis through var bindings plus the cycle
admission and refusals. Preflight/order baselines recorded for the new
fixtures; a full re-record changed no other fixture. Dependencies and
limitations docs describe the supported require forms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 06:24:04 -07:00
Malte UblandClaude Opus 5.5 e79380ce17 Name the runtime package in npm refusals and add transitive --npm-static
- A package typed only by an @types twin was judged under the twin's name
  and refused with "its import resolves to '@types/x/index.d.ts', not to
  runtime JavaScript". Selection now resolves the runtime package, and the
  refusal names it with the --npm-static option that compiles it anyway.
- Refusals the declaration and shipped-JS heuristics make carry the same
  remedy as a diagnostic hint; a dependency of a named package suggests
  the transitive form.
- `--npm-static=pkg...` (and `"pkg..."` in a library profile) selects the
  package and every package its files import, nested require() calls
  included, without the eligibility heuristics.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:39:21 -07:00
Malte UblandClaude Opus 5.5 d1639298ff Erase only import type edges, following Node's type stripping
Node runs TypeScript with verbatimModuleSyntax semantics: `import type` and
`export type … from` vanish, while `import { type A }` and
`export { type A } from` keep an empty clause and still load their module.

- Package selection skipped nothing: `import type { X } from "type-fest"`
  selected type-fest and failed with SC2013, and type imports pulled whole
  packages into the compile. Erased edges no longer select packages.
- Files reached only through erased edges are no longer program modules,
  so their imports (a `node:vm` import, say) no longer fence the build.
- Inline type-only clauses are real module edges again (their modules'
  side effects ran under Node but not in the binary); a cycle closed by
  one binds nothing and is admitted like a side-effect import.
- Interfaces, type aliases and type literals from an installed package's
  declarations map structurally, so values the program builds with a
  type-only package's types compile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:39:16 -07:00
Chris Tate f291f1c275 Monomorphize destructured options parameters of package functions
A package function that destructures its options object, such as
makeClass({ Base, name }), now specializes per call site like positional
parameters: each destructured name binds the static type of the matching
property, so a class passed as { Base } keeps its static type and
class extends Base builds a constructible subclass.

Fixes #938
Co-authored-by: phall <25888173+phall1@users.noreply.github.com>
2026-10-17 20:50:59 -05:00
Chris Tate 8bb3fa1077 Call valueOf and Symbol.toPrimitive on values held as any
`value.valueOf()` on a dynamic receiver was refused at compile time, a
class's own toString was not reached by `value.toString()`, and classes
could not declare a `[Symbol.toPrimitive]` method.

- `value.valueOf()` lowers to dyn.valueOf, which answers each kind's own
  valueOf: a primitive itself, a Date its time value, an object with a
  valueOf member that member's result, and any other object itself. A
  null-prototype dictionary throws "<spelling> is not a function", and
  null and undefined throw Node's property-read TypeError.
- When a boxed class declares valueOf or toString, `value.valueOf()` and
  `value.toString(argument)` call the class's method for its instances
  and keep the runtime call for every other value.
- Classes can declare `[Symbol.toPrimitive](hint)`. The dynamic
  conversions call it with "default" for `+` and `==`, "number" for the
  numeric operators and conversions, and "string" for template literals,
  String() and property keys, and throw Node's TypeError when it returns
  an object.
2026-10-17 19:01:59 -05:00
Chris Tate a5675b2279 Call factory-defined static methods with their receiver class
A static method that a function-local JavaScript class defines at
runtime and a program class inherits (Animal.extend("Dog")) is now
called directly with this bound to the receiver class when it captures
nothing from the factory's scope, so the subclass it builds has a static
base and constructs like Node.

Fixes #938
Co-authored-by: phall <25888173+phall1@users.noreply.github.com>
2026-10-17 17:31:30 -05:00
Chris Tate bbd24beba3 Split npm-static.test.ts across the Linux shards by measured test cost
npm-static.test.ts ran whole on one shard as an isolated suite: 406 s plain and
519 s sanitized in the cost table, and 672 s on san 2/20 in run 38835202089,
the second-longest job of that run.

skipUnownedTest (tests/harness/shard.ts), called from the suite's beforeEach,
balances the suite's tests across the shards of SCRIPTC_TEST_SHARD by their
measured milliseconds (tests/harness/npm-static-costs.json; an unmeasured test
weighs as much as the median) and skips the tests this shard does not own.
Repeated test.each titles get an occurrence suffix as their key. Without a
shard spec every test runs.

The CI plan runs the suite on every shard in its own vitest process
(caseShardedSideFiles) instead of on one owner. At 20 shards the largest
shares are 113 and 106 s plain and 181 and 137 s sanitized (the two published
Effect generator tests), and about 10 s elsewhere, plus about 11 s per shard to
collect the file. scripts/ci-test-costs.mjs also refreshes the per-test table
and drops side-queue files that no longer run whole.
2026-10-15 22:43:42 -05:00
Chris Tate 1771e6b5be Use console.trace as the still-unsupported import in the npm-static test 2026-10-13 19:40:12 -05:00
Chris Tate 5d184e3a73 Keep the console use-site test on members that stay unsupported 2026-10-13 11:25:58 -05:00
Chris Tate 7e6294ca0f Make scriptc compilation native-only 2026-10-12 12:25:30 -05:00
Chris Tate c08ab955ae Enforce linting and consistent source formatting
- Enforce oxlint and oxfmt for owned JavaScript and TypeScript with independent CI checks.
- Preserve compiler import boundaries and protected fixtures while cleaning up lint findings.
- Standardize source formatting and validate import, fixture, and embedded-source protections.
2026-10-05 17:51:24 -05:00
Chris Tate a07998f667 Expand static three.js workflows and host integration (#621)
* Expand static three.js workflows and host integration

* Preserve JavaScript class state in static three.js workflows

* Preserve inferred JavaScript behavior across static workflows

* Preserve inferred callables and native compatibility boundaries

* Retain annotated JavaScript factory exports and bootstrap-safe call spreads

* Preserve Buffer and child callback identities in static packages

* Clarify JavaScript symbol spread support
2026-10-02 19:56:34 -05:00
Chris Tate e2d58f60d2 Expand static support for common Effect 4 patterns (#600)
* Expand static compilation for common Effect 4 patterns

* Run every Effect 4 fixture slice in CI

* Preserve existing corpus behavior across Effect 4 lowering

* Preserve Effect platform callbacks and native stream state

* Record new corpus baselines and retain child stdin refusals

* Retire the obsolete stateful regex diagnostic

* Preserve promise reference count layout for cycle collection
2026-10-01 17:36:29 -05:00
Chris Tate 2069684b40 Expand static Effect support across common APIs (#598)
* Expand static Effect support across common APIs

* Preserve compiler parity across expanded Effect patterns

* Fix compiler regressions exposed by Effect coverage

* Bound shared type conversion traversal

* Clarify conversion contracts and tidy fixtures

* Run every Effect fixture in CI shards

* Preserve inferred array assignments in concurrent Effect programs

* Record inferred array fixture compiler ordering
2026-10-01 02:49:31 -05:00
Chris Tate c257368c5e Compile Effect generators statically (#589)
* Compile Effect generators statically

* test: declare the dormant array write's expected fence
2026-09-30 14:25:29 -05:00
Chris Tate d3dfdade8e Compile three.js math modules with LLVM
- Run published three.js vector, matrix, and quaternion operations natively and as Wasm without a JavaScript engine.
- Preserve shared class prototype data and JavaScript overload arguments.
- Support Math function values and distinct npm import and require entries.
2026-09-29 20:58:04 -05:00
Chris Tate 3f66c8e20b Make LLVM the sole production backend
- Remove C emission, debugging options, and automatic backend fallback.
- Complete LLVM lowering and native bootstrap coverage across supported targets.
- Link executables and libraries with precompiled C runtime packs, including iOS and Android.
2026-09-29 20:54:09 -05:00
Chris Tate 97a489845a Preserve native values through renderer initialization
- Carry BigInts, Sets, and regular expressions through checked native storage without a JavaScript engine.
- Preserve dictionary aliases, spreads, frozen metadata, and fluent initialization helpers.
- Collect checked object and closure cycles while preserving live references.
2026-09-29 00:20:53 -05:00
Chris Tate bf21f47827 Compile collection metadata and heterogeneous JavaScript tables natively
- Preserve async factory results and mixed table layouts through inference and destructuring.
- Support checked Map and Object.fromEntries construction with native weak collections.
- Keep native weak-key lifetimes and engine-backed collection identities intact.
2026-09-28 22:20:24 -05:00
Chris Tate 0053372853 Compile native renderer startup callables and dictionaries
- Support stored builtin helpers, typed rest callbacks, and shared FileHandle values.
- Preserve async results, specialized function bodies, and checked class receivers.
- Compile live export dictionaries and keep native property names distinct.
2026-09-28 14:53:57 -05:00
Chris Tate 7d5a471c67 Compile renderer values and callbacks natively
- Preserve unbound class methods, call-time receivers, and bound callback arguments.
- Keep native factory results, fallback functions, and mutable JavaScript renderer state intact.
- Support live Error.cause assignment, deletion, and property descriptors across aliases.
2026-09-28 13:54:28 -05:00
Chris Tate f7f5c6197a Preserve declared nullable callbacks through bundled class inheritance
- Compile zero-argument callback fields and derived arrow replacements using their declared nullable type.
- Preserve callback captures, identity, and null resets in native class storage.
2026-09-28 08:13:17 -05:00
Chris Tate 378eb2ffc6 Preserve declared scalar returns through bundled class aliases
- Carry declaration-backed string, number, and boolean method results into static JavaScript compilation.
- Match named class re-exports to their implementations while preserving self types and rejecting ambiguous aliases.
2026-09-28 07:55:21 -05:00
Chris Tate f251066719 Preserve JavaScript class values and inherited behavior
- Keep fields, accessor parameters, and return values inferred as undefined in native checked storage.
- Preserve virtual dispatch for overridden methods in JavaScript packages.
- Route assignments through class accessors without creating shadow fields.
2026-09-28 01:16:59 -05:00
Chris Tate 37a25ebf7f Support stable bundled loaders and native console imports
- Statically resolve stable let/var createRequire bindings while rejecting mutation, escape, and early use.
- Compile node:console output methods to native process streams and retain explicit custom Console refusals.
2026-09-27 22:20:25 -05:00
Chris Tate be1426a5cb feat(compiler): advance static OpenTUI support
- Extend native FFI with additional scalar widths and writable byte spans.
- Compile stored text codecs and supported bundled module patterns without a JavaScript engine.
- Document supported limits.
2026-09-27 21:49:40 -05:00