Callback contexts
Every callback gets a ctx. Derived values get read methods; queries also learn who is calling; mutations can write.
| API | Contract |
|---|---|
Context | The read-only context of derived values. Valid only during one call; don’t store it. |
QueryContext | Context plus principal() and history(). Queries, task due functions, authenticate and access predicates get it. |
ctx.now(): number | Server time in milliseconds, fixed for the call. Keep host clocks in sync: a query’s time can step backward after a leader change. |
ctx.get(collection, key): T | null | Read one record. Null means missing, or that null is stored there. Typed keys are checked (INVALID_KEY). |
ctx.get(derived, args?): Value | Compute or reuse a derived value for these arguments; omit them for null. If the derived value failed, its error is thrown here. |
ctx.scan(collection, options?: ScanOptions): Row[] | Read rows by key or index, with bounds, reverse, offset and limit. Sees the current mutation’s writes. Large offsets still walk the skipped rows; use ctx.range to page. |
ctx.query(query): T[] | Read values matching an equality query (values only, no keys). Sees the current mutation’s writes. |
ctx.range(query): RangePage | Read one ordered page of keys and values. See ranges and cursors. |
ctx.principal(): Principal | null | The caller admitted by the access check, or null for anonymous callers and apps without access checks. |
MutationContext | QueryContext plus the writes below. Mutations, task runs and triggers get it. Queries can’t write, even with a type cast. |
ctx.set(collection, key, value): void | Replace a record, checked against the collection’s schemas. All of a mutation’s writes commit together. |
ctx.delete(collection, key): void | Remove a record. Deleting a missing key is fine. |
ctx.materialize(derived, args?): void | Keep this derived value stored and updated as its inputs change. |
ctx.unmaterialize(derived, args?): void | Stop keeping it. Unreachable cached values can be collected; source records stay. |
- A mutation commits all of its writes or none. A throw, a
fail(), an invalid result or a budget overrun discards everything. - Materialize values you read often. Leave expensive, rarely read values unmaterialized.
- Cycles and very deep derived chains fail.
Query result cache
Flower reuses query results while their inputs are unchanged. Every hit still passes the access check per caller and still waits for a fresh read fence. Results that depend on time or managed crypto aren’t cached.
FLOWER_QUERY_CACHE_BYTES (default 16 MiB per logical database) sets the cache size. FLOWER_QUERY_FLIGHT_BYTES (default 512 KiB) bounds sharing between identical in-flight queries. Set either to 0 to disable it.
Definitions and methods
Wrap your functions with derive, query or mutation, then pass them to define. Only aliases in the http table are callable.
| API | Contract |
|---|---|
derive<A, V>(name, compute, options?): Derived<A, V> | A pure reactive function (ctx, args) => V. Read it with ctx.get. Never callable over HTTP. List it in definitions. |
DeriveOptions<A> | Optional materialize. Unknown options are rejected. |
Materialization<A> | "always" keeps the instance without arguments. { each: collection } keeps one instance per row, with the row key as its arguments, added and removed with the row; existing rows are picked up by a background task. |
query(name, compute)query(name, spec: QuerySpec, compute) | A read-only method (ctx: QueryContext, args) => V, returning a QueryMethod<A, V>. With spec.args, A comes from the schema and bad calls fail with INVALID_ARGUMENT. Reads are fresh unless consistency says otherwise. |
mutation(name, compute)mutation(name, spec: MethodSpec, compute) | An atomic method (ctx: MutationContext, args) => V, returning a MutationMethod<A, V>. |
MethodSpec<A> | Optional args (a schema) and access (see access). Unknown fields are rejected. |
QuerySpec<A> | MethodSpec plus optional consistency. |
QueryConsistency | "linearizable" (the default: fresh) or "replica-local". |
Derived<A = Json, V = Json> | Readonly kind: "derived", name, compute, optional aggregate. |
QueryMethod<A = Json, V = Json> | Readonly kind: "queryMethod", name, compute, optional consistency. |
MutationMethod<A = Json, V = Json> | Readonly kind: "mutationMethod", name, compute. |
Definition | Derived, QueryMethod, MutationMethod or TransactionMethod. |
HttpMethod | QueryMethod, MutationMethod or TransactionMethod (not Derived). |
HttpMap | Aliases to HttpMethods: the http table. |
define(config: ModuleConfig = {}): FlowerModule | Validates and freezes the application. Registers definitions from definitions, components and http; compiles every task into one maintenance handler; compiles auth and per-method access into one access check; declares collections. Two different definitions with the same name are rejected. |
ModuleConfig | Optional uses, collections, definitions, tasks, triggers and keys (as in a component), http (alias → method) and auth. Unknown fields are rejected. |
FlowerModule<H> | The frozen manifest: definitions, http (alias → ManifestMethod), maintenance (or null), authorize when an access check was compiled, collections and keys. Its type carries the http table, so typeof app types clients and tests. |
ManifestMethod | Readonly name, kind ("query" | "mutation" | "transaction") and, for replica-local queries, consistency. |
- A deployment swaps code, aliases, schema and derived state in one step. If it is rejected, the old version keeps running.
- Names starting with
$flower.are reserved for definitions and aliases. - Fresh (linearizable) queries can run on any replica. They confirm with a quorum before reading.
- Replica-local queries can be stale with no bound. They skip the quorum check. Data, code and aliases may lag, and switching replicas can move you back in time. Opt in per query, in code.
Type helpers
Clients, participants and test databases use these to type calls from an app or an http table.
| API | Contract |
|---|---|
ApiOf<App> | The http table of a FlowerModule, or the map itself. |
AliasOf<App> | Every public alias. |
QueryAliasOf<App>, MutationAliasOf<App> | The aliases of queries, or of mutations. |
ArgsOf<Method> | A method’s argument type. |
ResultOf<Method> | A method’s result type; TransactionResult<V> for transactions. |
ArgsParameter<A> | The argument slot of a typed call: optional when null is acceptable, required otherwise, anything for untyped apps. |