diff --git a/packages/devtools-kit/src/core/component/state/__test__/editor.test.ts b/packages/devtools-kit/src/core/component/state/__test__/editor.test.ts new file mode 100644 index 00000000..23973dcc --- /dev/null +++ b/packages/devtools-kit/src/core/component/state/__test__/editor.test.ts @@ -0,0 +1,24 @@ +import { RefStateEditor } from '../editor' + +describe('editor: RefStateEditor', () => { + const editor = new RefStateEditor() + + // eslint-disable-next-line test/consistent-test-it + test.each([ + // Add new key. + { refValue: { foo: 'bar' }, newValue: { foo: 'bar', bar: 'baz' } }, + // Add new key and modify origin value. + { refValue: { foo: 'bar' }, newValue: { foo: 'barr', bar: 'baz' } }, + // Modify origin value. + { refValue: { foo: 'bar' }, newValue: { foo: 'barr' } }, + // Remove key. + { refValue: { foo: 'bar' }, newValue: {} }, + // Remove key and modify origin value. + { refValue: { foo: 'bar' }, newValue: { foo: 'barr' } }, + // Remove key and add new key. + { refValue: { foo: 'bar' }, newValue: { bar: 'baz' } }, + ])('$refValue can be modified to $newValue by RefStateEditor.set', ({ refValue, newValue }) => { + editor.set(refValue as any, newValue) + expect(refValue).toEqual(newValue) + }) +}) diff --git a/packages/devtools-kit/src/core/component/state/editor.ts b/packages/devtools-kit/src/core/component/state/editor.ts index 4caea901..05fbc1a6 100644 --- a/packages/devtools-kit/src/core/component/state/editor.ts +++ b/packages/devtools-kit/src/core/component/state/editor.ts @@ -95,7 +95,7 @@ export class StateEditor { } } -class RefStateEditor { +export class RefStateEditor { set(ref: Ref, value: any): void { if (isRef(ref)) { ref.value = value @@ -103,18 +103,15 @@ class RefStateEditor { else { // if is reactive, then it must be object // to prevent loss reactivity, we should assign key by key - const previousKeys = Object.keys(ref) + const previousKeysSet = new Set(Object.keys(ref)) const currentKeys = Object.keys(value) // we should check the key diffs, if previous key is the longer // then remove the needless keys - // @TODO: performance optimization - if (previousKeys.length > currentKeys.length) { - const diffKeys = previousKeys.filter(key => !currentKeys.includes(key)) - diffKeys.forEach(key => Reflect.deleteProperty(ref, key)) - } currentKeys.forEach((key) => { Reflect.set(ref, key, Reflect.get(value, key)) + previousKeysSet.delete(key) }) + previousKeysSet.forEach(key => Reflect.deleteProperty(ref, key)) } }