- 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
+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+});
+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+}
+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