diff --git a/desktop/app/src/dispatcher/plugins.tsx b/desktop/app/src/dispatcher/plugins.tsx index 08a9214c1..850ccc9c5 100644 --- a/desktop/app/src/dispatcher/plugins.tsx +++ b/desktop/app/src/dispatcher/plugins.tsx @@ -68,7 +68,7 @@ export default (store: Store, _logger: Logger) => { sideEffect( store, - {name: 'setupMenuBar', throttleMs: 100}, + {name: 'setupMenuBar', throttleMs: 1000, fireImmediately: true}, (state) => state.plugins, (plugins, store) => { setupMenuBar( diff --git a/desktop/app/src/utils/__tests__/sideEffect.node.tsx b/desktop/app/src/utils/__tests__/sideEffect.node.tsx index 477a7ead2..b56bd0a69 100644 --- a/desktop/app/src/utils/__tests__/sideEffect.node.tsx +++ b/desktop/app/src/utils/__tests__/sideEffect.node.tsx @@ -221,4 +221,26 @@ describe('sideeffect', () => { await sleep(100); expect(events).toEqual(['counter: 1', 'counter: 3', 'counter: 5']); }); + + test('can fire immediately', async () => { + store.dispatch({type: 'inc'}); + store.dispatch({type: 'inc'}); + + unsubscribe = sideEffect( + store, + {name: 'test', throttleMs: 1, fireImmediately: true}, + (s) => s, + (s) => { + events.push(`counter: ${s.counter.count}`); + }, + ); + + expect(events).toEqual(['counter: 2']); + store.dispatch({type: 'inc'}); + store.dispatch({type: 'inc'}); + // arrive as a single effect + await sleep(10); + expect(events).toEqual(['counter: 2', 'counter: 4']); + unsubscribe?.(); + }); }); diff --git a/desktop/app/src/utils/sideEffect.tsx b/desktop/app/src/utils/sideEffect.tsx index 840fd086b..b9097be5b 100644 --- a/desktop/app/src/utils/sideEffect.tsx +++ b/desktop/app/src/utils/sideEffect.tsx @@ -28,7 +28,7 @@ export function sideEffect< State = Store extends ReduxStore ? S : never >( store: Store, - options: {name: string; throttleMs: number}, + options: {name: string; throttleMs: number; fireImmediately?: boolean}, selector: (state: State) => V, effect: (selectedState: V, store: Store) => void, ): () => void { @@ -54,9 +54,9 @@ export function sideEffect< const duration = lastRun - start; if (duration > 15 && duration > options.throttleMs / 10) { console.warn( - `Side effect '${ - options.name - }' took ${duration}ms, which exceeded its budget of ${Math.floor( + `Side effect '${options.name}' took ${Math.round( + duration, + )}ms, which exceeded its budget of ${Math.floor( options.throttleMs / 10, )}ms. Please make the effect faster or increase the throttle time.`, ); @@ -84,6 +84,10 @@ export function sideEffect< ); }); + if (options.fireImmediately) { + run(); + } + return () => { clearTimeout(timeout); unsubscribe();