diff --git a/cf_miniflare/gleam.toml b/cf_miniflare/gleam.toml new file mode 100644 index 0000000..bd99acf --- /dev/null +++ b/cf_miniflare/gleam.toml @@ -0,0 +1,18 @@ +name = "cf_miniflare" +version = "1.0.0" +target = "javascript" + +[repository] +type = "tangled" +user = "renatillas.dev" +repo = "cf" +path = "miniflare_cf" +tag_prefix = "cf_miniflare-" + +[dependencies] +cf = { git = "https://tangled.org/renatillas.dev/cf", ref = "main" } +gleam_javascript = ">= 1.0.0 and < 2.0.0" +gleam_stdlib = ">= 1.0.0 and < 2.0.0" + +[dev-dependencies] +gleeunit = ">= 1.0.0 and < 2.0.0" diff --git a/cf_miniflare/manifest.toml b/cf_miniflare/manifest.toml new file mode 100644 index 0000000..3b180a5 --- /dev/null +++ b/cf_miniflare/manifest.toml @@ -0,0 +1,20 @@ +# Do not manually edit this file, it is managed by Gleam. +# +# This file locks the dependency versions used, to make your build +# deterministic and to prevent unexpected versions from being included +# in your application. +# +# You should check this file into your source control repository. + +packages = [ + { name = "cf_workers", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_javascript", "gleam_stdlib"], source = "local", path = "../cf_workers" }, + { name = "gleam_javascript", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "EF6C77A506F026C6FB37941889477CD5E4234FCD4337FF0E9384E297CB8F97EB" }, + { name = "gleam_stdlib", version = "1.0.3", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "1F543AFBA5D33DA493E6087F4E4C4F20D899411343512686C98A8ABB2963CF22" }, + { name = "gleeunit", version = "1.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "EC31ABA74256AEA531EDF8169931D775BBB384FED0A8A1BDC4DD9354E3E21826" }, +] + +[requirements] +cf_workers = { path = "../cf_workers" } +gleam_javascript = { version = ">= 1.0.0 and < 2.0.0" } +gleam_stdlib = { version = ">= 1.0.0 and < 2.0.0" } +gleeunit = { version = ">= 1.0.0 and < 2.0.0" } diff --git a/cf_miniflare/src/cf/miniflare.gleam b/cf_miniflare/src/cf/miniflare.gleam new file mode 100644 index 0000000..d27eacf --- /dev/null +++ b/cf_miniflare/src/cf/miniflare.gleam @@ -0,0 +1,60 @@ +import gleam/javascript/array.{type Array} +import gleam/javascript/promise.{type Promise} + +pub type Miniflare + +pub opaque type Worker { + Worker( + name: String, + script: String, + compatibility_date: String, + d1_databases: Array(String), + r2_buckets: Array(String), + queues: Array(String), + ) +} + +pub fn worker(name: String, script: String, compatibility_date: String) -> Worker { + Worker( + name:, + script:, + compatibility_date:, + d1_databases: array.from_list([]), + r2_buckets: array.from_list([]), + queues: array.from_list([]), + ) +} + +pub fn with_d1_database(worker: Worker, binding: String) -> Worker { + Worker(..worker, d1_databases: array.from_list([ + binding, + ..array.to_list(worker.d1_databases) + ])) +} + +pub fn with_r2_bucket(worker: Worker, binding: String) -> Worker { + Worker(..worker, r2_buckets: array.from_list([ + binding, + ..array.to_list(worker.r2_buckets) + ])) +} + +pub fn with_queue(worker: Worker, binding: String) -> Worker { + Worker(..worker, queues: array.from_list([ + binding, + ..array.to_list(worker.queues) + ])) +} + +@external(javascript, "../cf_miniflare_ffi.mjs", "new_miniflare") +fn do_new(workers: Array(Worker)) -> Miniflare + +pub fn new(workers: List(Worker)) -> Miniflare { + do_new(array.from_list(workers)) +} + +@external(javascript, "../cf_miniflare_ffi.mjs", "ready") +pub fn ready(miniflare: Miniflare) -> Promise(Nil) + +@external(javascript, "../cf_miniflare_ffi.mjs", "dispose") +pub fn dispose(miniflare: Miniflare) -> Promise(Nil) diff --git a/cf_miniflare/src/cf/miniflare/bindings.gleam b/cf_miniflare/src/cf/miniflare/bindings.gleam new file mode 100644 index 0000000..bee1062 --- /dev/null +++ b/cf_miniflare/src/cf/miniflare/bindings.gleam @@ -0,0 +1,35 @@ +import cf/d1 +import cf/execution_context +import cf/images +import cf/miniflare.{type Miniflare} +import cf/queue +import cf/r2 +import gleam/javascript/promise.{type Promise} +import gleam/option.{type Option} + +@external(javascript, "../../cf_miniflare_bindings_ffi.mjs", "get_r2_bucket") +pub fn get_r2_bucket( + miniflare: Miniflare, + binding: String, + worker_name: Option(String), +) -> Promise(r2.Bucket) + +@external(javascript, "../../cf_miniflare_bindings_ffi.mjs", "get_queue") +pub fn get_queue( + miniflare: Miniflare, + binding: String, + worker_name: Option(String), +) -> Promise(queue.Queue) + +@external(javascript, "../../cf_miniflare_bindings_ffi.mjs", "get_mock_images_binding") +pub fn get_mock_images_binding() -> images.Binding + +@external(javascript, "../../cf_miniflare_bindings_ffi.mjs", "get_mock_wait_until") +pub fn get_mock_wait_until() -> execution_context.WaitUntil + +@external(javascript, "../../cf_miniflare_bindings_ffi.mjs", "get_database") +pub fn get_database( + miniflare: Miniflare, + binding: String, + worker_name: Option(String), +) -> Promise(d1.Database) diff --git a/cf_miniflare/src/cf_miniflare_bindings_ffi.mjs b/cf_miniflare/src/cf_miniflare_bindings_ffi.mjs new file mode 100644 index 0000000..fdc1c64 --- /dev/null +++ b/cf_miniflare/src/cf_miniflare_bindings_ffi.mjs @@ -0,0 +1,29 @@ +import { Option$isSome, Option$Some$0 } from "../gleam_stdlib/gleam/option.mjs"; + +export async function get_r2_bucket(miniflare, binding, workerName) { + return miniflare.getR2Bucket(binding, optionToValue(workerName)); +} + +export async function get_queue(miniflare, binding, workerName) { + return miniflare.getQueueProducer(binding, optionToValue(workerName)); +} + +export async function get_database(miniflare, binding, workerName) { + return miniflare.getD1Database(binding, optionToValue(workerName)); +} + + +export function get_mock_images_binding() { + return {}; +} + +export function get_mock_wait_until() { + return {}; +} + +function optionToValue(option) { + if (Option$isSome(option)) { + return Option$Some$0(option); + } + return undefined; +} diff --git a/cf_miniflare/src/cf_miniflare_ffi.mjs b/cf_miniflare/src/cf_miniflare_ffi.mjs new file mode 100644 index 0000000..ee43272 --- /dev/null +++ b/cf_miniflare/src/cf_miniflare_ffi.mjs @@ -0,0 +1,23 @@ +import { Miniflare } from "miniflare"; + +export function new_miniflare(workers) { + return new Miniflare({ + workers: workers.map((worker) => ({ + name: worker.name, + modules: true, + script: worker.script, + compatibilityDate: worker.compatibility_date, + d1Databases: worker.d1_databases, + r2Buckets: worker.r2_buckets, + queueProducers: worker.queues, + })), + }); +} + +export async function ready(miniflare) { + await miniflare.ready; +} + +export async function dispose(miniflare) { + await miniflare.dispose(); +} diff --git a/gleam.toml b/gleam.toml index 577c9af..ebb42ed 100644 --- a/gleam.toml +++ b/gleam.toml @@ -2,6 +2,12 @@ name = "cf" version = "1.0.0" target = "javascript" +[repository] +type = "tangled" +user = "renatillas.dev" +repo = "cf" +tag_prefix = "cf-" + [dependencies] gleam_stdlib = ">= 1.0.0 and < 2.0.0" gleam_javascript = ">= 1.0.0 and < 2.0.0"