Optionalopts: Partial<DreamAppOpts>Whether the per-worker test-database pool claim is active: needed by the runtime and supported by the default connection's driver. Consumers that key behavior off the claimed index (connection-cache suffixing) use this; the claim entry points additionally fail loud when the need is present but support is absent.
StaticsystemInternalThe database name to connect to for a given connection. In dev/prod this is
simply the configured name. Under vitest (test env) it is the per-worker
database claimed from the pool — see testDatabaseClaimEnabled and
src/db/testDatabasePool.ts.
This is synchronous because Kysely builds its pg.Pool synchronously. It
reads the already-claimed pool index; the claim is awaited earlier in the
worker — DreamApp.init() calls claimTestDatabase before the first
connection is built, and dream-spec-helpers' truncate awaits
testDatabaseName — so the index is always populated by the time any
connection resolves its name.
Claim this worker's pool database if it hasn't been claimed yet. Idempotent
and a no-op outside the test-under-vitest path. Called by DreamApp.init()
before any connection is built so the synchronous dbName always
sees a populated index.
Registers a callback for an app-level event. Callbacks for the same event run in the order they were registered.
'db:log': called with a KyselyLogEvent each time a query on a
Dream database connection completes or fails.'repl:start': called, and awaited, with the console's REPL context
when the Dream console starts.'encryption:legacy-key-used': called with an
EncryptionLegacyKeyUsedEvent when reading an @deco.Encrypted
property needed the legacy column encryption key, not current, to
open the stored value. Use it during a key rotation to find rows still
encrypted with the old key. The property decrypts on every read, so a
record whose value is still under the old key fires the event each time
the property is read. A row nobody reads never fires it, so a quiet
event does not prove that legacy is safe to drop;
Model.reencryptEncryptedColumns() rewrites every row instead. Neither
it nor the migration helpers fire the event. The callback runs
synchronously inside the property read, and an error it throws
propagates from that read. Reading the same property of the same
record inside the callback returns its value without firing the event
again, so a callback can read the property and assign the value back,
which re-encrypts it under current for the record's next save. That
holds only while the callback runs synchronously: a callback that
reads the property after an await fires the event again from that
read, so an async callback should read the property before its
first await.dreamApp.on('encryption:legacy-key-used', ({ dream, property }) => {
console.warn(`${dream.constructor.name} ${dream.primaryKeyValue()} ${property} still uses the legacy key`)
})
OptionalsecondaryOptions: ApplyOpt extends "db" ? DreamDbCredentialOptions : neverSingle source of truth for the claimed test-database name, used both by
dream's connection resolution and by dream-spec-helpers' truncate
(which opens its own pg.Client and so must read — not recompute — the
claim). Awaits the pool claim if it has not happened yet in this worker.
StaticgetReturns the cached dream application if it has been set. If it has not been set, an exception is raised.
The dream application can be set by calling DreamApp#init, or alternatively, if you are using Psychic along with Dream, it can be set during PsychicApp#init, which will set caches for both the dream and psychic applications at once.
Staticinitinitializes a new dream application and caches it for use within this processes lifecycle.
Within dream, we rely on cached information about your app to be able to serve routes, perform serializer lookups, generate files, connect to the database, etc...
In order for this to work properly, the DreamApp#init function must be called before anything else is called within Dream.
OptionaldeferCb: (dreamApp: DreamApp) => void | Promise<void>StaticlogStaticlogStaticlookupSince javascript is inherently vulnerable to circular dependencies, this function provides a workaround by enabling you to dynamically bring in classes that, if imported directly, would result in circular dependency issues.
NOTE: You should only use this as a last resort, since it can create quite a headache for you when leaning into your editor to apply renames, etc...
the global name you are trying to look up, i.e. 'User', or 'UserSerializer'.
// this pattern is safe from circular imports, since _UserSerializer
// is only being used to type something else, which will not result
// in the circular dependency issue.
import _UserSerializer from '../serializers/UserSerializer.js'
const UserSerializer = PsychicApp.lookupClassByGlobalName('UserSerializer') as _UserSerializer
Whether the runtime requires a per-worker test-database claim. Gated on test env under vitest (not on
parallelTests > 1): the slot-reuse collision reproduces even serially, because vitest respawns a process per file and the lingering process overlaps the new one on the same database. CLI db tasks (db:migrate,db:reset, …) do not run under vitest, so they keep the unsuffixed name and operate on the whole pool explicitly.This is independent of whether the default driver can actually claim — when the need is present but the capability is absent, the claim path fails loud (see requireTestDatabaseClaimSupport) rather than silently sharing one database.