From 1e2bff1f2f3014903d1bc9302412930bbe62f927 Mon Sep 17 00:00:00 2001 From: Nathaniel Tucker Date: Mon, 27 Jan 2020 01:50:06 -0800 Subject: [PATCH] enhance: Remove lodash dependency, reducing total bundle size (#250) --- packages/rest-hooks/package.json | 4 +- .../rest-hooks/src/state/NetworkManager.ts | 67 ++++++++++--------- .../src/state/SubscriptionManager.ts | 41 ++++++------ 3 files changed, 57 insertions(+), 55 deletions(-) diff --git a/packages/rest-hooks/package.json b/packages/rest-hooks/package.json index 953cd0de469..b6c7a227ee4 100644 --- a/packages/rest-hooks/package.json +++ b/packages/rest-hooks/package.json @@ -67,9 +67,7 @@ "dependencies": { "@babel/runtime": "^7.7.2", "@rest-hooks/normalizr": "^4.3.2", - "@types/lodash": "^4.14.149", - "flux-standard-action": "^2.1.1", - "lodash": "^4.17.15" + "flux-standard-action": "^2.1.1" }, "peerDependencies": { "@types/react": "^16.8.2", diff --git a/packages/rest-hooks/src/state/NetworkManager.ts b/packages/rest-hooks/src/state/NetworkManager.ts index 48387ce7e0f..84060153b99 100644 --- a/packages/rest-hooks/src/state/NetworkManager.ts +++ b/packages/rest-hooks/src/state/NetworkManager.ts @@ -1,5 +1,3 @@ -import { memoize } from 'lodash'; - import RIC from './RIC'; import { createReceive, createReceiveError } from './actionCreators'; @@ -7,6 +5,7 @@ import { FetchAction, ReceiveAction, MiddlewareAPI, + Middleware, Manager, Dispatch, } from '~/types'; @@ -35,9 +34,40 @@ export default class NetworkManager implements Manager { protected rejectors: { [k: string]: (value?: any) => void } = {}; declare readonly dataExpiryLength: number; declare readonly errorExpiryLength: number; + protected declare middleware: Middleware; + constructor(dataExpiryLength = 60000, errorExpiryLength = 1000) { this.dataExpiryLength = dataExpiryLength; this.errorExpiryLength = errorExpiryLength; + + this.middleware = >({ + dispatch, + }: MiddlewareAPI) => { + return (next: Dispatch) => ( + action: React.ReducerAction, + ): Promise => { + switch (action.type) { + case FETCH_TYPE: + this.handleFetch(action, dispatch); + if (process.env.NODE_ENV !== 'production') action.meta.nm = true; + return next(action); + case RECEIVE_DELETE_TYPE: + case RECEIVE_MUTATE_TYPE: + case RECEIVE_TYPE: + // only receive after new state is computed + return next(action).then(() => { + if (action.meta.url in this.fetched) { + this.handleReceive(action); + } + }); + case RESET_TYPE: + this.cleanup(); + return next(action); + default: + return next(action); + } + }; + }; } /** Ensures all promises are completed by rejecting remaining. */ @@ -112,36 +142,9 @@ export default class NetworkManager implements Manager { * Resolve/rejects a request when matching 'rest-hooks/receive' event * is seen. */ - getMiddleware = memoize(function(this: T) { - return >({ - dispatch, - }: MiddlewareAPI) => { - return (next: Dispatch) => ( - action: React.ReducerAction, - ): Promise => { - switch (action.type) { - case FETCH_TYPE: - this.handleFetch(action, dispatch); - if (process.env.NODE_ENV !== 'production') action.meta.nm = true; - return next(action); - case RECEIVE_DELETE_TYPE: - case RECEIVE_MUTATE_TYPE: - case RECEIVE_TYPE: - // only receive after new state is computed - return next(action).then(() => { - if (action.meta.url in this.fetched) { - this.handleReceive(action); - } - }); - case RESET_TYPE: - this.cleanup(); - return next(action); - default: - return next(action); - } - }; - }; - }); + getMiddleware(this: T) { + return this.middleware; + } /** Ensures only one request for a given url is in flight at any time * diff --git a/packages/rest-hooks/src/state/SubscriptionManager.ts b/packages/rest-hooks/src/state/SubscriptionManager.ts index 2173ebc3f50..83d1f82ac10 100644 --- a/packages/rest-hooks/src/state/SubscriptionManager.ts +++ b/packages/rest-hooks/src/state/SubscriptionManager.ts @@ -1,7 +1,6 @@ -import { memoize } from 'lodash'; - import { MiddlewareAPI, + Middleware, SubscribeAction, UnsubscribeAction, Manager, @@ -44,10 +43,27 @@ export default class SubscriptionManager } = {}; protected declare readonly Subscription: S; + protected declare middleware: Middleware; constructor(Subscription: S) { this.Subscription = Subscription; - this.getMiddleware = memoize(this.getMiddleware); + + this.middleware = >({ + dispatch, + }: MiddlewareAPI) => { + return (next: Dispatch) => (action: React.ReducerAction) => { + switch (action.type) { + case SUBSCRIBE_TYPE: + this.handleSubscribe(action, dispatch); + return Promise.resolve(); + case UNSUBSCRIBE_TYPE: + this.handleUnsubscribe(action, dispatch); + return Promise.resolve(); + default: + return next(action); + } + }; + }; } /** Ensures all subscriptions are cleaned up. */ @@ -104,22 +120,7 @@ export default class SubscriptionManager * Will possibly dispatch 'rest-hooks/fetch' or 'rest-hooks/receive' to keep resources fresh * */ - getMiddleware>(this: T) { - return >({ - dispatch, - }: MiddlewareAPI) => { - return (next: Dispatch) => (action: React.ReducerAction) => { - switch (action.type) { - case SUBSCRIBE_TYPE: - this.handleSubscribe(action, dispatch); - return Promise.resolve(); - case UNSUBSCRIBE_TYPE: - this.handleUnsubscribe(action, dispatch); - return Promise.resolve(); - default: - return next(action); - } - }; - }; + getMiddleware>(this: T) { + return this.middleware; } }