From 30e8e88e00df008d9a49ddb673ad124355af49c2 Mon Sep 17 00:00:00 2001 From: Eric Bower Date: Sat, 16 Sep 2023 15:09:32 -0400 Subject: [PATCH] refactor(redux): use signal instead of channel --- deps.ts | 3 +++ mod.ts | 2 ++ redux/fx.ts | 39 ++++++++++++++++++--------------------- redux/middleware.ts | 31 ++++++++----------------------- redux/put.test.ts | 10 ++++------ 5 files changed, 35 insertions(+), 50 deletions(-) diff --git a/deps.ts b/deps.ts index 3f918c5..04704f9 100644 --- a/deps.ts +++ b/deps.ts @@ -5,6 +5,7 @@ export type { Port, Result, Scope, + Signal, Stream, Subscription, Task, @@ -13,7 +14,9 @@ export { action, createChannel, createContext, + createQueue, createScope, + createSignal, each, Err, expect, diff --git a/mod.ts b/mod.ts index 4a28b0a..713c1fb 100644 --- a/mod.ts +++ b/mod.ts @@ -7,7 +7,9 @@ export { action, createChannel, createContext, + createQueue, createScope, + createSignal, each, Err, getframe, diff --git a/redux/fx.ts b/redux/fx.ts index ac1a56e..6369772 100644 --- a/redux/fx.ts +++ b/redux/fx.ts @@ -1,52 +1,48 @@ -import { Action, Channel, Operation } from "../deps.ts"; -import { createChannel, createContext, spawn } from "../deps.ts"; -import { call, parallel } from "../fx/mod.ts"; +import { Action, Operation, Signal } from "../deps.ts"; +import { createContext, createSignal, each, spawn } from "../deps.ts"; +import { call } from "../fx/mod.ts"; import { ActionPattern, matcher } from "../matcher.ts"; import type { ActionWPayload, AnyAction } from "../types.ts"; import type { StoreLike } from "./types.ts"; -export const ActionContext = createContext>( +export const ActionContext = createContext>( "redux:action", - createChannel(), + createSignal(), ); export const StoreContext = createContext("redux:store"); -export function* emit({ - channel, +export function emit({ + signal, action, }: { - channel: Operation>; + signal: Signal; action: AnyAction | AnyAction[]; }) { - const { input } = yield* channel; if (Array.isArray(action)) { if (action.length === 0) { return; } - yield* parallel(action.map((a) => () => input.send(a))); + action.map((a) => signal.send(a)); } else { - yield* input.send(action); + signal.send(action); } } export function* once({ - channel, + signal, pattern, }: { - channel: Operation>; + signal: Signal; pattern: ActionPattern; }) { - const { output } = yield* channel; - const msgList = yield* output; - let next = yield* msgList.next(); - while (!next.done) { + for (const action of yield* each(signal.stream)) { const match = matcher(pattern); - if (match(next.value)) { - return next.value; + if (match(action)) { + return action; } - next = yield* msgList.next(); + yield* each.next; } } @@ -57,8 +53,9 @@ export function* select(selectorFn: (s: S) => R) { export function take

(pattern: ActionPattern): Operation>; export function* take(pattern: ActionPattern): Operation { + const signal = yield* ActionContext; const action = yield* once({ - channel: ActionContext, + signal, pattern, }); return action as Action; diff --git a/redux/middleware.ts b/redux/middleware.ts index 54147c1..1f8b951 100644 --- a/redux/middleware.ts +++ b/redux/middleware.ts @@ -1,36 +1,21 @@ -import { - Action, - BATCH, - BatchAction, - ReducersMapObject, - Scope, -} from "../deps.ts"; +import { BATCH, BatchAction, ReducersMapObject, Scope } from "../deps.ts"; import { combineReducers, createScope, enableBatching } from "../deps.ts"; -import { parallel } from "../fx/mod.ts"; import type { AnyAction } from "../types.ts"; - import { ActionContext, emit, StoreContext } from "./fx.ts"; import { reducers as queryReducers } from "./query.ts"; import type { StoreLike } from "./types.ts"; function* send(action: AnyAction) { + const signal = yield* ActionContext; if (action.type === BATCH) { const actions = action.payload as BatchAction[]; - const group = yield* parallel( - actions.map( - (a) => - function* () { - yield* emit({ - channel: ActionContext, - action: a as Action, - }); - }, - ), - ); - yield* group; + emit({ + signal, + action: actions, + }); } else { - yield* emit({ - channel: ActionContext, + emit({ + signal, action, }); } diff --git a/redux/put.test.ts b/redux/put.test.ts index fe6693f..7132847 100644 --- a/redux/put.test.ts +++ b/redux/put.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "../test.ts"; -import { sleep, spawn } from "../deps.ts"; +import { each, sleep, spawn } from "../deps.ts"; import { ActionContext, put, take } from "./mod.ts"; import { createTestStore } from "./util.ts"; @@ -12,11 +12,9 @@ it(putTests, "should send actions through channel", async () => { function* genFn(arg: string) { yield* spawn(function* () { const actions = yield* ActionContext; - const msgs = yield* actions.output; - let action = yield* msgs.next(); - while (!action.done) { - actual.push(action.value.type); - action = yield* msgs.next(); + for (const action of yield* each(actions.stream)) { + actual.push(action.type); + yield* each.next; } });