Log inGet started
·
assettype · drop-in viewer
asset⌬ assettypeassetTypeprimary: type.yaml·part ofpackage zerojs.package·originates fromworld f63c1fe3-4…

zJs.assetType

A zJs asset is a JavaScript ES module: a `<name>.zJs/` folder whose `main.js` holds JavaScript source parsed and evaluated by the `zerojs` interpreter. The identity is `<name>` (the `.zJs` suffix strips).

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

zJs (asset type)

A zJs asset is a JavaScript ES module: a <name>.zJs/ folder whose main.js holds JavaScript source parsed and evaluated by the zerojs interpreter. The identity is <name> (the .zJs suffix strips).

Folder shape

  • main.js — the module body. Required.
  • README.md — instance documentation. Required.
  • .metadata — tags sidecar ({"tags": []}). Required.

How to create one

asset.create("zJs", "greeter")
-- Creates /zero/source/greeter.zJs/ with a hello-world main.js.
asset.create("zJs", "greeter", { source = "export const x = 1" })
-- main.js is the given source verbatim.

Static diagnostics

Every write to main.js reparses the module and resolves its import specifiers against the live asset index. asset.resolve("<name>", "zJs"):check() returns { ok, diagnostics }: ok is true when the module parses and every import resolves to another zJs module; each diagnostic carries a severity, message, line, and col. No JavaScript runs during a check.

Interface

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

conforms to

zero/asset-type/v1
⌬ Spec
suffix.zJscontainernoprimary aliasesmain.jsrequired filesmain.js, README.md, .metadata
Exposed API
⌬ Instance methods

check(self: ?) →

Static diagnostics for THIS module's `main.js`: parse errors plus imports that do not resolve to a zJs module. Reads the cache `onChange` maintains, running the parse+resolve pipeline once on a cold reference.

argtypedescription
self?

examples

local r = asset.resolve("greeter", "zJs"):check(); if not r.ok then ... end

run(self: ?, opts: { env: { [string]: any }? }?, opts.env: ?) → any

Execute THIS module on a fresh JavaScript VM and marshal the result to Luau. A plain script (no imports or exports) runs as a script and returns its completion value; a module evaluates through the module graph and returns nil, since module evaluation has no completion value. `opts.env` seeds host values as JavaScript globals. Refuses when the module carries diagnostics, naming the first, and directs a script that leaves asynchronous work pending to `runAsync`.

argtypedescription
self?
opts{ env: { [string]: any }? }?
opts.env?host values injected as JavaScript globals for this run.

examples

local sum = asset.resolve("calc", "zJs"):run({ env = { base = 10 } })

runAsync(self: ?, opts: { env: { [string]: any }?, timeoutMs: number? }?, opts.env: ?, opts.timeoutMs: ?) → any

Execute THIS module's program on a fresh VM under the asynchronous runner, driving armed timers and pending promises to completion. Returns the engine run handle: poll `handle.done`, then read `handle.ok` / `handle.value` / `handle.error`, or call `handle:await()` from a yieldable context. `opts.timeoutMs` bounds a never-settling run. Refuses when the module carries diagnostics, naming the first.

argtypedescription
self?
opts{ env: { [string]: any }?, timeoutMs: number? }?
opts.env?host values injected as JavaScript globals for this run.
opts.timeoutMs?milliseconds after which a never-settling run rejects.

examples

local h = asset.resolve("job", "zJs"):runAsync({ timeoutMs = 1000 }); h:await()

exports(self: ?, opts: { env: { [string]: any }? }?, opts.env: ?) → any

Evaluate THIS module as an ES module on a fresh VM and return its export namespace marshaled to a Luau table: each named export plus `default`. Cross-asset imports resolve through the live asset index, so a JS library built from several `.zJs` assets is consumed as one table. Refuses when the module carries diagnostics, naming the first; a cycle, an unresolved import, or a thrown module body surfaces as a Luau error.

argtypedescription
self?
opts{ env: { [string]: any }? }?
opts.env?host values injected as JavaScript globals for this evaluation.

examples

local lib = asset.resolve("mathlib", "zJs"):exports(); print(lib.add(1, 2))
⌬ Hooks

onCreate(name: string, opts: CreateOpts, opts.source: ?) →

Generic-creation hook for `asset.create("zJs", name, opts)`. Pure: returns the instance's content file map for the caller to persist. `opts.source`, when given, becomes `main.js` verbatim; otherwise a hello-world module naming the instance is scaffolded from the template.

argtypedescription
namestringzJs module identity (the instance name).
optsCreateOpts
opts.source?JavaScript module source for `main.js`.

examples

asset.create("zJs", "greeter", { source = "export const x = 1" })

onChange(ref: ?, change: ?) → void

Asset-type change callback: recompute this module's static diagnostics whenever its `main.js` is edited or the whole instance is seeded. Convergent: it reads the source and asset index and replaces the ref's cached pipeline result; it never writes to the VFS. Edits to sidecars (`README.md`, `.metadata`) leave the cache untouched.

argtypedescription
ref?
change?

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.

20+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
# api The ZeroJS public API: zerojs.new/eval, VM run/get/set, sentinels, and version. The package root init.luau re-exports this module.
▲ 0↑ born
▣
module · born here
❒asset
# parser The JavaScript parser: `parser.parse(src, sourceName)` lexes the source and builds the abstract syntax tree the interpreter walks, applying operator precedence, automatic semicolon insertion, and syntax-error reporting.
▲ 0↑ born
▣
module · born here
❒asset
# bridge Marshaling between Luau host values and a realm's JavaScript value model. `bridge.toJs(rt, luauValue)` lifts a Luau value into JS; `bridge.toLuau(rt, jsValue)` lowers a JS value back into Luau. Numbers, strings and booleans pass through both ways. Luau `nil` becomes `values.undefined`; `values.undefined` becomes `nil` and `values.null` returns the sentinel itself. A dense integer-keyed Luau table becomes a 0-based JS array; any other plain table becomes a JS object. Luau functions become JS functions (and vice versa), calling back across the boundary with arguments and return values marshaled. Tables carrying a metatable and userdata are opaque host handles, wrapped in a private JS field and unwrapped back to the original on the return trip, so values like AssetRefs survive round trips. Both directions are deep and cycle-safe: a per-call seen-map yields one result container per source container.
▲ 0↑ born
backing path · zerojs.package/zJs.assetType

Problems

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

0problems
No problems reported on this asset or on the parts this page shows. Parts it leaves out are not counted here.
⌬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.