Skip to content

Commit

Permalink
feat: allow dependencies in makeInitial
Browse files Browse the repository at this point in the history
  • Loading branch information
patroza committed Nov 10, 2023
1 parent 24f9338 commit be616fd
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 35 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-frogs-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect-app/infra": patch
---

allow deps in makeInitial
28 changes: 14 additions & 14 deletions packages/infra/_src/services/RepositoryBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ export function makeStore<
return mapTo(e, getEtag(e.id))
}

function makeStore(
makeInitial?: Effect<never, never, readonly T[]>,
function makeStore<R, E>(
makeInitial?: Effect<R, E, readonly T[]>,
config?: Omit<StoreConfig<PM>, "partitionValue"> & {
partitionValue?: (a: PM) => string
}
Expand All @@ -279,7 +279,7 @@ export function makeStore<
const { make } = $(StoreMaker)

const store = $(
make<PM, string>(
make<PM, string, R, E>(
pluralize(name),
makeInitial
? makeInitial
Expand Down Expand Up @@ -311,13 +311,13 @@ export const RepositoryBaseImpl = <Service>() => {
mapFrom: (pm: Omit<PM, "_etag">) => E,
mapTo: (e: E, etag: string | undefined) => PM
): (abstract new() => Repository<T, PM, Evt, ItemType>) & Tag<Service, Service> & {
make(
make<R, E>(
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<RequestCTX, never, void>,
makeInitial?: Effect<never, never, readonly T[]>,
makeInitial?: Effect<R, E, readonly T[]>,
config?: Omit<StoreConfig<PM>, "partitionValue"> & {
partitionValue?: (a: PM) => string
}
): Effect<StoreMaker, never, Repository<T, PM, Evt, ItemType>>
): Effect<StoreMaker | R, E, Repository<T, PM, Evt, ItemType>>
where: ReturnType<typeof makeWhere<PM>>
flatMap: <R1, E1, B>(f: (a: Service) => Effect<R1, E1, B>) => Effect<Service | R1, E1, B>
makeLayer: (svc: Service) => Layer<never, never, Service>
Expand Down Expand Up @@ -345,30 +345,30 @@ export const RepositoryDefaultImpl = <Service>() => {
new(
impl: Repository<T, PM, Evt, ItemType>
): Repository<T, PM, Evt, ItemType>
make(
make<R, E>(
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<RequestCTX, never, void>,
makeInitial?: Effect<never, never, readonly T[]>,
makeInitial?: Effect<R, E, readonly T[]>,
config?: Omit<StoreConfig<PM>, "partitionValue"> & {
partitionValue?: (a: PM) => string
}
): Effect<StoreMaker, never, Repository<T, PM, Evt, ItemType>>
toLayer(
): Effect<StoreMaker | R, E, Repository<T, PM, Evt, ItemType>>
toLayer<R, E>(
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<RequestCTX, never, void>,
makeInitial?: Effect<never, never, readonly T[]>,
makeInitial?: Effect<R, E, readonly T[]>,
config?: Omit<StoreConfig<PM>, "partitionValue"> & {
partitionValue?: (a: PM) => string
}
): Layer<StoreMaker, never, Service>
): Layer<StoreMaker | R, E, Service>
where: ReturnType<typeof makeWhere<PM>>
flatMap: <R1, E1, B>(f: (a: Service) => Effect<R1, E1, B>) => Effect<Service | R1, E1, B>
makeLayer: (svc: Service) => Layer<never, never, Service>
map: <B>(f: (a: Service) => B) => Effect<Service, never, B>
repo: Repository<T, PM, Evt, ItemType> // just a helper to type the constructor
} => {
return class extends RepositoryBaseImpl<Service>()<PM, Evt>()(itemType, schema, mapFrom, mapTo) {
static toLayer(
static toLayer<R, E>(
publishEvents: (evt: NonEmptyReadonlyArray<Evt>) => Effect<RequestCTX, never, void>,
makeInitial?: Effect<never, never, readonly T[]>,
makeInitial?: Effect<R, E, readonly T[]>,
config?: Omit<StoreConfig<PM>, "partitionValue"> & {
partitionValue?: (a: PM) => string
}
Expand Down
4 changes: 2 additions & 2 deletions packages/infra/_src/services/Store/Cosmos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ export function makeCosmosStore({ prefix }: StorageConfig) {
return Effect.gen(function*($) {
const { db } = yield* $(CosmosClient)
return {
make: <Id extends string, PM extends PersistenceModelType<Id>>(
make: <Id extends string, PM extends PersistenceModelType<Id>, R = never, E = never>(
name: string,
seed?: Effect<never, never, Iterable<PM>>,
seed?: Effect<R, E, Iterable<PM>>,
config?: StoreConfig<PM>
) =>
Effect.gen(function*($) {
Expand Down
18 changes: 10 additions & 8 deletions packages/infra/_src/services/Store/Disk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { makeMemoryStoreInt, storeId } from "./Memory.js"
import type { PersistenceModelType, StorageConfig, Store, StoreConfig } from "./service.js"
import { StoreMaker } from "./service.js"

function makeDiskStoreInt<Id extends string, PM extends PersistenceModelType<Id>>(
function makeDiskStoreInt<Id extends string, PM extends PersistenceModelType<Id>, R, E>(
prefix: string,
namespace: string,
dir: string,
name: string,
seed?: Effect<never, never, Iterable<PM>>
seed?: Effect<R, E, Iterable<PM>>
) {
return Effect.gen(function*($) {
const file = dir + "/" + prefix + name + (namespace === "primary" ? "" : "-" + namespace) + ".json"
Expand All @@ -25,7 +25,7 @@ function makeDiskStoreInt<Id extends string, PM extends PersistenceModelType<Id>
}

const store = yield* $(
makeMemoryStoreInt<Id, PM>(
makeMemoryStoreInt<Id, PM, R, E>(
name,
!fs.existsSync(file)
? seed
Expand Down Expand Up @@ -75,15 +75,16 @@ export function makeDiskStore({ prefix }: StorageConfig, dir: string) {
fs.mkdirSync(dir)
}
return {
make: <Id extends string, PM extends PersistenceModelType<Id>>(
make: <Id extends string, PM extends PersistenceModelType<Id>, R, E>(
name: string,
seed?: Effect<never, never, Iterable<PM>>,
seed?: Effect<R, E, Iterable<PM>>,
config?: StoreConfig<PM>
) =>
Effect.gen(function*($) {
const storesSem = Semaphore.unsafeMake(1)
const primary = yield* $(makeDiskStoreInt(prefix, "primary", dir, name, seed))
const stores = new Map<string, Store<PM, Id>>([["primary", primary]])
const ctx = yield* $(Effect.context<R>())
const getStore = !config?.allowNamespace ? Effect.succeed(primary) : storeId.get.flatMap((namespace) => {
const store = stores.get(namespace)
if (store) {
Expand All @@ -96,9 +97,10 @@ export function makeDiskStore({ prefix }: StorageConfig, dir: string) {
Effect.suspend(() => {
const existing = stores.get(namespace)
if (existing) return Effect(existing)
return makeDiskStoreInt<Id, PM>(prefix, namespace, dir, name, seed).tap((store) =>
Effect.sync(() => stores.set(namespace, store))
)
return makeDiskStoreInt<Id, PM, R, E>(prefix, namespace, dir, name, seed)
.orDie
.provide(ctx)
.tap((store) => Effect.sync(() => stores.set(namespace, store)))
})
)
})
Expand Down
16 changes: 10 additions & 6 deletions packages/infra/_src/services/Store/Memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ function logQuery(filter: any, cursor: any) {
}))
}

export function makeMemoryStoreInt<Id extends string, PM extends PersistenceModelType<Id>>(
export function makeMemoryStoreInt<Id extends string, PM extends PersistenceModelType<Id>, R = never, E = never>(
name: string,
seed?: Effect<never, never, Iterable<PM>>
seed?: Effect<R, E, Iterable<PM>>
) {
return Effect.gen(function*($) {
const updateETag = makeUpdateETag(name)
Expand Down Expand Up @@ -99,14 +99,15 @@ export function makeMemoryStoreInt<Id extends string, PM extends PersistenceMode
}

export const makeMemoryStore = () => ({
make: <Id extends string, PM extends PersistenceModelType<Id>>(
make: <Id extends string, PM extends PersistenceModelType<Id>, R = never, E = never>(
name: string,
seed?: Effect<never, never, Iterable<PM>>,
seed?: Effect<R, E, Iterable<PM>>,
config?: StoreConfig<PM>
) =>
Effect.gen(function*($) {
const storesSem = Semaphore.unsafeMake(1)
const primary = yield* $(makeMemoryStoreInt<Id, PM>(name, seed))
const primary = yield* $(makeMemoryStoreInt<Id, PM, R, E>(name, seed))
const ctx = yield* $(Effect.context<R>())
const stores = new Map([["primary", primary]])
const getStore = !config?.allowNamespace ? Effect.succeed(primary) : storeId.get.flatMap((namespace) => {
const store = stores.get(namespace)
Expand All @@ -119,7 +120,10 @@ export const makeMemoryStore = () => ({
return storesSem.withPermits(1)(Effect.suspend(() => {
const store = stores.get(namespace)
if (store) return Effect(store)
return makeMemoryStoreInt(name, seed).tap((store) => Effect.sync(() => stores.set(namespace, store)))
return makeMemoryStoreInt(name, seed)
.orDie
.provide(ctx)
.tap((store) => Effect.sync(() => stores.set(namespace, store)))
}))
})
const s: Store<PM, Id> = {
Expand Down
4 changes: 2 additions & 2 deletions packages/infra/_src/services/Store/Redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export function makeRedisStore({ prefix }: StorageConfig) {
return Effect.gen(function*($) {
const redis = yield* $(RedisClient)
return {
make: <Id extends string, PM extends PersistenceModelType<Id>>(
make: <Id extends string, PM extends PersistenceModelType<Id>, R = never, E = never>(
name: string,
seed?: Effect<never, never, Iterable<PM>>,
seed?: Effect<R, E, Iterable<PM>>,
_config?: StoreConfig<PM>
) =>
Effect.gen(function*($) {
Expand Down
6 changes: 3 additions & 3 deletions packages/infra/_src/services/Store/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ export interface Store<PM extends PersistenceModelType<Id>, Id extends string> {
* @tsplus companion StoreMaker.Ops
*/
export abstract class StoreMaker extends TagClass<StoreMaker>() {
abstract make: <PM extends PersistenceModelType<Id>, Id extends string>(
abstract make: <PM extends PersistenceModelType<Id>, Id extends string, R = never, E = never>(
name: string,
seed?: Effect<never, never, Iterable<PM>>,
seed?: Effect<R, E, Iterable<PM>>,
config?: StoreConfig<PM>
) => Effect<never, never, Store<PM, Id>>
) => Effect<R, E, Store<PM, Id>>
}

/**
Expand Down

0 comments on commit be616fd

Please sign in to comment.