Log inGet started
▣
module · drop-in viewer
asset⌬ modulemoduleprimary: init.luau·part ofpackage zerojs.package·originates fromworld f63c1fe3-4…▲1problem

globals

The minimal global surface installed onto a VM's global JS object.

byzero-proxy @ DESKTOP-DB3UJOJ·posted 3mo ago
What it does

globals

The minimal global surface installed onto a VM's global JS object.

globals.install(rt, globalObj) seeds globalThis (a self-reference), the undefined/NaN/Infinity values, a console with log/warn/error bound to the engine log (every line prefixed [zerojs]), Object (callable, with Object.keys), Array (with Array.isArray), and the Error, TypeError, RangeError, ReferenceError and SyntaxError constructors. Each error constructor is callable with and without new; instances carry the class prototype, own name/message/stack, and a stack captured from the interpreter's live call stack at construction, so instanceof Error holds for every subclass. Function name and length and prototype constructor are non-enumerable, following the realm's enumerability model.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

strict

isObject(v: any) → boolean

argtypedescription
vany

renderArg(rt: any, v: any) → string

Render one console argument: primitives via the realm's ToString, objects and arrays as a compact single-line form ({a: 1} / [1, 2]).

argtypedescription
rtany
vany

joinArgs(rt: any, args: { any }) → string

argtypedescription
rtany
args{ any }

tagLines(text: string) → string

Prefix each line of a console render with the package tag before it reaches the engine log.

argtypedescription
textstring

installErrors(rt: any, globalObj: any) → void

Build the Error constructor family. Each class is callable with and without `new`; instances get the class proto, own name/message/stack, and a stack captured from the interpreter's live call stack at construction.

argtypedescription
rtany
globalObjany

construct(_rt: any, args: { any }) → any

argtypedescription
_rtany
args{ any }

call(rt2: any, _this: any, args: { any }) → void

argtypedescription
rt2any
_thisany
args{ any }

construct(rt2: any, args: { any }, _newTarget: any) → void

argtypedescription
rt2any
args{ any }
_newTargetany

installConsole(rt: any, globalObj: any) → void

argtypedescription
rtany
globalObjany

