From 3bb84862ec295ca420c649dae3924f83549a1123 Mon Sep 17 00:00:00 2001 From: Ben Durrant Date: Wed, 27 Nov 2024 23:12:44 +0000 Subject: [PATCH] Simplify listener/dynamic middleware code --- .../toolkit/src/dynamicMiddleware/index.ts | 17 ++++----- .../toolkit/src/dynamicMiddleware/types.ts | 1 - .../toolkit/src/listenerMiddleware/index.ts | 27 +++++--------- .../toolkit/src/listenerMiddleware/types.ts | 35 ++++++++++++++----- packages/toolkit/src/utils.ts | 13 ------- 5 files changed, 42 insertions(+), 51 deletions(-) diff --git a/packages/toolkit/src/dynamicMiddleware/index.ts b/packages/toolkit/src/dynamicMiddleware/index.ts index 7fc5a60892..8e61d6769b 100644 --- a/packages/toolkit/src/dynamicMiddleware/index.ts +++ b/packages/toolkit/src/dynamicMiddleware/index.ts @@ -3,7 +3,7 @@ import { compose } from 'redux' import { createAction } from '../createAction' import { isAllOf } from '../matchers' import { nanoid } from '../nanoid' -import { find, getOrInsertComputed } from '../utils' +import { getOrInsertComputed } from '../utils' import type { AddMiddleware, DynamicMiddleware, @@ -23,7 +23,6 @@ const createMiddlewareEntry = < >( middleware: Middleware, ): MiddlewareEntry => ({ - id: nanoid(), middleware, applied: new Map(), }) @@ -38,7 +37,10 @@ export const createDynamicMiddleware = < DispatchType extends Dispatch = Dispatch, >(): DynamicMiddlewareInstance => { const instanceId = nanoid() - const middlewareMap = new Map>() + const middlewareMap = new Map< + Middleware, + MiddlewareEntry + >() const withMiddleware = Object.assign( createAction( @@ -58,14 +60,7 @@ export const createDynamicMiddleware = < ...middlewares: Middleware[] ) { middlewares.forEach((middleware) => { - let entry = find( - Array.from(middlewareMap.values()), - (entry) => entry.middleware === middleware, - ) - if (!entry) { - entry = createMiddlewareEntry(middleware) - } - middlewareMap.set(entry.id, entry) + getOrInsertComputed(middlewareMap, middleware, createMiddlewareEntry) }) }, { withTypes: () => addMiddleware }, diff --git a/packages/toolkit/src/dynamicMiddleware/types.ts b/packages/toolkit/src/dynamicMiddleware/types.ts index ee8c37a21b..989c7ffcc0 100644 --- a/packages/toolkit/src/dynamicMiddleware/types.ts +++ b/packages/toolkit/src/dynamicMiddleware/types.ts @@ -59,7 +59,6 @@ export type MiddlewareEntry< State = unknown, DispatchType extends Dispatch = Dispatch, > = { - id: string middleware: Middleware applied: Map< MiddlewareAPI, diff --git a/packages/toolkit/src/listenerMiddleware/index.ts b/packages/toolkit/src/listenerMiddleware/index.ts index efa2912ad3..9cb2e87dda 100644 --- a/packages/toolkit/src/listenerMiddleware/index.ts +++ b/packages/toolkit/src/listenerMiddleware/index.ts @@ -2,9 +2,7 @@ import type { Action, Dispatch, MiddlewareAPI, UnknownAction } from 'redux' import { isAction } from 'redux' import type { ThunkDispatch } from 'redux-thunk' import { createAction } from '../createAction' -import { nanoid } from '../nanoid' -import { find } from '../utils' import { TaskAbortError, listenerCancelled, @@ -48,6 +46,7 @@ import { catchRejection, noop, } from './utils' +import { getOrInsertComputed } from '@internal/utils' export { TaskAbortError } from './exceptions' export type { AsyncTaskExecutor, @@ -221,9 +220,7 @@ export const createListenerEntry: TypedCreateListenerEntry = (options: FallbackAddListenerOptions) => { const { type, predicate, effect } = getListenerEntryPropsFrom(options) - const id = nanoid() const entry: ListenerEntry = { - id, effect, type, predicate, @@ -247,7 +244,7 @@ const cancelActiveListeners = ( } const createClearListenerMiddleware = ( - listenerMap: Map, + listenerMap: Map, ) => { return () => { listenerMap.forEach(cancelActiveListeners) @@ -324,15 +321,15 @@ export const createListenerMiddleware = < >( middlewareOptions: CreateListenerMiddlewareOptions = {}, ) => { - const listenerMap = new Map() + const listenerMap = new Map() const { extra, onError = defaultErrorHandler } = middlewareOptions assertFunction(onError, 'onError') const insertEntry = (entry: ListenerEntry) => { - entry.unsubscribe = () => listenerMap.delete(entry!.id) + entry.unsubscribe = () => listenerMap.delete(entry.effect) - listenerMap.set(entry.id, entry) + listenerMap.set(entry.effect, entry) return (cancelOptions?: UnsubscribeListenerOptions) => { entry.unsubscribe() if (cancelOptions?.cancelActive) { @@ -342,15 +339,9 @@ export const createListenerMiddleware = < } const startListening = ((options: FallbackAddListenerOptions) => { - let entry = find( - Array.from(listenerMap.values()), - (existingEntry) => existingEntry.effect === options.effect, + const entry = getOrInsertComputed(listenerMap, options.effect, () => + createListenerEntry(options as any), ) - - if (!entry) { - entry = createListenerEntry(options as any) - } - return insertEntry(entry) }) as AddListenerOverloads @@ -363,7 +354,7 @@ export const createListenerMiddleware = < ): boolean => { const { type, effect, predicate } = getListenerEntryPropsFrom(options) - const entry = find(Array.from(listenerMap.values()), (entry) => { + const entry = Array.from(listenerMap.values()).find((entry) => { const matchPredicateOrType = typeof type === 'string' ? entry.type === type @@ -419,7 +410,7 @@ export const createListenerMiddleware = < fork: createFork(internalTaskController.signal, autoJoinPromises), unsubscribe: entry.unsubscribe, subscribe: () => { - listenerMap.set(entry.id, entry) + listenerMap.set(entry.effect, entry) }, cancelActiveListeners: () => { entry.pending.forEach((controller, _, set) => { diff --git a/packages/toolkit/src/listenerMiddleware/types.ts b/packages/toolkit/src/listenerMiddleware/types.ts index b5980e1085..8dceea993f 100644 --- a/packages/toolkit/src/listenerMiddleware/types.ts +++ b/packages/toolkit/src/listenerMiddleware/types.ts @@ -578,9 +578,13 @@ export type TypedAddListener< OverrideStateType, unknown, UnknownAction - >, - OverrideExtraArgument = unknown, - >() => TypedAddListener + >, + OverrideExtraArgument = unknown, + >() => TypedAddListener< + OverrideStateType, + OverrideDispatchType, + OverrideExtraArgument + > } /** @@ -641,7 +645,11 @@ export type TypedRemoveListener< UnknownAction >, OverrideExtraArgument = unknown, - >() => TypedRemoveListener + >() => TypedRemoveListener< + OverrideStateType, + OverrideDispatchType, + OverrideExtraArgument + > } /** @@ -701,7 +709,11 @@ export type TypedStartListening< UnknownAction >, OverrideExtraArgument = unknown, - >() => TypedStartListening + >() => TypedStartListening< + OverrideStateType, + OverrideDispatchType, + OverrideExtraArgument + > } /** @@ -756,7 +768,11 @@ export type TypedStopListening< UnknownAction >, OverrideExtraArgument = unknown, - >() => TypedStopListening + >() => TypedStopListening< + OverrideStateType, + OverrideDispatchType, + OverrideExtraArgument + > } /** @@ -813,7 +829,11 @@ export type TypedCreateListenerEntry< UnknownAction >, OverrideExtraArgument = unknown, - >() => TypedStopListening + >() => TypedStopListening< + OverrideStateType, + OverrideDispatchType, + OverrideExtraArgument + > } /** @@ -825,7 +845,6 @@ export type ListenerEntry< State = unknown, DispatchType extends Dispatch = Dispatch, > = { - id: string effect: ListenerEffect unsubscribe: () => void pending: Set diff --git a/packages/toolkit/src/utils.ts b/packages/toolkit/src/utils.ts index 157cc86b08..6607f4b339 100644 --- a/packages/toolkit/src/utils.ts +++ b/packages/toolkit/src/utils.ts @@ -26,19 +26,6 @@ export function delay(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)) } -export function find( - iterable: Iterable, - comparator: (item: T) => boolean, -): T | undefined { - for (const entry of iterable) { - if (comparator(entry)) { - return entry - } - } - - return undefined -} - export class Tuple = []> extends Array< Items[number] > {