feat: deno-first storage package with sqlite host and graph schemas

Scaffolded @alkdev/storage from @ade/storage_sqlite and @ade/core/graphs:
- graphs/ module: TypeBox schema types + SchemaBuilder (from @ade/core/graphs)
- sqlite/ module: Drizzle table defs, relations, injectable client (from @ade/storage_sqlite)
- pg/ module: placeholder for Postgres host
- deno.json configured for JSR with subpath exports (./graphs, ./sqlite, ./pg)
- Imports swapped: @sinclair/typebox → @alkdev/typebox, drizzle-typebox → @alkdev/drizzlebox
- Client is now injectable (no hardcoded env vars or module-level side effects)
- no-slow-types lint excluded (Drizzle generics); --allow-slow-types on publish
This commit is contained in:
2026-05-28 12:19:48 +00:00
parent c6ea6c15e9
commit 8c68dd6b07
20 changed files with 540 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
import { KindGuard, type TSchema } from "@alkdev/typebox";
import { Value } from "@alkdev/typebox/value";
import { assert } from "@std/assert";
import { GraphSchema, GraphConfig, NodeType, EdgeType } from "./types.ts";
export class SchemaBuilder {
private schema: {
config: Record<string, unknown>;
nodeTypes: Record<string, NodeType>;
edgeTypes: Record<string, EdgeType>;
} = {
config: {},
nodeTypes: {},
edgeTypes: {},
};
config(config: Partial<GraphConfig>): SchemaBuilder {
const configObj = Value.Default(GraphConfig, config) as GraphConfig;
this.check(GraphConfig, configObj);
this.schema.config = configObj as Record<string, unknown>;
return this;
}
nodeType(name: string, schema: TSchema): SchemaBuilder {
assert(KindGuard.IsSchema(schema), `type '${name}' is not a valid json schema.`);
if (!this.schema.nodeTypes) this.schema.nodeTypes = {};
const nodeTypeObj: NodeType = { name, schema };
this.check(NodeType, nodeTypeObj);
this.schema.nodeTypes[name] = nodeTypeObj;
return this;
}
edgeType(
name: string,
schema: TSchema,
options?: { allowedSourceTypes?: string[]; allowedTargetTypes?: string[] },
): SchemaBuilder {
assert(KindGuard.IsSchema(schema), `type '${name}' is not a valid json schema.`);
if (!this.schema.edgeTypes) this.schema.edgeTypes = {};
const edgeTypeObj: EdgeType = { name, schema, ...options };
this.check(EdgeType, edgeTypeObj);
this.schema.edgeTypes[name] = edgeTypeObj;
return this;
}
check(schema: TSchema, value: unknown): void {
if (!Value.Check(schema, value)) {
const errors = [...Value.Errors(schema, value)];
throw new Error(
`Invalid schema structure: ${JSON.stringify(errors.map((e) => `${e.path}: ${e.message}`))}`,
);
}
}
build(): GraphSchema {
this.check(GraphSchema, this.schema);
return this.schema as GraphSchema;
}
}