Skip to content

Commit

Permalink
fix: cache return types
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart committed Oct 3, 2023
1 parent 90882a2 commit 4c9bc32
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 15 deletions.
64 changes: 60 additions & 4 deletions src/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,43 @@ export type CacheOp<T> =
| { op: "update"; resourceId: string; resource: T }
| { op: "delete"; resourceId: string }

export interface ParentCache<EOps, EDriver, EMiss, EPMiss, A> {
readonly get: (
parentId: string,
id: string,
) => Effect.Effect<never, EDriver | EMiss, A>
readonly put: (_: A) => Effect.Effect<never, EDriver | EMiss, void>
readonly update: <R, E>(
parentId: string,
id: string,
f: (_: A) => Effect.Effect<R, E, A>,
) => Effect.Effect<R, EDriver | EMiss | E, A>
readonly getForParent: (
parentId: string,
) => Effect.Effect<never, EDriver | EPMiss, ReadonlyMap<string, A>>
readonly run: Effect.Effect<never, EOps | EDriver, void>
readonly size: Effect.Effect<never, EDriver, number>
readonly sizeForParent: (
parentId: string,
) => Effect.Effect<never, EDriver, number>
readonly set: (
parentId: string,
resourceId: string,
resource: A,
) => Effect.Effect<never, EDriver, void>
readonly delete: (
parentId: string,
resourceId: string,
) => Effect.Effect<never, EDriver, void>
readonly parentDelete: (
parentId: string,
) => Effect.Effect<never, EDriver, void>
readonly refreshTTL: (
parentId: string,
resourceId: string,
) => Effect.Effect<never, EDriver, void>
}

