repos / starfx

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

commit
a80c485
parent
86db183
author
Eric Bower
date
2023-08-28 15:54:42 +0000 UTC
Toolkit 2.0 (#11)

feat: added `prepareStore()`

BREAKING CHANGE: refactored `configureStore()` from `starfx/redux`
22 files changed,  +119, -140
M npm.ts
M deno.lock
+5, -5
 1@@ -144,7 +144,7 @@
 2     "https://deno.land/x/ts_morph@18.0.0/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed",
 3     "https://deno.land/x/ts_morph@18.0.0/common/ts_morph_common.js": "845671ca951073400ce142f8acefa2d39ea9a51e29ca80928642f3f8cf2b7700",
 4     "https://deno.land/x/ts_morph@18.0.0/common/typescript.js": "d5c598b6a2db2202d0428fca5fd79fc9a301a71880831a805d778797d2413c59",
 5-    "https://esm.sh/@reduxjs/toolkit@1.9.5?pin=v122": "90302cd219f485943878c9f023338f069f3141b8118438fa70eb5759bac6e4b4",
 6+    "https://esm.sh/@reduxjs/toolkit@2.0.0-beta.1?pin=v122": "2d1dfaafccc992b0a1b1a3ef1dbc7b310d9dccf48de5877510fddcfc38bf8528",
 7     "https://esm.sh/immer@10.0.2?pin=v122": "7ac87b9c76176de8384a67f8cd93d44f75be1a7496c92707252acb669595c393",
 8     "https://esm.sh/react-redux@8.0.5?pin=v122": "fa98e94dc8803fb84bee9eb08a13f11833f634d381003247207682823887dc51",
 9     "https://esm.sh/react@18.2.0?pin=v122": "8950a34a030620fce8349d6bd3913b3bdb186c5ec7968fa5ba4d054e22d78e6c",
10@@ -153,9 +153,8 @@
11     "https://esm.sh/robodux@15.0.1?pin=v122": "51ac2aa6f6fbaac2795f3d34117ba7e77c37e9e3e48bf667a994f6851399bf76",
12     "https://esm.sh/stable/react@18.2.0/denonext/react.mjs": "3c4f23bcfc53b256fcfaf6f834fa9f584c3bb7be667b2682c6cb6ba8ef88f8e6",
13     "https://esm.sh/v122/@babel/runtime@7.22.5/denonext/helpers/esm/extends.js": "3955a0ef35db01cd4efff831a9027924f90fa7d55621cd2b6b8519283e573c21",
14-    "https://esm.sh/v122/@babel/runtime@7.22.5/denonext/helpers/esm/objectSpread2.js": "39b25571151291cf2778cd3bb118c5336f7682f878f59fbcf79e2684ae55b194",
15     "https://esm.sh/v122/@babel/runtime@7.22.5/denonext/helpers/esm/objectWithoutPropertiesLoose.js": "fae2539db9a813ad1aab88d10a58d81d9403d242fb3f405e9070fc01c2d8808b",
16-    "https://esm.sh/v122/@reduxjs/toolkit@1.9.5/denonext/toolkit.mjs": "5d53890796741e2b082ff3fabe10486c1dfeab2a114cf326718e71ecfcdb9cce",
17+    "https://esm.sh/v122/@reduxjs/toolkit@2.0.0-beta.1/denonext/toolkit.mjs": "c5848f5c2d3fa361b8055ee191060a2fdcf11185060617524399290664a71337",
18     "https://esm.sh/v122/hoist-non-react-statics@3.3.2/denonext/hoist-non-react-statics.mjs": "41018d0142e45a133637f9a3e4da6b8babc22cab2b3ec05cfb202a727da5a0cb",
19     "https://esm.sh/v122/immer@10.0.2/denonext/immer.mjs": "694ebf85b769db4d026ec4b9655a8caaa6ce51776d857df7cedf3fa4774d5297",
20     "https://esm.sh/v122/immer@9.0.21/denonext/immer.mjs": "3819c7f2cc0f19de974517bd2421b80f800a9bc8bcdb87e3b3aaf022640bd7d6",
21@@ -164,9 +163,10 @@
22     "https://esm.sh/v122/react-is@18.2.0/denonext/react-is.mjs": "07ca6a7473ccbb06466e805c8253ade80bd664a0f486cf020864c22c27a60479",
23     "https://esm.sh/v122/react-redux@8.0.5/denonext/react-redux.mjs": "eeba4c3485907ed356f889ce071f63fde42e8397f14dede20d9732e5be188294",
24     "https://esm.sh/v122/redux-batched-actions@0.5.0/denonext/redux-batched-actions.mjs": "d115abd3bef58a81bb57be5ec013377fa841e9f6cea152f2851560a8e23a032f",
25-    "https://esm.sh/v122/redux-thunk@2.4.2/denonext/redux-thunk.mjs": "3de5f6f01b4315e3cc2924ecca9c93150c40b9b9785c2b5882dc60f6b8800b96",
26-    "https://esm.sh/v122/redux@4.2.1/denonext/redux.mjs": "8269d22284abebf2be1bbbbbcc53d1842b7858102f1f81e7df1d0144b688f5a4",
27+    "https://esm.sh/v122/redux-thunk@3.0.0-beta.0/denonext/redux-thunk.mjs": "52d6722a38e72ff206d7ddb6df808ebd33f63444f22aec8dc2c805a6fd309987",
28+    "https://esm.sh/v122/redux@5.0.0-beta.0/denonext/redux.mjs": "72c133fdb6fca2b20e15f0cd7a7cb659b70b0537800887805235d547af55f951",
29     "https://esm.sh/v122/reselect@4.1.8/denonext/reselect.mjs": "f8199f9e44453876a9ea6b5d1caedc0fe1ae789a73217543b1e6193e1edc0db7",
30+    "https://esm.sh/v122/reselect@5.0.0-alpha.2/denonext/reselect.mjs": "ea5f9df4e9d15dfce4c7751ccf276ffcce2974a53c021f4976160164a991c28c",
31     "https://esm.sh/v122/robodux@15.0.1/denonext/robodux.mjs": "31ba627f958ded9bdcaa7db1bd9bd57f610bb0cbefd871e1286e578f9a7c719a",
32     "https://esm.sh/v122/scheduler@0.23.0/denonext/scheduler.mjs": "69005eb830c0a486d51875e52d1a85443dc8d32b0b6ad1e3f06baceb55ed4cba",
33     "https://esm.sh/v122/use-sync-external-store@1.2.0/denonext/cjs/use-sync-external-store-shim.production.min.js": "5be7011cae1c9c79ad30989c95370a6d97083e01bb98ba76a333347e03af85db",
M deps.ts
+6, -10
 1@@ -1,9 +1,9 @@
 2-import type { Result } from "https://deno.land/x/effection@3.0.0-alpha.13/mod.ts";
 3 export type {
 4   Channel,
 5   Instruction,
 6   Operation,
 7   Port,
 8+  Result,
 9   Scope,
10   Stream,
11   Subscription,
12@@ -29,8 +29,6 @@ export {
13   useAbortSignal,
14 } from "https://deno.land/x/effection@3.0.0-alpha.13/mod.ts";
15 
16-export type { Result };
17-
18 import React from "https://esm.sh/react@18.2.0?pin=v122";
19 export { React };
20 export {
21@@ -49,18 +47,16 @@ export type { Patch } from "https://esm.sh/immer@10.0.2?pin=v122";
22 
23 export type {
24   Action,
25-  AnyAction,
26-  ConfigureEnhancersCallback,
27-  Middleware,
28   Reducer,
29   ReducersMapObject,
30-  StoreEnhancer,
31-} from "https://esm.sh/@reduxjs/toolkit@1.9.5?pin=v122";
32+  UnknownAction,
33+} from "https://esm.sh/@reduxjs/toolkit@2.0.0-beta.1?pin=v122";
34 export {
35   combineReducers,
36   configureStore,
37-  getDefaultMiddleware,
38-} from "https://esm.sh/@reduxjs/toolkit@1.9.5?pin=v122";
39+  Tuple,
40+} from "https://esm.sh/@reduxjs/toolkit@2.0.0-beta.1?pin=v122";
41+export type { BatchAction } from "https://esm.sh/redux-batched-actions@0.5.0?pin=v122";
42 export {
43   BATCH,
44   batchActions,
M matcher.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import type { AnyAction } from "./store/types.ts";
3+import type { AnyAction } from "./types.ts";
4 
5 type ActionType = string;
6 type GuardPredicate<G extends T, T = unknown> = (arg: T) => arg is G;
M npm.ts
+2, -2
 1@@ -55,9 +55,9 @@ async function main() {
 2         name: "robodux",
 3         version: "^15.0.1",
 4       },
 5-      "https://esm.sh/@reduxjs/toolkit@1.9.5?pin=v122": {
 6+      "https://esm.sh/@reduxjs/toolkit@2.0.0-beta.1?pin=v122": {
 7         name: "@reduxjs/toolkit",
 8-        version: "^1.9.5",
 9+        version: "2.0.0-beta.1",
10       },
11       "https://esm.sh/redux-batched-actions@0.5.0?pin=v122": {
12         name: "redux-batched-actions",
M redux/fx.ts
+5, -12
 1@@ -1,17 +1,10 @@
 2-import { Action, AnyAction, Channel, Operation } from "../deps.ts";
 3+import { Action, Channel, Operation, UnknownAction } from "../deps.ts";
 4 import { createChannel, createContext, spawn } from "../deps.ts";
 5 import { call, parallel } from "../fx/mod.ts";
 6 import { ActionPattern, matcher } from "../matcher.ts";
 7+import type { ActionWPayload, AnyAction } from "../types.ts";
 8 
 9-export interface ActionWPayload<P> {
10-  type: string;
11-  payload: P;
12-}
13-
14-export interface StoreLike<S = unknown> {
15-  getState: () => S;
16-  dispatch: (action: Action) => void;
17-}
18+import type { StoreLike } from "./types.ts";
19 
20 export const ActionContext = createContext<Channel<Action, void>>(
21   "redux:action",
22@@ -24,8 +17,8 @@ export function* emit({
23   channel,
24   action,
25 }: {
26-  channel: Operation<Channel<AnyAction, void>>;
27-  action: AnyAction | AnyAction[];
28+  channel: Operation<Channel<UnknownAction, void>>;
29+  action: UnknownAction | UnknownAction[];
30 }) {
31   const { input } = yield* channel;
32   if (Array.isArray(action)) {
M redux/middleware.ts
+24, -34
  1@@ -1,34 +1,28 @@
  2 import {
  3   Action,
  4-  AnyAction,
  5   BATCH,
  6-  ConfigureEnhancersCallback,
  7-  Middleware,
  8+  BatchAction,
  9   ReducersMapObject,
 10   Scope,
 11-  StoreEnhancer,
 12-} from "../deps.ts";
 13-import {
 14-  combineReducers,
 15-  configureStore as reduxStore,
 16-  createScope,
 17-  enableBatching,
 18+  UnknownAction,
 19 } from "../deps.ts";
 20+import { combineReducers, createScope, enableBatching } from "../deps.ts";
 21 import { parallel } from "../fx/mod.ts";
 22 
 23-import { ActionContext, emit, StoreContext, StoreLike } from "./fx.ts";
 24+import { ActionContext, emit, StoreContext } from "./fx.ts";
 25 import { reducers as queryReducers } from "./query.ts";
 26+import type { StoreLike } from "./types.ts";
 27 
 28-function* send(action: AnyAction) {
 29+function* send(action: UnknownAction) {
 30   if (action.type === BATCH) {
 31-    const actions: Action[] = action.payload;
 32+    const actions = action.payload as BatchAction[];
 33     const group = yield* parallel(
 34       actions.map(
 35         (a) =>
 36           function* () {
 37             yield* emit({
 38               channel: ActionContext,
 39-              action: a,
 40+              action: a as Action,
 41             });
 42           },
 43       ),
 44@@ -51,13 +45,13 @@ export function createFxMiddleware(initScope?: Scope) {
 45     scope = tuple[0];
 46   }
 47 
 48-  function middleware<S = unknown, T = unknown>(store: StoreLike<S>) {
 49+  function middleware<S = unknown>(store: StoreLike<S>) {
 50     scope.set(StoreContext, store);
 51 
 52-    return (next: (a: Action) => T) => (action: Action) => {
 53+    return (next: (a: unknown) => unknown) => (action: unknown) => {
 54       const result = next(action); // hit reducers
 55       scope.run(function* () {
 56-        yield* send(action);
 57+        yield* send(action as any);
 58       });
 59       return result;
 60     };
 61@@ -69,9 +63,6 @@ export function createFxMiddleware(initScope?: Scope) {
 62 // deno-lint-ignore no-explicit-any
 63 interface SetupStoreProps<S = any> {
 64   reducers: ReducersMapObject<S>;
 65-  middleware?: Middleware[];
 66-  enhancers?: StoreEnhancer[] | ConfigureEnhancersCallback;
 67-  initialState?: S;
 68 }
 69 
 70 /**
 71@@ -84,12 +75,17 @@ interface SetupStoreProps<S = any> {
 72  *
 73  * @example
 74  * ```ts
 75- * import { configureStore } from 'starfx/redux';
 76+ * import { prepareStore } from 'starfx/redux';
 77  *
 78- * const { store, fx } = prepareStore({
 79+ * const { reducer, fx } = prepareStore({
 80  *  reducers: { users: (state, action) => state },
 81  * });
 82  *
 83+ * const store = configureStore({
 84+ *  reducer,
 85+ *  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(fx),
 86+ * });
 87+ *
 88  * fx.run(function*() {
 89  *  yield* put({ type: 'LOADING' });
 90  *  yield* fetch('https://bower.sh');
 91@@ -97,18 +93,12 @@ interface SetupStoreProps<S = any> {
 92  * });
 93  * ```
 94  */
 95-export function configureStore(
 96-  { reducers, middleware = [], enhancers = [], initialState }: SetupStoreProps,
 97+export function prepareStore(
 98+  { reducers }: SetupStoreProps,
 99 ) {
100   const fx = createFxMiddleware();
101-  const rootReducer = combineReducers({ ...queryReducers, ...reducers });
102-  const store = reduxStore({
103-    reducer: enableBatching(rootReducer),
104-    middleware: (getDefaultMiddleware) =>
105-      getDefaultMiddleware().concat([fx.middleware, ...middleware]),
106-    enhancers,
107-    preloadedState: initialState,
108-  });
109-
110-  return { store, fx };
111+  const reducer = enableBatching(
112+    combineReducers({ ...queryReducers, ...reducers }),
113+  );
114+  return { reducer, fx };
115 }
M redux/mod.ts
+3, -2
1@@ -1,5 +1,6 @@
2 export * from "./fx.ts";
3 export * from "./query.ts";
4 export * from "./middleware.ts";
5-export type { ActionWPayload, AnyAction, AnyState } from "../store/types.ts";
6-export { createSelector } from "../deps.ts";
7+export * from "./types.ts";
8+export type { ActionWPayload, AnyAction, AnyState } from "../types.ts";
9+export { configureStore, createSelector } from "../deps.ts";
M redux/put.test.ts
+11, -18
 1@@ -1,7 +1,8 @@
 2 import { describe, expect, it } from "../test.ts";
 3 import { sleep, spawn } from "../deps.ts";
 4 
 5-import { ActionContext, configureStore, put, take } from "./mod.ts";
 6+import { ActionContext, put, take } from "./mod.ts";
 7+import { createStore } from "./util.ts";
 8 
 9 const putTests = describe("put()");
10 
11@@ -27,10 +28,8 @@ it(putTests, "should send actions through channel", async () => {
12     });
13   }
14 
15-  const store = configureStore({
16-    reducers: { def: (s = null, _) => s },
17-  });
18-  await store.fx.run(() => genFn("arg"));
19+  const { fx } = createStore();
20+  await fx.run(() => genFn("arg"));
21 
22   const expected = ["arg", "2"];
23   expect(actual).toEqual(expected);
24@@ -59,10 +58,8 @@ it(putTests, "should handle nested puts", async () => {
25     yield* spawn(genA);
26   }
27 
28-  const store = configureStore({
29-    reducers: { def: (s = null, _) => s },
30-  });
31-  await store.fx.run(root);
32+  const { fx } = createStore();
33+  await fx.run(root);
34 
35   const expected = ["put b", "put a"];
36   expect(actual).toEqual(expected);
37@@ -73,16 +70,14 @@ it(
38   "should not cause stack overflow when puts are emitted while dispatching saga",
39   async () => {
40     function* root() {
41-      for (let i = 0; i < 40_000; i += 1) {
42+      for (let i = 0; i < 10_000; i += 1) {
43         yield* put({ type: "test" });
44       }
45       yield* sleep(0);
46     }
47 
48-    const store = configureStore({
49-      reducers: { def: (s = null, _) => s },
50-    });
51-    await store.fx.run(root);
52+    const { fx } = createStore();
53+    await fx.run(root);
54     expect(true).toBe(true);
55   },
56 );
57@@ -109,10 +104,8 @@ it(
58       yield* tsk;
59     }
60 
61-    const store = configureStore({
62-      reducers: { def: (s = null, _) => s },
63-    });
64-    await store.fx.run(root);
65+    const { fx } = createStore();
66+    await fx.run(root);
67     const expected = ["didn't get missed"];
68     expect(actual).toEqual(expected);
69   },
M redux/query.ts
+1, -2
 1@@ -1,10 +1,9 @@
 2 import { createLoaderTable, createReducerMap, createTable } from "../deps.ts";
 3 import { compose } from "../compose.ts";
 4 export { defaultLoader } from "../store/mod.ts";
 5-import type { AnyAction } from "../store/mod.ts";
 6 import { ApiCtx, createKey, Next } from "../query/mod.ts";
 7 import { put, select } from "./mod.ts";
 8-import type { QueryState } from "../types.ts";
 9+import type { AnyAction, QueryState } from "../types.ts";
10 
11 export function reduxMdw<Ctx extends ApiCtx = ApiCtx>(
12   errorFn?: (ctx: Ctx) => string,
M redux/take-helper.test.ts
+4, -4
 1@@ -1,8 +1,8 @@
 2 import { describe, expect, it } from "../test.ts";
 3-import type { AnyAction } from "../deps.ts";
 4+import type { AnyAction } from "../types.ts";
 5 
 6-import { configureStore, take, takeEvery } from "./mod.ts";
 7-const reducers = { init: () => null };
 8+import { take, takeEvery } from "./mod.ts";
 9+import { createStore } from "./util.ts";
10 
11 const testEvery = describe("takeEvery()");
12 
13@@ -23,7 +23,7 @@ it(testEvery, "should work", async () => {
14     actual.push([arg1, arg2, action.payload]);
15   }
16 
17-  const { store, fx } = configureStore({ reducers });
18+  const { store, fx } = createStore();
19   const task = fx.run(root);
20 
21   for (let i = 1; i <= loop / 2; i += 1) {
M redux/take.test.ts
+8, -10
 1@@ -1,7 +1,9 @@
 2 import { describe, expect, it } from "../test.ts";
 3-import { AnyAction, sleep, spawn } from "../deps.ts";
 4+import { sleep, spawn } from "../deps.ts";
 5+import type { AnyAction } from "../types.ts";
 6 
 7-import { configureStore, put, take } from "./mod.ts";
 8+import { put, take } from "./mod.ts";
 9+import { createStore } from "./util.ts";
10 
11 const takeTests = describe("take()");
12 
13@@ -24,10 +26,8 @@ it(
14       actual.push(yield* take("action-1"));
15     }
16 
17-    const store = configureStore({
18-      reducers: { def: (s = null, _) => s },
19-    });
20-    await store.fx.run(root);
21+    const { fx } = createStore();
22+    await fx.run(root);
23 
24     expect(actual).toEqual([
25       { type: "action-1", payload: 1 },
26@@ -86,10 +86,8 @@ it(takeTests, "take from default channel", async () => {
27     }
28   }
29 
30-  const store = configureStore({
31-    reducers: { def: (s = null, _) => s },
32-  });
33-  await store.fx.run(genFn);
34+  const { fx } = createStore();
35+  await fx.run(genFn);
36 
37   const expected = [
38     {
A redux/types.ts
+6, -0
1@@ -0,0 +1,6 @@
2+import type { AnyAction } from "../types.ts";
3+
4+export interface StoreLike<S = unknown> {
5+  getState: () => S;
6+  dispatch: (action: AnyAction) => void;
7+}
A redux/util.ts
+16, -0
 1@@ -0,0 +1,16 @@
 2+import { configureStore, Tuple } from "../deps.ts";
 3+import { prepareStore } from "./middleware.ts";
 4+
 5+export const createStore = () => {
 6+  const { reducer, fx } = prepareStore({
 7+    reducers: {
 8+      def: (s = null, _) => s,
 9+    },
10+  });
11+  const store = configureStore({
12+    reducer,
13+    middleware: new Tuple(fx.middleware as any),
14+    preloadedState: {},
15+  });
16+  return { store, fx };
17+};
M store/context.ts
+2, -1
1@@ -1,6 +1,7 @@
2 import { Channel, createChannel, createContext } from "../deps.ts";
3+import type { AnyAction, AnyState } from "../types.ts";
4 
5-import type { AnyAction, AnyState, FxStore } from "./types.ts";
6+import type { FxStore } from "./types.ts";
7 
8 export const ActionContext = createContext<Channel<AnyAction, void>>(
9   "store:action",
M store/fx.ts
+2, -8
 1@@ -1,15 +1,9 @@
 2 import { Channel, filter, Operation, spawn, Stream, Task } from "../deps.ts";
 3 import { call, parallel } from "../fx/mod.ts";
 4 import { ActionPattern, matcher } from "../matcher.ts";
 5+import type { ActionWPayload, AnyAction, AnyState } from "../types.ts";
 6 
 7-import type {
 8-  ActionWPayload,
 9-  AnyAction,
10-  AnyState,
11-  FxStore,
12-  StoreUpdater,
13-  UpdaterCtx,
14-} from "./types.ts";
15+import type { FxStore, StoreUpdater, UpdaterCtx } from "./types.ts";
16 import { ActionContext, StoreContext } from "./context.ts";
17 
18 export function* updateStore<S extends AnyState>(
M store/query.ts
+1, -2
 1@@ -2,11 +2,10 @@ import { race } from "../fx/mod.ts";
 2 import { sleep } from "../deps.ts";
 3 import type { ApiCtx, LoaderCtx, Next } from "../query/mod.ts";
 4 import { compose } from "../compose.ts";
 5-import type { QueryState } from "../types.ts";
 6+import type { AnyAction, QueryState } from "../types.ts";
 7 import { createAction } from "../action.ts";
 8 
 9 import { put, select, take, updateStore } from "./fx.ts";
10-import type { AnyAction } from "./types.ts";
11 import {
12   addData,
13   resetLoaderById,
M store/store.ts
+2, -9
 1@@ -8,18 +8,11 @@ import {
 2   Task,
 3 } from "../deps.ts";
 4 import { BaseMiddleware, compose } from "../compose.ts";
 5-import type { OpFn } from "../types.ts";
 6+import type { AnyAction, AnyState, OpFn } from "../types.ts";
 7 import { safe } from "../fx/mod.ts";
 8 import { Next } from "../query/types.ts";
 9 
10-import type {
11-  AnyAction,
12-  AnyState,
13-  FxStore,
14-  Listener,
15-  StoreUpdater,
16-  UpdaterCtx,
17-} from "./types.ts";
18+import type { FxStore, Listener, StoreUpdater, UpdaterCtx } from "./types.ts";
19 import { StoreContext, StoreUpdateContext } from "./context.ts";
20 import { put } from "./fx.ts";
21 
M store/supervisor.ts
+2, -3
 1@@ -1,8 +1,7 @@
 2 import { call, race } from "../fx/mod.ts";
 3-import { ActionWPayload, take } from "../store/mod.ts";
 4-import type { AnyAction } from "../store/types.ts";
 5+import { take } from "../store/mod.ts";
 6 import { Operation, sleep, spawn, Task } from "../deps.ts";
 7-import type { OpFn } from "../types.ts";
 8+import type { ActionWPayload, AnyAction, OpFn } from "../types.ts";
 9 import type { CreateActionPayload } from "../query/types.ts";
10 
11 const MS = 1000;
M store/take-helper.test.ts
+1, -1
1@@ -1,7 +1,7 @@
2 import { describe, expect, it } from "../test.ts";
3 import { sleep } from "../deps.ts";
4+import type { AnyAction } from "../types.ts";
5 
6-import type { AnyAction } from "./types.ts";
7 import { configureStore } from "./mod.ts";
8 import { take, takeEvery, takeLatest, takeLeading } from "./fx.ts";
9 
M store/take.test.ts
+1, -1
1@@ -1,7 +1,7 @@
2 import { describe, expect, it } from "../test.ts";
3 import { sleep, spawn } from "../deps.ts";
4+import type { AnyAction } from "../types.ts";
5 
6-import type { AnyAction } from "./types.ts";
7 import { put, take } from "./mod.ts";
8 import { configureStore } from "./store.ts";
9 
M store/types.ts
+1, -15
 1@@ -1,6 +1,6 @@
 2 import type { Operation, Patch, Result, Scope, Task } from "../deps.ts";
 3 import { BaseCtx } from "../mod.ts";
 4-import type { OpFn } from "../types.ts";
 5+import type { AnyAction, AnyState, OpFn } from "../types.ts";
 6 
 7 export type StoreUpdater<S extends AnyState> = (s: S) => S | void;
 8 
 9@@ -11,20 +11,6 @@ export interface UpdaterCtx<S extends AnyState> extends BaseCtx {
10   patches: Patch[];
11 }
12 
13-export interface AnyAction {
14-  type: string;
15-  // deno-lint-ignore no-explicit-any
16-  [key: string]: any;
17-}
18-
19-export interface ActionWPayload<P> {
20-  type: string;
21-  payload: P;
22-}
23-
24-// deno-lint-ignore no-explicit-any
25-export type AnyState = Record<string, any>;
26-
27 declare global {
28   interface SymbolConstructor {
29     readonly observable: symbol;
M types.ts
+15, -0
 1@@ -42,6 +42,21 @@ export type LoadingPayload =
 2   & Pick<LoadingItemState, "id">
 3   & Partial<Pick<LoadingItemState, "message" | "meta">>;
 4 
 5+// deno-lint-ignore no-explicit-any
 6+export type AnyState = Record<string, any>;
 7+
 8+// deno-lint-ignore no-explicit-any
 9 export interface Payload<P = any> {
10   payload: P;
11 }
12+
13+export interface AnyAction {
14+  type: string;
15+  // deno-lint-ignore no-explicit-any
16+  [key: string]: any;
17+}
18+
19+export interface ActionWPayload<P> {
20+  type: string;
21+  payload: P;
22+}