( config: ExecutorConfig<TPlugins>, )
| 201 | // --------------------------------------------------------------------------- |
| 202 | |
| 203 | export const createExecutor = async <const TPlugins extends readonly AnyPlugin[] = readonly []>( |
| 204 | config: ExecutorConfig<TPlugins>, |
| 205 | ): Promise<Executor<TPlugins>> => { |
| 206 | const plugins = (config?.plugins ?? []) as TPlugins; |
| 207 | const db = |
| 208 | typeof config.db === "function" ? await config.db({ tables: collectTables() }) : config.db; |
| 209 | |
| 210 | const effectConfig = { |
| 211 | tenant: Tenant.make(config.tenant ?? "default-tenant"), |
| 212 | ...(config.subject !== undefined ? { subject: Subject.make(config.subject) } : {}), |
| 213 | plugins, |
| 214 | ...(config.providers ? { providers: config.providers } : {}), |
| 215 | onElicitation: toEffectOnElicitation(config.onElicitation), |
| 216 | ...(db ? { db } : {}), |
| 217 | }; |
| 218 | |
| 219 | // The SDK has no observability requirement; storage failures surface |
| 220 | // as raw `StorageError` / `UniqueViolationError` in the typed channel. |
| 221 | // `Effect.runPromise` turns them into Promise rejections — consumers |
| 222 | // get the tagged error as the rejected value. See |
| 223 | // notes/promise-sdk-typed-errors.md for the planned `runPromiseExit` |
| 224 | // rewrite that exposes the full error union to consumers. |
| 225 | const effectExecutor = await Effect.runPromise(createEffectExecutor(effectConfig)); |
| 226 | |
| 227 | const executor = promisifyDeep(effectExecutor) as Executor<TPlugins>; |
| 228 | return { |
| 229 | ...executor, |
| 230 | close: async () => { |
| 231 | await Effect.runPromise(effectExecutor.close()); |
| 232 | }, |
| 233 | } as Executor<TPlugins>; |
| 234 | }; |
no test coverage detected