Props working properly now (though solution is half mutable)

This commit is contained in:
josdejong 2020-04-27 11:26:17 +02:00
parent 80c7b2814f
commit cf027db855
4 changed files with 93 additions and 50 deletions

View File

@ -8,33 +8,33 @@
export let searchText = ''
let json = {
'array': [1, 2, 3, {
name: 'Item ' + 2,
id: String(2),
index: 2,
time: new Date().toISOString(),
location: {
latitude: 1.23,
longitude: 23.44,
coordinates: [23.44, 1.23]
},
}],
// 'array': [1, 2, 3, {
// name: 'Item ' + 2,
// id: String(2),
// index: 2,
// time: new Date().toISOString(),
// location: {
// latitude: 1.23,
// longitude: 23.44,
// coordinates: [23.44, 1.23]
// },
// }],
'boolean': true,
'color': '#82b92c',
'null': null,
'number': 123,
'object': {'a': 'b', 'c': 'd', nested: {
name: 'Item ' + 2,
id: String(2),
index: 2,
time: new Date().toISOString(),
location: {
latitude: 1.23,
longitude: 23.44,
coordinates: [23.44, 1.23]
},
}},
'string': 'Hello World'
// 'object': {'a': 'b', 'c': 'd', nested: {
// name: 'Item ' + 2,
// id: String(2),
// index: 2,
// time: new Date().toISOString(),
// location: {
// latitude: 1.23,
// longitude: 23.44,
// coordinates: [23.44, 1.23]
// },
// }},
// 'string': 'Hello World'
}
let uniDirectionalValue = 'test uni directional flow in Svelte';

View File

@ -4,9 +4,8 @@
import { SEARCH_PROPERTY, SEARCH_VALUE } from './search'
import classnames from 'classnames'
import { isUrl, valueType } from './utils/typeUtils'
import { escapeHTML } from './utils/stringUtils'
import uniqueId from 'lodash/uniqueId.js'
import remove from 'lodash/remove.js'
import { escapeHTML } from './utils/stringUtils.js'
import { createUpdateProps } from './utils/updateProps.js'
export let key = 'root'
export let value
@ -18,32 +17,18 @@
const DEFAULT_LIMIT = 10000
const escapeUnicode = false // TODO: pass via options
// create lazy, memoized updateProps function
let updateProps = function lazyUpdateProps (value) {
updateProps = createUpdateProps()
return updateProps(value)
}
let limit = DEFAULT_LIMIT
$: type = valueType (value)
function getOrCreateId (childKey) {
if (ids === undefined) {
ids = {}
}
if (ids[childKey] === undefined) {
ids[childKey] = uniqueId()
}
return ids[childKey]
}
// FIXME: this should not be needed, use Svelte notation for looping over an object
let ids = undefined
$: props = type === 'object'
? Object.keys(value).map(childKey => {
return {
id: getOrCreateId(childKey),
key: childKey
}
})
? updateProps(value)
: undefined
$: limited = type === 'array' && value.length > limit
@ -88,9 +73,10 @@
}
})
if (ids !== undefined) {
ids[newChildKey] = ids[oldChildKey]
delete ids[oldChildKey]
const index = props.findIndex(item => item.key === oldChildKey)
if (index !== -1) {
// FIXME: make immutable (not possible as long as prevProps is stored in updateProps
props[index].key = newChildKey
}
onChangeValue(updatedValue, key)

37
src/utils/updateProps.js Normal file
View File

@ -0,0 +1,37 @@
import { isObject } from './typeUtils.js'
import uniqueId from 'lodash/uniqueId.js'
export function createUpdateProps () {
let prevProps = undefined
return function updateProps (value) {
// TODO: optimize. check if value is the same as prevValue, if so, don't do anything
if (isObject(value)) {
const props = prevProps
? prevProps.filter(item => value[item.key] !== undefined) // copy the props that still exist
: []
// process added props
const prevKeys = new Set(props.map(item => item.key)) // TODO: this is inefficient, creating a set. cache this set?
console.log('updateProps', { value, prevProps, props})
Object.keys(value).forEach(key => {
if (!prevKeys.has(key)) {
console.log('add key', key)
props.push({
id: uniqueId(),
key
})
}
})
prevProps = props
return props
} else {
prevProps = undefined
return undefined
}
}
}

View File

@ -0,0 +1,20 @@
import { createUpdateProps } from './updateProps.js'
import { expect } from './testUtils.js' // FIXME: replace jest with mocha tests, or move to jest
const test = it // TODO: replace jest with mocha tests, or move to jest
test('updateProps (1)', () => {
const updateProps = createUpdateProps()
expect(updateProps({b: 2}).map(item => item.key)).toEqual(['b'])
const result2 = updateProps({a: 1, b: 2})
expect(result2.map(item => item.key)).toEqual(['b', 'a'])
expect(result2[0].id).toEqual('1')
})
test('updateProps (2)', () => {
const updateProps = createUpdateProps()
const result1 = updateProps({a: 1, b: 2})
expect(updateProps({a: 1, b: 2})).toEqual(result1)
})