method(sink: (string) → void

argtypedescription
sink(string

call(_rt: any, _this: any, args: { any }) → void

argtypedescription
_rtany
_thisany
args{ any }

isCallable(v: any) → boolean

Report whether a JS value is callable: an object carrying a native/JS call.

argtypedescription
vany

installQueueMicrotask(rt: any, globalObj: any, loop: any) → void

Install the JS global `queueMicrotask(fn)`, which enqueues a microtask on the VM's loop that invokes `fn` with no arguments and `this` undefined. A non-callable argument throws a TypeError, matching Node's contract.

argtypedescription
rtany
globalObjany
loopany

call(_rt: any, _this: any, args: { any }) → void

argtypedescription
_rtany
_thisany
args{ any }

coerceDelay(rt: any, v: any) → number

Coerce a JS delay argument to a whole non-negative millisecond count. ToNumber runs first (per HTML's timer steps); NaN and negatives clamp to 0, matching browser and Node behaviour where a bad delay schedules for the next turn.

argtypedescription
rtany
vany

installTimers(rt: any, globalObj: any, loop: any) → void

Install the JS timer globals `setTimeout`/`setInterval` and their `clearTimeout`/`clearInterval` cancellers onto `globalObj`, backed by the VM's loop. `setTimeout(fn, delay?, ...args)` arms a one-shot timer that invokes `fn` with `...args` and `this` undefined after `delay` ms; `setInterval` arms a repeating timer. Both return the loop's numeric id. A non-callable `fn` throws a TypeError; the delay is coerced via ToNumber with NaN/negative clamped to 0. `clearTimeout` and `clearInterval` both drop the timer of the given id and are interchangeable across one-shot and interval ids, matching the runtime reality that the two id spaces are shared.

argtypedescription
rtany
globalObjany
loopany

armGlobal(name: string, repeating: boolean) → any

argtypedescription
namestring
repeatingboolean

call(_rt: any, _this: any, args: { any }) → void

argtypedescription
_rtany
_thisany
args{ any }

invoke( ) → void

canceller(name: string) → any

argtypedescription
namestring

call(_rt: any, _this: any, args: { any }) → void

argtypedescription
_rtany
_thisany
args{ any }

install(rt: any, globalObj: any, loop: any) → void

Install the global surface onto `globalObj` and wire it as the JS global object so undeclared reads and top-level assignments resolve through it. The Object surface, the Array surface, Function.prototype, and the global conversion and parsing functions come from stdlib.install. `loop` is the VM's event loop, backing the asynchronous globals such as queueMicrotask.

argtypedescription
rtany
globalObjany
loopany

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

Showing up to 3 levels deep. Open a part to see what it holds further down.

25+items
❒
package · born here
❒asset
ZeroJS is a JavaScript interpreter for the Zero engine, written in Luau. It parses and executes ES2017-practical JavaScript entirely inside the Luau VM — no native code, no WebAssembly, no external dependency — and marshals values back to Luau transparently. ## Importing ```luau local zerojs = require("~zerojs.api") ``` `~zerojs` is this package's alias, registered from the `name` in its `package.yaml` wherever the package sits. The same spelling therefore works from the world that authors the package and from a world that installed it, at any depth. Every module is reachable the same way — `~zerojs.parser`, `~zerojs.stdlib.promise` — and the package's own modules reference each other with those ids. ## API surface ### Module-level | Symbol | Type | Description | |--------|------|-------------| | `zerojs.eval(src)` | `(string) -> any` | Parse and execute `src` in a fresh one-shot VM. Returns the marshaled JS completion value. Raises a Luau error on a JS exception. | | `zerojs.new(opts?)` | `(table?) -> VM` | Create a persistent VM. `opts.env` seeds additional JS globals from a Luau table. | | `zerojs.null` | sentinel | The JS `null` value (distinct from Luau `nil`). | | `zerojs.undefined` | sentinel | The JS `undefined` value, which marshals to Luau `nil` when returned. | | `zerojs.version` | `string` | Version string of this package. | | `zerojs.lastError(vm)` | `(VM) -> table?` | Returns the structured payload `{ name, message, stack }` from the most recent JS exception on `vm`. `nil` if no exception has occurred on that VM. | ### VM instance | Method | Description | |--------|-------------| | `vm:run(src, opts?)` | Execute `src` in this VM's persistent realm. `opts.sourceName` names the source for error messages and stack frames. Returns the marshaled completion value. Raises directing to `runAsync` when the script leaves a timer armed or a coroutine suspended across a frame. | | `vm:runAsync(src, opts?)` | Execute `src`, driving its event loop across engine frames until it settles. Returns a `RunHandle` immediately. `opts.timeoutMs` rejects the run if it outlasts that many milliseconds. Only one `runAsync` may be in flight per VM at a time; a second call while the first is unsettled raises. | | `vm:get(name)` | Read a global from the VM's realm. | | `vm:set(name, value)` | Write a marshaled Luau value as a JS global in the VM's realm. | ### `RunHandle` (returned by `vm:runAsync`) | Field | Description | |-------|-------------| | `done` | `false` until the run reaches a terminal state, then `true`. | | `ok` | Once `done`, `true` for a resolved run and `false` for a rejection or timeout. | | `value` | The marshaled completion value on a resolved run. | | `error` | The rendered message text on a rejected or timed-out run. | | `lastError` | The structured `{ name, message, stack }` payload for a failed run. | | `thread` | The engine `task.spawn` driver pumping the loop each frame — present only while the run is still pumping, and `nil` once the run settles on its arming frame (a synchronous or microtask-only completion needs no per-frame driver). | | `handle:await(maxFrames?)` | From a yieldable Luau context, poll `done` frame-by-frame until the handle settles, then return it. | A `runAsync` stays pending while the loop has work: an armed `setInterval` keeps it pending exactly as an un-`unref`'d handle keeps Node alive — clear the interval or bound the run with `timeoutMs`. ## Marshaling Luau values passed to `opts.env` or `vm:set` are converted to JS values. JS values returned from `run`/`eval` are converted back to Luau: numbers, strings, and booleans are transparent; arrays become 1-based Luau tables; objects become string-keyed Luau tables; JS functions become callable Luau closures; `undefined` becomes `nil`; `null` becomes `zerojs.null`. ## Step-budget sandbox Each VM runs with a default execution budget of 1,000,000 interpreter steps. A script that exceeds the budget raises a JS `RangeError: step budget exceeded`, which surfaces as a Luau error. The budget resets on each `run`/`eval` call. ## Language scope - Variable declarations: `var` (function-scoped hoisting), `let` and `const` with full TDZ enforcement - Functions: declarations, expressions, arrow functions, closures, rest parameters, default parameters - Classes: declarations and expressions, inheritance via `extends`, `super()` in constructors and methods, getter and setter accessors, instance fields, static fields and methods, computed method keys, named class expressions, TDZ before declaration - Destructuring: object and array patterns in declarations, assignment, and function parameters; nested patterns; rename, default, rest; computed keys in object patterns; elision in array patterns - Spread: array literals, call arguments, `new` arguments, object literals - Template literals (untagged) - Full coercion and equality semantics: `==`/`!=` abstract equality, `===`/`!==` strict equality, `typeof`, `instanceof` - `try`/`catch`/`finally`, `throw` - All loop forms: `for`, `while`, `do-while`, `for-in`, `for-of`; `switch` with fallthrough - `async`/`await` — real event-loop semantics: an async function returns a promise, runs synchronously up to the first `await`, and resumes from a microtask when its awaited operand settles - Property enumerability: `for-in` yields only own enumerable keys; object rest excludes prototype methods ### Asynchrony and the event loop - `Promise` with the full ES surface: `then`/`catch`/`finally`, `resolve`/`reject`, and the combinators `all`, `allSettled`, `race`, and `any` (with `AggregateError` when every input to `any` rejects) - `queueMicrotask` for scheduling a microtask directly - Timers: `setTimeout`/`clearTimeout` and `setInterval`/`clearInterval`, with extra arguments forwarded to the callback - `vm:runAsync(src, opts?)` drives a script's timers, microtasks, and promise settlements across engine frames and returns a `RunHandle` (see the VM table above) - A long synchronous loop under `runAsync` yields at each step-budget boundary and resumes on a later frame instead of raising `RangeError`; the same script under `vm:run` still raises ### Standard library - `Object`: callable coercion plus `keys`, `values`, `entries`, `assign`, `freeze`, `isFrozen`, `create`, `getPrototypeOf`, `defineProperty`, `fromEntries`, `hasOwn`, and the `Object.prototype` methods (`hasOwnProperty`, `toString`, `isPrototypeOf`) - `Function.prototype`: `call`, `apply`, `bind` - Global conversions and predicates: `parseInt`, `parseFloat`, `isNaN`, `isFinite`, `String`, `Number`, `Boolean` - `Array` and `Array.prototype`: construction, `isArray`, `from`, `of`, and the iteration/mutation/query methods (`map`, `filter`, `reduce`, `forEach`, `find`, `some`, `every`, `slice`, `splice`, `concat`, `join`, `indexOf`, `includes`, `sort`, `reverse`, `push`, `pop`, `shift`, `unshift`, `flat`, `fill`, `keys`, `values`, `entries`) - `String.prototype`: `slice`, `substring`, `substr`, `split`, `indexOf`, `includes`, `startsWith`, `endsWith`, `repeat`, `padStart`, `padEnd`, `trim`, `trimStart`, `trimEnd`, `toUpperCase`, `toLowerCase`, `charAt`, `charCodeAt`, `codePointAt`, `at`, `concat`, `replace`, `replaceAll`, `match`, `matchAll`, `search` - `Number`: `isInteger`, `isSafeInteger`, `isFinite`, `isNaN`, `parseFloat`, `parseInt`, `MAX_SAFE_INTEGER`, `MIN_SAFE_INTEGER`, `MAX_VALUE`, `MIN_VALUE`, `EPSILON`, `POSITIVE_INFINITY`, `NEGATIVE_INFINITY`, `NaN`, and `Number.prototype` (`toFixed`, `toString`, `toPrecision`) - `Math`: the constants and functions (`abs`, `floor`, `ceil`, `round`, `trunc`, `sign`, `min`, `max`, `pow`, `sqrt`, `cbrt`, `hypot`, `exp`, `log`, `log2`, `log10`, the trig family, `random`) - `Date`: construction as `new Date()` (now) and `new Date(ms)` (epoch milliseconds), `now`, `getTime`, `getFullYear`, `getMonth`, `getDate`, `getHours`, `getMinutes`, `getSeconds`, `getMilliseconds`, `getDay`, `toISOString`, `toJSON` - `JSON`: `parse` and `stringify` (indent argument and array replacer whitelist) - `Map` and `Set`: construction from iterables, `get`/`set`/`has`/`delete`/`clear`, `add`, `size`, `forEach`, `keys`, `values`, `entries`, insertion-order iteration - `RegExp`: literals and the constructor, `test`, `exec`, `lastIndex`, `source`, `flags`, `global`, `ignoreCase`, `multiline`, `dotAll`, and the `String` regex methods above - Errors: `Error`, `TypeError`, `RangeError`, `ReferenceError`, `SyntaxError` constructors and inheritance; `console.log`/`warn`/`error`; `globalThis`, `NaN`, `Infinity` ### Out of scope by design - Generators and iterators (`function*`, `yield`) - `Proxy` and `Reflect` - Labeled statements and `with` - Tagged template literals - Optional chaining (`?.`) and nullish coalescing (`??`) The full divergence list — where ZeroJS behavior differs from a browser engine — lives in the guide's divergence section. ## Test suites Seven suites ship with the package, run via `tools.tests.run`: ```luau tools.tests.run({ suite = "zerojs_lexer" }) -- tokenization tools.tests.run({ suite = "zerojs_parser" }) -- AST construction and error recovery tools.tests.run({ suite = "zerojs_semantics" }) -- runtime semantics end-to-end tools.tests.run({ suite = "zerojs_stdlib" }) -- the standard-library surface tools.tests.run({ suite = "zerojs_regex" }) -- the regex engine and RegExp methods tools.tests.run({ suite = "zerojs_async" }) -- the event loop, promises, and timers tools.tests.run({ suite = "zerojs_smoke" }) -- unmodified real-world JS programs ```
▲ 1↑ born
▣
module · born here
❒asset
# values The JavaScript value model: the `undefined` and `null` sentinels, their predicates, and `jsTypeof`, which classify the primitive and reference values the interpreter operates on.
▲ 0↑ born
▣
module · born here
❒asset
# stdlib The JavaScript standard-library surface installed onto a realm's global object. `stdlib.install(rt, globalObj)` applies each submodule installer. `object.luau` owns the `Object` callable and its statics, `Object.prototype`, `Function.prototype` (call/apply/bind), a minimal `Number.prototype.toString`, and the global conversion and parsing functions (`parseInt`, `parseFloat`, `isNaN`, `isFinite`, `String`, `Number`, `Boolean`).
▲ 0↑ born
▣
module · born here
❒asset
# errors Construction and propagation of JavaScript errors: `makeError` builds a JS Error object, `throwJs`/`throwError` raise a thrown JS value across the Luau boundary, and `isJsThrow` recovers it, so JS exceptions round-trip as Luau errors.
▲ 0↑ born
backing path · zerojs.package/globals.module

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

These counts cover only the parts this page shows. Problems on the parts it leaves out are not counted here.

1+problem

Inside

1 problem across 1 item
▲
dep.dangling.checksum_drift · L10
dep `~zerojs.stdlib` -> 3bc3cdba-62e1-46cf-9ad6-a1b2b4e4d2d9 no longer resolves (checksum_drift)
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.