1
0
Fork 0
mirror of synced 2024-07-03 13:30:46 +12:00

Simply and improve core client library logic

This commit is contained in:
Andrew Kingston 2022-02-01 16:32:37 +00:00
parent 5aa52f4b9d
commit ae9a5b19c0

View file

@ -9,7 +9,7 @@
<script>
import { getContext, setContext } from "svelte"
import { writable } from "svelte/store"
import { writable, get } from "svelte/store"
import * as AppComponents from "components/app"
import Router from "./Router.svelte"
import { enrichProps, propsAreSame } from "utils/componentProps"
@ -24,6 +24,14 @@
export let isScreen = false
export let isBlock = false
// Get parent contexts
const context = getContext("context")
const insideScreenslot = !!getContext("screenslot")
// Create component context
const componentStore = writable({})
setContext("component", componentStore)
// Ref to the svelte component
let ref
@ -34,13 +42,11 @@
// would happen if we spread cachedSettings directly to the component.
let initialSettings
// Component settings are the un-enriched settings for this component that
// need to be enriched at this level.
// Nested settings are the un-enriched block settings that are to be passed on
// and enriched at a deeper level.
// Dynamic settings contain bindings and need enriched
let dynamicSettings
// Static settings do not contain any bindings and can be passed on down
let staticSettings
let nestedSettings
// The enriched component settings
let enrichedSettings
@ -65,17 +71,11 @@
// Visibility flag used by conditional UI
let visible = true
// Get contexts
const context = getContext("context")
const insideScreenslot = !!getContext("screenslot")
// Create component context
const componentStore = writable({})
setContext("component", componentStore)
//
// Component information derived during initialisation
let constructor
let definition
// Set up initial state for each new component instance
$: initialise(instance)
// Extract component instance info
@ -113,19 +113,16 @@
$: emptyState = empty && showEmptyState
// Enrich component settings
$: enrichComponentSettings(dynamicSettings, $context)
$: enrichComponentSettings($context)
// Evaluate conditional UI settings and store any component setting changes
// which need to be made
$: evaluateConditions(enrichedSettings?._conditions)
// which need to be made. This is broken into 2 lines to avoid svelte
// reactivity re-evaluating conditions more often than necessary.
$: conditions = enrichedSettings?._conditions
$: evaluateConditions(conditions)
// Build up the final settings object to be passed to the component
$: cacheSettings(
staticSettings,
enrichedSettings,
nestedSettings,
conditionalSettings
)
// Determine and apply settings to the component
$: applySettings(staticSettings, enrichedSettings, conditionalSettings)
// Update component context
$: componentStore.set({
@ -183,10 +180,12 @@
InstanceSettingsCache[instanceKey] = instanceSettings
}
// Update the settings type in the component
// Update the settings types
staticSettings = instanceSettings.staticSettings
dynamicSettings = instanceSettings.dynamicSettings
nestedSettings = instanceSettings.nestedSettings
// Force an initial enrichment of the new settings
enrichComponentSettings(get(context), { force: true })
}
// Gets the component constructor for the specified component
@ -234,25 +233,21 @@
// Derive static, dynamic and nested settings if the instance changed
let newStaticSettings = { ...settings }
let newDynamicSettings = { ...settings }
let newNestedSettings = { ...settings }
settingsDefinition?.forEach(setting => {
if (setting.nested) {
delete newStaticSettings[setting.key]
delete newDynamicSettings[setting.key]
} else {
delete newNestedSettings[setting.key]
// This is a non-nested setting, but we need to find out if it is
// static or dynamic
const value = settings[setting.key]
if (value == null) {
delete newDynamicSettings[setting.key]
} else if (typeof value === "string" && value.includes("{{")) {
// Strings can be trivially checked
delete newStaticSettings[setting.key]
} else if (value[0]?.["##eventHandlerType"] != null) {
// Always treat button actions as dynamic
delete newStaticSettings[setting.key]
} else if (typeof value === "object") {
// Stringify and check objects
const stringified = JSON.stringify(value)
if (stringified.includes("{{")) {
delete newStaticSettings[setting.key]
@ -260,6 +255,7 @@
delete newDynamicSettings[setting.key]
}
} else {
// For other types, we can safely assume they are static
delete newDynamicSettings[setting.key]
}
}
@ -268,25 +264,23 @@
return {
staticSettings: newStaticSettings,
dynamicSettings: newDynamicSettings,
nestedSettings: newNestedSettings,
}
}
// Enriches any string component props using handlebars
const enrichComponentSettings = (settings, context) => {
const enrichComponentSettings = (context, options = { force: false }) => {
const contextChanged = context.key !== lastContextKey
if (!contextChanged) {
if (!contextChanged && !options?.force) {
return
} else {
lastContextKey = context.key
}
lastContextKey = context.key
// Record the timestamp so we can reference it after enrichment
latestUpdateTime = Date.now()
const enrichmentTime = latestUpdateTime
// Enrich settings with context
const newEnrichedSettings = enrichProps(settings, context)
const newEnrichedSettings = enrichProps(dynamicSettings, context)
// Abandon this update if a newer update has started
if (enrichmentTime !== latestUpdateTime) {
@ -321,12 +315,15 @@
// Combines and caches all settings which will be passed to the component
// instance. Settings are aggressively memoized to avoid triggering svelte
// reactive statements as much as possible.
const cacheSettings = (staticSettings, enriched, nested, conditional) => {
const applySettings = (
staticSettings,
enrichedSettings,
conditionalSettings
) => {
const allSettings = {
...staticSettings,
...enriched,
...nested,
...conditional,
...enrichedSettings,
...conditionalSettings,
}
if (!cachedSettings) {
cachedSettings = { ...allSettings }