@remote-ui/core
Advanced tools
Comparing version 2.2.4 to 2.2.5
@@ -99,2 +99,7 @@ 'use strict'; | ||
const [removed] = children.splice(index, 1); | ||
if (!removed) { | ||
return; | ||
} | ||
attached.version += 1; | ||
@@ -101,0 +106,0 @@ detach(removed); // eslint-disable-next-line promise/catch-or-return |
@@ -403,5 +403,4 @@ 'use strict'; | ||
seen.add(currentValue); | ||
if (typeof currentValue === 'function' && FUNCTION_CURRENT_IMPLEMENTATION_KEY in currentValue) { | ||
seen.add(currentValue); | ||
const result = [typeof newValue === 'function' ? IGNORE : makeValueHotSwappable(newValue), [[currentValue, newValue]]]; | ||
@@ -412,2 +411,3 @@ return result; | ||
if (Array.isArray(currentValue)) { | ||
seen.add(currentValue); | ||
const result = tryHotSwappingArrayValues(currentValue, newValue, seen); | ||
@@ -418,2 +418,3 @@ return result; | ||
if (rpc.isBasicObject(currentValue) && !utilities.isRemoteFragment(currentValue)) { | ||
seen.add(currentValue); | ||
const result = tryHotSwappingObjectValues(currentValue, newValue, seen); | ||
@@ -473,3 +474,2 @@ return result; | ||
seen.set(value, value); | ||
return value; | ||
@@ -579,4 +579,10 @@ } | ||
} = rootInternals; | ||
const childIndex = container.children.indexOf(child); | ||
if (childIndex === -1) { | ||
return undefined; | ||
} | ||
return perform(container, rootInternals, { | ||
remote: channel => channel(types.ACTION_REMOVE_CHILD, container.id, container.children.indexOf(child)), | ||
remote: channel => channel(types.ACTION_REMOVE_CHILD, container.id, childIndex), | ||
local: () => { | ||
@@ -583,0 +589,0 @@ removeNodeFromContainer(child, rootInternals); |
# Changelog | ||
## 2.2.5 | ||
### Patch Changes | ||
- [#522](https://github.com/Shopify/remote-dom/pull/522) [`0ade5f7`](https://github.com/Shopify/remote-dom/commit/0ade5f74ad96bdb2b8513b2b18c0b9298717e672) Thanks [@thomas-marcucci](https://github.com/thomas-marcucci)! - Fixes an issue when removeChild does not find a child node | ||
## 2.2.4 | ||
@@ -4,0 +10,0 @@ |
{ | ||
"name": "@remote-ui/core", | ||
"version": "2.2.4", | ||
"version": "2.2.5", | ||
"publishConfig": { | ||
@@ -5,0 +5,0 @@ "access": "public", |
@@ -205,4 +205,6 @@ import {retain, release} from '@remote-ui/rpc'; | ||
const {children} = attached; | ||
const [removed] = children.splice(index, 1); | ||
if (!removed) { | ||
return; | ||
} | ||
attached.version += 1; | ||
@@ -209,0 +211,0 @@ |
@@ -614,4 +614,2 @@ import type {RemoteComponentType} from '@remote-ui/types'; | ||
seen.add(currentValue); | ||
if ( | ||
@@ -621,2 +619,3 @@ typeof currentValue === 'function' && | ||
) { | ||
seen.add(currentValue); | ||
const result: HotSwapResult = [ | ||
@@ -631,2 +630,3 @@ typeof newValue === 'function' ? IGNORE : makeValueHotSwappable(newValue), | ||
if (Array.isArray(currentValue)) { | ||
seen.add(currentValue); | ||
const result = tryHotSwappingArrayValues(currentValue, newValue, seen); | ||
@@ -638,2 +638,3 @@ | ||
if (isBasicObject(currentValue) && !isRemoteFragment(currentValue)) { | ||
seen.add(currentValue); | ||
const result = tryHotSwappingObjectValues(currentValue, newValue, seen); | ||
@@ -704,4 +705,2 @@ | ||
seen.set(value, value); | ||
return value; | ||
@@ -850,12 +849,12 @@ } | ||
const childIndex = container.children.indexOf(child as any); | ||
if (childIndex === -1) { | ||
return undefined; | ||
} | ||
return perform(container, rootInternals, { | ||
remote: (channel) => | ||
channel( | ||
ACTION_REMOVE_CHILD, | ||
(container as any).id, | ||
container.children.indexOf(child as any), | ||
), | ||
channel(ACTION_REMOVE_CHILD, (container as any).id, childIndex), | ||
local: () => { | ||
removeNodeFromContainer(child, rootInternals); | ||
const newChildren = [...internals.children]; | ||
@@ -862,0 +861,0 @@ newChildren.splice(newChildren.indexOf(child), 1); |
import {createRemoteReceiver} from '../receiver'; | ||
import {ACTION_MOUNT} from '../types'; | ||
import { | ||
ACTION_MOUNT, | ||
ACTION_INSERT_CHILD, | ||
ACTION_REMOVE_CHILD, | ||
KIND_COMPONENT, | ||
} from '../types'; | ||
@@ -17,2 +22,51 @@ describe('createRemoteReceiver()', () => { | ||
}); | ||
describe('removeChild', () => { | ||
it('removes a given child node', () => { | ||
const receiver = createRemoteReceiver(); | ||
receiver.receive(ACTION_MOUNT, [ | ||
{ | ||
id: 'child1', | ||
children: [], | ||
kind: KIND_COMPONENT, | ||
props: {}, | ||
type: '', | ||
}, | ||
]); | ||
expect(receiver.attached.root.children).toHaveLength(1); | ||
expect(receiver.attached.root.children[0].id).toBe('child1'); | ||
receiver.receive( | ||
ACTION_INSERT_CHILD, | ||
undefined, | ||
0, | ||
{ | ||
id: 'child2', | ||
children: [], | ||
kind: KIND_COMPONENT, | ||
props: {}, | ||
type: '', | ||
}, | ||
'child2', | ||
); | ||
expect(receiver.attached.root.children).toHaveLength(2); | ||
expect(receiver.attached.root.children[0].id).toBe('child2'); | ||
expect(receiver.attached.root.children[1].id).toBe('child1'); | ||
receiver.receive(ACTION_REMOVE_CHILD, undefined, 0); | ||
expect(receiver.attached.root.children).toHaveLength(1); | ||
expect(receiver.attached.root.children[0].id).toBe('child1'); | ||
}); | ||
it('handles a missing child', () => { | ||
const receiver = createRemoteReceiver(); | ||
receiver.receive(ACTION_MOUNT, []); | ||
receiver.receive(ACTION_REMOVE_CHILD, undefined, -1); | ||
expect(receiver.attached.root.children).toHaveLength(0); | ||
}); | ||
}); | ||
}); |
@@ -128,2 +128,17 @@ import {createRemoteRoot} from '../root'; | ||
describe('removeChild', () => { | ||
it('does not call channel when child is not found', () => { | ||
const channelMock = jest.fn(); | ||
const root = createRemoteRoot(channelMock); | ||
root.mount(); | ||
// clear channel call from mount | ||
channelMock.mockClear(); | ||
const card = root.createComponent('Card'); | ||
root.removeChild(card); | ||
expect(channelMock).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
describe('hot-swapping', () => { | ||
@@ -330,2 +345,58 @@ it('hot-swaps function props', () => { | ||
}); | ||
it('hot-swaps arrays of primitive values', () => { | ||
const receiver = createDelayedReceiver(); | ||
const root = createRemoteRoot(receiver.receive); | ||
const component = root.createComponent('MyComponent', { | ||
array1: [1, 2, 3, 4], | ||
array2: [1, 2, 3, 4], | ||
}); | ||
root.append(component); | ||
root.mount(); | ||
component.updateProps({ | ||
array1: [1, 2, 3, 4], | ||
array2: [1, 3, 4], | ||
}); | ||
receiver.flush(); | ||
const {array2} = (receiver.children[0] as any).props; | ||
expect(array2).toStrictEqual([1, 3, 4]); | ||
}); | ||
it('hot-swaps arrays of primitive values nested in objects and arrays', () => { | ||
const receiver = createDelayedReceiver(); | ||
const root = createRemoteRoot(receiver.receive); | ||
const component = root.createComponent('MyComponent', { | ||
arrays: [ | ||
{ | ||
array1: [1, 2, 3, 4], | ||
array2: [1, 2, 3, 4], | ||
}, | ||
], | ||
}); | ||
root.append(component); | ||
root.mount(); | ||
component.updateProps({ | ||
arrays: [ | ||
{ | ||
array1: [1, 2, 3, 4], | ||
array2: [1, 3, 4], | ||
}, | ||
], | ||
}); | ||
receiver.flush(); | ||
const {arrays} = (receiver.children[0] as any).props; | ||
expect(arrays[0].array2).toStrictEqual(expect.arrayContaining([1, 3, 4])); | ||
}); | ||
}); | ||
@@ -332,0 +403,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
280791
4600