(fuma: IFumaClient)
| 180 | const toBlobRows = (rows: unknown): readonly BlobRow[] => rows as readonly BlobRow[]; |
| 181 | |
| 182 | export const makeFumaBlobStore = (fuma: IFumaClient): BlobStore => ({ |
| 183 | get: (namespace, key) => |
| 184 | fuma |
| 185 | .use("blob.get", (db) => |
| 186 | db.findFirst("blob", { |
| 187 | where: (b) => b.and(b("namespace", "=", namespace), b("key", "=", key)), |
| 188 | }), |
| 189 | ) |
| 190 | .pipe(Effect.map((row) => row as BlobRow | null)) |
| 191 | .pipe( |
| 192 | Effect.map((row) => row?.value ?? null), |
| 193 | Effect.mapError( |
| 194 | (cause) => new StorageError({ message: "FumaDB blob operation failed", cause }), |
| 195 | ), |
| 196 | ), |
| 197 | getMany: (namespaces, key) => |
| 198 | namespaces.length === 0 |
| 199 | ? Effect.succeed(new Map<string, string>()) |
| 200 | : fuma |
| 201 | .use("blob.getMany", (db) => |
| 202 | db.findMany("blob", { |
| 203 | where: (b) => b.and(b("namespace", "in", [...namespaces]), b("key", "=", key)), |
| 204 | }), |
| 205 | ) |
| 206 | .pipe(Effect.map(toBlobRows)) |
| 207 | .pipe( |
| 208 | Effect.map((rows) => { |
| 209 | const out = new Map<string, string>(); |
| 210 | for (const row of rows) out.set(row.namespace, row.value); |
| 211 | return out; |
| 212 | }), |
| 213 | Effect.mapError( |
| 214 | (cause) => new StorageError({ message: "FumaDB blob operation failed", cause }), |
| 215 | ), |
| 216 | ), |
| 217 | put: (namespace, key, value) => |
| 218 | Effect.gen(function* () { |
| 219 | const id = blobId(namespace, key); |
| 220 | const existing = (yield* fuma.use("blob.findForPut", (db) => |
| 221 | db.findFirst("blob", { where: (b) => b("id", "=", id) }), |
| 222 | )) as BlobRow | null; |
| 223 | if (existing) { |
| 224 | yield* fuma.use("blob.update", (db) => |
| 225 | db.updateMany("blob", { where: (b) => b("id", "=", id), set: { value } }), |
| 226 | ); |
| 227 | return; |
| 228 | } |
| 229 | yield* fuma.use("blob.create", (db) => db.create("blob", { id, namespace, key, value })); |
| 230 | }).pipe( |
| 231 | Effect.mapError( |
| 232 | (cause) => new StorageError({ message: "FumaDB blob operation failed", cause }), |
| 233 | ), |
| 234 | ), |
| 235 | delete: (namespace, key) => |
| 236 | fuma |
| 237 | .use("blob.delete", (db) => |
| 238 | db.deleteMany("blob", { where: (b) => b("id", "=", blobId(namespace, key)) }), |
| 239 | ) |
no test coverage detected