Eric Bower
·
15 Apr 24
types.ts
1import type { Operation, Result } from "../deps.ts";
2import type {
3 Action,
4 ActionWithPayload,
5 LoaderItemState,
6 LoaderPayload,
7 Next,
8 Payload,
9} from "../types.ts";
10
11type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N;
12
13export interface ThunkCtx<P = any> extends Payload<P> {
14 name: string;
15 key: string;
16 action: ActionWithPayload<CreateActionPayload<P>>;
17 actionFn: IfAny<
18 P,
19 CreateAction<ThunkCtx>,
20 CreateActionWithPayload<ThunkCtx<P>, P>
21 >;
22 result: Result<void>;
23}
24
25export interface ThunkCtxWLoader extends ThunkCtx {
26 loader: Omit<LoaderPayload<any>, "id"> | null;
27}
28
29export interface LoaderCtx<P = unknown> extends ThunkCtx<P> {
30 loader: Partial<LoaderItemState> | null;
31}
32
33export type ApiFetchResult<ApiSuccess = any, ApiError = any> =
34 | {
35 ok: true;
36 value: ApiSuccess;
37 }
38 | {
39 ok: false;
40 error: ApiError;
41 };
42
43export type ApiRequest = Partial<{ url: string } & RequestInit>;
44export type RequiredApiRequest = {
45 url: string;
46 headers: HeadersInit;
47} & Partial<RequestInit>;
48
49export interface FetchCtx<P = any> extends ThunkCtx<P> {
50 request: ApiRequest | null;
51 req: (r?: ApiRequest) => RequiredApiRequest;
52 response: Response | null;
53 bodyType: "arrayBuffer" | "blob" | "formData" | "json" | "text";
54}
55
56export interface FetchJson<ApiSuccess = any, ApiError = any> {
57 json: ApiFetchResult<ApiSuccess, ApiError>;
58}
59
60export interface FetchJsonCtx<P = any, ApiSuccess = any, ApiError = any>
61 extends FetchCtx<P>, FetchJson<ApiSuccess, ApiError> {}
62
63export interface ApiCtx<Payload = any, ApiSuccess = any, ApiError = any>
64 extends FetchJsonCtx<Payload, ApiSuccess, ApiError> {
65 actions: Action[];
66 loader: Omit<LoaderPayload<any>, "id"> | null;
67 // should we cache ctx.json?
68 cache: boolean;
69 // should we use mdw.stub?
70 stub: boolean;
71 // previously cached data
72 cacheData: any;
73 _success: ApiSuccess;
74 _error: ApiError;
75}
76
77export interface PerfCtx<P = unknown> extends ThunkCtx<P> {
78 performance: number;
79}
80
81export type Middleware<Ctx extends ThunkCtx = ThunkCtx> = (
82 ctx: Ctx,
83 next: Next,
84) => Operation<any>;
85export type MiddlewareCo<Ctx extends ThunkCtx = ThunkCtx> =
86 | Middleware<Ctx>
87 | Middleware<Ctx>[];
88
89export type MiddlewareApi<Ctx extends ApiCtx = ApiCtx> = (
90 ctx: Ctx,
91 next: Next,
92) => Operation<any>;
93export type MiddlewareApiCo<Ctx extends ApiCtx = ApiCtx> =
94 | Middleware<Ctx>
95 | Middleware<Ctx>[];
96
97export interface CreateActionPayload<P = any, ApiSuccess = any> {
98 name: string;
99 key: string;
100 options: P;
101 _result: ApiSuccess;
102}
103
104export type CreateActionFn<ApiSuccess = any> = () => ActionWithPayload<
105 CreateActionPayload<Record<string | number | symbol, never>, ApiSuccess>
106>;
107
108export interface CreateAction<
109 Ctx extends ThunkCtx = ThunkCtx,
110 ApiSuccess = any,
111> extends CreateActionFn<ApiSuccess> {
112 run: (
113 p?: ActionWithPayload<
114 CreateActionPayload<Record<string | number | symbol, never>, ApiSuccess>
115 >,
116 ) => Operation<Ctx>;
117 use: (mdw: Middleware<Ctx>) => void;
118}
119
120export type CreateActionFnWithPayload<P = any, ApiSuccess = any> = (
121 p: P,
122) => ActionWithPayload<CreateActionPayload<P, ApiSuccess>>;
123
124export interface CreateActionWithPayload<
125 Ctx extends ThunkCtx,
126 P,
127 ApiSuccess = any,
128> extends CreateActionFnWithPayload<P, ApiSuccess> {
129 run: (
130 a: ActionWithPayload<CreateActionPayload<P, ApiSuccess>> | P,
131 ) => Operation<Ctx>;
132 use: (mdw: Middleware<Ctx>) => void;
133}
134
135export type ThunkAction<P = any, ApiSuccess = any> = ActionWithPayload<
136 CreateActionPayload<P, ApiSuccess>
137>;
138
139export type Supervisor<T = unknown> = (
140 pattern: string,
141 op: (action: Action) => Operation<T>,
142) => Operation<T>;