Skip to content

Commit

Permalink
feat: add durable storage MVP
Browse files Browse the repository at this point in the history
  • Loading branch information
MasterPtato committed May 16, 2024
1 parent 911da30 commit 4ff9bac
Show file tree
Hide file tree
Showing 24 changed files with 797 additions and 71 deletions.
2 changes: 1 addition & 1 deletion artifacts/module_schema.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"type":"object","properties":{"status":{"enum":["beta","end_of_life","maintenance","preview","stable"],"type":"string"},"name":{"description":"The human readable name of the module.","type":"string"},"description":{"description":"A short description of the module.","type":"string"},"icon":{"description":"The [Font Awesome](https://fontawesome.com/icons) icon name of the module.","type":"string"},"tags":{"description":"The tags associated with this module.","type":"array","items":{"type":"string"}},"authors":{"description":"The GitHub handle of the authors of the module.","type":"array","items":{"type":"string"}},"scripts":{"type":"object","additionalProperties":{"$ref":"#/definitions/ScriptConfig"}},"errors":{"type":"object","additionalProperties":{"$ref":"#/definitions/ErrorConfig"}},"dependencies":{"type":"object","additionalProperties":{"$ref":"#/definitions/DependencyConfig"}}},"additionalProperties":false,"required":["errors","scripts"],"definitions":{"ScriptConfig":{"type":"object","properties":{"name":{"description":"The human readable name of the script.","type":"string"},"description":{"description":"A short description of the script.","type":"string"},"public":{"description":"If the script can be called from the public HTTP interface.\n\nIf enabled, ensure that authentication & rate limits are configured for\nthis endpoints. See the `user` and `rate_limit` modules.","default":false,"type":"boolean"}},"additionalProperties":false},"ErrorConfig":{"type":"object","properties":{"name":{"description":"The human readable name of the error.","type":"string"},"description":{"description":"A short description of the error.","type":"string"}},"additionalProperties":false},"DependencyConfig":{"type":"object","additionalProperties":false}},"$schema":"http://json-schema.org/draft-07/schema#"}
{"type":"object","properties":{"status":{"enum":["beta","end_of_life","maintenance","preview","stable"],"type":"string"},"name":{"description":"The human readable name of the module.","type":"string"},"description":{"description":"A short description of the module.","type":"string"},"icon":{"description":"The [Font Awesome](https://fontawesome.com/icons) icon name of the module.","type":"string"},"tags":{"description":"The tags associated with this module.","type":"array","items":{"type":"string"}},"authors":{"description":"The GitHub handle of the authors of the module.","type":"array","items":{"type":"string"}},"scripts":{"type":"object","additionalProperties":{"$ref":"#/definitions/ScriptConfig"}},"actors":{"type":"object","additionalProperties":{"$ref":"#/definitions/ActorConfig"}},"errors":{"type":"object","additionalProperties":{"$ref":"#/definitions/ErrorConfig"}},"dependencies":{"type":"object","additionalProperties":{"$ref":"#/definitions/DependencyConfig"}}},"additionalProperties":false,"required":["errors","scripts"],"definitions":{"ScriptConfig":{"type":"object","properties":{"name":{"description":"The human readable name of the script.","type":"string"},"description":{"description":"A short description of the script.","type":"string"},"public":{"description":"If the script can be called from the public HTTP interface.\n\nIf enabled, ensure that authentication & rate limits are configured for\nthis endpoints. See the `user` and `rate_limit` modules.","default":false,"type":"boolean"}},"additionalProperties":false},"ActorConfig":{"type":"object","properties":{"storage_id":{"description":"A globally unique string for storing data for this actor.\n\n**IMPORTANT** Changing this will effectively unlink all data stored in this actor. Changing it back to\nthe old value will restore the data.","type":"string"}},"additionalProperties":false,"required":["storage_id"]},"ErrorConfig":{"type":"object","properties":{"name":{"description":"The human readable name of the error.","type":"string"},"description":{"description":"A short description of the error.","type":"string"}},"additionalProperties":false},"DependencyConfig":{"type":"object","additionalProperties":false}},"$schema":"http://json-schema.org/draft-07/schema#"}
2 changes: 1 addition & 1 deletion artifacts/runtime_archive.json

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions deno.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"version": "3",
"packages": {
"specifiers": {
"npm:@prisma/adapter-pg@^5.12.0": "npm:@prisma/[email protected][email protected]",
"npm:@prisma/adapter-pg@^5.9.1": "npm:@prisma/[email protected][email protected]",
"npm:@rivet-gg/esbuild-plugin-polyfill-node@^0.4.0": "npm:@rivet-gg/[email protected][email protected]",
"npm:@types/node": "npm:@types/[email protected]",
Expand Down Expand Up @@ -146,6 +147,14 @@
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"dependencies": {}
},
"@prisma/[email protected][email protected]": {
"integrity": "sha512-7AlihIeGvEuuGlZcjv66KAcz/xiu3pqgZzihh+447CDgf8eC+YtuT4tKgewyuYVWDAFb/U1SefgnAjcjAxRrXg==",
"dependencies": {
"@prisma/driver-adapter-utils": "@prisma/[email protected]",
"pg": "[email protected]",
"postgres-array": "[email protected]"
}
},
"@prisma/[email protected][email protected]": {
"integrity": "sha512-0RhnB1sqLmSzilbIQS75YE5qTNotlGvLWhTG7cp+F59VJdQ5sWWXZ1j2W4Tn+AMb116Yp4AuFe0vggW2f+ujiQ==",
"dependencies": {
Expand All @@ -154,6 +163,16 @@
"postgres-array": "[email protected]"
}
},
"@prisma/[email protected]": {
"integrity": "sha512-699iqlEvzyCj9ETrXhs8o8wQc/eVW+FigSsHpiskSFydhjVuwTJEfj/nIYqTaWFYuxiWQRfm3r01meuW97SZaQ==",
"dependencies": {}
},
"@prisma/[email protected]": {
"integrity": "sha512-SaimwvGuvXJTsWH+FOfl7PlkZZlPiRGeMEchC0kvB08Xw9B3CLYo/Q7zaY5Fp+u5D8asrpcFQmCjXEgDvOmPkg==",
"dependencies": {
"@prisma/debug": "@prisma/[email protected]"
}
},
"@prisma/[email protected]": {
"integrity": "sha512-1h1+6kU3PfsE2CvQoU49Jt7yrXybU0C/H/+W8Bh0pJefMAbTY8KoWssYXgwQp1PUKBtdh1GDQsMf9ojFeQ0RWg==",
"dependencies": {
Expand Down Expand Up @@ -725,7 +744,9 @@
},
"redirects": {
"https://esm.sh/@neondatabase/serverless@^0.9.0": "https://esm.sh/@neondatabase/[email protected]",
"https://esm.sh/@neondatabase/serverless@^0.9.3": "https://esm.sh/@neondatabase/[email protected]",
"https://esm.sh/@prisma/adapter-neon@^5.10.2": "https://esm.sh/@prisma/[email protected]",
"https://esm.sh/@prisma/adapter-neon@^5.13.0": "https://esm.sh/@prisma/[email protected]",
"https://esm.sh/ajv-formats@^2.1.1": "https://esm.sh/[email protected]",
"https://esm.sh/ajv@^8.12.0": "https://esm.sh/[email protected]",
"https://esm.sh/pg@^8.11.3": "https://esm.sh/[email protected]",
Expand Down Expand Up @@ -2550,14 +2571,20 @@
"https://deno.land/x/[email protected]/cache.ts": "89eea5f3ce6035a1164b3e655c95f21300498920575ade23161421f5b01967f4",
"https://deno.land/x/[email protected]/loader.ts": "d98d195a715f823151cbc8baa3f32127337628379a02d9eb2a3c5902dbccfc02",
"https://esm.sh/@neondatabase/[email protected]": "3007f35c946e1ce273f644f2bfee27a9de48d1fbe332dab9d53566d12080e22d",
"https://esm.sh/@neondatabase/[email protected]": "44d18e016ebf3ce55f3e87f8f65976f6e8ff0624faafff1625bf6dd5863d21c6",
"https://esm.sh/@prisma/[email protected]": "0139f84d719977a05264596fef6bb34e4d0e9ddf15f73d6fd9ec6ff203a8d432",
"https://esm.sh/@prisma/[email protected]": "5b223ec54e4893e0191797043fda7eedbea8b3442f683e55a48633c5bad4b263",
"https://esm.sh/[email protected]": "575b3830618970ddc3aba96310bf4df7358bb37fcea101f58b36897ff3ac2ea7",
"https://esm.sh/[email protected]": "cc1a73af661466c7f4e6a94d93ece78542d700f2165bdb16a531e9db8856c5aa",
"https://esm.sh/v135/@neondatabase/[email protected]/denonext/serverless.mjs": "a45acb984910225aa035c9787133d117fb585d6d62536238e135580cf6a0a695",
"https://esm.sh/v135/@neondatabase/[email protected]/denonext/serverless.mjs": "170ea3600a913c22aa959044968d73c6a214f17ce6ea60ce2002d4e9225f2491",
"https://esm.sh/v135/@neondatabase/[email protected]/denonext/serverless.mjs": "5351e9d60196cfbec4e83de6a91fd2878c201a9d79262248fd615373725eb061",
"https://esm.sh/v135/@prisma/[email protected]/denonext/adapter-neon.mjs": "3639e2b49242e394582e1e36623a62ab75c60a487c502bc6d9665944531728dc",
"https://esm.sh/v135/@prisma/[email protected]/denonext/adapter-neon.mjs": "964ca03df72d71669e519581e826dce6c21208e2530b2be6c1b283d4efa1542a",
"https://esm.sh/v135/@prisma/[email protected]/denonext/debug.mjs": "cab0a6f1eb5df296ddf9b9590519e6bdc851bfad482961b7bd25e5bfe1cc428c",
"https://esm.sh/v135/@prisma/[email protected]/denonext/debug.mjs": "f9422affb4aed3f33c884f52160531fabb7f3bd311ad15e99be3796640533e6f",
"https://esm.sh/v135/@prisma/[email protected]/denonext/driver-adapter-utils.mjs": "2266fc26eebd8821b502bb0ada2488062259b3b4d8188cd5692e13f14caa174c",
"https://esm.sh/v135/@prisma/[email protected]/denonext/driver-adapter-utils.mjs": "db5e5076ba2dab34d8ccb96dc211dbab04fa3a3d25ef648a34689c85e8f34612",
"https://esm.sh/v135/[email protected]/denonext/ajv-formats.mjs": "06092e00b42202633ae6dab4b53287c133af882ddb14c6707277cdb237634967",
"https://esm.sh/v135/[email protected]/denonext/ajv.mjs": "4645df9093d0f8be0e964070a4a7aea8adea06e8883660340931f7a3f979fc65",
"https://esm.sh/v135/[email protected]/denonext/dist/compile/codegen.js": "d981238e5b1e78217e1c6db59cbd594369279722c608ed630d08717ee44edd84",
Expand Down
61 changes: 52 additions & 9 deletions src/build/entrypoint.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { resolve } from "../deps.ts";
import { dirname, fromFileUrl, resolve } from "../deps.ts";
import { Project } from "../project/mod.ts";
import { genRegistryMapPath, genRuntimeModPath, genRuntimePath } from "../project/project.ts";
import { CommandError } from "../error/mod.ts";
import { autoGenHeader } from "./misc.ts";
import { BuildOpts, DbDriver, Runtime } from "./mod.ts";
import { dedent } from "./deps.ts";

// Read source files as strings
const ACTOR_SOURCE = await Deno.readTextFile(resolve(dirname(fromFileUrl(import.meta.url)), "../dynamic/actor.ts"));
const ACTOR_CF_SOURCE = await Deno.readTextFile(
resolve(dirname(fromFileUrl(import.meta.url)), "../dynamic/actor_cf.ts"),
);

export async function generateEntrypoint(project: Project, opts: BuildOpts) {
const runtimeModPath = genRuntimeModPath(project);
const registryMapPath = genRegistryMapPath(project);
Expand All @@ -24,19 +30,27 @@ export async function generateEntrypoint(project: Project, opts: BuildOpts) {
} else if (opts.dbDriver == DbDriver.NeonServerless) {
imports += `
// Import Prisma serverless adapter for Neon
import * as neon from "https://esm.sh/@neondatabase/serverless@^0.9.0";
import { PrismaNeonHTTP } from "https://esm.sh/@prisma/adapter-neon@^5.10.2";
import * as neon from "https://esm.sh/@neondatabase/serverless@^0.9.3";
import { PrismaNeonHTTP } from "https://esm.sh/@prisma/adapter-neon@^5.13.0";
`;
}

let compat = "";
let actorSource = `
import { Config } from "${runtimeModPath}";
import config from "./runtime_config.ts";
`;

if (opts.runtime == Runtime.Deno) {
compat += `
// Create module for Prisma compatibility
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
`;

actorSource += ACTOR_SOURCE;
} else {
actorSource += ACTOR_CF_SOURCE;
}

// Generate config.ts
Expand All @@ -60,12 +74,17 @@ export async function generateEntrypoint(project: Project, opts: BuildOpts) {
entrypointSource = `
${autoGenHeader()}
import { Runtime } from "${runtimeModPath}";
import { camelToSnake } from "${registryMapPath};
import type { Registry, RegistryCamel } from "./registry.d.ts";
import { camelToSnake, actorCamelToSnake } from "${registryMapPath};
import type { Registry, RegistryCamel, ActorRegistry, ActorRegistryCamel } from "./registry.d.ts";
import config from "./runtime_config.ts";
import { ACTOR_DRIVER } from "./actor.ts";
async function main() {
const runtime = new Runtime<Registry, RegistryCamel>(config, camelToSnake);
const runtime = new Runtime<
Registry, RegistryCamel, ActorRegistry, ActorRegistryCamel
>(
config, ACTOR_DRIVER, camelToSnake, actorCamelToSnake
);
await runtime.serve();
}
Expand All @@ -81,12 +100,17 @@ export async function generateEntrypoint(project: Project, opts: BuildOpts) {
import type { IncomingRequestCf } from 'https://raw.githubusercontent.com/skymethod/denoflare/v0.6.0/common/cloudflare_workers_types.d.ts';
import { Runtime } from "${runtimeModPath}";
import { RuntimeError } from "${errorTsPath}";
import { camelToSnake } from "${registryMapPath}";
import type { Registry, RegistryCamel } from "./registry.d.ts";
import { camelToSnake, actorCamelToSnake } from "${registryMapPath}";
import type { Registry, RegistryCamel, ActorRegistry, ActorRegistryCamel } from "./registry.d.ts";
import config from "./runtime_config.ts";
import { ACTOR_DRIVER } from "./actor.ts";
import { serverHandler } from "${serverTsPath}";
const RUNTIME = new Runtime<Registry, RegistryCamel>(config, camelToSnake);
const RUNTIME = new Runtime<
Registry, RegistryCamel, ActorRegistry, ActorRegistryCamel
>(
config, ACTOR_DRIVER, camelToSnake, actorCamelToSnake
);
const SERVER_HANDLER = serverHandler(RUNTIME);
export default {
Expand All @@ -110,20 +134,25 @@ export async function generateEntrypoint(project: Project, opts: BuildOpts) {
});
}
}
// Export durable object binding
export { __GlobalDurableObject } from "./actor.ts";
`;
}

// Write files
const distDir = resolve(project.path, "_gen");
const configPath = resolve(distDir, "runtime_config.ts");
const entrypointPath = resolve(distDir, "entrypoint.ts");
const actorPath = resolve(distDir, "actor.ts");
await Deno.mkdir(distDir, { recursive: true });
await Deno.writeTextFile(configPath, configSource);
await Deno.writeTextFile(entrypointPath, entrypointSource);
await Deno.writeTextFile(
resolve(distDir, ".gitignore"),
".",
);
await Deno.writeTextFile(actorPath, actorSource);

// Format files
const fmtOutput = await new Deno.Command("deno", {
Expand Down Expand Up @@ -155,6 +184,20 @@ function generateModImports(project: Project, opts: BuildOpts) {
}
modConfig += "},";

// Generate actor configs
modConfig += "actors: {";
for (const actor of mod.actors.values()) {
const actorIdent = `modules$$${mod.name}$$${actor.name}$$Actor`;

modImports += `import { Actor as ${actorIdent} } from '${mod.path}/actors/${actor.name}.ts';\n`;

modConfig += `${JSON.stringify(actor.name)}: {`;
modConfig += `actor: ${actorIdent},`;
modConfig += `storageId: ${JSON.stringify(actor.config.storage_id)},`;
modConfig += `},`;
}
modConfig += "},";

// Generate error configs
modConfig += `errors: ${JSON.stringify(mod.config.errors)},`;

Expand Down

0 comments on commit 4ff9bac

Please sign in to comment.