Architecture
Layers
Section titled “Layers”Application (your code) ↓Client (Jsorm, TableMethods) ↓Core (types + metadata) ↓Compiler (shared SQL generation) ↓Provider (driver + execution) ↓DatabaseUpper layers depend on lower ones. Lower layers never depend on upper ones.
Core (@jsorm/core)
Section titled “Core (@jsorm/core)”Types and pure metadata. No SQL, no providers, no Node APIs, no execution.
Responsibilities:
defineModel()— creates models with typed metadatadefineConfig()— defines project configurationt.*,r.*— field types and relationsenv()— helper to mark values as env vars- AST types (
QueryAST,WhereCondition,ProviderResult, etc.) - Naming:
toSnakeCase(),sanitizeIdentifier()
Cannot know: SQL, Node, providers, client, filesystem, HTTP.
Compiler (@jsorm/compiler)
Section titled “Compiler (@jsorm/compiler)”Shared SQL generation. Used by SQL providers (pg-node, sqlite-node). NOT edge-compatible (uses node:crypto for sync HMAC cursors).
Responsibilities:
- Compile QueryAST → SQL strings
- Dialect-configurable (placeholder style, type mapping, LIKE operator, defaults)
- Ship dialect configs: postgresDialect, sqliteDialect, mysqlDialect
Cannot know: drivers, connections, models, client, application.
Client (@jsorm/client)
Section titled “Client (@jsorm/client)”Main runtime. Edge-compatible.
Responsibilities:
createJsorm<DB>()— factory function with ProxyTableMethods— table access via Proxy (jsorm.users.get())ProviderManager— AST → provider routing- AST builders — constructing AST from user input
Cannot know: SQL, dialects, drivers, Node APIs, filesystem.
Provider (@jsorm/provider-*)
Section titled “Provider (@jsorm/provider-*)”Receive QueryAST, execute, return { data: T }.
Each provider is self-contained:
- Driver (better-sqlite3, pg, IndexedDB API) or hydra
- Connection manager
- Schema sync
- SQL generation delegated to @jsorm/compiler (pg, sqlite) or own non-SQL compiler (IndexedDB)
Cannot: know models, config, or other layers. Interchangeable without modifying client or core.
CLI (@jsorm/cli)
Section titled “CLI (@jsorm/cli)”Development tools. Node 22+.
Responsibilities:
jsorm configure— interactive assistantjsorm gen— generates types and runtimejsorm watch— watch mode
Parser: tree-sitter-typescript.
Not part of the runtime.
Layer rules
Section titled “Layer rules”| Layer | Rule |
|---|---|
| Core | Does not import SQL, Node, providers, or infrastructure |
| Client | Contains no drivers or SQL. Proxy creates TableMethods per table |
| Provider | Receives pure QueryAST. Interchangeable without modifying client or core |
| Compiler | Generates SQL, never executes. Not edge-compatible (node:crypto). Providers depend on it |
| CLI | Only layer with filesystem and process access |
Model rules
Section titled “Model rules”| Layer | Rule |
|---|---|
| Models | Metadata only, no logic or queries |
| Relations | Always reference models by name, no cross imports |
| Queries | Everything goes through AST. No SQL in public API. No callbacks |
Runtime files
Section titled “Runtime files”| File | Content |
|---|---|
jsorm.server.ts |
Server instance with createJsorm<DB> |
jsorm.client.ts |
Client instance with createJsorm<DBClient> |
.jsorm/types.ts |
Record interfaces, query types, DB, DBClient |
