Test databases
@flower-js/sdk/testing runs an application on Flower’s reference engine, in-process. It is Node only; keep it out of application bundles. The testing guide shows it in use.
| API | Contract |
|---|---|
testDatabase<App>(app, options?): Promise<TestDatabase<App>> | Starts a database. Pass the imported define(...) module to run it directly, or a path to bundle it and run it in an isolated node:vm context, as the server does; with a path, pass typeof app yourself for typed calls. |
TestDatabaseOptions | Optional now (starting server time; 1,000,000 ms), credentials (sent by the client and by calls that pass none) and partitions (names of extra logical databases running the same app). |
TestCallOptions | Optional credentials and requestId, as the last argument of a call. |
TestDatabase<App> | The root database. Mutable now; readonly client; getters revision and data (a copy of the raw state, for debugging; its format isn’t stable). |
constructor(module, engine, options?, local?) | Used by testDatabase; call that instead. |
query(alias, args?, options?): V | Calls an exposed query synchronously and returns its value. Arguments, access checks and failures behave as over HTTP: failures throw FlowerError with the same status, code and failure. |
mutate(alias, args?, options?): V | Calls an exposed mutation or transaction and commits it. A reused request ID replays the first result; with different arguments it throws REQUEST_ID_REUSED. |
call(alias, args?, options?): V | Calls any alias. Transactions run across the test partitions and return { results }, plus value when the plan has one; a participant failure throws TRANSACTION_ABORTED with its failure, and nothing commits. |
maintain(limit = 10_000, partition = ""): number | Runs due maintenance like the leader, one task per commit, while tasks stay due. Returns the number of committed runs. |
advance(ms): number | Moves now forward, then runs due maintenance in every partition and refreshes watches. Returns the number of committed runs. |
partition(name): TestPartition<App> | A named partition from options.partitions; unknown names throw PARTITION_NOT_FOUND. Partitions share the clock. |
fetch(url, init): Promise<Response> | A FlowerFetch serving /v1/query, /v1/mutate, /v1/call and /v1/watch from this database, for root and partition URLs. client uses it; pass it to other clients. |
TestPartition<App> | One named partition. Readonly client, scoped to the partition. |
constructor(database, name) | Used by db.partition(name); call that instead. |
query(alias, args?, options?), mutate(…), call(…) | The same calls as on TestDatabase, against this partition. |
maintain(limit?): number | Runs this partition’s due maintenance. |
- Time moves only through
nowandadvance. Maintenance runs only throughmaintainandadvance. - If the app has access checks, a partition’s principals must carry its name as their tenant, as on a server.
- Native crypto isn’t available: NaCl, JWT, managed keys and
jwtBearerfail. Retry sessions and bounded retries aren’t simulated. - Index reads on indexes that aren’t declared fail with
UNDECLARED_INDEX, where a server would silently scan. - Watches send full snapshots rather than patches.