Make all blindings global and improve client component performance
This commit is contained in:
parent
a896a75f8f
commit
d03f96ceb8
|
@ -199,15 +199,7 @@ export const getContextProviderComponents = (
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the component tree leading up to this component, ignoring the component
|
return findAllMatchingComponents(asset.props, component => {
|
||||||
// itself
|
|
||||||
const path = findComponentPath(asset.props, componentId)
|
|
||||||
if (!options?.includeSelf) {
|
|
||||||
path.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter by only data provider components
|
|
||||||
return path.filter(component => {
|
|
||||||
const def = store.actions.components.getDefinition(component._component)
|
const def = store.actions.components.getDefinition(component._component)
|
||||||
if (!def?.context) {
|
if (!def?.context) {
|
||||||
return false
|
return false
|
||||||
|
@ -222,6 +214,30 @@ export const getContextProviderComponents = (
|
||||||
const contexts = Array.isArray(def.context) ? def.context : [def.context]
|
const contexts = Array.isArray(def.context) ? def.context : [def.context]
|
||||||
return contexts.find(context => context.type === type) != null
|
return contexts.find(context => context.type === type) != null
|
||||||
})
|
})
|
||||||
|
//
|
||||||
|
// // Get the component tree leading up to this component, ignoring the component
|
||||||
|
// // itself
|
||||||
|
// const path = findComponentPath(asset.props, componentId)
|
||||||
|
// if (!options?.includeSelf) {
|
||||||
|
// path.pop()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Filter by only data provider components
|
||||||
|
// return path.filter(component => {
|
||||||
|
// const def = store.actions.components.getDefinition(component._component)
|
||||||
|
// if (!def?.context) {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // If no type specified, return anything that exposes context
|
||||||
|
// if (!type) {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Otherwise only match components with the specific context type
|
||||||
|
// const contexts = Array.isArray(def.context) ? def.context : [def.context]
|
||||||
|
// return contexts.find(context => context.type === type) != null
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -621,10 +621,9 @@ export const getFrontendStore = () => {
|
||||||
else {
|
else {
|
||||||
if (setting.type === "dataProvider") {
|
if (setting.type === "dataProvider") {
|
||||||
// Validate data provider exists, or else clear it
|
// Validate data provider exists, or else clear it
|
||||||
const treeId = parent?._id || component._id
|
const providers = findAllMatchingComponents(
|
||||||
const path = findComponentPath(screen?.props, treeId)
|
screen?.props,
|
||||||
const providers = path.filter(component =>
|
component => component._component?.endsWith("/dataprovider")
|
||||||
component._component?.endsWith("/dataprovider")
|
|
||||||
)
|
)
|
||||||
// Validate non-empty values
|
// Validate non-empty values
|
||||||
const valid = providers?.some(dp => value.includes?.(dp._id))
|
const valid = providers?.some(dp => value.includes?.(dp._id))
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
<script>
|
<script>
|
||||||
import { Select } from "@budibase/bbui"
|
import { Select } from "@budibase/bbui"
|
||||||
import { makePropSafe } from "@budibase/string-templates"
|
import { makePropSafe } from "@budibase/string-templates"
|
||||||
import { currentAsset, store } from "builderStore"
|
import { currentAsset } from "builderStore"
|
||||||
import { findComponentPath } from "builderStore/componentUtils"
|
import { findAllMatchingComponents } from "builderStore/componentUtils"
|
||||||
|
|
||||||
export let value
|
export let value
|
||||||
|
|
||||||
const getValue = component => `{{ literal ${makePropSafe(component._id)} }}`
|
const getValue = component => `{{ literal ${makePropSafe(component._id)} }}`
|
||||||
|
|
||||||
$: path = findComponentPath($currentAsset?.props, $store.selectedComponentId)
|
$: providers = findAllMatchingComponents($currentAsset?.props, c =>
|
||||||
$: providers = path.filter(c => c._component?.endsWith("/dataprovider"))
|
c._component?.endsWith("/dataprovider")
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
|
|
|
@ -394,7 +394,6 @@
|
||||||
"description": "A configurable data list that attaches to your backend tables.",
|
"description": "A configurable data list that attaches to your backend tables.",
|
||||||
"icon": "JourneyData",
|
"icon": "JourneyData",
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"hasChildren": true,
|
"hasChildren": true,
|
||||||
"size": {
|
"size": {
|
||||||
"width": 400,
|
"width": 400,
|
||||||
|
@ -1385,7 +1384,6 @@
|
||||||
"name": "Bar Chart",
|
"name": "Bar Chart",
|
||||||
"description": "Bar chart",
|
"description": "Bar chart",
|
||||||
"icon": "GraphBarVertical",
|
"icon": "GraphBarVertical",
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"size": {
|
"size": {
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 400
|
"height": 400
|
||||||
|
@ -1548,7 +1546,6 @@
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 400
|
"height": 400
|
||||||
},
|
},
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
@ -1702,7 +1699,6 @@
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 400
|
"height": 400
|
||||||
},
|
},
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
@ -1868,7 +1864,6 @@
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 400
|
"height": 400
|
||||||
},
|
},
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
@ -1998,7 +1993,6 @@
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 400
|
"height": 400
|
||||||
},
|
},
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
@ -2128,7 +2122,6 @@
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 400
|
"height": 400
|
||||||
},
|
},
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
@ -3177,7 +3170,6 @@
|
||||||
"width": 400,
|
"width": 400,
|
||||||
"height": 320
|
"height": 320
|
||||||
},
|
},
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "dataProvider",
|
"type": "dataProvider",
|
||||||
|
@ -3601,7 +3593,6 @@
|
||||||
"name": "Table",
|
"name": "Table",
|
||||||
"icon": "Table",
|
"icon": "Table",
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"hasChildren": true,
|
"hasChildren": true,
|
||||||
"showEmptyState": false,
|
"showEmptyState": false,
|
||||||
"size": {
|
"size": {
|
||||||
|
@ -3692,7 +3683,6 @@
|
||||||
"name": "Date Range",
|
"name": "Date Range",
|
||||||
"icon": "Calendar",
|
"icon": "Calendar",
|
||||||
"styles": ["size"],
|
"styles": ["size"],
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"hasChildren": false,
|
"hasChildren": false,
|
||||||
"size": {
|
"size": {
|
||||||
"width": 200,
|
"width": 200,
|
||||||
|
@ -3800,7 +3790,6 @@
|
||||||
"width": 100,
|
"width": 100,
|
||||||
"height": 35
|
"height": 35
|
||||||
},
|
},
|
||||||
"requiredAncestors": ["dataprovider"],
|
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "dataProvider",
|
"type": "dataProvider",
|
||||||
|
|
|
@ -30,6 +30,11 @@
|
||||||
import ScreenPlaceholder from "components/app/ScreenPlaceholder.svelte"
|
import ScreenPlaceholder from "components/app/ScreenPlaceholder.svelte"
|
||||||
import ComponentErrorState from "components/error-states/ComponentErrorState.svelte"
|
import ComponentErrorState from "components/error-states/ComponentErrorState.svelte"
|
||||||
import { BudibasePrefix } from "../stores/components.js"
|
import { BudibasePrefix } from "../stores/components.js"
|
||||||
|
import {
|
||||||
|
decodeJSBinding,
|
||||||
|
findHBSBlocks,
|
||||||
|
isJSBinding,
|
||||||
|
} from "@budibase/string-templates"
|
||||||
|
|
||||||
export let instance = {}
|
export let instance = {}
|
||||||
export let isLayout = false
|
export let isLayout = false
|
||||||
|
@ -98,6 +103,13 @@
|
||||||
// We clear these whenever a new instance is received.
|
// We clear these whenever a new instance is received.
|
||||||
let ephemeralStyles
|
let ephemeralStyles
|
||||||
|
|
||||||
|
// Single string of all HBS blocks, used to check if we use a certain binding
|
||||||
|
// or not
|
||||||
|
let bindingString = ""
|
||||||
|
|
||||||
|
// List of context keys which we use inside bindings
|
||||||
|
let knownContextKeyMap = {}
|
||||||
|
|
||||||
// Set up initial state for each new component instance
|
// Set up initial state for each new component instance
|
||||||
$: initialise(instance)
|
$: initialise(instance)
|
||||||
|
|
||||||
|
@ -155,7 +167,7 @@
|
||||||
$: emptyState = empty && showEmptyState
|
$: emptyState = empty && showEmptyState
|
||||||
|
|
||||||
// Enrich component settings
|
// Enrich component settings
|
||||||
$: enrichComponentSettings($context, settingsDefinitionMap)
|
// $: enrichComponentSettings($context, settingsDefinitionMap)
|
||||||
|
|
||||||
// Evaluate conditional UI settings and store any component setting changes
|
// Evaluate conditional UI settings and store any component setting changes
|
||||||
// which need to be made
|
// which need to be made
|
||||||
|
@ -212,7 +224,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure we're processing a new instance
|
// Ensure we're processing a new instance
|
||||||
const instanceKey = Helpers.hashString(JSON.stringify(instance))
|
const stringifiedInstance = JSON.stringify(instance)
|
||||||
|
const instanceKey = Helpers.hashString(stringifiedInstance)
|
||||||
if (instanceKey === lastInstanceKey && !force) {
|
if (instanceKey === lastInstanceKey && !force) {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
@ -272,10 +285,22 @@
|
||||||
return missing
|
return missing
|
||||||
})
|
})
|
||||||
|
|
||||||
// Force an initial enrichment of the new settings
|
// When considering bindings we can ignore children, so we remove that
|
||||||
enrichComponentSettings(get(context), settingsDefinitionMap, {
|
// before storing the reference stringified version
|
||||||
force: true,
|
const noChildren = JSON.stringify({ ...instance, _children: null })
|
||||||
|
const bindings = findHBSBlocks(noChildren).map(binding => {
|
||||||
|
let sanitizedBinding = binding.replace(/\\"/g, '"')
|
||||||
|
if (isJSBinding(sanitizedBinding)) {
|
||||||
|
return decodeJSBinding(sanitizedBinding)
|
||||||
|
} else {
|
||||||
|
return sanitizedBinding
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
bindingString = bindings.join(" ")
|
||||||
|
knownContextKeyMap = {}
|
||||||
|
|
||||||
|
// Force an initial enrichment of the new settings
|
||||||
|
enrichComponentSettings($context, settingsDefinitionMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSettingsDefinitionMap = settingsDefinition => {
|
const getSettingsDefinitionMap = settingsDefinition => {
|
||||||
|
@ -355,17 +380,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enriches any string component props using handlebars
|
// Enriches any string component props using handlebars
|
||||||
const enrichComponentSettings = (
|
const enrichComponentSettings = (context, settingsDefinitionMap) => {
|
||||||
context,
|
|
||||||
settingsDefinitionMap,
|
|
||||||
options = { force: false }
|
|
||||||
) => {
|
|
||||||
const contextChanged = context.key !== lastContextKey
|
|
||||||
if (!contextChanged && !options?.force) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
lastContextKey = context.key
|
|
||||||
|
|
||||||
// Record the timestamp so we can reference it after enrichment
|
// Record the timestamp so we can reference it after enrichment
|
||||||
latestUpdateTime = Date.now()
|
latestUpdateTime = Date.now()
|
||||||
const enrichmentTime = latestUpdateTime
|
const enrichmentTime = latestUpdateTime
|
||||||
|
@ -480,6 +495,28 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleContextChange = key => {
|
||||||
|
// Check if we already know if this key is used
|
||||||
|
let used = knownContextKeyMap[key]
|
||||||
|
|
||||||
|
// If we don't know, check
|
||||||
|
if (used == null) {
|
||||||
|
// Check HBS
|
||||||
|
if (bindingString.indexOf(`[${key}]`) !== -1) {
|
||||||
|
used = true
|
||||||
|
} else {
|
||||||
|
used = false
|
||||||
|
}
|
||||||
|
// Cache result
|
||||||
|
knownContextKeyMap[key] = used
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enrich settings if we use this key
|
||||||
|
if (used) {
|
||||||
|
enrichComponentSettings($context, settingsDefinitionMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (
|
if (
|
||||||
$appStore.isDevApp &&
|
$appStore.isDevApp &&
|
||||||
|
@ -497,6 +534,8 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onMount(() => context.actions.observeChanges(handleContextChange))
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (
|
if (
|
||||||
$appStore.isDevApp &&
|
$appStore.isDevApp &&
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
// Clone and create new data context for this component tree
|
// Clone and create new data context for this component tree
|
||||||
const context = getContext("context")
|
const context = getContext("context")
|
||||||
const component = getContext("component")
|
const component = getContext("component")
|
||||||
const newContext = createContextStore(context)
|
|
||||||
setContext("context", newContext)
|
|
||||||
|
|
||||||
const providerKey = key || $component.id
|
const providerKey = key || $component.id
|
||||||
|
|
||||||
|
@ -30,7 +28,7 @@
|
||||||
const provideData = newData => {
|
const provideData = newData => {
|
||||||
const dataKey = JSON.stringify(newData)
|
const dataKey = JSON.stringify(newData)
|
||||||
if (dataKey !== lastDataKey) {
|
if (dataKey !== lastDataKey) {
|
||||||
newContext.actions.provideData(providerKey, newData)
|
context.actions.provideData(providerKey, newData)
|
||||||
lastDataKey = dataKey
|
lastDataKey = dataKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +38,7 @@
|
||||||
if (actionsKey !== lastActionsKey) {
|
if (actionsKey !== lastActionsKey) {
|
||||||
lastActionsKey = actionsKey
|
lastActionsKey = actionsKey
|
||||||
newActions?.forEach(({ type, callback, metadata }) => {
|
newActions?.forEach(({ type, callback, metadata }) => {
|
||||||
newContext.actions.provideAction(providerKey, type, callback)
|
context.actions.provideAction(providerKey, type, callback)
|
||||||
|
|
||||||
// Register any "refresh datasource" actions with a singleton store
|
// Register any "refresh datasource" actions with a singleton store
|
||||||
// so we can easily refresh data at all levels for any datasource
|
// so we can easily refresh data at all levels for any datasource
|
||||||
|
|
|
@ -1,44 +1,21 @@
|
||||||
import { writable, derived } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import { Helpers } from "@budibase/bbui"
|
|
||||||
|
|
||||||
export const createContextStore = oldContext => {
|
export const createContextStore = () => {
|
||||||
const newContext = writable({})
|
const context = writable({})
|
||||||
const contexts = oldContext ? [oldContext, newContext] : [newContext]
|
let observers = []
|
||||||
const totalContext = derived(contexts, $contexts => {
|
|
||||||
// The key is the serialized representation of context
|
|
||||||
let key = ""
|
|
||||||
for (let i = 0; i < $contexts.length - 1; i++) {
|
|
||||||
key += $contexts[i].key
|
|
||||||
}
|
|
||||||
key = Helpers.hashString(
|
|
||||||
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
|
// Adds a data context layer to the tree
|
||||||
const provideData = (providerId, data) => {
|
const provideData = (providerId, data) => {
|
||||||
if (!providerId || data === undefined) {
|
if (!providerId || data === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
newContext.update(state => {
|
// console.log(`[${providerId}]`, data)
|
||||||
|
context.update(state => {
|
||||||
state[providerId] = data
|
state[providerId] = data
|
||||||
|
|
||||||
// Keep track of the closest component ID so we can later hydrate a "data" prop.
|
|
||||||
// This is only required for legacy bindings that used "data" rather than a
|
|
||||||
// component ID.
|
|
||||||
state.closestComponentId = providerId
|
|
||||||
|
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
|
||||||
|
broadcastChange(providerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds an action context layer to the tree
|
// Adds an action context layer to the tree
|
||||||
|
@ -46,14 +23,30 @@ export const createContextStore = oldContext => {
|
||||||
if (!providerId || !actionType) {
|
if (!providerId || !actionType) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
newContext.update(state => {
|
context.update(state => {
|
||||||
state[`${providerId}_${actionType}`] = callback
|
state[`${providerId}_${actionType}`] = callback
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const observeChanges = callback => {
|
||||||
|
observers.push(callback)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observers = observers.filter(cb => cb !== callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const broadcastChange = key => {
|
||||||
|
observers.forEach(cb => cb(key))
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subscribe: totalContext.subscribe,
|
subscribe: context.subscribe,
|
||||||
actions: { provideData, provideAction },
|
actions: {
|
||||||
|
provideData,
|
||||||
|
provideAction,
|
||||||
|
observeChanges,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,6 @@ export const propsAreSame = (a, b) => {
|
||||||
* Data bindings are enriched, and button actions are enriched.
|
* Data bindings are enriched, and button actions are enriched.
|
||||||
*/
|
*/
|
||||||
export const enrichProps = (props, context, settingsDefinitionMap) => {
|
export const enrichProps = (props, context, settingsDefinitionMap) => {
|
||||||
// Create context of all bindings and data contexts
|
|
||||||
// Duplicate the closest context as "data" which the builder requires
|
|
||||||
const totalContext = {
|
|
||||||
...context,
|
|
||||||
|
|
||||||
// This is only required for legacy bindings that used "data" rather than a
|
|
||||||
// component ID.
|
|
||||||
data: context[context.closestComponentId],
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to exclude any button actions from enrichment at this stage.
|
// We want to exclude any button actions from enrichment at this stage.
|
||||||
// Extract top level button action settings.
|
// Extract top level button action settings.
|
||||||
let normalProps = { ...props }
|
let normalProps = { ...props }
|
||||||
|
@ -49,13 +39,13 @@ export const enrichProps = (props, context, settingsDefinitionMap) => {
|
||||||
let rawConditions = normalProps._conditions
|
let rawConditions = normalProps._conditions
|
||||||
|
|
||||||
// Enrich all props except button actions
|
// Enrich all props except button actions
|
||||||
let enrichedProps = enrichDataBindings(normalProps, totalContext)
|
let enrichedProps = enrichDataBindings(normalProps, context)
|
||||||
|
|
||||||
// Enrich button actions.
|
// Enrich button actions.
|
||||||
// Actions are enriched into a function at this stage, but actual data
|
// Actions are enriched into a function at this stage, but actual data
|
||||||
// binding enrichment is done dynamically at runtime.
|
// binding enrichment is done dynamically at runtime.
|
||||||
Object.keys(actionProps).forEach(prop => {
|
Object.keys(actionProps).forEach(prop => {
|
||||||
enrichedProps[prop] = enrichButtonActions(actionProps[prop], totalContext)
|
enrichedProps[prop] = enrichButtonActions(actionProps[prop], context)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Conditions
|
// Conditions
|
||||||
|
@ -66,7 +56,7 @@ export const enrichProps = (props, context, settingsDefinitionMap) => {
|
||||||
// action
|
// action
|
||||||
condition.settingValue = enrichButtonActions(
|
condition.settingValue = enrichButtonActions(
|
||||||
rawConditions[idx].settingValue,
|
rawConditions[idx].settingValue,
|
||||||
totalContext
|
context
|
||||||
)
|
)
|
||||||
|
|
||||||
// Since we can't compare functions, we need to assume that conditions
|
// Since we can't compare functions, we need to assume that conditions
|
||||||
|
|
|
@ -24,5 +24,6 @@ export const enrichDataBinding = async (input, context) => {
|
||||||
* Props are deeply cloned so that no mutation is done to the source object.
|
* Props are deeply cloned so that no mutation is done to the source object.
|
||||||
*/
|
*/
|
||||||
export const enrichDataBindings = (props, context) => {
|
export const enrichDataBindings = (props, context) => {
|
||||||
|
console.log("enrich")
|
||||||
return processObjectSync(Helpers.cloneDeep(props), context, { cache: true })
|
return processObjectSync(Helpers.cloneDeep(props), context, { cache: true })
|
||||||
}
|
}
|
||||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -1486,15 +1486,15 @@
|
||||||
pouchdb-promise "^6.0.4"
|
pouchdb-promise "^6.0.4"
|
||||||
through2 "^2.0.0"
|
through2 "^2.0.0"
|
||||||
|
|
||||||
"@budibase/pro@2.5.6-alpha.36":
|
"@budibase/pro@2.5.6-alpha.37":
|
||||||
version "2.5.6-alpha.36"
|
version "2.5.6-alpha.37"
|
||||||
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.5.6-alpha.36.tgz#361afe64b0881ee436a5ef294fb315c05ea94ce6"
|
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.5.6-alpha.37.tgz#3f4c7ba36bd01e2f7cbc56461c1249cc4098bc38"
|
||||||
integrity sha512-uX1wgOk47aVGl/yIJZiZS8x31sTS6wGDEFv0AMZ2h6rwIp6GwHDGq2/QT6a8hRMsAM4sqr8R2GkyyAG+dm0DGQ==
|
integrity sha512-D0P4ePioE43yZ+CvLE5XdO84x6/UcF8oY3rHIhd8+bS1LW1yrzAf4kG9lyBRsNUPZoTMPmJeD9zqGRw67pdjzA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@budibase/backend-core" "2.5.6-alpha.36"
|
"@budibase/backend-core" "2.5.6-alpha.37"
|
||||||
"@budibase/shared-core" "2.4.44-alpha.1"
|
"@budibase/shared-core" "2.4.44-alpha.1"
|
||||||
"@budibase/string-templates" "2.4.44-alpha.1"
|
"@budibase/string-templates" "2.4.44-alpha.1"
|
||||||
"@budibase/types" "2.5.6-alpha.36"
|
"@budibase/types" "2.5.6-alpha.37"
|
||||||
"@koa/router" "8.0.8"
|
"@koa/router" "8.0.8"
|
||||||
bull "4.10.1"
|
bull "4.10.1"
|
||||||
joi "17.6.0"
|
joi "17.6.0"
|
||||||
|
|
Loading…
Reference in New Issue