-
-
Notifications
You must be signed in to change notification settings - Fork 522
Open
Labels
enhancementNew feature or requestNew feature or request
Description
I found that unjs/unstorage is very suitable for implementing the KeyValueStore interface of Effect.
Here is a simple example implementation I wrote:
import {Effect, Layer, Option} from "effect"
import {KeyValueStore, Error as PlatformError} from "@effect/platform"
import {createStorage, type CreateStorageOptions} from "unstorage"
export const make = (options?: CreateStorageOptions) =>
Layer.effect(
KeyValueStore.KeyValueStore,
Effect.gen(function* () {
const storage = createStorage(options)
const mapSystemError = (method: string) => (cause: unknown) =>
new PlatformError.SystemError({
reason: "Unknown",
module: "KeyValueStore",
method,
cause
})
const invalidDataError = (method: string, description: string) =>
new PlatformError.SystemError({
reason: "InvalidData",
module: "KeyValueStore",
method,
description
})
return KeyValueStore.make({
get: key =>
Effect.tryPromise(() => storage.getItem(key)).pipe(
Effect.map(Option.fromNullable),
Effect.mapError(mapSystemError("get")),
Effect.flatMap(
Option.match({
onNone: () => Effect.succeed(Option.none()),
onSome: value =>
typeof value === "string"
? Effect.succeed(Option.some(value))
: Effect.fail(
invalidDataError("get", "Expected string value")
)
})
)
),
getUint8Array: key =>
Effect.tryPromise(() => storage.getItem(key)).pipe(
Effect.map(Option.fromNullable),
Effect.mapError(mapSystemError("getUint8Array")),
Effect.flatMap(
Option.match({
onNone: () => Effect.succeed(Option.none()),
onSome: value =>
value instanceof Uint8Array
? Effect.succeed(Option.some(value))
: Effect.fail(
invalidDataError(
"getUint8Array",
"Expected Uint8Array value"
)
)
})
)
),
set: (key, value) =>
Effect.tryPromise(() => storage.setItem(key, value)).pipe(
Effect.mapError(mapSystemError("set"))
),
remove: key =>
Effect.tryPromise(() => storage.removeItem(key)).pipe(
Effect.mapError(mapSystemError("remove"))
),
clear: Effect.tryPromise(() => storage.clear()).pipe(
Effect.mapError(mapSystemError("clear"))
),
size: Effect.tryPromise(
() => storage.getKeys() as Promise<string[]>
).pipe(
Effect.map(keys => keys.length),
Effect.mapError(mapSystemError("size"))
),
has: key =>
Effect.tryPromise(
() => storage.hasItem(key) as Promise<boolean>
).pipe(Effect.mapError(mapSystemError("has")))
})
})
)Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request