Caleb Cox
Caleb Cox•3d ago

Iterator is not defined when creating a snapshot with init_ops_and_esm

I've been following the roll your own runtime blog post series to make a simple CLI powered by deno_core. It's worked great, but I'm having trouble on part 3: setting up snapshots. My runtime.js file is just this:
class StdinIterator extends Iterator {
next() {
const line = Deno.core.ops.op_stdin_line();
if (line === null) {
return { done: true };
}
return { value: line, done: false };
}
}

globalThis.stdin = new StdinIterator();
class StdinIterator extends Iterator {
next() {
const line = Deno.core.ops.op_stdin_line();
if (line === null) {
return { done: true };
}
return { value: line, done: false };
}
}

globalThis.stdin = new StdinIterator();
In my build.rs, I'm creating the snapshot like this:
create_snapshot(
CreateSnapshotOptions {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
startup_snapshot: None,
skip_op_registration: false,
extensions: vec![kaw::init_ops_and_esm()],
with_runtime_cb: None,
extension_transpiler: None,
},
None,
)
create_snapshot(
CreateSnapshotOptions {
cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"),
startup_snapshot: None,
skip_op_registration: false,
extensions: vec![kaw::init_ops_and_esm()],
with_runtime_cb: None,
extension_transpiler: None,
},
None,
)
But I get the error Failed to initialize JsRuntime for snapshotting: Uncaught ReferenceError: Iterator is not defined. Inheriting from Iterator works fine without using snapshots. Also, I found that switching to extensions: vec![kaw::init_ops()] in build.rs when creating the snapshot seems to work fine, but the docs seem to indicate that I should use init_ops_and_esm when creating the snapshot and init_ops only when using the snapshot in main.rs. So my question is is it OK to create the snapshot with init_ops instead of init_ops_and_esm? If not, is there a way to access Iterator inside snapshotted code? Thanks in advance for any help! It's been really fun getting Rust and JS working together with deno_core!
2 Replies
Caleb Cox
Caleb Cox•3d ago
I was able to work around this by rewriting my runtime.js script to use generators:
const lines = function* () {
while (true) {
const line = Deno.core.ops.op_stdin_line();
if (line === null) {
return;
}
yield line;
}
};


globalThis.stdin = lines();
const lines = function* () {
while (true) {
const line = Deno.core.ops.op_stdin_line();
if (line === null) {
return;
}
yield line;
}
};


globalThis.stdin = lines();
bartlomieju
bartlomieju•3d ago
Some globals are not available in the snapshot 😭 but V8 does provide a list of what's not working