Example: Adding to Deno API
Last updated
Was this helpful?
Was this helpful?
import * as msg from "gen/msg_generated";
import * as flatbuffers from "./flatbuffers";
import { assert } from "./util";
import * as dispatch from "./dispatch";function req(
from: number,
to: number,
): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] {
// Get a builder to create a serialized buffer
const builder = flatbuffers.createBuilder();
msg.RandRange.startRandRange(builder);
// Put stuff inside the buffer!
msg.RandRange.addFrom(builder, from);
msg.RandRange.addTo(builder, to);
const inner = msg.RandRange.endRandRange(builder);
// We return these 3 pieces of information.
// dispatch.sendSync/sendAsync will need these as arguments!
// (treat such as boilerplate)
return [builder, msg.Any.RandRange, inner];
}
function res(baseRes: null | msg.Base): number {
// Some checks
assert(baseRes !== null);
// Make sure we actually do get a correct response type
assert(msg.Any.RandRangeRes === baseRes!.innerType());
// Create the RandRangeRes template
const res = new msg.RandRangeRes();
// Deserialize!
assert(baseRes!.inner(res) !== null);
// Extract the result
return res.result();
}// Sync
export function randRangeSync(from: number, to: number): number {
return res(dispatch.sendSync(...req(from, to)));
}
// Async
export async function randRange(from: number, to: number): Promise<number> {
return res(await dispatch.sendAsync(...req(from, to)));
}export { randRangeSync, randRange } from "./rand_range";ts_sources = [
"js/assets.ts",
"js/blob.ts",
"js/buffer.ts",
# ...
"js/rand_range.ts"
]use rand::{Rng, thread_rng};fn op_rand_range(
_state: &IsolateState,
base: &msg::Base,
data: libdeno::deno_buf,
) -> Box<Op> {
assert_eq!(data.len(), 0);
// Decode the message as RandRange
let inner = base.inner_as_rand_range().unwrap();
// Get the command id, used to respond to async calls
let cmd_id = base.cmd_id();
// Get `from` and `to` out of the buffer
let from = inner.from();
let to = inner.to();
// Wrap our potentially slow code and respond code here
// Based on dispatch.sendSync and dispatch.sendAsync,
// base.sync() will be true or false.
// If true, blocking() will spawn the task on the main thread
// Else, blocking() would spawn it in the Tokio thread pool
blocking(base.sync(), move || -> OpResult {
// Actual random number generation code!
let result = thread_rng().gen_range(from, to);
// Prepare respond message serialization
// Treat these as boilerplate code for now
let builder = &mut FlatBufferBuilder::new();
// We want the message type to be RandRangeRes
let inner = msg::RandRangeRes::create(
builder,
&msg::RandRangeResArgs {
result, // put in our result here
},
);
// Get message serialized
Ok(serialize_response(
cmd_id, // Used to reply to TypeScript if this is an async call
builder,
msg::BaseArgs {
inner: Some(inner.as_union_value()),
inner_type: msg::Any::RandRangeRes,
..Default::default()
},
))
})
}pub fn dispatch(
// ...
) -> (bool, Box<Op>) {
// ...
let op_creator: OpCreator = match inner_type {
msg::Any::Accept => op_accept,
msg::Any::Chdir => op_chdir,
// ...
/* ADD THE FOLLOWING LINE! */
msg::Any::RandRange => op_rand_range,
// ...
_ => panic!(format!(
"Unhandled message {}",
msg::enum_name_any(inner_type)
)),
}
}$ ./target/debug/deno
> deno.randRangeSync(0, 100)
96
> (async () => console.log(await deno.randRange(0, 100)))()
Promise {}
> 74import { test, assert } from "./test_util.ts";
import * as deno from "deno";
test(function randRangeSync() {
const v = deno.randRangeSync(0, 100);
assert(0 <= v && v < 100);
});
test(async function randRange() {
const v = await deno.randRange(0, 100);
assert(0 <= v && v < 100);
});// ADD THIS LINE
import "./rand_range_test.ts";test randRangeSync_permW0N0E0R0
... ok
test randRange_permW0N0E0R0
... ok./tools/format.py
./tools/lint.py
./tools/build.py
./tools/test.py