import { Layer, pipe, type Context } from 'effect';
import type { Tag } from 'effect/Context';
import type { SimplifyDeep, Split } from 'type-fest';
import type { RuntimeConfig, RuntimeContext, RuntimeInstance } from '@/types';
import type { PropService } from './effect';
export declare const link: typeof pipe;
export declare const isRuntimeContext: <T>(input: unknown) => input is RuntimeContext<T>;
export declare const isRuntimeConfig: (input: unknown) => input is RuntimeConfig;
export declare const isRuntimeInstance: <T>(input: unknown) => input is RuntimeInstance<T>;
export declare const createRuntimeContext: (options: {
    name: string;
    providers?: () => ReturnType<typeof getProviders>;
}) => <R, E, A>(layer: Layer.Layer<R, E, A>) => RuntimeContext<R, E, A>;
export declare const getProviders: <P extends Tag<any, any>[]>(callback: (from: <R>(runtime: RuntimeContext<R, never, PropService>) => {
    provide: <T extends Tag<any, any>>(service: T & Context.Tag.Service<T> extends R ? T : R) => T;
}) => [...P]) => {
    map: Map<string, RuntimeContext<any>>;
    from: SimplifyDeep<NestServices<[...P]>>;
};
type Nest<K extends string[], V> = K extends [
    infer Head extends string,
    ...infer Rest extends string[]
] ? {
    [P in Head]: Nest<Extract<Rest, string[]>, V>;
} : V;
type Merge<A, B> = {
    [K in keyof A | keyof B]: K extends keyof A ? K extends keyof B ? Merge<A[K], B[K]> : A[K] : K extends keyof B ? B[K] : never;
};
type StripAt<S extends string> = S extends `@${infer Rest}` ? Rest : S;
export type NestServices<T extends readonly Context.Tag<any, any>[]> = T extends [
    infer First extends Context.Tag<any, any>,
    ...infer Rest extends Context.Tag<any, any>[]
] ? Merge<Nest<Split<StripAt<First['key']>, '/'>, First>, NestServices<Rest>> : object;
export {};
