| type | Domain |
|---|---|
| description | Hub-and-spoke worker thread infrastructure — WorkerBridge/WorkerPool message routing plus the connection and compute worker entry points |
src/core/worker-bridge/ implements WorkerBridge, an ObserverRelay<TEvents, Record<string, never>> subclass (from @logosdx/observer) that wraps a Worker (parent side) or parentPort (worker side) and exposes a typed request()/emit() protocol over worker_threads.postMessage.
WorkerPool holds N WorkerBridge instances and dispatches request() calls round-robin across them.
src/workers/ holds the two worker thread entry points that run inside spawned threads: connection.ts (persistent, owns one Kysely instance) and compute.ts (stateless serialize/deserialize).
src/core/worker-bridge/bridge.ts—WorkerBridgeclass: constructor branches on whether ascriptarg is passed (parent, spawnsnew Worker(script)) or omitted (worker, requiresparentPort);request()generates arandomUUID()correlation id, sends{ ...data, __cid: cid }, and races aonce(^event:res:cid$)listener against a per-instance death promisesrc/core/worker-bridge/pool.ts—WorkerPoolclass: constructsMath.max(1, options.size)WorkerBridgeinstances in the constructor, round-robinsrequest()via#nextIndex,shutdown()awaitsPromise.allof every worker'sshutdown()src/core/worker-bridge/order-buffer.ts—OrderBuffer<T>class:add(index, item)buffers into aMap<number, T>and drains every contiguous entry starting at#nextIndex; throws on a non-integer index, an index below#nextIndex, or a duplicate index already in the buffersrc/core/worker-bridge/pending-set.ts—PendingSetclass:track(promise)wraps the promise with.then(() => undefined, () => undefined)before adding it to aSet, so a rejected task still removes itself;settleAny()races the set,settleAll()loopsPromise.allSettleduntil the set is emptysrc/core/worker-bridge/paths.ts—resolveWorker(name): returnsnew URL('./workers/${name}.js', import.meta.url)whenimport.meta.urlcontains$bunfs(compiled binary), otherwiseresolve(WORKER_DIR, '${name}.js')whereWORKER_DIR = resolve(MODULE_DIR, '../../workers')src/core/worker-bridge/types.ts—WireMessage({ event: string; data: unknown }),ResKey<K>(](../..) `${K}:res` [template type),Correlated<T>(T & { __cid: string }),ConnectionEvents,ComputeEvents,PoolOptions; importsDtColumn/DtValuefromsrc/core/dt/types.tsandDialectfromsrc/core/connection/types.tssrc/core/worker-bridge/index.ts— barrel export:WorkerBridge,WorkerPool,OrderBuffer,resolveWorker, and theWireMessage/ResKey/Correlated/ConnectionEvents/ComputeEvents/PoolOptionstypes (PendingSetis not re-exported here — importers reach it viasrc/core/worker-bridge/pending-set.jsdirectly, assrc/core/dt/index.tsdoes)src/workers/connection.ts— connection worker entry point: builds aKyselyinstance viacreateDialectConnection, which dynamically imports one ofsrc/core/connection/dialects/{sqlite-bun,sqlite,postgres,mysql,mssql}.jsbased on thedialectargument (sqlite branches ontypeof globalThis.Bun); handlesconnect,disconnect,query,query:batch,executesrc/workers/compute.ts— compute worker entry point: handlesserialize(callsserializeRowfromsrc/core/dt/serialize.js) anddeserialize(callsdeserializeRowfromsrc/core/dt/deserialize.js), both wrapped inattemptSync
None indexed.
src/core/worker-bridge/types.tsimportsDtColumn/DtValuefromsrc/core/dt/types.tsandDialectfromsrc/core/connection/types.ts— changing those types' shapes changes the worker wire contract.src/core/dt/index.ts(sdk domain) is the primary consumer: it importsWorkerPool,OrderBuffer,PendingSet, andresolveWorkerdirectly, constructs aWorkerPool<ComputeEvents>viacreateDefaultComputePool(), and usesresolveWorker('compute')to locate the compute worker script — a change toComputeEventsintypes.tsor tocompute.ts's handler shape requires a matching change insrc/core/dt/index.ts.src/core/connection/manager.ts(core-db domain) importsWorkerBridgeandConnectionEventsas types, keeps aMap<string, WorkerBridge<ConnectionEvents>>in#bridges, and exposestrackBridge(configName, bridge)so the connection worker'sWorkerBridgeis shut down alongside regular connections onapp:shutdown.src/cli/dev/test-workers.ts(cli domain) importsresolveWorker,WorkerBridge, andWorkerBridge.poolto run worker thread diagnostics against bothcomputeandconnectionworkers.WorkerBridgeextendsObserverRelayfrom@logosdx/observer— itson/once/off/emit/queuemethods andreceive()/shutdown()/isShutdowncome from that base class, not from this domain.src/workers/connection.tsdynamically imports dialect factories fromsrc/core/connection/dialects/— adding a dialect there requires a matching branch increateDialectConnection.
- Worker scripts live at
src/workers/, a sibling ofsrc/core/, not insidesrc/core/worker-bridge/— they are standalone entry points forbun build --compile, not library code. - Never hardcode a worker script path; always resolve it through
resolveWorker(name). It handles three execution contexts differently: Bun dev mode resolves.jsto.tsautomatically, Node fromdist/resolves todist/workers/*.js, and a Bun-compiled binary resolves againstimport.meta.urlinside$bunfsbecausebun build --compilestrips thesrc/root and compiles.tsto.js. request()'s correlation id (__cid) is injected into the outgoing payload and echoed back in the response event name (](../..) `${event}:res:${cid}` [); worker-side handlers destructure__cidfromdata(typed viaCorrelated<T>) to build that response event name.- A
WorkerBridgein parent mode listens for its worker'sexitevent; a nonzero exit code while not already shut down calls#failPending, which rejects every tracked pending request and stores#deathErrorso subsequentrequest()calls reject immediately rather than hanging. OrderBufferandPendingSetexist because dispatching requests to aWorkerPoolreturns responses out of order and a naivewhile (inFlight > 0) await sleep(1)backpressure loop leaks its counter when a dispatch fails before reaching its downstream callback — both classes are designed around real promise settlement instead of a counter.src/core/worker-bridge/pending-set.ts'strack()deliberately double-swallows rejections (the caller attaches its own handler first) sosettleAny/settleAllnever turn a task failure into an unhandled rejection.