This commit is contained in:
parent
a740da1099
commit
540d0549d7
@ -23,7 +23,7 @@
|
|||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
{#if !activeUser}
|
{#if !activeUser}
|
||||||
{#await registry.fetchUsers()}
|
{#await registry.fetchUsers()}
|
||||||
<div>Loading...</div>
|
<div>Loading Users...</div>
|
||||||
{:then users}
|
{:then users}
|
||||||
{#each users as user}
|
{#each users as user}
|
||||||
<button
|
<button
|
||||||
@ -37,7 +37,7 @@
|
|||||||
{/await}
|
{/await}
|
||||||
{:else if !activeCollection}
|
{:else if !activeCollection}
|
||||||
{#await registry.fetchUser(activeUser)}
|
{#await registry.fetchUser(activeUser)}
|
||||||
<div>Loading...</div>
|
<div>Loading User...</div>
|
||||||
{:then user}
|
{:then user}
|
||||||
{#each user.collections as collection}
|
{#each user.collections as collection}
|
||||||
<button
|
<button
|
||||||
@ -53,11 +53,11 @@
|
|||||||
{/await}
|
{/await}
|
||||||
{:else if !activeNode}
|
{:else if !activeNode}
|
||||||
{#await registry.fetchCollection(`${activeUser}/${activeCollection}`)}
|
{#await registry.fetchCollection(`${activeUser}/${activeCollection}`)}
|
||||||
<div>Loading...</div>
|
<div>Loading Collection...</div>
|
||||||
{:then collection}
|
{:then collection}
|
||||||
{#each collection.nodes as node}
|
{#each collection.nodes as node}
|
||||||
{#await registry.fetchNodeDefinition(node.id)}
|
{#await registry.fetchNodeDefinition(node.id)}
|
||||||
<div>Loading... {node.id}</div>
|
<div>Loading Node... {node.id}</div>
|
||||||
{:then node}
|
{:then node}
|
||||||
{#if node}
|
{#if node}
|
||||||
<DraggableNode {node} />
|
<DraggableNode {node} />
|
||||||
|
@ -32,8 +32,7 @@
|
|||||||
let performanceStore = createPerformanceStore();
|
let performanceStore = createPerformanceStore();
|
||||||
|
|
||||||
const registryCache = new IndexDBCache("node-registry");
|
const registryCache = new IndexDBCache("node-registry");
|
||||||
const nodeRegistry = new RemoteNodeRegistry("");
|
const nodeRegistry = new RemoteNodeRegistry("", registryCache);
|
||||||
nodeRegistry.cache = registryCache;
|
|
||||||
const workerRuntime = new WorkerRuntimeExecutor();
|
const workerRuntime = new WorkerRuntimeExecutor();
|
||||||
const runtimeCache = new MemoryRuntimeCache();
|
const runtimeCache = new MemoryRuntimeCache();
|
||||||
const memoryRuntime = new MemoryRuntimeExecutor(nodeRegistry, runtimeCache);
|
const memoryRuntime = new MemoryRuntimeExecutor(nodeRegistry, runtimeCache);
|
||||||
|
@ -13,7 +13,7 @@ export class RemoteNodeRegistry implements NodeRegistry {
|
|||||||
|
|
||||||
fetch: typeof fetch = globalThis.fetch.bind(globalThis);
|
fetch: typeof fetch = globalThis.fetch.bind(globalThis);
|
||||||
|
|
||||||
constructor(private url: string) { }
|
constructor(private url: string, private cache?: AsyncCache<ArrayBuffer>) { }
|
||||||
|
|
||||||
async fetchUsers() {
|
async fetchUsers() {
|
||||||
const response = await this.fetch(`${this.url}/nodes/users.json`);
|
const response = await this.fetch(`${this.url}/nodes/users.json`);
|
||||||
@ -24,7 +24,7 @@ export class RemoteNodeRegistry implements NodeRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fetchUser(userId: `${string}`) {
|
async fetchUser(userId: `${string}`) {
|
||||||
const response = await this.fetch(`${this.url}/nodes/${userId}.json`);
|
const response = await this.fetch(`${this.url}/user/${userId}.json`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Failed to load user ${userId}`);
|
throw new Error(`Failed to load user ${userId}`);
|
||||||
}
|
}
|
||||||
|
13
store/Dockerfile
Normal file
13
store/Dockerfile
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
FROM denoland/deno:alpine
|
||||||
|
|
||||||
|
ARG GIT_REVISION
|
||||||
|
ENV DENO_DEPLOYMENT_ID=${GIT_REVISION}
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
RUN deno cache main.ts && deno task build
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["task", "run"]
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"dev": "deno run -A --watch src/main.ts",
|
"dev": "deno run -A --watch src/server.ts",
|
||||||
|
"run": "deno run -A src/server.ts",
|
||||||
"test": "deno run vitest",
|
"test": "deno run vitest",
|
||||||
"drizzle": "podman-compose exec app deno --env -A --node-modules-dir npm:drizzle-kit",
|
"drizzle": "podman-compose exec app deno --env -A --node-modules-dir npm:drizzle-kit",
|
||||||
"upload": "deno run --allow-read --allow-net bin/upload.ts"
|
"upload": "deno run --allow-read --allow-net bin/upload.ts"
|
||||||
|
File diff suppressed because one or more lines are too long
@ -8,8 +8,8 @@ const { Pool } = pg;
|
|||||||
// Instantiate Drizzle client with pg driver and schema.
|
// Instantiate Drizzle client with pg driver and schema.
|
||||||
export const db = drizzle({
|
export const db = drizzle({
|
||||||
client: new Pool({
|
client: new Pool({
|
||||||
|
max: 20,
|
||||||
connectionString: Deno.env.get("DATABASE_URL"),
|
connectionString: Deno.env.get("DATABASE_URL"),
|
||||||
}),
|
}),
|
||||||
schema,
|
schema,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ const getNodeWasmRoute = createRoute({
|
|||||||
nodeRouter.openapi(getNodeWasmRoute, async (c) => {
|
nodeRouter.openapi(getNodeWasmRoute, async (c) => {
|
||||||
const { user, system, nodeId } = c.req.valid("param");
|
const { user, system, nodeId } = c.req.valid("param");
|
||||||
|
|
||||||
|
const a = performance.now();
|
||||||
const wasmContent = await service.getNodeWasmById(
|
const wasmContent = await service.getNodeWasmById(
|
||||||
user,
|
user,
|
||||||
system,
|
system,
|
||||||
|
@ -110,6 +110,7 @@ export async function getNodeWasmById(
|
|||||||
systemId: string,
|
systemId: string,
|
||||||
nodeId: string,
|
nodeId: string,
|
||||||
) {
|
) {
|
||||||
|
const a = performance.now();
|
||||||
const node = await db.select({ content: nodeTable.content }).from(nodeTable)
|
const node = await db.select({ content: nodeTable.content }).from(nodeTable)
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
@ -117,7 +118,8 @@ export async function getNodeWasmById(
|
|||||||
eq(nodeTable.systemId, systemId),
|
eq(nodeTable.systemId, systemId),
|
||||||
eq(nodeTable.nodeId, nodeId),
|
eq(nodeTable.nodeId, nodeId),
|
||||||
),
|
),
|
||||||
).limit(1);
|
).limit(1).execute();
|
||||||
|
console.log("Time to load wasm", performance.now() - a);
|
||||||
|
|
||||||
if (!node[0]) {
|
if (!node[0]) {
|
||||||
throw new Error("Node not found");
|
throw new Error("Node not found");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
customType,
|
customType,
|
||||||
|
index,
|
||||||
integer,
|
integer,
|
||||||
json,
|
json,
|
||||||
pgTable,
|
pgTable,
|
||||||
@ -27,7 +28,12 @@ export const nodeTable = pgTable("nodes", {
|
|||||||
definition: json().notNull(),
|
definition: json().notNull(),
|
||||||
hash: varchar({ length: 8 }).notNull(),
|
hash: varchar({ length: 8 }).notNull(),
|
||||||
previous: integer(),
|
previous: integer(),
|
||||||
});
|
}, (table) => [
|
||||||
|
index("user_id_idx").on(table.userId),
|
||||||
|
index("system_id_idx").on(table.systemId),
|
||||||
|
index("node_id_idx").on(table.nodeId),
|
||||||
|
index("hash_idx").on(table.hash),
|
||||||
|
]);
|
||||||
|
|
||||||
export const nodeRelations = relations(nodeTable, ({ one }) => ({
|
export const nodeRelations = relations(nodeTable, ({ one }) => ({
|
||||||
userId: one(usersTable, {
|
userId: one(usersTable, {
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { OpenAPIHono } from "@hono/zod-openapi";
|
|
||||||
import { nodeRouter } from "./node/node.controller.ts";
|
|
||||||
import { userRouter } from "./user/user.controller.ts";
|
|
||||||
|
|
||||||
const router = new OpenAPIHono();
|
|
||||||
|
|
||||||
router.route("nodes", nodeRouter);
|
|
||||||
router.route("users", userRouter);
|
|
||||||
|
|
||||||
export { router };
|
|
@ -1,14 +1,6 @@
|
|||||||
import { pgTable, text, uuid } from "drizzle-orm/pg-core";
|
import { pgTable, text, uuid } from "drizzle-orm/pg-core";
|
||||||
import { z } from "@hono/zod-openapi";
|
|
||||||
|
|
||||||
export const usersTable = pgTable("users", {
|
export const usersTable = pgTable("users", {
|
||||||
id: uuid().primaryKey().defaultRandom(),
|
id: uuid().primaryKey().defaultRandom(),
|
||||||
name: text().unique().notNull(),
|
name: text().unique().notNull(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const UserSchema = z
|
|
||||||
.object({
|
|
||||||
id: z.string().uuid(),
|
|
||||||
name: z.string().min(1), // Non-null text with a unique constraint (enforced at the database level)
|
|
||||||
})
|
|
||||||
.openapi("User");
|
|
||||||
|
8
store/src/routes/user/user.validation.ts
Normal file
8
store/src/routes/user/user.validation.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { z } from "@hono/zod-openapi";
|
||||||
|
|
||||||
|
export const UserSchema = z
|
||||||
|
.object({
|
||||||
|
id: z.string().uuid(),
|
||||||
|
name: z.string().min(1),
|
||||||
|
})
|
||||||
|
.openapi("User");
|
@ -1,20 +1,17 @@
|
|||||||
import { router } from "./routes/router.ts";
|
|
||||||
import { createUser } from "./routes/user/user.service.ts";
|
import { createUser } from "./routes/user/user.service.ts";
|
||||||
import { swaggerUI } from "@hono/swagger-ui";
|
import { swaggerUI } from "@hono/swagger-ui";
|
||||||
import { logger } from "hono/logger";
|
import { logger } from "hono/logger";
|
||||||
import { cors } from "hono/cors";
|
import { cors } from "hono/cors";
|
||||||
|
import { OpenAPIHono } from "@hono/zod-openapi";
|
||||||
|
import { nodeRouter } from "./routes/node/node.controller.ts";
|
||||||
|
import { userRouter } from "./routes/user/user.controller.ts";
|
||||||
|
|
||||||
async function init() {
|
const router = new OpenAPIHono();
|
||||||
const openapi = await router.request("/openapi.json");
|
|
||||||
const json = await openapi.text();
|
|
||||||
Deno.writeTextFile("openapi.json", json);
|
|
||||||
|
|
||||||
await createUser("max");
|
|
||||||
}
|
|
||||||
await init();
|
|
||||||
|
|
||||||
router.use(logger());
|
router.use(logger());
|
||||||
router.use(cors());
|
router.use(cors());
|
||||||
|
router.route("nodes", nodeRouter);
|
||||||
|
router.route("users", userRouter);
|
||||||
|
|
||||||
router.doc("/openapi.json", {
|
router.doc("/openapi.json", {
|
||||||
openapi: "3.0.0",
|
openapi: "3.0.0",
|
||||||
@ -27,3 +24,12 @@ router.doc("/openapi.json", {
|
|||||||
router.get("/ui", swaggerUI({ url: "/openapi.json" }));
|
router.get("/ui", swaggerUI({ url: "/openapi.json" }));
|
||||||
|
|
||||||
Deno.serve(router.fetch);
|
Deno.serve(router.fetch);
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
const openapi = await router.request("/openapi.json");
|
||||||
|
const json = await openapi.text();
|
||||||
|
Deno.writeTextFile("openapi.json", json);
|
||||||
|
|
||||||
|
await createUser("max");
|
||||||
|
}
|
||||||
|
await init();
|
Loading…
x
Reference in New Issue
Block a user