Skip to main content

SQLite

Server Source code Package Beta

Persists walkerOS events to SQLite. One destination, two drivers behind a single interface: better-sqlite3 for local files (and :memory:), and @libsql/client for remote Turso / libSQL / sqld over HTTP or WebSocket. Driver selection is URL-driven; both SDKs are optional peer dependencies so you install only the one you need.

Where this fits

SQLite is a server destination in the walkerOS flow:

Receives events server-side from the collector, serializes them into a canonical row, and inserts them into a SQLite-compatible database. Good fit for single-host deployments (local file), embedded analytics (in-memory), and edge-deployed Turso databases.

Installation

Loading...
Loading...

Configuration

This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see destination configuration. Package-specific fields live under config.settings and are listed below.

Settings

PropertyTypeDescriptionMore
sqlite*sqliteSQLite / libSQL configuration
url*stringSQLite connection URL. libsql://, http(s)://, ws(s):// route to libSQL/Turso. Anything else is treated as a local file path via better-sqlite3. Use ':memory:' for an ephemeral in-memory database.
authTokenstringlibSQL / Turso auth token. Ignored for better-sqlite3 (local) connections.
tablestringTarget table name. Defaults to "events".
schema'auto' | 'manual'[DEPRECATED] Use config.setup instead. "auto" maps to "setup: true" (run `walkeros setup destination.<id>`); "manual" maps to "setup: false". Removed in the next major.
* Required fields

Mapping

Per-event rules under config.mapping. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.

PropertyTypeDescriptionMore
tablestringOverride target table name for this rule. Takes precedence over settings.sqlite.table.

Examples

Custom table

A destination-level table setting inserts events into a custom SQLite table with the same column layout.

Event
Out

Default insert

A walker event is inserted into the default events table with canonical columns and JSON-encoded sections.

Event
Out

Order insert

An order complete is inserted with numeric data serialized as JSON in the data column.

Event
Out

Table override

A mapping rule overrides the target table so specific events are inserted into a dedicated SQLite table.

Event
Mapping
Out

The destination opens the connection during init() and prepares the INSERT statement once. Schema creation lives in the setup lifecycle (see below), not in init(). On destroy() the connection is closed cleanly. User-provided clients (wired via env.client or settings.sqlite._client) are left untouched.

Setup

Create the events table and apply pragmas with one command:

Loading...

This runs CREATE TABLE IF NOT EXISTS with the canonical 15-column walkerOS Event v4 schema and applies four pragmas:

  • journal_mode = WAL (better concurrent reads)
  • synchronous = NORMAL (good durability vs. perf balance)
  • foreign_keys = ON
  • temp_store = MEMORY

Setup is idempotent. Re-running against a populated database is a safe no-op. Drift between the declared schema and the actual table is logged as WARN setup.drift {field, declared, actual}. Setup never auto-mutates an existing table, no ALTER TABLE, no destructive recreates.

The default 15-column schema mirrors the canonical walkerOS Event v4 layout. Only name is NOT NULL. See Event Model for the full field reference.

CREATE TABLE IF NOT EXISTS events (
name TEXT NOT NULL,
data TEXT,
context TEXT,
globals TEXT,
custom TEXT,
user TEXT,
nested TEXT,
consent TEXT,
id TEXT,
trigger TEXT,
entity TEXT,
action TEXT,
timestamp TEXT,
timing INTEGER,
source TEXT
)

Nested objects (data, context, globals, custom, user, nested, consent, source) are stored as JSON strings.

Override defaults in config.setup:

Loading...

setup: true accepts all defaults. setup: false (or omitted) means walkeros setup destination.sqlite is a no-op for this destination.

Use mapping.settings.table to route specific events to a dedicated table (for example orders to orders, identities to identities).

Migration from schema

Deprecated

The package-local settings.sqlite.schema setting is deprecated. The framework now owns the setup lifecycle through config.setup. The deprecated form still works and emits a one-time WARN through the destination logger.

Old (settings.sqlite.schema)New (config.setup)Effect
'auto'truewalkeros setup destination.sqlite creates table.
'manual'falseSetup is a no-op. Bring your own schema + mapping.
omittedomittedNo-op until setup is set explicitly.

Remove the schema field from settings.sqlite and add setup: true (or false) at the config level.

Drivers

Local, better-sqlite3

Sync native driver, fastest option for single-host deployments. The URL is treated as a filesystem path; :memory: works too. All four default pragmas are honored.

Loading...

Remote, @libsql/client

Async HTTP/WSS driver for Turso, self-hosted sqld, or any libSQL-compatible endpoint. Auth via authToken. The remote server controls journaling, so a client-side journal_mode pragma is silently ignored. The other pragmas (synchronous, foreign_keys, temp_store) still apply.

Loading...

URL prefixes libsql://, http://, https://, ws://, wss:// route to the libSQL driver. Anything else (bare paths, :memory:) routes to better-sqlite3.

Limitations

  • v1 issues one INSERT per event. A pushBatch path is planned for v2.
  • Connection death is not auto-retried; a fatal driver error logs and drops events until the flow restarts.
💡 Need implementation support?
elbwalker offers hands-on support: setup review, measurement planning, destination mapping, and live troubleshooting. Book a 2-hour session (€399)