From a5999ff0279cec77de0921fd7498657fdd6684a9 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Thu, 25 Mar 2021 22:51:53 -0400 Subject: [PATCH 1/3] Remove leftover perf benchmarks file --- src/immutablePerfBenchmarks.ts | 256 --------------------------------- 1 file changed, 256 deletions(-) delete mode 100644 src/immutablePerfBenchmarks.ts diff --git a/src/immutablePerfBenchmarks.ts b/src/immutablePerfBenchmarks.ts deleted file mode 100644 index d535bf0246..0000000000 --- a/src/immutablePerfBenchmarks.ts +++ /dev/null @@ -1,256 +0,0 @@ -// import Benchmark from 'benchmark' -import { Store, MiddlewareAPI, Dispatch } from 'redux' -import faker from 'faker' - -import { configureStore } from './configureStore' -import { createSlice } from './createSlice' - -import { - createImmutableStateInvariantMiddleware, - tm2, - ImmutableStateInvariantMiddlewareOptions -} from './immutableStateInvariantMiddleware' - -export class TaskInfo { - private _taskName: string - private _percentage: string | undefined - private _timeMillis: number - - constructor(taskName: string, timeMillis: number) { - this._taskName = taskName - this._timeMillis = timeMillis - } - - get taskName(): string { - return this._taskName - } - - get timeMills(): number { - return this._timeMillis - } - - get percentage(): string | undefined { - return this._percentage - } - - calculatePercentage(totalTimeMillis: number): string { - this._percentage = ((this._timeMillis * 100) / totalTimeMillis).toFixed(2) - return this._percentage - } -} - -export class StopWatch { - public static NoTaskMessage = 'No task info kept' - - private id: string - private currentTaskName: string | null = null - private startTimeMillis = 0 - private totalTimeMillis = 0 - private taskList: Array = [] - - constructor(id = '') { - this.id = id - } - - /** - * start a task - */ - start(taskName = ''): void { - this.currentTaskName !== null && - this.throwError("Can't start StopWatch: it's already running") - this.currentTaskName = taskName - this.startTimeMillis = Date.now() - } - - /** - * stop the current task - */ - stop(): void { - this.currentTaskName === null && - this.throwError("Can't stop StopWatch: it's not running") - const lastTime: number = Date.now() - this.startTimeMillis - this.totalTimeMillis += lastTime - const lastTaskInfo = new TaskInfo(this.currentTaskName!, lastTime) - this.taskList.push(lastTaskInfo) - this.currentTaskName = null - } - - /** - * Return a string with a table describing all tasks performed. - */ - prettyPrint(): string { - const output: Array = [this.shortSummary()] - if (this.taskList.length) { - output.push('------------------------------------------') - output.push('ms \t\t % \t\t Task name') - output.push('------------------------------------------') - this.taskList.forEach((task: TaskInfo) => { - let percentage = '0' - try { - percentage = task.calculatePercentage(this.totalTimeMillis) - } catch (e) {} - output.push( - `${task.timeMills} \t\t ${percentage} \t\t ${task.taskName}` - ) - }) - } else { - output.push(StopWatch.NoTaskMessage) - } - const outputString = output.join('\n') - - console.info(outputString) - return outputString - } - - /** - * Return a task matching the given name - */ - getTask(taskName: string): TaskInfo | undefined { - const task = this.taskList.find(task => task.taskName === taskName) - if (task) { - task.calculatePercentage(this.totalTimeMillis) - } - - return task - } - - /** - * Return the total running time in milliseconds - */ - getTotalTime(): number { - return this.totalTimeMillis - } - - /** - * Return a short description of the total running time. - */ - shortSummary(): string { - return `StopWatch '${this.id}' running time (millis) = ${this.totalTimeMillis}` - } - - /** - * Return whether the stop watch is currently running - */ - isRunning(): boolean { - return this.currentTaskName !== null - } - - /** - * Return the number of tasks timed. - */ - getTaskCount(): number { - return this.taskList.length - } - - private throwError(msg: string): never { - throw new Error(msg) - } -} - -/* -let state: any -const getState: Store['getState'] = () => state - -function middleware(options: ImmutableStateInvariantMiddlewareOptions = {}) { - return createImmutableStateInvariantMiddleware(options)({ - getState - } as MiddlewareAPI) -} - -const next: Dispatch = action => action -*/ - -function createSliceData() { - const people = Array.from({ length: 10000 }).map( - () => faker.helpers.userCard() as any - ) - people.forEach(person => { - person.vehicles = Array.from({ length: 2 }).map(() => - faker.vehicle.vehicle() - ) - }) - - return people -} - -const state: any = { - a: createSliceData(), - b: createSliceData(), - c: createSliceData() -} - -// debugger -// let q = 42 - -const dummySlice = createSlice({ - name: 'dummy', - initialState: state, - reducers: {} -}) - -const originalStore = configureStore({ - reducer: dummySlice.reducer, - middleware: gdm => - gdm({ - // serializableCheck: false - }) -}) - -function runOriginal() { - // const dispatch = middleware()(next) - // dispatch({ type: 'SOME_ACTION' }) - originalStore.dispatch({ type: 'SOME_ACTION' }) -} - -const queuedStore = configureStore({ - reducer: dummySlice.reducer, - middleware: gdm => - gdm({ - // serializableCheck: false, - immutableCheck: { - trackFunction: tm2 - } - }) -}) - -function runQueued() { - queuedStore.dispatch({ type: 'SOME_ACTION' }) -} -/* -const suite = new Benchmark.Suite('abcd', { - setup() { - state = { - a: createSliceData(), - b: createSliceData(), - c: createSliceData() - } - } -}) - -suite - .add('Original', ) - .add('Queued', ) - .on('cycle', function(event: any) { - console.log(String(event.target)) - }) - .on('complete', function(this: any) { - console.log('Fastest is ' + this.filter('fastest').map('name')) - }) - .run({}) -*/ - -const stopwatch = new StopWatch() - -stopwatch.start('Original') -runOriginal() -stopwatch.stop() - -stopwatch.start('Queued') -runQueued() -stopwatch.stop() - -// debugger - -stopwatch.prettyPrint() - -// let z = q From 394a8a4024047842fe74fdd20b48d7ac7b6d2cc5 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Thu, 25 Mar 2021 22:55:28 -0400 Subject: [PATCH 2/3] Export isDraft from Immer --- etc/redux-toolkit.api.md | 3 +++ src/index.ts | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/etc/redux-toolkit.api.md b/etc/redux-toolkit.api.md index 58ad0cb00f..90d4314de8 100644 --- a/etc/redux-toolkit.api.md +++ b/etc/redux-toolkit.api.md @@ -14,6 +14,7 @@ import { DeepPartial } from 'redux'; import { Dispatch } from 'redux'; import { Draft } from 'immer'; import { freeze } from 'immer'; +import { isDraft } from 'immer'; import { Middleware } from 'redux'; import { original } from 'immer'; import { OutputParametricSelector } from 'reselect'; @@ -315,6 +316,8 @@ export function isAsyncThunkAction action is UnknownAsyncThunkFulfilledAction; diff --git a/src/index.ts b/src/index.ts index 0911fa6ca4..b93380523e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,8 @@ export { Draft, current, freeze, - original + original, + isDraft } from 'immer' export { createSelector, From c7ab2fc4b1b11d2750861b1135f72ae425bb7598 Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Thu, 25 Mar 2021 22:58:14 -0400 Subject: [PATCH 3/3] Update Immer exports docs --- docs/api/otherExports.mdx | 4 ++++ docs/usage/immer-reducers.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/api/otherExports.mdx b/docs/api/otherExports.mdx index 7de8f27cb2..c01fecfca8 100644 --- a/docs/api/otherExports.mdx +++ b/docs/api/otherExports.mdx @@ -52,6 +52,10 @@ const todosReducer = createReducer(initialState, builder => { }) ``` +### `isDraft` + +[The `isDraft` function](https://immerjs.github.io/immer/original) from the [`immer` library](https://immerjs.github.io/immer/), which checks to see if a given value is a Proxy-wrapped "draft" state. + ### `combineReducers` Redux's [`combineReducers`](https://redux.js.org/api/combinereducers), re-exported for convenience. While `configureStore` calls this internally, you may wish to call it yourself to compose multiple levels of slice reducers. diff --git a/docs/usage/immer-reducers.md b/docs/usage/immer-reducers.md index 8b97a87954..ffc6592b54 100644 --- a/docs/usage/immer-reducers.md +++ b/docs/usage/immer-reducers.md @@ -386,7 +386,7 @@ The correct output would look like this instead: ![Logged current value](/img/usage/immer-reducers/logged-current-state.png) -Immer also provides [`original` and `isDraft` functions](https://immerjs.github.io/immer/original), which retrieves the original data without any updates applied and check to see if a given value is a Proxy-wrapped draft. As of RTK 1.5.0, neither of those is re-exported - you'll need to specifically import them from `immer` yourself. We may re-export them from RTK in an upcoming release. +Immer also provides [`original` and `isDraft` functions](https://immerjs.github.io/immer/original), which retrieves the original data without any updates applied and check to see if a given value is a Proxy-wrapped draft. As of RTK 1.5.1, both of those are re-exported from RTK as well. ### Updating Nested Data