Skip to content

Commit

Permalink
fix: fix ts types for actor bindings (#1470)
Browse files Browse the repository at this point in the history
<!-- Please make sure there is an issue that this PR is correlated to. -->
Fixes RVT-4214
## Changes

<!-- If there are frontend changes, please include screenshots. -->
  • Loading branch information
MasterPtato committed Nov 26, 2024
1 parent e020054 commit 6ca6764
Show file tree
Hide file tree
Showing 10 changed files with 301 additions and 294 deletions.
65 changes: 33 additions & 32 deletions packages/infra/client/isolate-v8-runner/js/40_rivet_kv.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ import { core } from "ext:core/mod.js";
/**
* Retrieves a value from the key-value store.
*
* @param {any|any[]} key - The key to retrieve the value for.
* @param {Key} key - The key to retrieve the value for.
* @param {GetOptions} [options] - Options.
* @returns {Promise<any|undefined>} The retrieved value, or undefined if the key does not exist.
* @returns {Promise<Entry | null>} The retrieved value, or undefined if the key does not exist.
*/
async function get(key, options) {
let entry = (await op_rivet_kv_get(serializeKey(key))) ?? undefined;
let entry = await op_rivet_kv_get(serializeKey(key));
if (entry == null)
return null;
return deserializeValue(key, entry.value, options?.format);
}
/**
* Retrieves a batch of key-value pairs.
*
* @param {string[]} keys - A list of keys to retrieve.
* @param {Key[]} keys - A list of keys to retrieve.
* @param {GetBatchOptions} [options] - Options.
* @returns {Promise<Map<string, any>>} The retrieved values.
* @returns {Promise<Map<Key, Entry>>} The retrieved values.
*/
async function getBatch(keys, options) {
let entries = await op_rivet_kv_get_batch(keys.map((x) => serializeKey(x)));
Expand All @@ -35,7 +37,7 @@ async function getBatch(keys, options) {
* Retrieves all key-value pairs in the KV store.
*
* @param {ListOptions} [options] - Options.
* @returns {Promise<Map<string, any>>} The retrieved values.
* @returns {Promise<Map<Key, Entry>>} The retrieved values.
*/
async function list(options) {
// Build query
Expand All @@ -50,21 +52,15 @@ async function list(options) {
throw new Error("must set options.end with options.start");
}
query = {
rangeInclusive: [
serializeListKey(options.start),
serializeKey(options.end),
],
rangeInclusive: [serializeListKey(options.start), serializeKey(options.end)],
};
}
else if (options?.startAfter) {
if (!options.end) {
throw new Error("must set options.end with options.startAfter");
}
query = {
rangeExclusive: [
serializeListKey(options.startAfter),
serializeKey(options.end),
],
rangeExclusive: [serializeListKey(options.startAfter), serializeKey(options.end)],
};
}
else if (options?.end) {
Expand All @@ -84,51 +80,56 @@ async function list(options) {
/**
* Stores a key-value pair in the key-value store.
*
* @param {any|any[]} key - The key under which the value will be stored.
* @param {any|ArrayBuffer} value - The value to be stored, which will be serialized.
* @param {Key} key - The key under which the value will be stored.
* @param {Entry | ArrayBuffer} value - The value to be stored, which will be serialized.
* @param {PutOptions} [options] - Options.
* @returns {Promise<void>} A promise that resolves when the operation is complete.
*/
async function put(key, givenValue, options) {
validateType(givenValue, null, options?.format);
async function put(key, value, options) {
validateType(value, null, options?.format);
let format = options?.format ?? "value";
let value;
let serializedValue;
if (format == "value") {
value = core.serialize(givenValue, { forStorage: true });
value = core.serialize(value, { forStorage: true });
}
else if (format == "arrayBuffer") {
value = new Uint8Array(givenValue);
if (value instanceof ArrayBuffer)
value = new Uint8Array(value);
else
throw new Error(`value must be of type \`ArrayBuffer\` if format is "arrayBuffer"`);
}
await op_rivet_kv_put(serializeKey(key), value);
await op_rivet_kv_put(serializeKey(key), serializedValue);
}
/**
* Asynchronously stores a batch of key-value pairs.
*
* @param {Record<any, any|ArrayBuffer>} obj - An object containing key-value pairs to be stored.
* @param {Record<Key, Entry | ArrayBuffer>} obj - An object containing key-value pairs to be stored.
* @param {PutBatchOptions} [options] - Options.
* @returns {Promise<void>} A promise that resolves when the batch operation is complete.
*/
async function putBatch(obj, options) {
let serializedObj = new Map();
let format = options?.format ?? "value";
for (let key in obj) {
let givenValue = obj[key];
validateType(givenValue, key, format);
let value;
for (let [key, value] of obj) {
validateType(value, key, format);
let serializedValue;
if (format == "value") {
value = core.serialize(givenValue, { forStorage: true });
value = core.serialize(serializedValue, { forStorage: true });
}
else if (format == "arrayBuffer") {
value = new Uint8Array(givenValue);
if (value instanceof ArrayBuffer)
value = new Uint8Array(value);
else
throw new Error(`value in key "${key}" must be of type \`ArrayBuffer\` if format is "arrayBuffer"`);
}
serializedObj.set(serializeKey(key), value);
serializedObj.set(serializeKey(key), serializedValue);
}
await op_rivet_kv_put_batch(serializedObj);
}
/**
* Deletes a key-value pair from the key-value store.
*
* @param {string} key - The key of the key-value pair to delete.
* @param {Key} key - The key of the key-value pair to delete.
* @returns {Promise<void>} A promise that resolves when the operation is complete.
*/
async function delete_(key) {
Expand Down Expand Up @@ -172,7 +173,7 @@ function validateType(value, key, format = "value") {
}
function serializeKey(key) {
if (key instanceof Array) {
return { jsInKey: [key.map((x) => core.serialize(x))] };
return { jsInKey: key.map((x) => core.serialize(x)) };
}
else {
return { jsInKey: [core.serialize(key)] };
Expand Down
23 changes: 20 additions & 3 deletions packages/infra/client/isolate-v8-runner/src/ext/kv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ enum Key {
impl From<actor_kv::key::Key> for Key {
fn from(value: actor_kv::key::Key) -> Self {
match value {
// actor_kv::key::Key::JsInKey(tuple) => Key::InKey(tuple),
// TODO: Currently, JsBuffer cannot be serialized back to v8 as a buffer. We must convert it until
// fixed.
// actor_kv::key::Key::JsInKey(tuple) => Key::InKey(tuple),
actor_kv::key::Key::JsInKey(tuple) => Key::OutKey(
tuple
.into_iter()
Expand All @@ -58,20 +58,37 @@ impl From<actor_kv::key::Key> for Key {
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Entry {
metadata: actor_kv::Metadata,
metadata: Metadata,
value: ToJsBuffer,
}

impl From<actor_kv::Entry> for Entry {
fn from(value: actor_kv::Entry) -> Self {
Entry {
metadata: value.metadata,
metadata: value.metadata.into(),
value: value.value.into(),
}
}
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Metadata {
pub kv_version: ToJsBuffer,
pub create_ts: i64,
}

impl From<actor_kv::Metadata> for Metadata {
fn from(value: actor_kv::Metadata) -> Self {
Metadata {
kv_version: value.kv_version.into(),
create_ts: value.create_ts,
}
}
}

#[op2(async)]
#[serde]
pub fn op_rivet_kv_get(
Expand Down
Loading

0 comments on commit 6ca6764

Please sign in to comment.