Engine Core
About 728 wordsAbout 2 min
2026-03-28
packages/engine-core is the framework-agnostic TypeScript library containing all database schema, business logic, and shared types.
Directory structure
packages/engine-core/
├── src/
│ ├── index.ts # All exports
│ ├── types.ts # Domain types
│ ├── engine.ts # Engine state logic (take, clear, etc.)
│ └── db/
│ ├── connection.ts # Database creation and migration
│ └── schema.ts # Drizzle ORM table definitions
├── drizzle/ # Generated SQL migrations
├── tests/ # Vitest test suite
└── vitest.config.tsDatabase
Connection
import { createDatabase } from 'engine-core';
const db = createDatabase('path/to/ceegee.db');createDatabase(dbPath, migrationsFolder?) creates a SQLite database with:
- WAL mode enabled
- Foreign keys enforced
- Drizzle migrations applied automatically
The Nuxt app uses a singleton pattern in server/utils/db.ts (useDb()) so all API routes share one connection.
Schema (Drizzle)
Seven tables defined in src/db/schema.ts:
| Table | Purpose |
|---|---|
workspaces | Top-level project containers with display config and theme tokens |
channels | Output buses within a workspace |
layers | Grouped collections of elements with z-index ordering |
modules | Registry of available graphics module types |
elements | Instances of modules on layers, with config JSON |
assets | Workspace-scoped media files (logos, backgrounds) |
elementRuntimeState | Live visibility and runtime data per element |
Key conventions:
- All IDs are
INTEGER PRIMARY KEY(auto-increment). - Timestamps are ISO 8601 strings (
TEXT). - JSON data stored as
TEXTcolumns (e.g.,configJson,themeTokensJson). - Foreign keys cascade on delete.
Migrations
Migrations live in packages/engine-core/drizzle/ and are generated by Drizzle Kit:
cd packages/engine-core
pnpm drizzle-kit generateThe Drizzle config is in drizzle.config.ts:
- Schema source:
./src/db/schema.ts - Output:
./drizzle - Dialect:
sqlite
CRUD functions
All functions are exported from src/index.ts and accept the database instance as the first argument.
Workspaces
createWorkspace(db, input: CreateWorkspaceInput): Workspace
getWorkspace(db, id: WorkspaceId): Workspace | undefined
listWorkspaces(db): Workspace[]
updateWorkspace(db, id, input: UpdateWorkspaceInput): Workspace
deleteWorkspace(db, id): voidChannels
createChannel(db, input): Channel
getChannel(db, id): Channel | undefined
listChannels(db, workspaceId): Channel[]
updateChannel(db, id, input): Channel
deleteChannel(db, id): voidLayers
createLayer(db, input): Layer
getLayer(db, id): Layer | undefined
listLayers(db, channelId): Layer[] // ordered by zIndex asc
updateLayer(db, id, input): Layer
deleteLayer(db, id): voidElements
createElement(db, input): Element
getElement(db, id): Element | undefined
listElements(db, layerId): Element[] // ordered by sortOrder asc
listElementsByChannel(db, channelId): Element[]
updateElement(db, id, input): Element
deleteElement(db, id): voidModules
upsertModule(db, input): ModuleRecord // insert or update by moduleKey
getModule(db, id): ModuleRecord | undefined
getModuleByKey(db, moduleKey): ModuleRecord | undefined
listModules(db): ModuleRecord[]Assets
createAsset(db, input): Asset
getAsset(db, id): Asset | undefined
listAssets(db, workspaceId): Asset[]
updateAsset(db, id, input): Asset // name, tags, folderPath only
deleteAsset(db, id): voidRuntime state
setRuntimeState(db, input): ElementRuntimeState // upsert by elementId
getRuntimeState(db, elementId): ElementRuntimeState | undefined
listRuntimeStateByChannel(db, channelId): ElementRuntimeState[]
clearRuntimeState(db, elementId): voidEngine logic
Engine functions in src/engine.ts implement the live show control operations.
buildChannelState(db, workspaceId, channelId): ChannelState
Builds the full state snapshot for a channel:
- Loads all layers for the channel (ordered by zIndex).
- Loads all elements and their runtime states.
- Assembles a
ChannelStatewithLayerState[], each containingElementRuntimeState[]. - Elements without persisted state default to
visibility: 'hidden'.
take(db, elementId): ChannelState
Takes an element live:
- Hides all other visible elements on the same layer (sets visibility to
hidden). - Sets the target element's visibility to
visible. - Returns the updated
ChannelState.
clear(db, elementId): ChannelState
Removes an element from air:
- Sets the target element's visibility to
hidden. - Returns the updated
ChannelState.
elementAction(db, elementId, actionId, args?): EngineEvent
Triggers a module-specific action:
- Records the action in the element's
runtimeData.lastAction. - Returns an
element:actionevent for broadcast.
Types
All types are defined in src/types.ts and re-exported from src/index.ts.
Key types:
| Type | Description |
|---|---|
Workspace | Workspace with display config and theme tokens |
Channel | Output bus within a workspace |
Layer | Element group with z-index and optional region |
Element | Instance of a module with config JSON |
ModuleRecord | Database representation of a registered module |
ModuleManifest | Runtime contract for a module (manifest file) |
ModuleComponentProps | Props passed to module Vue components |
Asset | Media file metadata |
ElementRuntimeState | Visibility and runtime data for an element |
ElementVisibility | 'hidden' | 'entering' | 'visible' | 'exiting' |
ChannelState | Full state of a channel (layers + element states) |
EngineEvent | WebSocket event union (state:init, state:update, element:action, telemetry) |
LayerRegion | Layout region hint ('band-lower', 'corner-tr', 'full', etc.) |