CodeVetter · Repo Unpack · Behavior traces
effect-ts/effect
Three source-level flows were followed to their completion boundaries: managed-runtime startup/execution/disposal, HTTP API registration/request handling, and schema-backed SQLite persistence. Each trace includes the functions responsible for state ownership and relevant conditional branches. These are execution-order reconstructions from source, not observed runs. Documentation's Hono integration provides a concrete consumer of the managed-runtime bridge.
- Runtime startup: ManagedRuntime.make creates a MemoMap and sequential root/layer scopes plus a parallel fiber scope; the first contextEffect starts Effect.runFork → Layer.buildWithMemoMap → layer.build and caches the resulting Context.
- Runtime primary action: runtime.runPromise chooses provide(contextEffect, program) before initialization or runPromiseWith(cachedContext) afterward; runPromiseExitWith → runForkWith → FiberImpl.evaluate leads to a Promise resolved from Exit or rejected from causeSquash.
- Runtime completion: dispose → Effect.runPromise(disposeEffect) invalidates contextEffect, clears cachedContext, and calls Scope.close. The Hono example invokes disposal on SIGINT/SIGTERM; regression tests assert request cleanup finishes before layer resources close.
- HTTP registration: HttpApiBuilder.group calls build(makeHandlers(group)), converts handlers via handlerToRoute, and stores routes under group.key; HttpApiBuilder.layer collects those group services and calls router.addAll, dying with a diagnostic if a group is missing.
- HTTP request: HttpRouter.asHttpEffect → router.find → request/route Context installation → middleware-wrapped handlerToHttpEffect → slot decoders → handler → success encoder. Missing routes fail as RouteNotFound; raw responses return directly, and declared handler errors pass through encodeError.
- SQLite storage initialization: SqliteClient.layer → make → makeConnection opens DatabaseSync, registers db.close as a scope finalizer, configures busy_timeout and optional WAL, and creates the generic client; KeyValueStore.layerSql obtains it and creates the dialect-specific table.
- Persistence write: SchemaStore.set → schema encode → KeyValueStore.set → UTF-8 bytes/value_type → SQLite upsert.unprepared → Statement.withConnection → compile → executeUnprepared → prepare → runStatement → StatementSync.run/all.packages/effect/src/persistence/KeyValueStore.ts#L799-L799packages/effect/src/persistence/KeyValueStore.ts#L580-L585packages/effect/src/persistence/KeyValueStore.ts#L661-L675packages/sql/sqlite-node/src/SqliteClient.ts#L269-L271packages/effect/src/sql/Statement.ts#L1363-L1375packages/effect/src/sql/Statement.ts#L1432-L1437packages/sql/sqlite-node/src/SqliteClient.ts#L154-L158packages/sql/sqlite-node/src/SqliteClient.ts#L166-L184
- Persistence read: SchemaStore.get → SQL SELECT by key → first-row value_type decoding → schema JSON decode → Option.some; missing rows return undefined at the backend and Option.none at the schema boundary, while invalid stored type discriminators fail with KeyValueStoreError.