// ets_tracing: off import type { Has, Tag } from "../Has/index.js" import type { Effect } from "./effect.js" import * as has from "./has.js" export type ShapeFn = Pick< T, { [k in keyof T]: T[k] extends ( ...args: infer ARGS ) => Effect ? ((...args: ARGS) => Effect) extends T[k] ? k : never : never }[keyof T] > export type ShapeCn = Pick< T, { [k in keyof T]: T[k] extends Effect ? k : never }[keyof T] > export type DerivedLifted< T, Fns extends keyof ShapeFn, Cns extends keyof ShapeCn, Values extends keyof T > = { [k in Fns]: T[k] extends (...args: infer ARGS) => Effect ? (...args: ARGS) => Effect, E, A> : never } & { [k in Cns]: T[k] extends Effect ? Effect, E, A> : never } & { [k in Values]: Effect, never, T[k]> } export function deriveLifted( H: Tag ): < Fns extends keyof ShapeFn = never, Cns extends keyof ShapeCn = never, Values extends keyof T = never >( functions: Fns[], effects: Cns[], values: Values[] ) => DerivedLifted { return (functions, constants, values) => { const ret = {} as any for (const k of functions) { ret[k] = (...args: any[]) => has.accessServiceM(H)((h) => (h[k] as any)(...args)) } for (const k of constants) { ret[k] = has.accessServiceM(H)((h) => h[k] as any) } for (const k of values) { ret[k] = has.accessService(H)((h) => h[k]) } return ret as any } } export type DerivedAccessM = { [k in Gens]: ( f: (_: T[k]) => Effect, __trace?: string ) => Effect, E_, A_> } export function deriveAccessM( H: Tag ): (generics: Gens[]) => DerivedAccessM { return (generics) => { const ret = {} as any for (const k of generics) { ret[k] = (f: any, trace?: string) => has.accessServiceM(H)((h) => f(h[k]), trace) } return ret as any } } export type DerivedAccess = { [k in Gens]: (f: (_: T[k]) => A_, __trace?: string) => Effect, never, A_> } export function deriveAccess( H: Tag ): (generics: Gens[]) => DerivedAccess { return (generics) => { const ret = {} as any for (const k of generics) { ret[k] = (f: any, trace?: string) => has.accessService(H)((h) => f(h[k]), trace) } return ret as any } }