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).
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/source-extract/v2module ZJsAssetTypeRef Per-instance methods exposed on every `AssetRef<zJs>`. Loaded lazily by `asset_ref.module` the first time a zJs ref is touched in a VM. A zJs asset is a `<name>.zJs/` folder whose `main.js` holds a JavaScript ES module. The methods here surface the static write-time diagnostics the type computes for that module and execute it: `run` / `runAsync` for a script or module, and `exports` to read a module's export namespace as a Luau table.
hashSource(src: string) → number
Cheap content hash: a 31-polynomial rolling sum over the source bytes, kept inside 2^31-1 so every intermediate stays exactly representable as a double. It observes whether a cached parse still matches the on-disk source; it is not a cryptographic digest.
| arg | type | description |
|---|---|---|
| src | string |
mainPathOf(self: ?) → string
Resolve THIS instance's `main.js` from the reference's tracked path. `asset.resolve` hands back the `.zJs` folder; the body lives in its `main.js` (the path may already point at the entry when resolved from it).
| arg | type | description |
|---|---|---|
| self | ? |
identityOf(ref: ?) → string
A stable identity string for a reference, the same across every specifier spelling that resolves to it: the asset guid, falling back to its canonical identity, then its tracked path. Module evaluation keys modules by this, so two imports of one asset dedupe onto one evaluation and a self-import is seen as a cycle.
| arg | type | description |
|---|---|---|
| ref | ? |
nameOf(ref: ?) → string
The instance name a refusal message names, falling back to its identity.
| arg | type | description |
|---|---|---|
| ref | ? |
describeParseError(err: ?) → void
Render a parser error object (`{ message, line, col }`) into diagnostic fields.
| arg | type | description |
|---|---|---|
| err | ? |
resolveRef(spec: string) → any
Resolve an import specifier to the asset reference it names, or nil when the live index registers nothing under either the bare specifier or its `.zJs`-suffixed identity form. `asset.resolve` raises on an unknown name, so each candidate is guarded.
| arg | type | description |
|---|---|---|
| spec | string |
resolveSpecifierType(spec: string) → string
The type name of the asset a specifier resolves to, or nil when nothing matches. Both spellings an import may use are tried through `resolveRef`.
| arg | type | description |
|---|---|---|
| spec | string |
resolveZjsRef(spec: string) → any
The asset reference a specifier resolves to when it names a zJs module, or nil otherwise. The runtime resolver hands `vm:evalModule` only zJs sources.
| arg | type | description |
|---|---|---|
| spec | string |
parsePipeline(self: ?) → Cache
Parse `main.js` in module mode and resolve its imports, producing the cache consumed by `check` and the execution methods. Pure: it reads the source and the asset index, and never writes to the VFS. A parse failure yields a single error diagnostic and a nil ast; a successful parse yields per-import diagnostics for specifiers that do not resolve to a zJs module. The source is captured on `src` so a later `run`/`exports` drives the VM from the cache.
| arg | type | description |
|---|---|---|
| self | ? |
ensureCache(self: ?) → Cache
Return the cached pipeline result, running the pipeline once on a cold ref.
| arg | type | description |
|---|---|---|
| self | ? |
requireClean(self: ?, verb: string) → Cache
Read the parse cache, refusing when it carries diagnostics: `run`, `runAsync` and `exports` never surface a parse error at call time, so a non-empty diagnostics list (a parse error or an unresolved import, both produced by `onChange`) becomes a refusal naming the first diagnostic. A clean cache is returned for the caller to execute.
| arg | type | description |
|---|---|---|
| self | ? | |
| verb | string |
isModuleCache(c: Cache) → boolean
A module has at least one import or export; a plain script has neither. The distinction decides whether `run` evaluates through the module graph (a module has no completion value) or as a script (whose completion value is returned).
| arg | type | description |
|---|---|---|
| c | Cache |
makeResolver( ) → void
The host resolver `vm:evalModule` calls for each import specifier. It resolves a specifier to a sibling zJs asset through the live index (the same world-relative and `.zJs`-suffixed forms the diagnostics pipeline tries), keys the target by its stable identity so two spellings of one asset dedupe onto one evaluation and a self-import reads as a cycle, and reads the target's `main.js` from the VFS so an edited sibling is picked up on the next call. A specifier that resolves to no readable zJs asset yields nil, which the module graph reports as an unresolved-import error naming the specifier and its importer.
evalModuleNamespace(self: ?, c: Cache, env: { [string]: any }?) → void
Evaluate `self` as the root of a module graph on a fresh VM, threading each import through the asset-backed resolver. `c` is the already-clean cache; its source drives the root and `identityOf(self)` is the root id, so a self-import is a cycle. Returns the VM realm and the root namespace object for the caller to marshal or discard.
| arg | type | description |
|---|---|---|
| self | ? | |
| c | Cache | |
| env | { [string]: any }? |
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.
| arg | type | description |
|---|---|---|
| self | ? |
examples
local r = asset.resolve("greeter", "zJs"):check(); if not r.ok then ... endrun(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`.
| arg | type | description |
|---|---|---|
| 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.
| arg | type | description |
|---|---|---|
| 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.
| arg | type | description |
|---|---|---|
| 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))helloWorld(name: string) → string
Default JavaScript module scaffolded when `asset.create("zJs", name)` is called without an explicit `source`. Mirrors `template/main.js` with `[name]` bound to the instance name.
| arg | type | description |
|---|---|---|
| name | string |
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.
| arg | type | description |
|---|---|---|
| name | string | zJs module identity (the instance name). |
| opts | CreateOpts | |
| 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.
| arg | type | description |
|---|---|---|
| ref | ? | |
| change | ? |
Diagnostic = {Cache = {CreateOpts = {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.
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.
Inside
2 problems across 1 itemagent_score is exposed.+ 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".
Scoped to this part · feeds back into the world's score.