repos / starfx

a micro-mvc framework for react apps
git clone https://github.com/neurosnap/starfx.git

starfx / src / query
Eric Bower  ·  2025-06-06

types.ts

  1import type { Operation, Result } from "effection";
  2import type {
  3  Action,
  4  ActionWithPayload,
  5  LoaderItemState,
  6  LoaderPayload,
  7  Next,
  8  Payload,
  9} from "../types.js";
 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>,
 62    FetchJson<ApiSuccess, ApiError> {}
 63
 64export interface ApiCtx<Payload = any, ApiSuccess = any, ApiError = any>
 65  extends FetchJsonCtx<Payload, ApiSuccess, ApiError> {
 66  actions: Action[];
 67  loader: Omit<LoaderPayload<any>, "id"> | null;
 68  // should we cache ctx.json?
 69  cache: boolean;
 70  // should we use mdw.stub?
 71  stub: boolean;
 72  // previously cached data
 73  cacheData: any;
 74  _success: ApiSuccess;
 75  _error: ApiError;
 76}
 77
 78export interface PerfCtx<P = unknown> extends ThunkCtx<P> {
 79  performance: number;
 80}
 81
 82export type Middleware<Ctx extends ThunkCtx = ThunkCtx> = (
 83  ctx: Ctx,
 84  next: Next,
 85) => Operation<any>;
 86export type MiddlewareCo<Ctx extends ThunkCtx = ThunkCtx> =
 87  | Middleware<Ctx>
 88  | Middleware<Ctx>[];
 89
 90export type MiddlewareApi<Ctx extends ApiCtx = ApiCtx> = (
 91  ctx: Ctx,
 92  next: Next,
 93) => Operation<any>;
 94export type MiddlewareApiCo<Ctx extends ApiCtx = ApiCtx> =
 95  | Middleware<Ctx>
 96  | Middleware<Ctx>[];
 97
 98export interface CreateActionPayload<P = any, ApiSuccess = any> {
 99  name: string;
100  key: string;
101  options: P;
102  _result: ApiSuccess;
103}
104
105export type CreateActionFn<ApiSuccess = any> = () => ActionWithPayload<
106  CreateActionPayload<Record<string | number | symbol, never>, ApiSuccess>
107>;
108
109export interface CreateAction<Ctx extends ThunkCtx = ThunkCtx, ApiSuccess = any>
110  extends CreateActionFn<ApiSuccess> {
111  run: (
112    p?: ActionWithPayload<
113      CreateActionPayload<Record<string | number | symbol, never>, ApiSuccess>
114    >,
115  ) => Operation<Ctx>;
116  use: (mdw: Middleware<Ctx>) => void;
117}
118
119export type CreateActionFnWithPayload<P = any, ApiSuccess = any> = (
120  p: P,
121) => ActionWithPayload<CreateActionPayload<P, ApiSuccess>>;
122
123export interface CreateActionWithPayload<
124  Ctx extends ThunkCtx,
125  P,
126  ApiSuccess = any,
127> extends CreateActionFnWithPayload<P, ApiSuccess> {
128  run: (
129    a: ActionWithPayload<CreateActionPayload<P, ApiSuccess>> | P,
130  ) => Operation<Ctx>;
131  use: (mdw: Middleware<Ctx>) => void;
132}
133
134export type ThunkAction<P = any, ApiSuccess = any> = ActionWithPayload<
135  CreateActionPayload<P, ApiSuccess>
136>;
137
138export type Supervisor<T = unknown> = (
139  pattern: string,
140  op: (action: Action) => Operation<T>,
141) => Operation<T>;