- commit
- 30e8e88
- parent
- 9bffca8
- author
- Eric Bower
- date
- 2023-09-16 19:09:32 +0000 UTC
refactor(redux): use signal instead of channel
5 files changed,
+35,
-50
M
deps.ts
+3,
-0
1@@ -5,6 +5,7 @@ export type {
2 Port,
3 Result,
4 Scope,
5+ Signal,
6 Stream,
7 Subscription,
8 Task,
9@@ -13,7 +14,9 @@ export {
10 action,
11 createChannel,
12 createContext,
13+ createQueue,
14 createScope,
15+ createSignal,
16 each,
17 Err,
18 expect,
M
mod.ts
+2,
-0
1@@ -7,7 +7,9 @@ export {
2 action,
3 createChannel,
4 createContext,
5+ createQueue,
6 createScope,
7+ createSignal,
8 each,
9 Err,
10 getframe,
+18,
-21
1@@ -1,52 +1,48 @@
2-import { Action, Channel, Operation } from "../deps.ts";
3-import { createChannel, createContext, spawn } from "../deps.ts";
4-import { call, parallel } from "../fx/mod.ts";
5+import { Action, Operation, Signal } from "../deps.ts";
6+import { createContext, createSignal, each, spawn } from "../deps.ts";
7+import { call } from "../fx/mod.ts";
8 import { ActionPattern, matcher } from "../matcher.ts";
9 import type { ActionWPayload, AnyAction } from "../types.ts";
10
11 import type { StoreLike } from "./types.ts";
12
13-export const ActionContext = createContext<Channel<Action, void>>(
14+export const ActionContext = createContext<Signal<Action, void>>(
15 "redux:action",
16- createChannel<Action, void>(),
17+ createSignal<Action, void>(),
18 );
19
20 export const StoreContext = createContext<StoreLike>("redux:store");
21
22-export function* emit({
23- channel,
24+export function emit({
25+ signal,
26 action,
27 }: {
28- channel: Operation<Channel<AnyAction, void>>;
29+ signal: Signal<AnyAction, void>;
30 action: AnyAction | AnyAction[];
31 }) {
32- const { input } = yield* channel;
33 if (Array.isArray(action)) {
34 if (action.length === 0) {
35 return;
36 }
37- yield* parallel(action.map((a) => () => input.send(a)));
38+ action.map((a) => signal.send(a));
39 } else {
40- yield* input.send(action);
41+ signal.send(action);
42 }
43 }
44
45 export function* once({
46- channel,
47+ signal,
48 pattern,
49 }: {
50- channel: Operation<Channel<Action, void>>;
51+ signal: Signal<Action, void>;
52 pattern: ActionPattern;
53 }) {
54- const { output } = yield* channel;
55- const msgList = yield* output;
56- let next = yield* msgList.next();
57- while (!next.done) {
58+ for (const action of yield* each(signal.stream)) {
59 const match = matcher(pattern);
60- if (match(next.value)) {
61- return next.value;
62+ if (match(action)) {
63+ return action;
64 }
65- next = yield* msgList.next();
66+ yield* each.next;
67 }
68 }
69
70@@ -57,8 +53,9 @@ export function* select<S, R>(selectorFn: (s: S) => R) {
71
72 export function take<P>(pattern: ActionPattern): Operation<ActionWPayload<P>>;
73 export function* take(pattern: ActionPattern): Operation<Action> {
74+ const signal = yield* ActionContext;
75 const action = yield* once({
76- channel: ActionContext,
77+ signal,
78 pattern,
79 });
80 return action as Action;
+8,
-23
1@@ -1,36 +1,21 @@
2-import {
3- Action,
4- BATCH,
5- BatchAction,
6- ReducersMapObject,
7- Scope,
8-} from "../deps.ts";
9+import { BATCH, BatchAction, ReducersMapObject, Scope } from "../deps.ts";
10 import { combineReducers, createScope, enableBatching } from "../deps.ts";
11-import { parallel } from "../fx/mod.ts";
12 import type { AnyAction } from "../types.ts";
13-
14 import { ActionContext, emit, StoreContext } from "./fx.ts";
15 import { reducers as queryReducers } from "./query.ts";
16 import type { StoreLike } from "./types.ts";
17
18 function* send(action: AnyAction) {
19+ const signal = yield* ActionContext;
20 if (action.type === BATCH) {
21 const actions = action.payload as BatchAction[];
22- const group = yield* parallel(
23- actions.map(
24- (a) =>
25- function* () {
26- yield* emit({
27- channel: ActionContext,
28- action: a as Action,
29- });
30- },
31- ),
32- );
33- yield* group;
34+ emit({
35+ signal,
36+ action: actions,
37+ });
38 } else {
39- yield* emit({
40- channel: ActionContext,
41+ emit({
42+ signal,
43 action,
44 });
45 }
+4,
-6
1@@ -1,5 +1,5 @@
2 import { describe, expect, it } from "../test.ts";
3-import { sleep, spawn } from "../deps.ts";
4+import { each, sleep, spawn } from "../deps.ts";
5
6 import { ActionContext, put, take } from "./mod.ts";
7 import { createTestStore } from "./util.ts";
8@@ -12,11 +12,9 @@ it(putTests, "should send actions through channel", async () => {
9 function* genFn(arg: string) {
10 yield* spawn(function* () {
11 const actions = yield* ActionContext;
12- const msgs = yield* actions.output;
13- let action = yield* msgs.next();
14- while (!action.done) {
15- actual.push(action.value.type);
16- action = yield* msgs.next();
17+ for (const action of yield* each(actions.stream)) {
18+ actual.push(action.type);
19+ yield* each.next;
20 }
21 });
22