|
1 | | -import * as Context from "effect/Context"; |
2 | | -import type * as Effect from "effect/Effect"; |
| 1 | +import type { Effect } from "effect/Effect"; |
| 2 | +import type { Layer } from "effect/Layer"; |
3 | 3 | import type { Capability } from "./capability.ts"; |
4 | | -import type { Policy } from "./policy.ts"; |
5 | 4 | import type { Resource } from "./resource.ts"; |
6 | 5 | import type { Runtime } from "./runtime.ts"; |
7 | 6 |
|
8 | | -export type Bindings = ReturnType<typeof Bindings>; |
9 | | - |
10 | | -export const Bindings = <S extends any[]>( |
11 | | - ...capabilities: S |
12 | | -): Policy<S[number]> => ({ |
13 | | - capabilities, |
14 | | - and: <C extends Capability[]>(...caps: C): Policy<C[number] | S[number]> => |
15 | | - Bindings(...capabilities, ...caps), |
16 | | -}); |
17 | | - |
18 | | -export type $ = typeof $; |
19 | | -export const $ = Bindings; |
20 | | - |
21 | 7 | export interface BindingProps { |
22 | 8 | [key: string]: any; |
23 | 9 | } |
24 | 10 |
|
| 11 | +export const isBinding = (b: any): b is Binding<any, any, any> => |
| 12 | + "runtime" in b && "capability" in b && "tag" in b && "output" in b; |
| 13 | + |
| 14 | +export type AnyBinding<F extends Runtime = any> = Binding<F, any, any>; |
| 15 | + |
25 | 16 | export interface Binding< |
26 | 17 | Run extends Runtime, |
27 | 18 | Cap extends Capability = Capability, |
28 | | - Output = any, |
29 | | -> extends Context.TagClass< |
30 | | - Runtime.Binding<Run, Cap>, |
31 | | - `${Cap["action"]}(${Cap["resource"]["type"]}, ${Run["type"]})`, |
32 | | - BindingService<Cap["resource"], Output> |
33 | | - > { |
| 19 | + Tag = Cap["type"], |
| 20 | +> { |
34 | 21 | runtime: Run; |
35 | 22 | capability: Cap; |
36 | | - output: Output; |
| 23 | + tag: Tag; |
37 | 24 | } |
38 | 25 |
|
39 | | -export const Binding = |
40 | | - < |
41 | | - const Runtime extends string, |
42 | | - Cap extends Capability, |
43 | | - Props extends BindingProps, |
44 | | - >( |
45 | | - runtime: Runtime, |
46 | | - capability: Cap, |
47 | | - ) => |
48 | | - <Self>(): Self => |
49 | | - Object.assign( |
50 | | - Context.Tag( |
51 | | - `${capability.action}(${capability.resource.type}, ${runtime})` as `${Cap["action"]}(${Cap["resource"]["type"]}, ${Runtime})`, |
52 | | - )<Self, BindingService<Cap["resource"], Props>>(), |
53 | | - { |
54 | | - Kind: "Binding", |
55 | | - Capability: capability, |
| 26 | +export const Binding = <F extends (resource: any, props?: any) => AnyBinding>( |
| 27 | + runtime: ReturnType<F>["runtime"], |
| 28 | + resource: new () => ReturnType<F>["capability"]["resource"], |
| 29 | + tag: ReturnType<F>["tag"], |
| 30 | +): F & BindingDeclaration<ReturnType<F>["runtime"], F> => { |
| 31 | + type Runtime = ReturnType<F>["runtime"]; |
| 32 | + type Tag = ReturnType<F>["tag"]; |
| 33 | + type Resource = new () => ReturnType<F>["capability"]["resource"]; |
| 34 | + |
| 35 | + const handler = (() => { |
| 36 | + throw new Error(`Should never be called`); |
| 37 | + }) as unknown as F; |
| 38 | + |
| 39 | + return Object.assign(handler, { |
| 40 | + layer: { |
| 41 | + effect: () => { |
| 42 | + throw new Error(`Not implemented`); |
56 | 43 | }, |
57 | | - ) as Self; |
| 44 | + succeed: () => { |
| 45 | + throw new Error(`Not implemented`); |
| 46 | + }, |
| 47 | + }, |
| 48 | + }); |
| 49 | +}; |
| 50 | + |
| 51 | +export interface BindingDeclaration< |
| 52 | + Run extends Runtime, |
| 53 | + F extends (target: any, props?: any) => Binding<Run, any>, |
| 54 | + Tag = ReturnType<F>["tag"], |
| 55 | +> { |
| 56 | + layer: { |
| 57 | + effect<Err, Req>( |
| 58 | + eff: Effect< |
| 59 | + BindingService<Run["props"], Parameters<F>[0], Parameters<F>[1]>, |
| 60 | + Err, |
| 61 | + Req |
| 62 | + >, |
| 63 | + ): Layer<Tag, Err, Req>; |
| 64 | + succeed( |
| 65 | + service: BindingService<Run["props"], Parameters<F>[0], Parameters<F>[1]>, |
| 66 | + ): Layer<BindingService<Run["props"], Parameters<F>[0], Parameters<F>[1]>>; |
| 67 | + }; |
| 68 | +} |
| 69 | + |
| 70 | +// <Self>(): Self => |
| 71 | +// Object.assign( |
| 72 | +// Context.Tag( |
| 73 | +// `${capability.action}(${tag}, ${runtime})` as `${Cap["action"]}(${Tag}, ${Runtime})`, |
| 74 | +// )<Self, BindingService<Cap["resource"], Props>>(), |
| 75 | +// { |
| 76 | +// Kind: "Binding", |
| 77 | +// Capability: capability, |
| 78 | +// }, |
| 79 | +// ) as Self; |
58 | 80 |
|
59 | 81 | export type BindingService< |
60 | 82 | Target = any, |
|
0 commit comments