Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions examples/sync-kv/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "sync-kv"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
serde_json.workspace = true
worker.workspace = true
worker-macros.workspace = true
59 changes: 59 additions & 0 deletions examples/sync-kv/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use serde_json::{json, Value};
use worker::*;

#[durable_object]
pub struct SyncKvDurableObject {
state: State,
}

impl DurableObject for SyncKvDurableObject {
fn new(state: State, _env: Env) -> Self {
Self { state }
}

async fn fetch(&self, _req: Request) -> Result<Response> {
let kv = self.state.storage().kv();

// CLEAN
kv.delete("a")?;
kv.delete("b")?;

// CREATE
kv.put("a", json!({ "x": 1 }))?;
kv.put("b", json!({ "x": 2 }))?;

// READ
let a: Option<Value> = kv.get("a")?;
let b: Option<Value> = kv.get("b")?;
let missing: Option<Value> = kv.get("c")?;

// UPDATE
kv.put("a", json!({ "x": 42 }))?;
let a_updated: Option<Value> = kv.get("a")?;

// DELETE
let deleted = kv.delete("b")?;
let after_delete: Option<Value> = kv.get("b")?;

// LIST
let mut list = Vec::new();
for item in kv.list::<Value>()? {
let (k, v) = item?;
list.push((k, v));
}

Response::from_json(&json!({
"read": { "a": a, "b": b, "missing": missing },
"update": a_updated,
"delete": { "deleted": deleted, "after_delete": after_delete },
"list": list
}))
}
}

#[event(fetch)]
async fn fetch(req: Request, env: Env, _ctx: Context) -> Result<Response> {
let durable_obj = env.durable_object("SYNC_KV")?;
let stub = durable_obj.id_from_name("singleton")?.get_stub()?;
stub.fetch_with_request(req).await
}
14 changes: 14 additions & 0 deletions examples/sync-kv/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name = "sync-kv-example"
main = "build/index.js"
compatibility_date = "2025-09-23"

[build]
command = "cargo install \"worker-build@^0.8\" && worker-build --release"

[[durable_objects.bindings]]
name = "SYNC_KV"
class_name = "SyncKvDurableObject"

[[migrations]]
tag = "v1"
new_sqlite_classes = ["SyncKvDurableObject"]
1 change: 1 addition & 0 deletions test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod signal;
mod socket;
mod sql_counter;
mod sql_iterator;
mod synchronous_storage;
mod user;
mod ws;

Expand Down
11 changes: 10 additions & 1 deletion test/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::signal;
use crate::{
alarm, analytics_engine, assets, auto_response, cache, container, counter, d1, durable, fetch,
form, js_snippets, kv, put_raw, queue, r2, rate_limit, request, secret_store, service, socket,
sql_counter, sql_iterator, user, ws, SomeSharedData, GLOBAL_SECOND_START, GLOBAL_STATE,
sql_counter, sql_iterator, synchronous_storage, user, ws, SomeSharedData, GLOBAL_SECOND_START,
GLOBAL_STATE,
};
#[cfg(feature = "http")]
use std::convert::TryInto;
Expand Down Expand Up @@ -240,6 +241,14 @@ macro_rules! add_routes (
add_route!($obj, get, format_route!("/rate-limit/key/{}", "key"), rate_limit::handle_rate_limit_with_key);
add_route!($obj, get, "/rate-limit/bulk-test", rate_limit::handle_rate_limit_bulk_test);
add_route!($obj, get, "/rate-limit/reset", rate_limit::handle_rate_limit_reset);
add_route!($obj, get, "/synchronous-storage/smoke", synchronous_storage::handle_synchronous_storage_smoke);
add_route!($obj, get, "/synchronous-storage/overwrite", synchronous_storage::handle_synchronous_storage_overwrite);
add_route!($obj, get, "/synchronous-storage/not_found", synchronous_storage::handle_synchronous_storage_not_found);
add_route!($obj, get, "/synchronous-storage/list", synchronous_storage::handle_synchronous_storage_list);
add_route!($obj, get, "/synchronous-storage/list_options", synchronous_storage::handle_synchronous_storage_list_options);
add_route!($obj, get, "/synchronous-storage/persist_fill", synchronous_storage::handle_synchronous_storage_persist_fill);
add_route!($obj, get, "/synchronous-storage/persist_check", synchronous_storage::handle_synchronous_storage_persist_check);
add_route!($obj, get, "/synchronous-storage/persist_cleanup", synchronous_storage::handle_synchronous_storage_persist_cleanup);
add_route!($obj, get, "/signal/poll", signal::handle_signal_poll);
});

Expand Down
Loading
Loading