@nordcraft/runtime 1.0.95 → 1.0.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/createAPI.js +29 -11
- package/dist/api/createAPI.js.map +1 -1
- package/dist/api/createAPIv2.js +49 -11
- package/dist/api/createAPIv2.js.map +1 -1
- package/dist/components/createComponent.js +19 -10
- package/dist/components/createComponent.js.map +1 -1
- package/dist/components/createElement.js +48 -16
- package/dist/components/createElement.js.map +1 -1
- package/dist/components/createNode.js +22 -11
- package/dist/components/createNode.js.map +1 -1
- package/dist/components/createNode.test.js +3 -3
- package/dist/components/createNode.test.js.map +1 -1
- package/dist/components/createSlot.js +2 -1
- package/dist/components/createSlot.js.map +1 -1
- package/dist/components/createText.js +7 -2
- package/dist/components/createText.js.map +1 -1
- package/dist/components/renderComponent.d.ts +4 -1
- package/dist/components/renderComponent.js +4 -2
- package/dist/components/renderComponent.js.map +1 -1
- package/dist/context/subscribeToContext.js +12 -2
- package/dist/context/subscribeToContext.js.map +1 -1
- package/dist/custom-element/ToddleComponent.js +12 -4
- package/dist/custom-element/ToddleComponent.js.map +1 -1
- package/dist/custom-element.main.esm.js +29 -29
- package/dist/custom-element.main.esm.js.map +4 -4
- package/dist/editor/editorUtils.d.ts +2 -0
- package/dist/editor/editorUtils.js +26 -0
- package/dist/editor/editorUtils.js.map +1 -0
- package/dist/editor/types.d.ts +4 -0
- package/dist/editor/types.js.map +1 -1
- package/dist/editor-preview.main.js +82 -18
- package/dist/editor-preview.main.js.map +1 -1
- package/dist/events/handleAction.js +74 -42
- package/dist/events/handleAction.js.map +1 -1
- package/dist/page.main.esm.js +3 -3
- package/dist/page.main.esm.js.map +4 -4
- package/dist/page.main.js +39 -8
- package/dist/page.main.js.map +1 -1
- package/dist/utils/createFormulaCache.js.map +1 -1
- package/dist/utils/nodes.d.ts +1 -0
- package/dist/utils/nodes.js +9 -0
- package/dist/utils/nodes.js.map +1 -1
- package/dist/utils/nodes.test.d.ts +1 -0
- package/dist/utils/nodes.test.js +192 -0
- package/dist/utils/nodes.test.js.map +1 -0
- package/dist/utils/subscribeCustomProperty.d.ts +1 -1
- package/dist/utils/subscribeCustomProperty.js +8 -4
- package/dist/utils/subscribeCustomProperty.js.map +1 -1
- package/dist/utils/subscribeCustomProperty.test.d.ts +1 -0
- package/dist/utils/subscribeCustomProperty.test.js +63 -0
- package/dist/utils/subscribeCustomProperty.test.js.map +1 -0
- package/package.json +3 -3
- package/src/api/createAPI.ts +90 -46
- package/src/api/createAPIv2.ts +79 -13
- package/src/components/createComponent.ts +123 -85
- package/src/components/createElement.ts +63 -27
- package/src/components/createNode.test.ts +3 -3
- package/src/components/createNode.ts +55 -31
- package/src/components/createSlot.ts +2 -1
- package/src/components/createText.ts +35 -18
- package/src/components/renderComponent.ts +8 -1
- package/src/context/subscribeToContext.ts +12 -2
- package/src/custom-element/ToddleComponent.ts +37 -22
- package/src/editor/editorUtils.ts +28 -0
- package/src/editor/types.ts +5 -0
- package/src/editor-preview.main.ts +137 -46
- package/src/events/handleAction.ts +190 -113
- package/src/page.main.ts +64 -26
- package/src/types.d.ts +3 -0
- package/src/utils/createFormulaCache.ts +2 -2
- package/src/utils/nodes.test.ts +246 -0
- package/src/utils/nodes.ts +11 -0
- package/src/utils/subscribeCustomProperty.test.ts +78 -0
- package/src/utils/subscribeCustomProperty.ts +21 -22
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from '@nordcraft/core/dist/formula/formula'
|
|
22
22
|
import {
|
|
23
23
|
type CodeFormula,
|
|
24
|
+
type FormulaEvaluationReporter,
|
|
24
25
|
type PluginFormula,
|
|
25
26
|
type ToddleFormula,
|
|
26
27
|
} from '@nordcraft/core/dist/formula/formulaTypes'
|
|
@@ -63,6 +64,7 @@ import { dragEnded } from './editor/drag-drop/dragEnded'
|
|
|
63
64
|
import { dragMove } from './editor/drag-drop/dragMove'
|
|
64
65
|
import { dragReorder } from './editor/drag-drop/dragReorder'
|
|
65
66
|
import { dragStarted } from './editor/drag-drop/dragStarted'
|
|
67
|
+
import { throttleToIdleCallback } from './editor/editorUtils'
|
|
66
68
|
import { introspectApiRequest } from './editor/graphql'
|
|
67
69
|
import { isInputTarget } from './editor/input'
|
|
68
70
|
import { updateComponentLinks } from './editor/links'
|
|
@@ -91,7 +93,11 @@ import type {
|
|
|
91
93
|
import { createFormulaCache } from './utils/createFormulaCache'
|
|
92
94
|
import { getThemeSignal } from './utils/getThemeSignal'
|
|
93
95
|
import { markSelectedElement } from './utils/markSelectedElement'
|
|
94
|
-
import {
|
|
96
|
+
import {
|
|
97
|
+
getNodeAndAncestors,
|
|
98
|
+
isNodeOrAncestorConditional,
|
|
99
|
+
stripNodeIdRepeatIndices,
|
|
100
|
+
} from './utils/nodes'
|
|
95
101
|
import { rectHasPoint } from './utils/rectHasPoint'
|
|
96
102
|
import {
|
|
97
103
|
getScrollStateRestorer,
|
|
@@ -243,6 +249,37 @@ export const createRoot = (
|
|
|
243
249
|
...(packageComponents ?? []),
|
|
244
250
|
]
|
|
245
251
|
let component: Component | null = null
|
|
252
|
+
let componentFormulaData: Record<string, any> = {}
|
|
253
|
+
|
|
254
|
+
const reportFormulaEvaluation: FormulaEvaluationReporter = (
|
|
255
|
+
path,
|
|
256
|
+
data,
|
|
257
|
+
ctx,
|
|
258
|
+
) => {
|
|
259
|
+
if (
|
|
260
|
+
data !== undefined &&
|
|
261
|
+
path.length > 0 &&
|
|
262
|
+
// We are currently skipping all children formulas to lower the scope of reporting to what the user can see in the canvas
|
|
263
|
+
ctx.component?.name === component?.name
|
|
264
|
+
) {
|
|
265
|
+
try {
|
|
266
|
+
componentFormulaData[path.join('/')] = JSON.parse(JSON.stringify(data))
|
|
267
|
+
} catch {
|
|
268
|
+
componentFormulaData[path.join('/')] =
|
|
269
|
+
`[Unserializable value of type ${typeof data}]`
|
|
270
|
+
} finally {
|
|
271
|
+
reportComponentFormulaData()
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const reportComponentFormulaData = throttleToIdleCallback(() => {
|
|
276
|
+
postMessageToEditor({
|
|
277
|
+
type: 'componentFormulaData',
|
|
278
|
+
data: componentFormulaData,
|
|
279
|
+
component: component?.name,
|
|
280
|
+
})
|
|
281
|
+
componentFormulaData = {}
|
|
282
|
+
})
|
|
246
283
|
let selectedNodeId: string | null = null
|
|
247
284
|
let highlightedNodeId: string | null = null
|
|
248
285
|
let styleVariantSelection: {
|
|
@@ -311,6 +348,8 @@ export const createRoot = (
|
|
|
311
348
|
)
|
|
312
349
|
// Destroy the dataSignal (including subscribers) for the previous component
|
|
313
350
|
dataSignal.destroy()
|
|
351
|
+
// Reset all evaluated formula data
|
|
352
|
+
componentFormulaData = {}
|
|
314
353
|
// Re-subscribe all dataSignal subscribers
|
|
315
354
|
setupDataSignalSubscribers()
|
|
316
355
|
// Re-initialize the data signal for the new component
|
|
@@ -512,7 +551,13 @@ export const createRoot = (
|
|
|
512
551
|
return
|
|
513
552
|
}
|
|
514
553
|
case 'highlight': {
|
|
515
|
-
|
|
554
|
+
const highlightId = message.data.highlightedNodeId
|
|
555
|
+
highlightedNodeId = highlightId
|
|
556
|
+
? highlightId
|
|
557
|
+
.split('.')
|
|
558
|
+
.map((part) => part.split('(')[0])
|
|
559
|
+
.join('.')
|
|
560
|
+
: null
|
|
516
561
|
return
|
|
517
562
|
}
|
|
518
563
|
case 'mousemove':
|
|
@@ -614,7 +659,7 @@ export const createRoot = (
|
|
|
614
659
|
} else if (type === 'mousemove' && id !== highlightedNodeId) {
|
|
615
660
|
postMessageToEditor({
|
|
616
661
|
type: 'highlight',
|
|
617
|
-
highlightedNodeId: id,
|
|
662
|
+
highlightedNodeId: stripNodeIdRepeatIndices(id),
|
|
618
663
|
})
|
|
619
664
|
} else if (
|
|
620
665
|
type === 'dblclick' &&
|
|
@@ -704,6 +749,7 @@ export const createRoot = (
|
|
|
704
749
|
package: ctx?.package,
|
|
705
750
|
toddle: window.toddle,
|
|
706
751
|
env,
|
|
752
|
+
jsonPath: [],
|
|
707
753
|
}
|
|
708
754
|
const introspectionResult = await introspectApiRequest({
|
|
709
755
|
api,
|
|
@@ -1181,19 +1227,32 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1181
1227
|
.map(([customPropertyName, customProperty]) => [
|
|
1182
1228
|
customPropertyName,
|
|
1183
1229
|
appendUnit(
|
|
1184
|
-
applyFormula(
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1230
|
+
applyFormula(
|
|
1231
|
+
customProperty.formula,
|
|
1232
|
+
{
|
|
1233
|
+
data: {
|
|
1234
|
+
Attributes: dataSignal.get().Attributes,
|
|
1235
|
+
Variables: dataSignal.get().Variables,
|
|
1236
|
+
Contexts: ctxDataSignal?.get().Contexts ?? {},
|
|
1237
|
+
},
|
|
1238
|
+
component: getCurrentComponent(),
|
|
1239
|
+
root: ctx?.root,
|
|
1240
|
+
formulaCache: {},
|
|
1241
|
+
package: ctx?.package,
|
|
1242
|
+
toddle: window.toddle,
|
|
1243
|
+
env,
|
|
1244
|
+
// TODO: Ensure we have the node id here
|
|
1245
|
+
jsonPath: [
|
|
1246
|
+
'nodes',
|
|
1247
|
+
'<random id>',
|
|
1248
|
+
'variants',
|
|
1249
|
+
styleVariantSelection?.styleVariantIndex ?? 0,
|
|
1250
|
+
customPropertyName,
|
|
1251
|
+
],
|
|
1252
|
+
reportFormulaEvaluation,
|
|
1253
|
+
} as FormulaContext,
|
|
1254
|
+
[],
|
|
1255
|
+
),
|
|
1197
1256
|
customProperty.unit,
|
|
1198
1257
|
),
|
|
1199
1258
|
])
|
|
@@ -1306,6 +1365,8 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1306
1365
|
package: ctx?.package,
|
|
1307
1366
|
toddle: window.toddle,
|
|
1308
1367
|
env,
|
|
1368
|
+
jsonPath: ['route', 'info', 'meta'],
|
|
1369
|
+
reportFormulaEvaluation,
|
|
1309
1370
|
})
|
|
1310
1371
|
}
|
|
1311
1372
|
if (fastDeepEqual(_component.contexts, ctx?.component.contexts) === false) {
|
|
@@ -1351,6 +1412,9 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1351
1412
|
package: ctx?.package,
|
|
1352
1413
|
toddle: window.toddle,
|
|
1353
1414
|
env,
|
|
1415
|
+
jsonPath: [],
|
|
1416
|
+
// We don't evaluate formulas in context providers in preview mode currently
|
|
1417
|
+
reportFormulaEvaluation: undefined,
|
|
1354
1418
|
}
|
|
1355
1419
|
|
|
1356
1420
|
// Pages can also be context-providers!
|
|
@@ -1373,7 +1437,10 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1373
1437
|
providerComponent.variables ?? {},
|
|
1374
1438
|
([name, variable]) => [
|
|
1375
1439
|
name,
|
|
1376
|
-
applyFormula(variable.initialValue, formulaContext
|
|
1440
|
+
applyFormula(variable.initialValue, formulaContext, [
|
|
1441
|
+
'variables',
|
|
1442
|
+
name,
|
|
1443
|
+
]),
|
|
1377
1444
|
],
|
|
1378
1445
|
)
|
|
1379
1446
|
|
|
@@ -1391,7 +1458,10 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1391
1458
|
|
|
1392
1459
|
return [
|
|
1393
1460
|
formulaName,
|
|
1394
|
-
applyFormula(formula.formula, formulaContext
|
|
1461
|
+
applyFormula(formula.formula, formulaContext, [
|
|
1462
|
+
'formulas',
|
|
1463
|
+
formulaName,
|
|
1464
|
+
]),
|
|
1395
1465
|
]
|
|
1396
1466
|
}),
|
|
1397
1467
|
),
|
|
@@ -1407,14 +1477,20 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1407
1477
|
_component.variables ?? {},
|
|
1408
1478
|
([name, { initialValue }]) => [
|
|
1409
1479
|
name,
|
|
1410
|
-
applyFormula(
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1480
|
+
applyFormula(
|
|
1481
|
+
initialValue,
|
|
1482
|
+
{
|
|
1483
|
+
data: { Attributes, Contexts },
|
|
1484
|
+
component: _component!,
|
|
1485
|
+
root: document,
|
|
1486
|
+
package: ctx?.package,
|
|
1487
|
+
toddle: window.toddle,
|
|
1488
|
+
env,
|
|
1489
|
+
jsonPath: ctx?.jsonPath,
|
|
1490
|
+
reportFormulaEvaluation,
|
|
1491
|
+
},
|
|
1492
|
+
['variables', name],
|
|
1493
|
+
),
|
|
1418
1494
|
],
|
|
1419
1495
|
)
|
|
1420
1496
|
}
|
|
@@ -1455,6 +1531,9 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1455
1531
|
for (const api in newCtx.component.apis) {
|
|
1456
1532
|
// check if the api has changed (ignoring onCompleted and onFailed).
|
|
1457
1533
|
const apiInstance = newCtx.component.apis[api]
|
|
1534
|
+
if (!apiInstance) {
|
|
1535
|
+
continue
|
|
1536
|
+
}
|
|
1458
1537
|
const previousApiInstance = ctx?.component.apis?.[api]
|
|
1459
1538
|
if (isLegacyApi(apiInstance)) {
|
|
1460
1539
|
if (
|
|
@@ -1478,14 +1557,17 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1478
1557
|
]),
|
|
1479
1558
|
}
|
|
1480
1559
|
})
|
|
1481
|
-
newCtx.apis[api] = createLegacyAPI(apiInstance,
|
|
1560
|
+
newCtx.apis[api] = createLegacyAPI(apiInstance, {
|
|
1561
|
+
...newCtx,
|
|
1562
|
+
jsonPath: ['apis', api],
|
|
1563
|
+
})
|
|
1482
1564
|
}
|
|
1483
1565
|
} else {
|
|
1484
1566
|
const existingApi = newCtx.apis[api] as ContextApiV2 | undefined
|
|
1485
1567
|
if (!existingApi) {
|
|
1486
1568
|
newCtx.apis[api] = createAPI({
|
|
1487
1569
|
apiRequest: apiInstance,
|
|
1488
|
-
ctx: newCtx,
|
|
1570
|
+
ctx: { ...newCtx, jsonPath: ['apis', api] },
|
|
1489
1571
|
componentData: dataSignal.get(),
|
|
1490
1572
|
})
|
|
1491
1573
|
} else {
|
|
@@ -1520,7 +1602,7 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1520
1602
|
id: 'root',
|
|
1521
1603
|
path: '0',
|
|
1522
1604
|
dataSignal: ctxDataSignal,
|
|
1523
|
-
ctx: newCtx,
|
|
1605
|
+
ctx: { ...newCtx, jsonPath: ['nodes', 'root'] },
|
|
1524
1606
|
parentElement: domNode,
|
|
1525
1607
|
instance: { [newCtx.component.name]: 'root' },
|
|
1526
1608
|
})
|
|
@@ -1625,6 +1707,8 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1625
1707
|
package: undefined,
|
|
1626
1708
|
toddle: window.toddle,
|
|
1627
1709
|
env,
|
|
1710
|
+
jsonPath: [], // TODO: decide if the component path is needed here
|
|
1711
|
+
reportFormulaEvaluation,
|
|
1628
1712
|
}
|
|
1629
1713
|
|
|
1630
1714
|
setupThemeSubscription(ctx.component, ctx.dataSignal, env).subscribe(
|
|
@@ -1641,15 +1725,21 @@ body[data-mode="design"] [data-id="${animationState.animatedElementId}"], body[d
|
|
|
1641
1725
|
.map(([name, formula]) => [
|
|
1642
1726
|
name,
|
|
1643
1727
|
dataSignal.map((data) =>
|
|
1644
|
-
applyFormula(
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1728
|
+
applyFormula(
|
|
1729
|
+
formula.formula,
|
|
1730
|
+
{
|
|
1731
|
+
data,
|
|
1732
|
+
component,
|
|
1733
|
+
formulaCache: ctx.formulaCache,
|
|
1734
|
+
root: ctx.root,
|
|
1735
|
+
package: ctx.package,
|
|
1736
|
+
toddle: window.toddle,
|
|
1737
|
+
env,
|
|
1738
|
+
jsonPath: ctx.jsonPath,
|
|
1739
|
+
reportFormulaEvaluation,
|
|
1740
|
+
},
|
|
1741
|
+
['formulas', name],
|
|
1742
|
+
),
|
|
1653
1743
|
),
|
|
1654
1744
|
]),
|
|
1655
1745
|
)
|
|
@@ -1756,7 +1846,10 @@ const insertHeadTags = (
|
|
|
1756
1846
|
<link
|
|
1757
1847
|
data-meta-id="${id}"
|
|
1758
1848
|
${Object.entries(entry.attrs ?? {})
|
|
1759
|
-
.map(
|
|
1849
|
+
.map(
|
|
1850
|
+
([key, value]) =>
|
|
1851
|
+
`${key}="${applyFormula(value, context, [id, 'attrs', key])}"`,
|
|
1852
|
+
)
|
|
1760
1853
|
.join(' ')}
|
|
1761
1854
|
/>
|
|
1762
1855
|
`),
|
|
@@ -1768,7 +1861,10 @@ const insertHeadTags = (
|
|
|
1768
1861
|
<script
|
|
1769
1862
|
data-meta-id="${id}"
|
|
1770
1863
|
${Object.entries(entry.attrs ?? {})
|
|
1771
|
-
.map(
|
|
1864
|
+
.map(
|
|
1865
|
+
([key, value]) =>
|
|
1866
|
+
`${key}="${applyFormula(value, context, [id, 'attrs', key])}"`,
|
|
1867
|
+
)
|
|
1772
1868
|
.join(' ')}
|
|
1773
1869
|
>${applyFormula(entry.content ?? '', context)}</script>
|
|
1774
1870
|
`),
|
|
@@ -1801,7 +1897,7 @@ export function getDOMNodeFromNodeId(
|
|
|
1801
1897
|
}
|
|
1802
1898
|
|
|
1803
1899
|
return document.querySelector(
|
|
1804
|
-
`[data-id="${selectedNodeId}"]:not([data-component])`,
|
|
1900
|
+
`[data-id="${stripNodeIdRepeatIndices(selectedNodeId)}"]:not([data-component])`,
|
|
1805
1901
|
)
|
|
1806
1902
|
}
|
|
1807
1903
|
|
|
@@ -1818,11 +1914,6 @@ function getNodeId(component: Component, path: string[]) {
|
|
|
1818
1914
|
return null
|
|
1819
1915
|
}
|
|
1820
1916
|
|
|
1821
|
-
// We only allow selecting the first element in a repeat (which does not have a repeat-index "()")
|
|
1822
|
-
if (nextChild.endsWith(')')) {
|
|
1823
|
-
return null
|
|
1824
|
-
}
|
|
1825
|
-
|
|
1826
1917
|
return getId(path, currentNode.children[parseInt(nextChild)])
|
|
1827
1918
|
}
|
|
1828
1919
|
return getId(path, 'root')
|