Skip to content

Architecture

Application (your code)
↓
Client (Jsorm, TableMethods)
↓
Core (types + metadata)
↓
Compiler (shared SQL generation)
↓
Provider (driver + execution)
↓
Database

Upper layers depend on lower ones. Lower layers never depend on upper ones.


Types and pure metadata. No SQL, no providers, no Node APIs, no execution.

Responsibilities:

  • defineModel() — creates models with typed metadata
  • defineConfig() — defines project configuration
  • t.*, r.* — field types and relations
  • env() — helper to mark values as env vars
  • AST types (QueryAST, WhereCondition, ProviderResult, etc.)
  • Naming: toSnakeCase(), sanitizeIdentifier()

Cannot know: SQL, Node, providers, client, filesystem, HTTP.


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.


Main runtime. Edge-compatible.

Responsibilities:

  • createJsorm<DB>() — factory function with Proxy
  • TableMethods — 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.


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.


Development tools. Node 22+.

Responsibilities:

  • jsorm configure — interactive assistant
  • jsorm gen — generates types and runtime
  • jsorm watch — watch mode

Parser: tree-sitter-typescript.

Not part of the runtime.


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

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

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