Skip to content
Merged
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
17 changes: 3 additions & 14 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion uzumibi-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "uzumibi-cli"
version = "0.7.1"
version = "0.8.0"
edition = "2024"
authors = ["Uchio Kondo <udzura@udzura.jp>"]
description = "Uzumibi CLI tool to generate serverless mruby/edge apps"
Expand Down
33 changes: 27 additions & 6 deletions uzumibi-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,10 +374,25 @@ fn print_project_next_steps(template: &str, _project_name: &str, features: &[Str
println!();
println!(" 1. Install dependencies:");
println!(" \x1b[36mpnpm install\x1b[0m");
println!(" 2. Build and start development server:");
println!(" \x1b[36mpnpm run dev\x1b[0m");
println!(" 3. Deploy to Cloudflare:");
println!(" \x1b[36mpnpm run deploy\x1b[0m");
if has_enable_external || has_queue {
println!(" 2. Set up a KV namespace for Uzumibi::KV:");
println!(" • Create a new namespace:");
println!(" \x1b[36mnpx wrangler kv namespace create UZUMIBI_KV\x1b[0m");
println!(" • Or list existing namespaces to reuse one:");
println!(" \x1b[36mnpx wrangler kv namespace list\x1b[0m");
println!(
" Then replace \x1b[36m<YOUR_KV_NAMESPACE_ID>\x1b[0m in \x1b[36mwrangler.jsonc\x1b[0m with the namespace ID."
);
println!(" 3. Build and start development server:");
println!(" \x1b[36mpnpm run dev\x1b[0m");
println!(" 4. Deploy to Cloudflare:");
println!(" \x1b[36mpnpm run deploy\x1b[0m");
} else {
println!(" 2. Build and start development server:");
println!(" \x1b[36mpnpm run dev\x1b[0m");
println!(" 3. Deploy to Cloudflare:");
println!(" \x1b[36mpnpm run deploy\x1b[0m");
}
if has_queue {
println!();
println!(
Expand All @@ -394,7 +409,10 @@ fn print_project_next_steps(template: &str, _project_name: &str, features: &[Str
" • \x1b[36mUzumibi::Fetch.fetch(url, method, body)\x1b[0m → Uzumibi::Response"
);
println!(
" • \x1b[36mUzumibi::KV.get(key)\x1b[0m / \x1b[36mUzumibi::KV.set(key, value)\x1b[0m → Durable Object storage"
" • \x1b[36mUzumibi::KV.get(key)\x1b[0m / \x1b[36mUzumibi::KV.set(key, value)\x1b[0m → Cloudflare KV"
);
println!(
" • \x1b[36mUzumibi::LegacyKV.get(key)\x1b[0m / \x1b[36mUzumibi::LegacyKV.set(key, value)\x1b[0m → Durable Object storage"
);
println!(
" • \x1b[36mUzumibi::Queue.send(queue_name, message)\x1b[0m → Cloudflare Queue"
Expand All @@ -407,7 +425,10 @@ fn print_project_next_steps(template: &str, _project_name: &str, features: &[Str
" • \x1b[36mUzumibi::Fetch.fetch(url, method, body)\x1b[0m → Uzumibi::Response"
);
println!(
" • \x1b[36mUzumibi::KV.get(key)\x1b[0m / \x1b[36mUzumibi::KV.set(key, value)\x1b[0m → Durable Object storage"
" • \x1b[36mUzumibi::KV.get(key)\x1b[0m / \x1b[36mUzumibi::KV.set(key, value)\x1b[0m → Cloudflare KV"
);
println!(
" • \x1b[36mUzumibi::LegacyKV.get(key)\x1b[0m / \x1b[36mUzumibi::LegacyKV.set(key, value)\x1b[0m → Durable Object storage"
);
println!(
" • \x1b[36mUzumibi::Queue.send(queue_name, message)\x1b[0m → Cloudflare Queue"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import mod from "./$$PROJECT_NAME_UNDERSCORE$$.wasm";
const wasmModule = mod;

/**
* Durable Object for Uzumibi::KV storage
* Durable Object storage retained for Uzumibi::LegacyKV.
*/
export class UzumibiKVObject extends DurableObject {
async get(key) {
Expand All @@ -27,7 +27,9 @@ export default {

const query = new URL(request.url).searchParams;

// Durable Object stub (if binding exists)
const kv = env.UZUMIBI_KV ?? null;

// Durable Object stub retained for Uzumibi::LegacyKV.
const doStub = env.UZUMIBI_KV_DATA
? env.UZUMIBI_KV_DATA.getByName("default")
: null;
Expand Down Expand Up @@ -137,7 +139,35 @@ export default {
return pos;
},

// KV.get(key) -> value string (via Durable Object)
// KV.get(key) -> value string
uzumibi_cf_kv_get: async (keyPtr, keySize, resultPtr, resultMaxSize) => {
if (!kv) return -1;
const memory = exports.memory;
const key = decoder.decode(new Uint8Array(memory.buffer, keyPtr, keySize));

const value = await kv.get(key);
if (value === null) {
return -1;
}
const valueBytes = encoder.encode(value);
const length = Math.min(valueBytes.length, resultMaxSize);
const resultBuffer = new Uint8Array(memory.buffer, resultPtr, resultMaxSize);
resultBuffer.set(valueBytes.slice(0, length));
return length;
},

// KV.set(key, value)
uzumibi_cf_kv_set: async (keyPtr, keySize, valuePtr, valueSize) => {
if (!kv) return -1;
const memory = exports.memory;
const key = decoder.decode(new Uint8Array(memory.buffer, keyPtr, keySize));
const value = decoder.decode(new Uint8Array(memory.buffer, valuePtr, valueSize));

await kv.put(key, value);
return 0;
},

// LegacyKV.get(key) -> value string (via Durable Object)
uzumibi_cf_durable_object_get: async (keyPtr, keySize, resultPtr, resultMaxSize) => {
if (!doStub) return -1;
const memory = exports.memory;
Expand All @@ -154,7 +184,7 @@ export default {
return length;
},

// KV.set(key, value) (via Durable Object)
// LegacyKV.set(key, value) (via Durable Object)
uzumibi_cf_durable_object_set: async (keyPtr, keySize, valuePtr, valueSize) => {
if (!doStub) return -1;
const memory = exports.memory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mrubyedge = { version = ">= 1.1.12", features = [
], default-features = false }
uzumibi-gem = ">= 0.6.0"
uzumibi-art-router = ">= 0.3.1"
uzumibi-cloudflare-ext = ">= 0.2.2"
uzumibi-cloudflare-ext = ">= 0.3.1"
mrubyedge-serde-json = ">= 0.1.2"

[build-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@
"directory": "./public",
"binding": "ASSETS"
},
/**
* KV Namespace
* Used for Uzumibi::KV.get/set.
* Replace the placeholder with a namespace ID from `wrangler kv namespace create`.
*/
"kv_namespaces": [
{
"binding": "UZUMIBI_KV",
"id": "<YOUR_KV_NAMESPACE_ID>"
}
],
/**
* Queues
* Used for Uzumibi::Queue.send
Expand All @@ -36,7 +47,7 @@
// },
/**
* Durable Objects
* Used for Uzumibi::KV.get/set
* Used for Uzumibi::LegacyKV.get/set
* https://developers.cloudflare.com/durable-objects/
*/
"durable_objects": {
Expand Down
37 changes: 33 additions & 4 deletions uzumibi-cli/templates/cloudflare/__features__/queue/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import mod from "./$$PROJECT_NAME_UNDERSCORE$$_queue.wasm";
const wasmModule = mod;

/**
* Durable Object for Uzumibi::KV storage
* Durable Object storage retained for Uzumibi::LegacyKV.
*/
export class UzumibiKVObject extends DurableObject {
async get(key) {
Expand All @@ -27,7 +27,9 @@ export default {
const decoder = new TextDecoder();
const encoder = new TextEncoder();

// Durable Object stub (if binding exists)
const kv = env.UZUMIBI_KV ?? null;

// Durable Object stub retained for Uzumibi::LegacyKV.
const doStub = env.UZUMIBI_KV_DATA
? env.UZUMIBI_KV_DATA.getByName("default")
: null;
Expand Down Expand Up @@ -133,7 +135,34 @@ export default {
return pos;
},

// KV.get(key) -> value string (via Durable Object)
// KV.get(key) -> value string
uzumibi_cf_kv_get: async (keyPtr, keySize, resultPtr, resultMaxSize) => {
if (!kv) return -1;
const memory = exports.memory;
const key = decoder.decode(new Uint8Array(memory.buffer, keyPtr, keySize));

const value = await kv.get(key);
if (value === null) return -1;

const valueBytes = encoder.encode(value);
const length = Math.min(valueBytes.length, resultMaxSize);
const resultBuffer = new Uint8Array(memory.buffer, resultPtr, resultMaxSize);
resultBuffer.set(valueBytes.slice(0, length));
return length;
},

// KV.set(key, value)
uzumibi_cf_kv_set: async (keyPtr, keySize, valuePtr, valueSize) => {
if (!kv) return -1;
const memory = exports.memory;
const key = decoder.decode(new Uint8Array(memory.buffer, keyPtr, keySize));
const value = decoder.decode(new Uint8Array(memory.buffer, valuePtr, valueSize));

await kv.put(key, value);
return 0;
},

// LegacyKV.get(key) -> value string (via Durable Object)
uzumibi_cf_durable_object_get: async (keyPtr, keySize, resultPtr, resultMaxSize) => {
if (!doStub) return -1;
const memory = exports.memory;
Expand All @@ -149,7 +178,7 @@ export default {
return length;
},

// KV.set(key, value) (via Durable Object)
// LegacyKV.set(key, value) (via Durable Object)
uzumibi_cf_durable_object_set: async (keyPtr, keySize, valuePtr, valueSize) => {
if (!doStub) return -1;
const memory = exports.memory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mrubyedge = { version = ">= 1.1.12", features = [
], default-features = false }
uzumibi-gem = ">= 0.6.0"
uzumibi-art-router = ">= 0.3.1"
uzumibi-cloudflare-ext = ">= 0.2.0"
uzumibi-cloudflare-ext = ">= 0.3.1"
mrubyedge-serde-json = ">= 0.1.2"

[build-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,20 @@
"observability": {
"enabled": true
},
/**
* KV Namespace
* Used for Uzumibi::KV.get/set.
* Replace the placeholder with a namespace ID from `wrangler kv namespace create`.
*/
"kv_namespaces": [
{
"binding": "UZUMIBI_KV",
"id": "<YOUR_KV_NAMESPACE_ID>"
}
],
/**
* Durable Objects
* Used for Uzumibi::KV.get/set
* Used for Uzumibi::LegacyKV.get/set
* https://developers.cloudflare.com/durable-objects/
*/
"durable_objects": {
Expand Down
2 changes: 1 addition & 1 deletion uzumibi-cli/templates/cloudflare/wasm-app/Cargo.toml_
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mrubyedge = { version = ">= 1.1.12", features = [
], default-features = false }
uzumibi-gem = ">= 0.6.0"
uzumibi-art-router = ">= 0.3.1"
uzumibi-cloudflare-ext = ">= 0.2.0"
uzumibi-cloudflare-ext = ">= 0.3.1"
mrubyedge-serde-json = ">= 0.1.2"

[build-dependencies]
Expand Down
1 change: 1 addition & 0 deletions uzumibi-cli/tests/runn/new_cloudflare.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ steps:
desc: Build the WASM app
exec:
command: cd {{ vars.tmpdir }}/{{ vars.project_name }}/wasm-app && cargo build --target wasm32-unknown-unknown --release
dump: steps
test: current.exit_code == 0

start_server:
Expand Down
2 changes: 1 addition & 1 deletion uzumibi-cloudflare-ext/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "uzumibi-cloudflare-ext"
version = "0.2.2"
version = "0.3.1"
edition = "2024"
authors = ["Uchio Kondo <udzura@udzura.jp>"]
description = "Cloudflare Workers extension for Uzumibi (mruby/edge serverless framework)"
Expand Down
Loading
Loading