(
withNsSql: WithNsSqlFn,
{ prefix }: StorageConfig
)
| 391 | |
| 392 | // Eagerly seed primary namespace on initialization. A seed failure at |
| 393 | // construction is fatal (orDie); the per-call `seedNamespace` still |
| 394 | // surfaces DatabaseError to callers. |
| 395 | yield* seedNamespace("primary").pipe(Effect.orDie) |
| 396 | |
| 397 | return s |
| 398 | }) |
| 399 | } |
| 400 | }) |
| 401 | } |
| 402 | |
| 403 | type WithNsSqlFn = <A, E2, R2>( |
| 404 | ns: string, |
| 405 | f: (sql: SqlClient.SqlClient) => Effect.Effect<A, E2, R2> |
| 406 | ) => Effect.Effect<A, E2, R2> |
| 407 | |
| 408 | function makeSQLiteStorePerNs( |
| 409 | withNsSql: WithNsSqlFn, |
| 410 | { prefix }: StorageConfig |
| 411 | ) { |
| 412 | return { |
| 413 | make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>( |
| 414 | name: string, |
| 415 | idKey: IdKey, |
| 416 | seed?: Effect.Effect<Iterable<Encoded>, E, R>, |
| 417 | config?: StoreConfig<Encoded> |
| 418 | ) { |
| 419 | type PM = PersistenceModelType<Encoded> |
| 420 | const tableName = `${prefix}${name}` |
| 421 | const defaultValues = config?.defaultValues ?? {} |
| 422 | |
| 423 | const resolveNamespace = !config?.allowNamespace |
| 424 | ? Effect.succeed("primary") |
| 425 | : storeId.pipe(Effect.map((namespace) => { |
| 426 | if (namespace !== "primary" && !config.allowNamespace!(namespace)) { |
| 427 | throw new Error(`Namespace ${namespace} not allowed!`) |
| 428 | } |
| 429 | return namespace |
| 430 | })) |
| 431 | |
| 432 | const toRow = (e: PM) => { |
| 433 | const newE = makeETag(e) |
| 434 | const id = newE[idKey] as string |
| 435 | const { _etag, [idKey]: _id, ...rest } = newE as any |
| 436 | const data = JSON.stringify(rest) |
| 437 | return { id, _etag: newE._etag!, data, item: newE } |
| 438 | } |
| 439 | |
| 440 | const exec = (ns: string, query: string, params?: readonly unknown[]) => |
| 441 | withNsSql(ns, (sql) => sql.unsafe(query, params as any).pipe(Effect.mapError(toDatabaseError))) |
| 442 | |
| 443 | const ensureTable = (ns: string) => |
| 444 | withNsSql(ns, (sql) => |
| 445 | sql |
| 446 | .unsafe( |
| 447 | `CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL PRIMARY KEY, _etag TEXT, data JSON NOT NULL)` |
| 448 | ) |
| 449 | .pipe( |
| 450 | Effect.andThen( |
no test coverage detected
searching dependent graphs…