Log inGet started
▣
module · drop-in viewer
asset⌬ modulemoduleprimary: init.luau·originates fromworld 07158574-5…●1problem

vfs_async_read

Pure-Luau wrapper that grafts a yielding `vfs.read` over the engine's sync `vfs.read` binding. The `vfs` API module (`modules/api/engine/vfs`) calls `M.installInto(vfs)` on itself as it loads, so every VM holding `vfs` (user VMs and the trusted VM alike) reads through it; user co…

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

vfs_async_read

Pure-Luau wrapper that grafts a yielding vfs.read over the engine's sync vfs.read binding. The vfs API module (modules/api/engine/vfs) calls M.installInto(vfs) on itself as it loads, so every VM holding vfs (user VMs and the trusted VM alike) reads through it; user code never requires this module directly: it just calls vfs.read(path) and the wrapper handles cache misses by yielding the running coroutine until the bytes resolve.

Exports

  • M.installInto(vfs: VfsNamespace): replace vfs.read (and vfs.readBounded) with the yielding wrapper. No-op when the target lacks read and readAsync as functions.
  • M.CANNOT_WAIT: "VFS_READ_CANNOT_WAIT", the code a read raises when it names a known file whose bytes have not arrived and the reading code cannot yield.

Types:

  • VfsNamespace = { read?, readAsync?, readBounded? }: the engine's vfs global shape.

Usage

-- The `vfs` API module installs the wrapper onto itself as it loads:
require("@builtin::modules.vfs_async_read").installInto(vfs)

-- After install, every `vfs.read` call yields on cache miss:
local bytes = vfs.read("/zero/source/some.asset")

Where a read can wait

  • On a miss the wrapper schedules vfs.readAsync(path, opts), which fires BlobProvider::fetch under the hood, and task.awaits the promise. The resolved value can still be nil if the path isn't in the manifest at all.
  • Waiting takes a yield, so it happens where coroutine.isyieldable() is true: a task, the component hooks the engine runs on a coroutine (awake, start, update, fixedUpdate, onEnable, onOwnerChanged, onSyncReceived), a replicated event's handlers, and a world or scene entrypoint's hooks.
  • Where it is false (onDisable, onDestroy, onPropertyChanged, a received synced-function call, a vfs.watch callback, a module's top level while require runs it, a metamethod, a table.sort comparator, a VM's main thread) a miss the engine's read answers nil, "pending" for (a file vfs.exists knows that is no directory and whose bytes can still arrive, a render surface being captured) raises VFS_READ_CANNOT_WAIT: vfs.read("<path>") ..., naming the path and the places it can be read from. Every other miss answers nil there as everywhere else.
  • installInto is idempotent in the trivial sense: calling it twice re-wraps vfs.read around the already-wrapped function, which is fine but pointless.

Interface

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

conforms to

zero/source-extract/v2

VfsAsyncRead Module Wraps `vfs.read` so a byte-cache miss yields-and-fetches transparently. Pure Luau: the `vfs` API module grafts this onto itself as it loads, so every VM holding `vfs` reads through it. Scripts always call `vfs.read(path)` and never need to choose between the sync and async variant. The Rust binding `vfs.read` is a sync fast path that returns the bytes if they're in MemFs or in the BlobStore disk cache, and nil otherwise, with `"pending"` beside the nil when the bytes are on their way (a known file not held here yet, a render surface being captured). This wrapper layers the lazy-fetch behavior on top: 1. Try the sync fast path (MemFs / disk cache). 2. On miss, call `vfs.readAsync(path, opts)` to schedule a `BlobProvider::fetch` and yield the coroutine via `task.await`. 3. Return the bytes once the fetch resolves (or nil if the path is not known to the manifest). Code that cannot yield (`coroutine.isyieldable()` is false: the VM's main thread, a module's top level while `require` runs it, a `vfs.watch` callback, a metamethod, a `table.sort` comparator, `onPropertyChanged`, which runs inside the property write, a hook the engine runs to completion before it acts, such as `onDisable` / `onDestroy`) cannot wait for bytes still on their way. There a pending miss raises `VFS_READ_CANNOT_WAIT`, naming the path and the ways to read it, and a miss on a path the VFS does not know answers nil. Consumers: local VfsAsyncRead = require("modules.vfs_async_read") VfsAsyncRead.installInto(vfs) -- the `vfs` API module does this once local bytes = vfs.read("/zero/source/some.asset") -- yields on miss

cannotWaitMessage(verb: string, path: string) → string

The refusal a read raises from code that cannot yield, for a file whose bytes are still on their way.

argtypedescription
verbstring
pathstring

installInto(vfs: VfsNamespace) → void

Install the yielding `read` wrapper onto the supplied `vfs`-shaped namespace. The `vfs` API module calls this once on itself as it loads; users shouldn't call it directly. No-op if the target doesn't expose both `read` and `readAsync` as functions. A miss the target's `read` answers `nil, "pending"` for raises `VFS_READ_CANNOT_WAIT` where the reading code cannot yield. function fields (the engine's `vfs` global does); otherwise the install is a no-op.

argtypedescription
vfsVfsNamespaceThe target namespace table. Must carry `read` and `readAsync`

examples

require("modules.vfs_async_read").installInto(vfs)

read(path: ?, opts: ?) → void

argtypedescription
path?
opts?

readBounded(path: string, maxBytes: number) → void

argtypedescription
pathstring
maxBytesnumber
⌬ Types
VfsNamespace = {

Sub-parts

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

3items
·
other · born here
▤file
▲ 0↑ born
backing path · modules/vfs_async_read.module

Problems

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

1problem

Inside

1 problem across 1 item
●
dep.unresolved · L57
could not resolve `{path}`
⌬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.