In-memory
The dependency-free in-memory storage adapter for tests and prototyping.
createMemoryStorage(seed?) returns a dependency-free TeardownStorage backed by plain Maps. It is the primary test fake for the domain services (the core of the SDK's TDD strategy) and is handy for local prototyping and demos.
It is single-process and non-persistent — everything is lost when the process exits. Do not use it in production.
Usage
import { createTeardown } from "@teardown/server";
import { createMemoryStorage } from "@teardown/server/adapters/memory";
const td = createTeardown({
storage: createMemoryStorage(),
config: { sessionSecret: "test-secret" },
});Seeding
Identify and events resolve the request against the projects and environments you seed. In hosted/multi-tenant mode they also authenticate the API key against apiKeys; in single-tenant mode (tenant on createTeardown) you can omit apiKeys entirely. The in-memory store starts empty, so seed the fixtures up front via the optional MemorySeed:
import { createMemoryStorage } from "@teardown/server/adapters/memory";
const storage = createMemoryStorage({
projects: [
{
id: "proj_1",
org_id: "org_1",
name: "Demo",
slug: "demo",
type: "EXPO",
status: "ACTIVE",
push_notifications_enabled: false,
first_session_at: null,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
},
],
environments: [
{
id: "env_1",
project_id: "proj_1",
name: "Production",
slug: "production",
type: "PRODUCTION",
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
},
],
apiKeys: [{ key: "pk_test_123", project_id: "proj_1", org_id: "org_1" }],
});MemorySeed
| Field | Type | Description |
|---|---|---|
projects | ProjectEntity[] | Projects to seed (looked up by the API-key auth and the management services) |
environments | EnvironmentEntity[] | Environments to seed (resolved by environment_slug during identify/events) |
apiKeys | Array<{ key; key_id?; project_id; org_id }> | Publishable keys mapped to their project/org. key_id defaults to a random uuid |
Everything created at runtime (users, devices, sessions, versions, builds, push tokens, events) is generated with random UUID ids and ISO-8601 timestamps, matching the entity conventions.
Behaviour parity
The in-memory adapter implements the same subtle behaviours a production storage layer must, so it's a faithful stand-in for service-level tests:
sessions.findValidForDevicereturns the newest non-expired session (newest-first bycreated_at), matching the production query.builds.updatesettingstatusmarks the buildstatus_overridden = true, unless an explicitstatus_overriddenis also passed (then the explicit value wins).builds.updateStatusByVersionresetsstatus_overridden = falseon every build (a full cascade supersedes manual overrides);updateStatusByVersionExcludingOverriddenskips overridden builds.versions.upsertByName/builds.upsertByVersionBuildPlatformreturn the existing row on a natural-key conflict.
It intentionally does not implement transaction, which exercises the runtime's no-mandatory-transaction path.
Testing with a fixed clock
Combine the in-memory store with an injected clock for deterministic assertions on timestamps and generated ids:
const td = createTeardown({
storage: createMemoryStorage(),
config: { sessionSecret: "test-secret" },
clock: {
now: () => new Date("2026-01-01T00:00:00.000Z"),
uuid: () => "00000000-0000-0000-0000-000000000000",
},
});