chore: bypass immer for first evaluation, fixed cloneDeep issue and using mutative instead of immer (#38993)
## Description - Using mutative instead of immer, this has reduced the main thread scripting by about 1 second. - Removed a cloneDeep during table onMount which saves about 70ms in main thread scripting. - Bypassed mutative when applying the first tree to reduce the overhead associated to mutative. Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/13164792224> > Commit: 4cb821723d10198c9db70312a9604df5aa5f80c1 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13164792224&attempt=2" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Thu, 06 Feb 2025 04:21:41 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Dependency** - Integrated a new library to enhance overall state management. - **Refactor** - Updated state update mechanisms across interactive components and data flows. - Improved table widget processing for more consistent behavior. - **Chore** - Removed legacy development-only configuration settings. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
6604f36bc1
commit
2b9299e2d3
|
|
@ -140,7 +140,6 @@
|
|||
"fusioncharts": "^3.18.0",
|
||||
"graphql": "^16.8.1",
|
||||
"history": "^4.10.1",
|
||||
"immer": "^9.0.6",
|
||||
"interweave": "^12.7.2",
|
||||
"interweave-autolink": "^4.4.2",
|
||||
"js-regex-pl": "^1.0.1",
|
||||
|
|
@ -161,6 +160,7 @@
|
|||
"mixpanel-browser": "^2.55.1",
|
||||
"moment": "2.29.4",
|
||||
"moment-timezone": "^0.5.35",
|
||||
"mutative": "^1.1.0",
|
||||
"nanoid": "^2.0.4",
|
||||
"node-forge": "^1.3.0",
|
||||
"object-hash": "^3.0.0",
|
||||
|
|
@ -331,6 +331,7 @@
|
|||
"eslint-plugin-testing-library": "^6.2.0",
|
||||
"factory.ts": "^0.5.1",
|
||||
"husky": "^8.0.0",
|
||||
"immer": "^9.0.6",
|
||||
"jest": "^29.6.1",
|
||||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-environment-jsdom": "^29.6.1",
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import {
|
|||
import type { RegisteredWidgetFeatures } from "../../utils/WidgetFeatures";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
import { freeze, memoize } from "./decorators";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
import type {
|
||||
CopiedWidgetData,
|
||||
|
|
@ -418,7 +418,7 @@ class WidgetFactory {
|
|||
|
||||
if (dynamicProperties && dynamicProperties.length) {
|
||||
addPropertyConfigIds(dynamicProperties, false);
|
||||
section = produce(section, (draft) => {
|
||||
section = create(section, (draft) => {
|
||||
draft.children = [...dynamicProperties, ...section.children];
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type { Datasource } from "entities/Datasource";
|
|||
import { isStoredDatasource } from "entities/Action";
|
||||
import type { WidgetProps } from "widgets/BaseWidget";
|
||||
import log from "loglevel";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import type { CanvasStructure } from "reducers/uiReducers/pageCanvasStructureReducer";
|
||||
import { getActions, getDatasources } from "ee/selectors/entitiesSelector";
|
||||
import type { ActionData } from "ee/reducers/entityReducers/actionsReducer";
|
||||
|
|
@ -184,7 +184,7 @@ export const useActions = (searchKeyword?: string) => {
|
|||
return useMemo(() => {
|
||||
if (searchKeyword) {
|
||||
const start = performance.now();
|
||||
const filteredActions = produce(actions, (draft) => {
|
||||
const filteredActions = create(actions, (draft) => {
|
||||
for (const [key, value] of Object.entries(draft)) {
|
||||
if (pageIds.includes(key)) {
|
||||
draft[key] = value;
|
||||
|
|
@ -225,7 +225,7 @@ export const useWidgets = (searchKeyword?: string) => {
|
|||
return useMemo(() => {
|
||||
if (searchKeyword && pageCanvasStructures) {
|
||||
const start = performance.now();
|
||||
const filteredDSLs = produce(pageCanvasStructures, (draft) => {
|
||||
const filteredDSLs = create(pageCanvasStructures, (draft) => {
|
||||
for (const [key, value] of Object.entries(draft)) {
|
||||
if (pageIds.includes(key)) {
|
||||
draft[key] = value;
|
||||
|
|
@ -256,7 +256,7 @@ export const usePageIds = (searchKeyword?: string) => {
|
|||
|
||||
return useMemo(() => {
|
||||
if (searchKeyword) {
|
||||
const filteredPages = produce(pages, (draft) => {
|
||||
const filteredPages = create(pages, (draft) => {
|
||||
draft.forEach((page, index) => {
|
||||
const searchMatches =
|
||||
page.pageName.toLowerCase().indexOf(searchKeyword.toLowerCase()) >
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
ReduxActionErrorTypes,
|
||||
} from "ee/constants/ReduxActionConstants";
|
||||
import { set, keyBy, findIndex, unset } from "lodash";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import { klona } from "klona";
|
||||
|
||||
export const initialState: JSCollectionDataState = [];
|
||||
|
|
@ -400,7 +400,7 @@ export const handlers = {
|
|||
}>
|
||||
>,
|
||||
) => {
|
||||
return produce(state, (draft) => {
|
||||
return create(state, (draft) => {
|
||||
const CollectionUpdateSearch = keyBy(action.payload, "collectionId");
|
||||
const actionUpdateSearch = keyBy(action.payload, "id");
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import {
|
|||
defaultNavigationSetting,
|
||||
defaultThemeSetting,
|
||||
} from "constants/AppConstants";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import { isEmpty } from "lodash";
|
||||
import type { ApplicationPayload } from "entities/Application";
|
||||
import { gitConnectSuccess, type GitConnectSuccessPayload } from "git";
|
||||
|
|
@ -530,7 +530,7 @@ export const handlers = {
|
|||
state: ApplicationsReduxState,
|
||||
action: ReduxAction<NavigationSetting["logoAssetId"]>,
|
||||
) => {
|
||||
return produce(state, (draftState: ApplicationsReduxState) => {
|
||||
return create(state, (draftState: ApplicationsReduxState) => {
|
||||
draftState.isUploadingNavigationLogo = false;
|
||||
|
||||
if (
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import { noop, set } from "lodash";
|
||||
|
||||
import { CommonControls } from "./CommonControls";
|
||||
|
|
@ -179,7 +179,7 @@ function WidgetQueryGeneratorForm(props: Props) {
|
|||
setPristine(false);
|
||||
|
||||
setConfig(
|
||||
produce(config, (draftConfig) => {
|
||||
create(config, (draftConfig) => {
|
||||
if (
|
||||
property === "datasource" ||
|
||||
(typeof property === "object" &&
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { ControlData, ControlProps } from "./BaseControl";
|
|||
import BaseControl from "./BaseControl";
|
||||
import type { ToggleGroupOption } from "@appsmith/ads";
|
||||
import { ToggleButtonGroup } from "@appsmith/ads";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import type { DSEventDetail } from "utils/AppsmithUtils";
|
||||
import {
|
||||
DSEventTypes,
|
||||
|
|
@ -62,7 +62,7 @@ class ButtonTabControl extends BaseControl<ButtonTabControlProps> {
|
|||
isUpdatedViaKeyboard,
|
||||
);
|
||||
} else {
|
||||
const updatedValues: string[] = produce(values, (draft: string[]) => {
|
||||
const updatedValues: string[] = create(values, (draft: string[]) => {
|
||||
draft.push(value);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -23,15 +23,12 @@ import "./assets/styles/index.css";
|
|||
import "./polyfills";
|
||||
import GlobalStyles from "globalStyles";
|
||||
// enable autofreeze only in development
|
||||
import { setAutoFreeze } from "immer";
|
||||
|
||||
import AppErrorBoundary from "./AppErrorBoundry";
|
||||
import log from "loglevel";
|
||||
import { FaroErrorBoundary } from "@grafana/faro-react";
|
||||
import { isTracingEnabled } from "instrumentation/utils";
|
||||
|
||||
const shouldAutoFreeze = process.env.NODE_ENV === "development";
|
||||
|
||||
setAutoFreeze(shouldAutoFreeze);
|
||||
runSagaMiddleware();
|
||||
|
||||
appInitializer();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import type {
|
|||
import { ToastMessageType } from "entities/Datasource";
|
||||
import { TEMP_DATASOURCE_ID } from "constants/Datasource";
|
||||
import type { DropdownOption } from "@appsmith/ads-old";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import { assign } from "lodash";
|
||||
|
||||
export interface DatasourceDataState {
|
||||
|
|
@ -466,7 +466,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
state: DatasourceDataState,
|
||||
action: ReduxAction<Datasource>,
|
||||
): DatasourceDataState => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.loading = false;
|
||||
draftState.list.forEach((datasource) => {
|
||||
if (datasource.id === action.payload.id) {
|
||||
|
|
@ -656,7 +656,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
[ReduxActionTypes.FETCH_GSHEET_SPREADSHEETS]: (
|
||||
state: DatasourceDataState,
|
||||
) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.isFetchingSpreadsheets = true;
|
||||
});
|
||||
},
|
||||
|
|
@ -664,7 +664,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
state: DatasourceDataState,
|
||||
action: ReduxAction<{ id: string; data: DropdownOption[] }>,
|
||||
) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.spreadsheets[action.payload.id] = {
|
||||
value: action.payload.data,
|
||||
};
|
||||
|
|
@ -676,7 +676,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
state: DatasourceDataState,
|
||||
action: ReduxAction<{ id: string; error: string }>,
|
||||
) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.spreadsheets[action.payload.id] = {
|
||||
error: action.payload.error,
|
||||
};
|
||||
|
|
@ -685,7 +685,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
});
|
||||
},
|
||||
[ReduxActionTypes.FETCH_GSHEET_SHEETS]: (state: DatasourceDataState) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.isFetchingSheets = true;
|
||||
});
|
||||
},
|
||||
|
|
@ -693,7 +693,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
state: DatasourceDataState,
|
||||
action: ReduxAction<{ id: string; data: DropdownOption[] }>,
|
||||
) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.sheets[action.payload.id] = {
|
||||
value: action.payload.data,
|
||||
};
|
||||
|
|
@ -704,7 +704,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
state: DatasourceDataState,
|
||||
action: ReduxAction<{ id: string; error: string }>,
|
||||
) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.sheets[action.payload.id] = {
|
||||
error: action.payload.error,
|
||||
};
|
||||
|
|
@ -712,7 +712,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
});
|
||||
},
|
||||
[ReduxActionTypes.FETCH_GSHEET_COLUMNS]: (state: DatasourceDataState) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.isFetchingColumns = true;
|
||||
});
|
||||
},
|
||||
|
|
@ -720,7 +720,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
state: DatasourceDataState,
|
||||
action: ReduxAction<{ id: string; data: DropdownOption[] }>,
|
||||
) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.columns[action.payload.id] = {
|
||||
value: action.payload.data,
|
||||
};
|
||||
|
|
@ -731,7 +731,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
state: DatasourceDataState,
|
||||
action: ReduxAction<{ id: string; error: string }>,
|
||||
) => {
|
||||
return produce(state, (draftState) => {
|
||||
return create(state, (draftState) => {
|
||||
draftState.gsheetStructure.columns[action.payload.id] = {
|
||||
error: action.payload.error,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
ReduxActionTypes,
|
||||
WidgetReduxActionTypes,
|
||||
} from "ee/constants/ReduxActionConstants";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import type { EvalMetaUpdates } from "ee/workers/common/DataTreeEvaluator/types";
|
||||
import {
|
||||
getMetaWidgetResetObj,
|
||||
|
|
@ -38,7 +38,7 @@ export const metaReducer = createReducer(initialState, {
|
|||
state: MetaState,
|
||||
action: ReduxAction<UpdateWidgetMetaPropertyPayload>,
|
||||
) => {
|
||||
const nextState = produce(state, (draftMetaState) => {
|
||||
const nextState = create(state, (draftMetaState) => {
|
||||
set(
|
||||
draftMetaState,
|
||||
`${action.payload.widgetId}.${action.payload.propertyName}`,
|
||||
|
|
@ -54,7 +54,7 @@ export const metaReducer = createReducer(initialState, {
|
|||
state: MetaState,
|
||||
action: ReduxAction<BatchUpdateWidgetMetaPropertyPayload>,
|
||||
) => {
|
||||
const nextState = produce(state, (draftMetaState) => {
|
||||
const nextState = create(state, (draftMetaState) => {
|
||||
const { batchMetaUpdates } = action.payload;
|
||||
|
||||
batchMetaUpdates.forEach(({ propertyName, propertyValue, widgetId }) => {
|
||||
|
|
@ -70,7 +70,7 @@ export const metaReducer = createReducer(initialState, {
|
|||
state: MetaState,
|
||||
action: ReduxAction<UpdateWidgetMetaPropertyPayload>,
|
||||
) => {
|
||||
const nextState = produce(state, (draftMetaState) => {
|
||||
const nextState = create(state, (draftMetaState) => {
|
||||
set(
|
||||
draftMetaState,
|
||||
`${action.payload.widgetId}.${action.payload.propertyName}`,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type {
|
|||
import type { MetaState, WidgetMetaState } from ".";
|
||||
import type { ReduxAction } from "actions/ReduxActionTypes";
|
||||
import type { EvalMetaUpdates } from "ee/workers/common/DataTreeEvaluator/types";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import { set, unset } from "lodash";
|
||||
import { klonaRegularWithTelemetry } from "utils/helpers";
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ export function getNextMetaStateWithUpdates(
|
|||
if (!evalMetaUpdates.length) return state;
|
||||
|
||||
// if metaObject is updated in dataTree we also update meta values, to keep meta state in sync.
|
||||
const newMetaState = produce(state, (draftMetaState) => {
|
||||
const newMetaState = create(state, (draftMetaState) => {
|
||||
evalMetaUpdates.forEach(({ metaPropertyPath, value, widgetId }) => {
|
||||
set(draftMetaState, [widgetId, ...metaPropertyPath], value);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import type { ReduxAction } from "actions/ReduxActionTypes";
|
||||
import { ReduxActionTypes } from "ee/constants/ReduxActionConstants";
|
||||
import { applyChange } from "deep-diff";
|
||||
import { applyChange, type Diff } from "deep-diff";
|
||||
import type { DataTree } from "entities/DataTree/dataTreeTypes";
|
||||
import { createImmerReducer } from "utils/ReducerUtils";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import type { DiffWithNewTreeState } from "workers/Evaluation/helpers";
|
||||
|
||||
export type EvaluatedTreeState = DataTree;
|
||||
|
||||
|
|
@ -15,7 +14,7 @@ const evaluatedTreeReducer = createImmerReducer(initialState, {
|
|||
state: EvaluatedTreeState,
|
||||
action: ReduxAction<{
|
||||
dataTree: DataTree;
|
||||
updates: DiffWithNewTreeState[];
|
||||
updates: Diff<DataTree, DataTree>[];
|
||||
removedPaths: [string];
|
||||
}>,
|
||||
) => {
|
||||
|
|
@ -27,15 +26,11 @@ const evaluatedTreeReducer = createImmerReducer(initialState, {
|
|||
|
||||
for (const update of updates) {
|
||||
try {
|
||||
if (update.kind === "newTree") {
|
||||
return update.rhs;
|
||||
} else {
|
||||
if (!update.path || update.path.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
applyChange(state, undefined, update);
|
||||
if (!update.path || update.path.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
applyChange(state, undefined, update);
|
||||
} catch (e) {
|
||||
Sentry.captureException(e, {
|
||||
extra: {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import {
|
|||
} from "constants/WidgetConstants";
|
||||
import { toast } from "@appsmith/ads";
|
||||
import type { DataTree } from "entities/DataTree/dataTreeTypes";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import { klona as clone } from "klona/full";
|
||||
import { getWidgetMinMaxDimensionsInPixel } from "layoutSystems/autolayout/utils/flexWidgetUtils";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
|
|
@ -112,7 +112,7 @@ function* getChildWidgetProps(
|
|||
// if (props) props.children = [];
|
||||
|
||||
if (props) {
|
||||
props = produce(props, (draft: WidgetProps) => {
|
||||
props = create(props, (draft) => {
|
||||
if (!draft.children || !Array.isArray(draft.children)) {
|
||||
draft.children = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ReduxAction } from "actions/ReduxActionTypes";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
|
||||
export const createReducer = (
|
||||
// TODO: Fix this the next time the file is edited
|
||||
|
|
@ -32,7 +32,19 @@ export const createImmerReducer = (
|
|||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return function reducer(state = initialState, action: ReduxAction<any>) {
|
||||
if (handlers.hasOwnProperty(action.type)) {
|
||||
return produce(handlers[action.type])(state, action);
|
||||
if (action?.payload?.updates) {
|
||||
const updates = action?.payload?.updates;
|
||||
|
||||
for (const update of updates) {
|
||||
if (update.kind === "newTree") {
|
||||
return update.rhs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const fn = handlers[action.type];
|
||||
|
||||
return create(state, (draft) => fn(draft, action));
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import log from "loglevel";
|
|||
import memoizeOne from "memoize-one";
|
||||
|
||||
import _, {
|
||||
cloneDeep,
|
||||
filter,
|
||||
isArray,
|
||||
isEmpty,
|
||||
|
|
@ -142,6 +141,7 @@ import IconSVG from "../icon.svg";
|
|||
import ThumbnailSVG from "../thumbnail.svg";
|
||||
import { klonaRegularWithTelemetry } from "utils/helpers";
|
||||
import HTMLCell from "../component/cellComponents/HTMLCell";
|
||||
import { objectKeys } from "@appsmith/utils";
|
||||
|
||||
const ReactTableComponent = lazy(async () =>
|
||||
retryPromise(async () => import("../component")),
|
||||
|
|
@ -928,16 +928,23 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
|
|||
* @rahulbarwal Remove this once we remove the feature flag
|
||||
*/
|
||||
if (!TableWidgetV2.getFeatureFlag(HTML_COLUMN_TYPE_ENABLED)) {
|
||||
const updatedPrimaryColumns = cloneDeep(this.props.primaryColumns);
|
||||
let hasHTMLColumns = false;
|
||||
const { primaryColumns } = this.props;
|
||||
|
||||
const updatedPrimaryColumns = objectKeys(primaryColumns).reduce(
|
||||
(acc, widgetId) => {
|
||||
const column = primaryColumns[widgetId];
|
||||
|
||||
Object.values(updatedPrimaryColumns).forEach(
|
||||
(column: ColumnProperties) => {
|
||||
if (column.columnType === ColumnTypes.HTML) {
|
||||
column.columnType = ColumnTypes.TEXT;
|
||||
acc[widgetId] = { ...column, columnType: ColumnTypes.TEXT };
|
||||
hasHTMLColumns = true;
|
||||
} else {
|
||||
acc[widgetId] = column;
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
{} as Record<string, ColumnProperties>,
|
||||
);
|
||||
|
||||
if (hasHTMLColumns) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { WidgetEntity } from "ee/entities/DataTree/types";
|
||||
import { applyChange } from "deep-diff";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import { klona } from "klona/full";
|
||||
import { range } from "lodash";
|
||||
import moment from "moment";
|
||||
|
|
@ -110,7 +110,7 @@ const oldState: dataTreeWithWidget = {
|
|||
describe("generateOptimisedUpdates", () => {
|
||||
describe("regular diff", () => {
|
||||
test("should not generate any diff when the constrainedDiffPaths is empty", () => {
|
||||
const newState = produce(oldState, (draft) => {
|
||||
const newState = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = 17;
|
||||
});
|
||||
const updates = generateOptimisedUpdates(oldState, newState, []);
|
||||
|
|
@ -119,7 +119,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
expect(updates).toEqual([]);
|
||||
});
|
||||
test("should not generate any diff when the constrainedDiffPaths nodes are the same ", () => {
|
||||
const newState = produce(oldState, (draft) => {
|
||||
const newState = create(oldState, (draft) => {
|
||||
//making an unrelated change
|
||||
draft.Table1.triggerRowSelection = true;
|
||||
});
|
||||
|
|
@ -131,7 +131,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
expect(updates).toEqual([]);
|
||||
});
|
||||
test("should generate regular diff updates when a simple property changes in the widget property segment", () => {
|
||||
const newState = produce(oldState, (draft) => {
|
||||
const newState = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = 17;
|
||||
});
|
||||
const updates = generateOptimisedUpdates(oldState, newState, [
|
||||
|
|
@ -145,7 +145,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
test("should generate regular diff updates when a simple property changes in the __evaluation__ segment ", () => {
|
||||
const validationError =
|
||||
"Some validation error" as unknown as EvaluationError[];
|
||||
const newState = produce(oldState, (draft) => {
|
||||
const newState = create(oldState, (draft) => {
|
||||
draft.Table1.__evaluation__.errors.tableData = validationError;
|
||||
});
|
||||
const updates = generateOptimisedUpdates(oldState, newState, [
|
||||
|
|
@ -162,7 +162,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
]);
|
||||
});
|
||||
test("should generate a replace collection patch when the size of the collection exceeds 100 instead of generating granular updates", () => {
|
||||
const newState = produce(oldState, (draft) => {
|
||||
const newState = create(oldState, (draft) => {
|
||||
draft.Table1.tableData = largeDataSet;
|
||||
});
|
||||
const updates = generateOptimisedUpdates(oldState, newState, [
|
||||
|
|
@ -179,10 +179,10 @@ describe("generateOptimisedUpdates", () => {
|
|||
});
|
||||
describe("undefined value updates in a collection", () => {
|
||||
test("should generate replace patch when a single node is set to undefined in a collection", () => {
|
||||
const statWithLargeCollection = produce(oldState, (draft) => {
|
||||
const statWithLargeCollection = create(oldState, (draft) => {
|
||||
draft.Table1.tableData = ["a", "b"];
|
||||
});
|
||||
const newStateWithAnElementDeleted = produce(
|
||||
const newStateWithAnElementDeleted = create(
|
||||
statWithLargeCollection,
|
||||
(draft) => {
|
||||
draft.Table1.tableData = ["a", undefined];
|
||||
|
|
@ -204,10 +204,10 @@ describe("generateOptimisedUpdates", () => {
|
|||
]);
|
||||
});
|
||||
test("should generate generate regular diff updates for non undefined updates in a collection", () => {
|
||||
const statWithLargeCollection = produce(oldState, (draft) => {
|
||||
const statWithLargeCollection = create(oldState, (draft) => {
|
||||
draft.Table1.tableData = ["a", "b"];
|
||||
});
|
||||
const newStateWithAnElementDeleted = produce(
|
||||
const newStateWithAnElementDeleted = create(
|
||||
statWithLargeCollection,
|
||||
(draft) => {
|
||||
draft.Table1.tableData = ["a", "e"];
|
||||
|
|
@ -244,7 +244,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
expect(serialisedUpdates).toEqual(JSON.stringify(additionalUpdates));
|
||||
});
|
||||
it("should ignore undefined updates", () => {
|
||||
const oldStateWithUndefinedValues = produce(oldState, (draft) => {
|
||||
const oldStateWithUndefinedValues = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = undefined;
|
||||
});
|
||||
|
||||
|
|
@ -260,7 +260,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
expect(serialisedUpdates).toEqual(JSON.stringify(additionalUpdates));
|
||||
});
|
||||
it("should generate a delete patch when a property is transformed to undefined", () => {
|
||||
const oldStateWithUndefinedValues = produce(oldState, (draft) => {
|
||||
const oldStateWithUndefinedValues = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = undefined;
|
||||
});
|
||||
|
||||
|
|
@ -281,7 +281,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
]);
|
||||
});
|
||||
it("should generate an error when there is a serialisation error", () => {
|
||||
const oldStateWithUndefinedValues = produce(oldState, (draft) => {
|
||||
const oldStateWithUndefinedValues = create(oldState, (draft) => {
|
||||
//generate a cyclical object
|
||||
draft.Table1.filteredTableData = draft.Table1;
|
||||
});
|
||||
|
|
@ -302,7 +302,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
const someEvalFn = (() => {}) as unknown as EvaluationError[];
|
||||
|
||||
it("should clean out new function properties added to the generated state", () => {
|
||||
const newStateWithSomeFnProperty = produce(oldState, (draft) => {
|
||||
const newStateWithSomeFnProperty = create(oldState, (draft) => {
|
||||
draft.Table1.someFn = () => {};
|
||||
draft.Table1.__evaluation__.errors.someEvalFn = someEvalFn;
|
||||
});
|
||||
|
|
@ -320,7 +320,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
//should delete all function updates
|
||||
expect(parsedUpdates).toEqual([]);
|
||||
|
||||
const parseAndApplyUpdatesToOldState = produce(oldState, (draft) => {
|
||||
const parseAndApplyUpdatesToOldState = create(oldState, (draft) => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
parsedUpdates.forEach((v: any) => {
|
||||
|
|
@ -333,7 +333,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
});
|
||||
|
||||
it("should delete properties which get updated to a function", () => {
|
||||
const newStateWithSomeFnProperty = produce(oldState, (draft) => {
|
||||
const newStateWithSomeFnProperty = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = () => {};
|
||||
draft.Table1.__evaluation__.errors.transientTableData = someEvalFn;
|
||||
});
|
||||
|
|
@ -362,14 +362,14 @@ describe("generateOptimisedUpdates", () => {
|
|||
},
|
||||
]);
|
||||
|
||||
const parseAndApplyUpdatesToOldState = produce(oldState, (draft) => {
|
||||
const parseAndApplyUpdatesToOldState = create(oldState, (draft) => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
parsedUpdates.forEach((v: any) => {
|
||||
applyChange(draft, undefined, v);
|
||||
});
|
||||
});
|
||||
const expectedState = produce(oldState, (draft) => {
|
||||
const expectedState = create(oldState, (draft) => {
|
||||
delete draft.Table1.pageSize;
|
||||
delete draft.Table1.__evaluation__.errors.transientTableData;
|
||||
});
|
||||
|
|
@ -377,14 +377,14 @@ describe("generateOptimisedUpdates", () => {
|
|||
expect(parseAndApplyUpdatesToOldState).toEqual(expectedState);
|
||||
});
|
||||
it("should delete function properties which get updated to undefined", () => {
|
||||
const oldStateWithSomeFnProperty = produce(oldState, (draft) => {
|
||||
const oldStateWithSomeFnProperty = create(oldState, (draft) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
draft.Table1.pageSize = () => {};
|
||||
draft.Table1.__evaluation__.errors.transientTableData =
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
someEvalFn;
|
||||
});
|
||||
const newStateWithFnsTransformedToUndefined = produce(
|
||||
const newStateWithFnsTransformedToUndefined = create(
|
||||
oldState,
|
||||
(draft) => {
|
||||
draft.Table1.pageSize = undefined;
|
||||
|
|
@ -417,14 +417,14 @@ describe("generateOptimisedUpdates", () => {
|
|||
},
|
||||
]);
|
||||
|
||||
const parseAndApplyUpdatesToOldState = produce(oldState, (draft) => {
|
||||
const parseAndApplyUpdatesToOldState = create(oldState, (draft) => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
parsedUpdates.forEach((v: any) => {
|
||||
applyChange(draft, undefined, v);
|
||||
});
|
||||
});
|
||||
const expectedState = produce(oldState, (draft) => {
|
||||
const expectedState = create(oldState, (draft) => {
|
||||
delete draft.Table1.pageSize;
|
||||
delete draft.Table1.__evaluation__.errors.transientTableData;
|
||||
});
|
||||
|
|
@ -443,7 +443,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
rhs: { someOtherKey: BigInt(3323232) },
|
||||
},
|
||||
];
|
||||
const newStateWithBigInt = produce(oldState, (draft) => {
|
||||
const newStateWithBigInt = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = someBigInt;
|
||||
});
|
||||
const { serialisedUpdates } = generateSerialisedUpdates(
|
||||
|
|
@ -472,14 +472,14 @@ describe("generateOptimisedUpdates", () => {
|
|||
},
|
||||
]);
|
||||
|
||||
const parseAndApplyUpdatesToOldState = produce(oldState, (draft) => {
|
||||
const parseAndApplyUpdatesToOldState = create(oldState, (draft) => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
parsedUpdates.forEach((v: any) => {
|
||||
applyChange(draft, undefined, v);
|
||||
});
|
||||
});
|
||||
const expectedState = produce(oldState, (draft) => {
|
||||
const expectedState = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = "121221";
|
||||
draft.Table1.someNewProp = { someOtherKey: "3323232" };
|
||||
});
|
||||
|
|
@ -488,7 +488,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
});
|
||||
describe("serialise momement updates directly", () => {
|
||||
test("should generate a null update when it sees an invalid moment object", () => {
|
||||
const newState = produce(oldState, (draft) => {
|
||||
const newState = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = moment("invalid value");
|
||||
});
|
||||
const { serialisedUpdates } = generateSerialisedUpdates(
|
||||
|
|
@ -504,7 +504,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
});
|
||||
test("should generate a regular update when it sees a valid moment object", () => {
|
||||
const validMoment = moment();
|
||||
const newState = produce(oldState, (draft) => {
|
||||
const newState = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = validMoment;
|
||||
});
|
||||
const { serialisedUpdates } = generateSerialisedUpdates(
|
||||
|
|
@ -529,7 +529,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
const parsedUpdates =
|
||||
parseUpdatesAndDeleteUndefinedUpdates(serialisedUpdates);
|
||||
|
||||
return produce(prevState, (draft) => {
|
||||
return create(prevState, (draft) => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
parsedUpdates.forEach((v: any) => {
|
||||
|
|
@ -552,7 +552,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
}
|
||||
|
||||
//attaching a collection to some property in the workerState
|
||||
workerStateWithCollection = produce(oldState, (draft) => {
|
||||
workerStateWithCollection = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = largeCollection;
|
||||
});
|
||||
//generate serialised diff updates
|
||||
|
|
@ -569,7 +569,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
oldState,
|
||||
);
|
||||
|
||||
const expectedMainThreadState = produce(oldState, (draft) => {
|
||||
const expectedMainThreadState = create(oldState, (draft) => {
|
||||
draft.Table1.pageSize = JSON.parse(JSON.stringify(largeCollection));
|
||||
});
|
||||
|
||||
|
|
@ -583,7 +583,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
test("update in a single moment value in a collection should always be serialised ", () => {
|
||||
const someNewDate = "2023-12-07T19:05:11.930Z";
|
||||
// updating a single value in the prev worker state
|
||||
const updatedWorkerStateWithASingleValue = produce(
|
||||
const updatedWorkerStateWithASingleValue = create(
|
||||
klona(workerStateWithCollection),
|
||||
(draft) => {
|
||||
draft.Table1.pageSize[0].c = moment(someNewDate);
|
||||
|
|
@ -613,7 +613,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
someNewDate,
|
||||
);
|
||||
|
||||
const expectedMainThreadState = produce(
|
||||
const expectedMainThreadState = create(
|
||||
mainThreadStateWithCollection,
|
||||
(draft) => {
|
||||
draft.Table1.pageSize[0].c = JSON.parse(
|
||||
|
|
@ -628,7 +628,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
//some garbage value
|
||||
const someNewDate = "fdfdfd";
|
||||
// updating a single value in the prev worker state
|
||||
const updatedWorkerStateWithASingleValue = produce(
|
||||
const updatedWorkerStateWithASingleValue = create(
|
||||
klona(workerStateWithCollection),
|
||||
(draft) => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
|
|
@ -658,7 +658,7 @@ describe("generateOptimisedUpdates", () => {
|
|||
// check if the main thread state has the updated invalid value which should be null
|
||||
expect(updatedMainThreadState.Table1.pageSize[0].c).toEqual(null);
|
||||
|
||||
const expectedMainThreadState = produce(
|
||||
const expectedMainThreadState = create(
|
||||
mainThreadStateWithCollection,
|
||||
(draft) => {
|
||||
draft.Table1.pageSize[0].c = JSON.parse(
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { RenderModes } from "constants/WidgetConstants";
|
|||
import { ENTITY_TYPE } from "ee/entities/DataTree/types";
|
||||
import type { ConfigTree } from "entities/DataTree/dataTreeTypes";
|
||||
import { generateDataTreeWidget } from "entities/DataTree/dataTreeWidget";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
import type { WidgetEntity } from "plugins/Linting/lib/entity/WidgetEntity";
|
||||
import type { UpdateDataTreeMessageData } from "sagas/EvalWorkerActionSagas";
|
||||
import DataTreeEvaluator from "workers/common/DataTreeEvaluator";
|
||||
|
|
@ -259,7 +259,7 @@ describe("evaluateAndGenerateResponse", () => {
|
|||
test("should generate updates based on the unEvalUpdates", () => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updatedLabelUnevalTree = produce(unEvalTree, (draft: any) => {
|
||||
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
||||
draft.Text1.text = UPDATED_LABEL;
|
||||
draft.Text1.label = UPDATED_LABEL;
|
||||
});
|
||||
|
|
@ -311,7 +311,7 @@ describe("evaluateAndGenerateResponse", () => {
|
|||
test("should generate updates based on the evalOrder", () => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updatedLabelUnevalTree = produce(unEvalTree, (draft: any) => {
|
||||
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
||||
draft.Text1.text = UPDATED_LABEL;
|
||||
});
|
||||
const updateTreeResponse = evaluator.setupUpdateTree(
|
||||
|
|
@ -346,7 +346,7 @@ describe("evaluateAndGenerateResponse", () => {
|
|||
test("should generate the correct updates to be sent to the main thread's state when the value tied to a binding changes ", () => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updatedLabelUnevalTree = produce(unEvalTree, (draft: any) => {
|
||||
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
||||
if (draft.Text1?.text) {
|
||||
draft.Text1.text = UPDATED_LABEL;
|
||||
}
|
||||
|
|
@ -386,7 +386,7 @@ describe("evaluateAndGenerateResponse", () => {
|
|||
test("should merge additional updates to the dataTree as well as push the updates back to the main thread's state when unEvalUpdates is ignored", () => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updatedLabelUnevalTree = produce(unEvalTree, (draft: any) => {
|
||||
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
||||
if (draft.Text1?.text) {
|
||||
draft.Text1.text = UPDATED_LABEL;
|
||||
}
|
||||
|
|
@ -426,7 +426,7 @@ describe("evaluateAndGenerateResponse", () => {
|
|||
test("should add metaUpdates in the webworker's response", () => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updatedLabelUnevalTree = produce(unEvalTree, (draft: any) => {
|
||||
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
||||
if (draft.Text1?.text) {
|
||||
draft.Text1.text = UPDATED_LABEL;
|
||||
}
|
||||
|
|
@ -456,7 +456,7 @@ describe("evaluateAndGenerateResponse", () => {
|
|||
test("should sanitise metaUpdates in the webworker's response and strip out non serialisable properties", () => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updatedLabelUnevalTree = produce(unEvalTree, (draft: any) => {
|
||||
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
||||
if (draft.Text1?.text) {
|
||||
draft.Text1.text = UPDATED_LABEL;
|
||||
}
|
||||
|
|
@ -495,7 +495,7 @@ describe("evaluateAndGenerateResponse", () => {
|
|||
test("should add unEvalUpdates to the web worker response", () => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updatedLabelUnevalTree = produce(unEvalTree, (draft: any) => {
|
||||
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
||||
if (draft.Text1?.text) {
|
||||
draft.Text1.text = UPDATED_LABEL;
|
||||
}
|
||||
|
|
@ -533,7 +533,7 @@ describe("evaluateAndGenerateResponse", () => {
|
|||
test("should ignore generating updates when unEvalUpdates is empty", () => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updatedLabelUnevalTree = produce(unEvalTree, (draft: any) => {
|
||||
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
||||
if (draft.Text1?.text) {
|
||||
draft.Text1.text = UPDATED_LABEL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
getAllPathsBasedOnDiffPaths,
|
||||
type DataTreeDiff,
|
||||
} from "ee/workers/Evaluation/evaluationUtils";
|
||||
import produce from "immer";
|
||||
import { create } from "mutative";
|
||||
|
||||
describe("getOnlyAffectedJSObjects", () => {
|
||||
const dataTree = {
|
||||
|
|
@ -170,7 +170,7 @@ describe("getAllPathsBasedOnDiffPaths", () => {
|
|||
expect(initialAllKeys).toEqual(updatedAllKeys);
|
||||
});
|
||||
test("should delete the correct paths within allKeys when a node within a widget is deleted", () => {
|
||||
const deletedWidgetName = produce(initialTree, (draft) => {
|
||||
const deletedWidgetName = create(initialTree, (draft) => {
|
||||
// a property within the widget is deleted
|
||||
delete draft.WidgetName.name;
|
||||
});
|
||||
|
|
@ -187,7 +187,7 @@ describe("getAllPathsBasedOnDiffPaths", () => {
|
|||
// we have to make a copy since allKeys is mutable
|
||||
{ ...initialAllKeys },
|
||||
);
|
||||
const deletedWidgetNameInAllKeys = produce(initialAllKeys, (draft) => {
|
||||
const deletedWidgetNameInAllKeys = create(initialAllKeys, (draft) => {
|
||||
delete draft["WidgetName.name"];
|
||||
});
|
||||
|
||||
|
|
@ -195,7 +195,7 @@ describe("getAllPathsBasedOnDiffPaths", () => {
|
|||
});
|
||||
|
||||
test("should add the correct paths to the allKeys when a node within a widget is added", () => {
|
||||
const addedNewWidgetProperty = produce(initialTree, (draft) => {
|
||||
const addedNewWidgetProperty = create(initialTree, (draft) => {
|
||||
// new property is added to the widget
|
||||
draft.WidgetName.widgetNewProperty = "newValue";
|
||||
});
|
||||
|
|
@ -213,7 +213,7 @@ describe("getAllPathsBasedOnDiffPaths", () => {
|
|||
// we have to make a copy since allKeys is mutable
|
||||
{ ...initialAllKeys },
|
||||
);
|
||||
const addedNewWidgetPropertyInAllKeys = produce(initialAllKeys, (draft) => {
|
||||
const addedNewWidgetPropertyInAllKeys = create(initialAllKeys, (draft) => {
|
||||
draft["WidgetName.widgetNewProperty"] = true;
|
||||
});
|
||||
|
||||
|
|
@ -221,7 +221,7 @@ describe("getAllPathsBasedOnDiffPaths", () => {
|
|||
});
|
||||
|
||||
test("should generate the correct paths when the value changes form a simple primitive to a collection, this is for EDIT diffs", () => {
|
||||
const addedNewWidgetProperty = produce(initialTree, (draft) => {
|
||||
const addedNewWidgetProperty = create(initialTree, (draft) => {
|
||||
//existing property within the widget is edited
|
||||
draft.WidgetName.name = [{ a: 1 }];
|
||||
});
|
||||
|
|
@ -239,7 +239,7 @@ describe("getAllPathsBasedOnDiffPaths", () => {
|
|||
// we have to make a copy since allKeys is mutable
|
||||
{ ...initialAllKeys },
|
||||
);
|
||||
const addedACollectionInAllKeys = produce(initialAllKeys, (draft) => {
|
||||
const addedACollectionInAllKeys = create(initialAllKeys, (draft) => {
|
||||
draft["WidgetName.name[0]"] = true;
|
||||
draft["WidgetName.name[0].a"] = true;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13338,6 +13338,7 @@ __metadata:
|
|||
moment: 2.29.4
|
||||
moment-timezone: ^0.5.35
|
||||
msw: ^0.28.0
|
||||
mutative: ^1.1.0
|
||||
nanoid: ^2.0.4
|
||||
node-forge: ^1.3.0
|
||||
object-hash: ^3.0.0
|
||||
|
|
@ -25747,6 +25748,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mutative@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "mutative@npm:1.1.0"
|
||||
checksum: 5eaf505a97c713ecb45bdadfe905045692414ff6f08e35d9cad0e6e27d9005a06e9696350c23bff70d39488973841384ed01d800d67f8b2957c7a1daf3d24d3c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mute-stream@npm:0.0.8":
|
||||
version: 0.0.8
|
||||
resolution: "mute-stream@npm:0.0.8"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user