Aggressively optimise client library to prevent handlebars enrichment where possible
This commit is contained in:
parent
83a337e20e
commit
be2ec9b427
|
@ -23,6 +23,11 @@
|
|||
// props with old ones, depending on how long enrichment takes.
|
||||
let latestUpdateTime
|
||||
|
||||
// Keep track of stringified representations of context and instance
|
||||
// to avoid enriching bindings as much as possible
|
||||
let lastContextKey
|
||||
let lastInstanceKey
|
||||
|
||||
// Get contexts
|
||||
const context = getContext("context")
|
||||
const insideScreenslot = !!getContext("screenslot")
|
||||
|
@ -42,7 +47,9 @@
|
|||
definition?.hasChildren &&
|
||||
definition?.showEmptyState !== false &&
|
||||
$builderStore.inBuilder
|
||||
$: updateComponentProps(instance, $context)
|
||||
$: rawProps = getRawProps(instance)
|
||||
$: instanceKey = JSON.stringify(rawProps)
|
||||
$: updateComponentProps(rawProps, instanceKey, $context)
|
||||
$: selected =
|
||||
$builderStore.inBuilder &&
|
||||
$builderStore.selectedComponentId === instance._id
|
||||
|
@ -59,6 +66,16 @@
|
|||
name,
|
||||
})
|
||||
|
||||
const getRawProps = instance => {
|
||||
let validProps = {}
|
||||
Object.entries(instance)
|
||||
.filter(([name]) => !name.startsWith("_"))
|
||||
.forEach(([key, value]) => {
|
||||
validProps[key] = value
|
||||
})
|
||||
return validProps
|
||||
}
|
||||
|
||||
// Gets the component constructor for the specified component
|
||||
const getComponentConstructor = component => {
|
||||
const split = component?.split("/")
|
||||
|
@ -76,13 +93,23 @@
|
|||
}
|
||||
|
||||
// Enriches any string component props using handlebars
|
||||
const updateComponentProps = (instance, context) => {
|
||||
const updateComponentProps = (rawProps, instanceKey, context) => {
|
||||
const instanceSame = instanceKey === lastInstanceKey
|
||||
const contextSame = context.key === lastContextKey
|
||||
|
||||
if (instanceSame && contextSame) {
|
||||
return
|
||||
} else {
|
||||
lastInstanceKey = instanceKey
|
||||
lastContextKey = context.key
|
||||
}
|
||||
|
||||
// Record the timestamp so we can reference it after enrichment
|
||||
latestUpdateTime = Date.now()
|
||||
const enrichmentTime = latestUpdateTime
|
||||
|
||||
// Enrich props with context
|
||||
const enrichedProps = enrichProps(instance, context)
|
||||
const enrichedProps = enrichProps(rawProps, context)
|
||||
|
||||
// Abandon this update if a newer update has started
|
||||
if (enrichmentTime !== latestUpdateTime) {
|
||||
|
|
|
@ -14,18 +14,32 @@
|
|||
const newContext = createContextStore(context)
|
||||
setContext("context", newContext)
|
||||
|
||||
$: providerKey = key || $component.id
|
||||
const providerKey = key || $component.id
|
||||
|
||||
// Add data context
|
||||
$: newContext.actions.provideData(providerKey, data)
|
||||
// Generate a permanent unique ID for this component and use it to register
|
||||
// any datasource actions
|
||||
const instanceId = generate()
|
||||
|
||||
// Instance ID is unique to each instance of a provider
|
||||
let instanceId
|
||||
// Keep previous state around so we can avoid updating unless necessary
|
||||
let lastDataKey
|
||||
let lastActionsKey
|
||||
|
||||
// Add actions context
|
||||
$: {
|
||||
if (instanceId) {
|
||||
actions?.forEach(({ type, callback, metadata }) => {
|
||||
$: provideData(data)
|
||||
$: provideActions(actions, instanceId)
|
||||
|
||||
const provideData = newData => {
|
||||
const dataKey = JSON.stringify(newData)
|
||||
if (dataKey !== lastDataKey) {
|
||||
newContext.actions.provideData(providerKey, newData)
|
||||
lastDataKey = dataKey
|
||||
}
|
||||
}
|
||||
|
||||
const provideActions = newActions => {
|
||||
const actionsKey = JSON.stringify(newActions)
|
||||
if (actionsKey !== lastActionsKey) {
|
||||
lastActionsKey = actionsKey
|
||||
newActions?.forEach(({ type, callback, metadata }) => {
|
||||
newContext.actions.provideAction(providerKey, type, callback)
|
||||
|
||||
// Register any "refresh datasource" actions with a singleton store
|
||||
|
@ -43,10 +57,6 @@
|
|||
}
|
||||
|
||||
onMount(() => {
|
||||
// Generate a permanent unique ID for this component and use it to register
|
||||
// any datasource actions
|
||||
instanceId = generate()
|
||||
|
||||
// Unregister all datasource instances when unmounting this provider
|
||||
return () => dataSourceStore.actions.unregisterInstance(instanceId)
|
||||
})
|
||||
|
|
|
@ -4,7 +4,21 @@ export const createContextStore = oldContext => {
|
|||
const newContext = writable({})
|
||||
const contexts = oldContext ? [oldContext, newContext] : [newContext]
|
||||
const totalContext = derived(contexts, $contexts => {
|
||||
return $contexts.reduce((total, context) => ({ ...total, ...context }), {})
|
||||
// The key is the serialized representation of context
|
||||
let key = ""
|
||||
for (let i = 0; i < $contexts.length - 1; i++) {
|
||||
key += $contexts[i].key
|
||||
}
|
||||
key += JSON.stringify($contexts[$contexts.length - 1])
|
||||
|
||||
// Reduce global state
|
||||
const reducer = (total, context) => ({ ...total, ...context })
|
||||
const context = $contexts.reduce(reducer, {})
|
||||
|
||||
return {
|
||||
...context,
|
||||
key,
|
||||
}
|
||||
})
|
||||
|
||||
// Adds a data context layer to the tree
|
||||
|
|
|
@ -22,14 +22,6 @@ export const propsAreSame = (a, b) => {
|
|||
* Data bindings are enriched, and button actions are enriched.
|
||||
*/
|
||||
export const enrichProps = (props, context) => {
|
||||
// Exclude all private props that start with an underscore
|
||||
let validProps = {}
|
||||
Object.entries(props)
|
||||
.filter(([name]) => !name.startsWith("_"))
|
||||
.forEach(([key, value]) => {
|
||||
validProps[key] = value
|
||||
})
|
||||
|
||||
// Create context of all bindings and data contexts
|
||||
// Duplicate the closest context as "data" which the builder requires
|
||||
const totalContext = {
|
||||
|
@ -41,7 +33,7 @@ export const enrichProps = (props, context) => {
|
|||
}
|
||||
|
||||
// Enrich all data bindings in top level props
|
||||
let enrichedProps = enrichDataBindings(validProps, totalContext)
|
||||
let enrichedProps = enrichDataBindings(props, totalContext)
|
||||
|
||||
// Enrich click actions if they exist
|
||||
if (enrichedProps.onClick) {
|
||||
|
|
Loading…
Reference in New Issue