repos / starfx

supercharged async flow control library.
git clone https://github.com/neurosnap/starfx.git

commit
a4e1819
parent
bb56c4c
author
Eric Bower
date
2024-01-06 03:21:28 +0000 UTC
feat(query): `mdw.predicate`
3 files changed,  +71, -0
M query/mdw.test.ts
+39, -0
 1@@ -546,3 +546,42 @@ it(tests, "errorHandler", () => {
 2   });
 3   expect(a).toEqual(2);
 4 });
 5+
 6+it(tests, "stub predicate", async () => {
 7+  let actual = null;
 8+  const api = createApi();
 9+  api.use(function* (ctx, next) {
10+    ctx.stub = true;
11+    yield* next();
12+  });
13+  api.use(mdw.api());
14+  api.use(api.routes());
15+  api.use(mdw.fetch({ baseUrl: "http://nowhere.com" }));
16+
17+  const stub = mdw.predicate((ctx) => ctx.stub === true);
18+
19+  const fetchUsers = api.get("/users", { supervisor: takeEvery }, [
20+    function* (ctx, next) {
21+      yield* next();
22+      actual = ctx.json;
23+    },
24+    stub(function* (ctx, next) {
25+      ctx.response = new Response(JSON.stringify({ frodo: "shire" }));
26+      yield* next();
27+    }),
28+  ]);
29+
30+  const store = configureStore({
31+    initialState: {
32+      ...createQueryState(),
33+    },
34+  });
35+  store.run(api.bootup);
36+  store.dispatch(fetchUsers());
37+  await sleep(150);
38+  expect(actual).toEqual({
39+    ok: true,
40+    value: { frodo: "shire" },
41+    data: { frodo: "shire" },
42+  });
43+});
M query/mdw.ts
+28, -0
 1@@ -4,6 +4,7 @@ import type {
 2   ApiCtx,
 3   ApiRequest,
 4   FetchJsonCtx,
 5+  MiddlewareApi,
 6   Next,
 7   PerfCtx,
 8   RequiredApiRequest,
 9@@ -12,6 +13,7 @@ import type {
10 import { mergeRequest } from "./util.ts";
11 import * as fetchMdw from "./fetch.ts";
12 import { log } from "../log.ts";
13+import { call, Operation } from "../deps.ts";
14 export * from "./fetch.ts";
15 
16 /**
17@@ -139,3 +141,29 @@ export function fetch<CurCtx extends FetchJsonCtx = FetchJsonCtx>(
18     fetchMdw.json,
19   ]);
20 }
21+
22+type Callable<T> =
23+  | (() => Operation<T>)
24+  | (() => Promise<T>)
25+  | (() => T)
26+  | Operation<T>
27+  | Promise<T>;
28+
29+/**
30+ * This middleware will only be activated if predicate is true.
31+ */
32+export function predicate<Ctx extends ApiCtx = ApiCtx>(
33+  predicate: ((ctx: Ctx) => boolean) | ((ctx: Ctx) => Callable<boolean>),
34+) {
35+  return (mdw: MiddlewareApi) => {
36+    return function* (ctx: Ctx, next: Next) {
37+      const valid = yield* call(() => predicate(ctx));
38+      if (!valid) {
39+        yield* next();
40+        return;
41+      }
42+
43+      yield* mdw(ctx, next);
44+    };
45+  };
46+}
M query/types.ts
+4, -0
 1@@ -61,7 +61,11 @@ export interface ApiCtx<Payload = any, ApiSuccess = any, ApiError = any>
 2   extends FetchJsonCtx<Payload, ApiSuccess, ApiError> {
 3   actions: Action[];
 4   loader: Omit<LoaderPayload<any>, "id"> | null;
 5+  // should we cache ctx.json?
 6   cache: boolean;
 7+  // should we use mdw.stub?
 8+  stub: boolean;
 9+  // previously cached data
10   cacheData: any;
11 }
12