export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
driver,
id,
Expand All @@ -40,7 +77,7 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
onParentMiss: (
parentId: string,
) => Effect.Effect<never, EPMiss, Array<[id: string, resource: A]>>
}) => {
}): ParentCache<EOps, EDriver, EMiss, EPMiss, A> => {
const sync = Stream.runDrain(
Stream.tap(ops, (op): Effect.Effect<never, EDriver, void> => {
switch (op.op) {
Expand Down Expand Up @@ -109,7 +146,26 @@ export const makeWithParent = <EOps, EDriver, EMiss, EPMiss, A>({
concurrency: "unbounded",
discard: true,
}),
}
} as const
}

export interface Cache<EOps, EDriver, EMiss, A> {
readonly get: (id: string) => Effect.Effect<never, EDriver | EMiss, A>
readonly put: (_: A) => Effect.Effect<never, EDriver, void>
readonly update: <R, E>(
id: string,
f: (_: A) => Effect.Effect<R, E, A>,
) => Effect.Effect<R, EDriver | EMiss | E, A>
readonly run: Effect.Effect<never, EOps | EDriver, void>
readonly size: Effect.Effect<never, EDriver, number>
readonly set: (
resourceId: string,
resource: A,
) => Effect.Effect<never, EDriver, void>
readonly delete: (resourceId: string) => Effect.Effect<never, EDriver, void>
readonly refreshTTL: (
resourceId: string,
) => Effect.Effect<never, EDriver, void>
}

export const make = <EOps, EDriver, EMiss, A>({
Expand All @@ -122,7 +178,7 @@ export const make = <EOps, EDriver, EMiss, A>({
ops?: Stream.Stream<never, EOps, CacheOp<A>>
id: (_: A) => string
onMiss: (id: string) => Effect.Effect<never, EMiss, A>
}) => {
}): Cache<EOps, EDriver, EMiss, A> => {
const sync = Stream.runDrain(
Stream.tap(ops, (op): Effect.Effect<never, EDriver, void> => {
switch (op.op) {
Expand Down Expand Up @@ -162,7 +218,7 @@ export const make = <EOps, EDriver, EMiss, A>({
concurrency: "unbounded",
discard: true,
}),
}
} as const
}

export class CacheMissError {
Expand Down
13 changes: 11 additions & 2 deletions src/Cache/memory.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import * as Option from "effect/Option"
import * as Effect from "effect/Effect"
import type { CacheDriver, ParentCacheDriver } from "dfx/Cache/driver"
import { createDriver, createParentDriver } from "dfx/Cache/driver"

export const createWithParent = <T>() =>
export const createWithParent = <T>(): Effect.Effect<
never,
never,
ParentCacheDriver<never, T>
> =>
Effect.sync(() => {
const map = new Map<string, Map<string, T>>()

Expand Down Expand Up @@ -51,7 +56,11 @@ export const createWithParent = <T>() =>
})
})

export const create = <T>() =>
export const create = <T>(): Effect.Effect<
never,
never,
CacheDriver<never, T>
> =>
Effect.sync(() => {
const map = new Map<string, T>()

Expand Down
11 changes: 8 additions & 3 deletions src/Cache/memoryTTL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as Duration from "effect/Duration"
import * as Option from "effect/Option"
import * as ReadonlyArray from "effect/ReadonlyArray"
import * as Effect from "effect/Effect"
import type { CacheDriver, ParentCacheDriver } from "dfx/Cache/driver"
import { createDriver, createParentDriver } from "dfx/Cache/driver"

export interface MemoryTTLOpts {
Expand Down Expand Up @@ -37,7 +38,7 @@ const make = <T>({
resolution = Duration.minutes(1),
strategy = "usage",
ttl,
}: MemoryTTLOpts) => {
}: MemoryTTLOpts): CacheDriver<never, T> => {
const resolutionMs = Duration.toMillis(resolution)
const additionalMilliseconds =
(Math.floor(Duration.toMillis(ttl) / resolutionMs) + 1) * resolutionMs
Expand Down Expand Up @@ -131,10 +132,14 @@ const make = <T>({
})
}

export const create = <T>(opts: MemoryTTLOpts) =>
export const create = <T>(
opts: MemoryTTLOpts,
): Effect.Effect<never, never, CacheDriver<never, T>> =>
Effect.sync(() => make<T>(opts))

export const createWithParent = <T>(opts: MemoryTTLOpts) =>
export const createWithParent = <T>(
opts: MemoryTTLOpts,
): Effect.Effect<never, never, ParentCacheDriver<never, T>> =>
Effect.sync(() => {
const store = make<T>(opts)
const parentIds = new Map<string, Set<string>>()
Expand Down
45 changes: 39 additions & 6 deletions src/Cache/prelude.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import * as Effect from "effect/Effect"
import * as Stream from "effect/Stream"
import { DiscordREST } from "dfx"
import type { DiscordRESTError } from "dfx/DiscordREST"
import { DiscordREST } from "dfx/DiscordREST"
import type { ResponseError } from "@effect/platform/Http/ClientError"
import type {
CacheDriver,
CacheOp,
ParentCacheDriver,
ParentCacheOp,
Cache,
ParentCache,
} from "dfx/Cache"
import { CacheMissError, make, makeWithParent } from "dfx/Cache"
import { DiscordGateway } from "dfx/DiscordGateway"
Expand All @@ -31,7 +35,7 @@ export const opsWithParent = <E, T>({
parentRemove,
remove,
update,
}: OptsWithParentOptions<E, T>) => {
}: OptsWithParentOptions<E, T>): Stream.Stream<never, E, ParentCacheOp<T>> => {
const fromParentOps = Stream.flatMap(fromParent, ([parentId, a]) =>
Stream.fromIterable(
a.map(
Expand Down Expand Up @@ -96,7 +100,12 @@ export interface OpsOptions<E, A> {
remove: Stream.Stream<never, E, string>
}

export const ops = <E, T>({ create, id, remove, update }: OpsOptions<E, T>) => {
export const ops = <E, T>({
create,
id,
remove,
update,
}: OpsOptions<E, T>): Stream.Stream<never, E, CacheOp<T>> => {
const createOps = Stream.map(
create,
(resource): CacheOp<T> => ({
Expand Down Expand Up @@ -128,7 +137,11 @@ export const ops = <E, T>({ create, id, remove, update }: OpsOptions<E, T>) => {

export const guilds = <RM, EM, E>(
makeDriver: Effect.Effect<RM, EM, CacheDriver<E, Discord.Guild>>,
) =>
): Effect.Effect<
RM | DiscordGateway | DiscordREST,
EM,
Cache<never, E, ResponseError | DiscordRESTError, Discord.Guild>
> =>
Effect.gen(function* (_) {
const driver = yield* _(makeDriver)
const gateway = yield* _(DiscordGateway)
Expand All @@ -155,7 +168,17 @@ export const guilds = <RM, EM, E>(

export const channels = <RM, EM, E>(
makeDriver: Effect.Effect<RM, EM, ParentCacheDriver<E, Discord.Channel>>,
) =>
): Effect.Effect<
DiscordGateway | DiscordREST | RM,
EM,
ParentCache<
never,
E,
ResponseError | DiscordRESTError,
ResponseError | DiscordRESTError,
Discord.Channel
>
> =>
Effect.gen(function* (_) {
const driver = yield* _(makeDriver)
const gateway = yield* _(DiscordGateway)
Expand Down Expand Up @@ -198,7 +221,17 @@ export const channels = <RM, EM, E>(

export const roles = <RM, EM, E>(
makeDriver: Effect.Effect<RM, EM, ParentCacheDriver<E, Discord.Role>>,
) =>
): Effect.Effect<
DiscordGateway | DiscordREST | RM,
EM,
ParentCache<
never,
E,
CacheMissError,
ResponseError | DiscordRESTError,
Discord.Role
>
> =>
Effect.gen(function* (_) {
const driver = yield* _(makeDriver)
const gateway = yield* _(DiscordGateway)
Expand Down

0 comments on commit 4c9bc32

Please sign in to comment.