@fugood/bricks-project 2.24.0-beta.4 → 2.24.0-beta.41
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/compile/action-name-map.ts +38 -0
- package/compile/index.ts +429 -160
- package/compile/util.ts +2 -0
- package/package.json +7 -3
- package/package.json.bak +27 -0
- package/skills/{bricks-project → bricks-ctor}/SKILL.md +2 -2
- package/skills/{bricks-project → bricks-ctor}/rules/animation.md +1 -1
- package/skills/{bricks-project → bricks-ctor}/rules/architecture-patterns.md +7 -0
- package/skills/bricks-ctor/rules/automations.md +221 -0
- package/skills/{bricks-project → bricks-ctor}/rules/buttress.md +10 -7
- package/skills/{bricks-project → bricks-ctor}/rules/data-calculation.md +1 -1
- package/skills/{bricks-project → bricks-ctor}/rules/local-sync.md +2 -2
- package/skills/{bricks-project → bricks-ctor}/rules/media-flow.md +3 -3
- package/skills/{bricks-project → bricks-ctor}/rules/remote-data-bank.md +6 -6
- package/skills/{bricks-project → bricks-ctor}/rules/standby-transition.md +1 -1
- package/skills/bricks-design/LICENSE.txt +180 -0
- package/skills/bricks-design/SKILL.md +66 -0
- package/tools/deploy.ts +66 -12
- package/tools/icons/fa6pro-meta.json +3669 -26125
- package/tools/mcp-server.ts +11 -878
- package/tools/mcp-tools/compile.ts +91 -0
- package/tools/mcp-tools/huggingface.ts +762 -0
- package/tools/mcp-tools/icons.ts +70 -0
- package/tools/mcp-tools/lottie.ts +102 -0
- package/tools/mcp-tools/media.ts +110 -0
- package/tools/postinstall.ts +137 -40
- package/tools/preview-main.mjs +146 -9
- package/tools/preview.ts +30 -2
- package/tools/pull.ts +37 -19
- package/tsconfig.json +16 -0
- package/types/animation.ts +4 -0
- package/types/automation.ts +4 -1
- package/types/brick-base.ts +1 -1
- package/types/bricks/Camera.ts +48 -13
- package/types/bricks/Chart.ts +10 -4
- package/types/bricks/GenerativeMedia.ts +30 -14
- package/types/bricks/Icon.ts +9 -5
- package/types/bricks/Image.ts +10 -6
- package/types/bricks/Items.ts +29 -15
- package/types/bricks/Lottie.ts +15 -7
- package/types/bricks/Maps.ts +16 -8
- package/types/bricks/QrCode.ts +9 -5
- package/types/bricks/Rect.ts +45 -6
- package/types/bricks/RichText.ts +9 -5
- package/types/bricks/Rive.ts +21 -11
- package/types/bricks/Slideshow.ts +20 -10
- package/types/bricks/Svg.ts +8 -4
- package/types/bricks/Text.ts +9 -5
- package/types/bricks/TextInput.ts +23 -13
- package/types/bricks/Video.ts +11 -7
- package/types/bricks/VideoStreaming.ts +8 -4
- package/types/bricks/WebRtcStream.ts +7 -3
- package/types/bricks/WebView.ts +12 -8
- package/types/canvas.ts +4 -2
- package/types/common.ts +19 -12
- package/types/data-calc-command.ts +2 -0
- package/types/data-calc.ts +1 -0
- package/types/data.ts +2 -0
- package/types/generators/AlarmClock.ts +17 -11
- package/types/generators/Assistant.ts +69 -18
- package/types/generators/BleCentral.ts +31 -11
- package/types/generators/BlePeripheral.ts +11 -7
- package/types/generators/CanvasMap.ts +10 -6
- package/types/generators/CastlesPay.ts +15 -7
- package/types/generators/DataBank.ts +44 -9
- package/types/generators/File.ts +109 -30
- package/types/generators/GraphQl.ts +12 -6
- package/types/generators/Http.ts +33 -10
- package/types/generators/HttpServer.ts +23 -15
- package/types/generators/Information.ts +9 -5
- package/types/generators/Intent.ts +15 -5
- package/types/generators/Iterator.ts +15 -11
- package/types/generators/Keyboard.ts +27 -13
- package/types/generators/LlmAnthropicCompat.ts +33 -11
- package/types/generators/LlmAppleBuiltin.ts +25 -10
- package/types/generators/LlmGgml.ts +140 -31
- package/types/generators/LlmMediaTekNeuroPilot.ts +235 -0
- package/types/generators/LlmMlx.ts +227 -0
- package/types/generators/LlmOnnx.ts +34 -14
- package/types/generators/LlmOpenAiCompat.ts +47 -11
- package/types/generators/LlmQualcommAiEngine.ts +45 -13
- package/types/generators/Mcp.ts +375 -34
- package/types/generators/McpServer.ts +58 -19
- package/types/generators/MediaFlow.ts +38 -12
- package/types/generators/MqttBroker.ts +29 -11
- package/types/generators/MqttClient.ts +19 -9
- package/types/generators/Question.ts +13 -9
- package/types/generators/RealtimeTranscription.ts +108 -19
- package/types/generators/RerankerGgml.ts +43 -12
- package/types/generators/SerialPort.ts +18 -10
- package/types/generators/SoundPlayer.ts +10 -4
- package/types/generators/SoundRecorder.ts +24 -9
- package/types/generators/SpeechToTextGgml.ts +52 -18
- package/types/generators/SpeechToTextOnnx.ts +18 -11
- package/types/generators/SpeechToTextPlatform.ts +15 -7
- package/types/generators/SqLite.ts +20 -10
- package/types/generators/Step.ts +9 -5
- package/types/generators/SttAppleBuiltin.ts +22 -9
- package/types/generators/Tcp.ts +13 -9
- package/types/generators/TcpServer.ts +20 -14
- package/types/generators/TextToSpeechAppleBuiltin.ts +21 -8
- package/types/generators/TextToSpeechGgml.ts +29 -11
- package/types/generators/TextToSpeechOnnx.ts +19 -12
- package/types/generators/TextToSpeechOpenAiLike.ts +14 -8
- package/types/generators/ThermalPrinter.ts +13 -9
- package/types/generators/Tick.ts +11 -7
- package/types/generators/Udp.ts +17 -8
- package/types/generators/VadGgml.ts +51 -14
- package/types/generators/VadOnnx.ts +42 -12
- package/types/generators/VadTraditional.ts +28 -13
- package/types/generators/VectorStore.ts +33 -12
- package/types/generators/Watchdog.ts +19 -10
- package/types/generators/WebCrawler.ts +11 -7
- package/types/generators/WebRtc.ts +30 -16
- package/types/generators/WebSocket.ts +11 -7
- package/types/generators/index.ts +2 -0
- package/types/subspace.ts +3 -0
- package/types/system.ts +1 -1
- package/utils/calc.ts +12 -8
- package/utils/event-props.ts +833 -1022
- package/utils/id.ts +4 -0
- package/api/index.ts +0 -1
- package/api/instance.ts +0 -213
- package/skills/bricks-project/rules/automations.md +0 -175
- package/types/generators/TextToSpeechApple.ts +0 -113
- package/types/generators/TtsAppleBuiltin.ts +0 -105
package/compile/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/* eslint-disable no-underscore-dangle -- Uses __typename, __actionName, etc. for type system */
|
|
2
|
-
import
|
|
2
|
+
import camelCase from 'lodash/camelCase'
|
|
3
|
+
import upperFirst from 'lodash/upperFirst'
|
|
4
|
+
import snakeCase from 'lodash/snakeCase'
|
|
5
|
+
import omit from 'lodash/omit'
|
|
3
6
|
import { parse as parseAST } from 'acorn'
|
|
4
7
|
import type { ExportNamedDeclaration, FunctionDeclaration } from 'acorn'
|
|
5
8
|
import escodegen from 'escodegen'
|
|
@@ -33,6 +36,40 @@ import type {
|
|
|
33
36
|
TestVariable,
|
|
34
37
|
} from '../types'
|
|
35
38
|
|
|
39
|
+
const uuidPattern = '[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}'
|
|
40
|
+
|
|
41
|
+
const entryIdPatterns = {
|
|
42
|
+
SUBSPACE: new RegExp(`^SUBSPACE_${uuidPattern}$`),
|
|
43
|
+
CANVAS: new RegExp(`^CANVAS_${uuidPattern}$`),
|
|
44
|
+
BRICK: new RegExp(`^BRICK_${uuidPattern}$`),
|
|
45
|
+
GENERATOR: new RegExp(`^(GENERATOR|AUTO_GENERATOR)_${uuidPattern}$`),
|
|
46
|
+
ANIMATION: new RegExp(`^ANIMATION_${uuidPattern}$`),
|
|
47
|
+
PROPERTY_BANK_DATA_NODE: new RegExp(`^PROPERTY_BANK_DATA_NODE_${uuidPattern}$`),
|
|
48
|
+
PROPERTY_BANK_COMMAND_NODE: new RegExp(`^PROPERTY_BANK_COMMAND_NODE_${uuidPattern}$`),
|
|
49
|
+
PROPERTY_BANK_COMMAND_MAP: new RegExp(`^PROPERTY_BANK_COMMAND_MAP_${uuidPattern}$`),
|
|
50
|
+
BRICK_STATE_GROUP: new RegExp(`^BRICK_STATE_GROUP_${uuidPattern}$`),
|
|
51
|
+
TEST: new RegExp(`^TEST_${uuidPattern}$`),
|
|
52
|
+
TEST_CASE: new RegExp(`^TEST_CASE_${uuidPattern}$`),
|
|
53
|
+
TEST_VAR: new RegExp(`^TEST_VAR_${uuidPattern}$`),
|
|
54
|
+
AUTOMATION_MAP: /^AUTOMATION_MAP_.*/,
|
|
55
|
+
} as const
|
|
56
|
+
|
|
57
|
+
type EntryIdPatternKey = keyof typeof entryIdPatterns
|
|
58
|
+
|
|
59
|
+
const assertEntryId = (
|
|
60
|
+
id: unknown,
|
|
61
|
+
patternKey: EntryIdPatternKey,
|
|
62
|
+
errorReference: string = '',
|
|
63
|
+
): string => {
|
|
64
|
+
const pattern = entryIdPatterns[patternKey]
|
|
65
|
+
if (typeof id !== 'string' || !pattern.test(id)) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`Invalid ${patternKey} id${errorReference ? ` ${errorReference}` : ''}: ${String(id)}`,
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
return id
|
|
71
|
+
}
|
|
72
|
+
|
|
36
73
|
const compileProperty = (property, errorReference: string, result = {}) => {
|
|
37
74
|
if (Array.isArray(property)) {
|
|
38
75
|
return property.map((p) => compileProperty(p, errorReference))
|
|
@@ -56,21 +93,46 @@ const compileProperty = (property, errorReference: string, result = {}) => {
|
|
|
56
93
|
return property
|
|
57
94
|
}
|
|
58
95
|
|
|
96
|
+
const compileScriptCalculationCode = (code = '') => {
|
|
97
|
+
try {
|
|
98
|
+
const program = parseAST(code, { sourceType: 'module', ecmaVersion: 2020 })
|
|
99
|
+
// export function main() { ... }
|
|
100
|
+
const declarationBody = (
|
|
101
|
+
(program.body[0] as ExportNamedDeclaration).declaration as FunctionDeclaration
|
|
102
|
+
)?.body
|
|
103
|
+
return escodegen.generate(declarationBody, {
|
|
104
|
+
format: {
|
|
105
|
+
indent: { style: ' ' },
|
|
106
|
+
semicolons: false,
|
|
107
|
+
},
|
|
108
|
+
comment: true,
|
|
109
|
+
})
|
|
110
|
+
} catch {
|
|
111
|
+
return code || ''
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const getTemplateName = (key: string) =>
|
|
116
|
+
upperFirst(camelCase(key.replace(/^(BRICK|GENERATOR)_/, '')))
|
|
117
|
+
|
|
59
118
|
const compileEventActionValue = (templateKey, eventKey, value, errorReference) => {
|
|
60
|
-
const tmplEventProperties = templateEventPropsMap[templateKey]
|
|
119
|
+
const tmplEventProperties = templateEventPropsMap[getTemplateName(templateKey)]
|
|
61
120
|
const props = tmplEventProperties?.[eventKey]
|
|
62
121
|
if (!props) return compileProperty(value, errorReference)
|
|
63
|
-
if (
|
|
64
|
-
|
|
122
|
+
if (typeof value === 'string' && value in props) {
|
|
123
|
+
const expectedType = props[value]
|
|
124
|
+
if (expectedType) return value
|
|
125
|
+
}
|
|
126
|
+
if (typeof value === 'string' && /^(BRICK|GENERATOR)_/.test(value)) {
|
|
65
127
|
console.warn(
|
|
66
|
-
`[Warning]
|
|
128
|
+
`[Warning] Event property "${value}" is not compatible with event "${eventKey}" of ${templateKey} ${errorReference}`,
|
|
67
129
|
)
|
|
68
130
|
}
|
|
69
131
|
return compileProperty(value, errorReference)
|
|
70
132
|
}
|
|
71
133
|
|
|
72
134
|
const convertOutletKey = (templateKey: string, key: string) =>
|
|
73
|
-
`${templateKey}_${
|
|
135
|
+
`${templateKey}_${snakeCase(key).toUpperCase()}`
|
|
74
136
|
|
|
75
137
|
const compileOutlets = (
|
|
76
138
|
templateKey: string,
|
|
@@ -78,13 +140,14 @@ const compileOutlets = (
|
|
|
78
140
|
errorReference: string,
|
|
79
141
|
) =>
|
|
80
142
|
Object.entries(outlets).reduce((acc, [key, data]) => {
|
|
81
|
-
|
|
82
|
-
|
|
143
|
+
const dataInstance = data?.()
|
|
144
|
+
const dataId = assertEntryId(dataInstance?.id, 'PROPERTY_BANK_DATA_NODE', errorReference)
|
|
145
|
+
acc[convertOutletKey(templateKey, key)] = dataId
|
|
83
146
|
return acc
|
|
84
147
|
}, {})
|
|
85
148
|
|
|
86
149
|
const convertEventKey = (templateKey: string, key: string) =>
|
|
87
|
-
`${templateKey ? `${templateKey}_` : ''}${
|
|
150
|
+
`${templateKey ? `${templateKey}_` : ''}${snakeCase(key).toUpperCase()}`
|
|
88
151
|
|
|
89
152
|
const basicAnimationEvents = ['show', 'standby', 'breatheStart']
|
|
90
153
|
|
|
@@ -94,9 +157,9 @@ const compileAnimations = (
|
|
|
94
157
|
errorReference: string,
|
|
95
158
|
) =>
|
|
96
159
|
Object.entries(animations).reduce((acc, [key, animation]) => {
|
|
97
|
-
|
|
160
|
+
const animationId = assertEntryId(animation?.id, 'ANIMATION', errorReference)
|
|
98
161
|
acc[convertEventKey(basicAnimationEvents.includes(key) ? 'BRICK' : templateKey, key)] =
|
|
99
|
-
`ANIMATION#${
|
|
162
|
+
`ANIMATION#${animationId}`
|
|
100
163
|
return acc
|
|
101
164
|
}, {})
|
|
102
165
|
|
|
@@ -133,7 +196,7 @@ const compileEvents = (
|
|
|
133
196
|
if (!handlerKey) throw new Error(`Invalid handler: ${handler} ${errorReference}`)
|
|
134
197
|
|
|
135
198
|
const parameterList: Array<object> = []
|
|
136
|
-
if (Object.
|
|
199
|
+
if (Object.prototype.hasOwnProperty.call(action, 'params')) {
|
|
137
200
|
const actionDef = action as ActionWithParams
|
|
138
201
|
;(actionDef.params || []).forEach(({ input, value, mapping }) => {
|
|
139
202
|
const param = {
|
|
@@ -146,7 +209,7 @@ const compileEvents = (
|
|
|
146
209
|
if (mapping) param[camelCase ? 'resultDataMapping' : 'result_data_mapping'] = true
|
|
147
210
|
parameterList.push(param)
|
|
148
211
|
})
|
|
149
|
-
} else if (Object.
|
|
212
|
+
} else if (Object.prototype.hasOwnProperty.call(action, 'dataParams')) {
|
|
150
213
|
const actionDef = action as ActionWithDataParams
|
|
151
214
|
;(actionDef.dataParams || []).forEach(({ input, value, mapping }) => {
|
|
152
215
|
if (!input) return
|
|
@@ -230,6 +293,7 @@ const compileApplicationSettings = (settings: Application['settings']) => ({
|
|
|
230
293
|
use_gemini_api_key_system_data: settings.ai.useGeminiApiKeySystemData,
|
|
231
294
|
}
|
|
232
295
|
: undefined,
|
|
296
|
+
hide_short_refs: settings?.hideShortRefs,
|
|
233
297
|
})
|
|
234
298
|
|
|
235
299
|
const animationTypeMap = {
|
|
@@ -349,20 +413,28 @@ function compileRunArray(run: unknown[]): unknown[] {
|
|
|
349
413
|
const compileTestCase = (testCase: TestCase) => ({
|
|
350
414
|
id: testCase.id,
|
|
351
415
|
name: testCase.name,
|
|
416
|
+
hide_short_ref: testCase.hideShortRef,
|
|
352
417
|
run: compileRunArray(testCase.run),
|
|
353
418
|
exit_on_failed: testCase.exit_on_failed,
|
|
354
419
|
commented: testCase.commented,
|
|
355
420
|
pre_delay: testCase.pre_delay,
|
|
356
421
|
post_delay: testCase.post_delay,
|
|
357
422
|
post_delay_rule: testCase.post_delay_rule,
|
|
358
|
-
jump_cond: testCase.jump_cond.map((cond) =>
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
423
|
+
jump_cond: testCase.jump_cond.map((cond) => {
|
|
424
|
+
if (cond.jump_to == null) {
|
|
425
|
+
console.warn(
|
|
426
|
+
`[Warning] jump_cond is missing jump_to in test case "${testCase.name}" (${testCase.id})`,
|
|
427
|
+
)
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
type: cond.type,
|
|
431
|
+
status: cond.status,
|
|
432
|
+
variable: cond.variable,
|
|
433
|
+
operator: cond.operator,
|
|
434
|
+
value: cond.value,
|
|
435
|
+
jump_to: cond.jump_to,
|
|
436
|
+
}
|
|
437
|
+
}),
|
|
366
438
|
})
|
|
367
439
|
|
|
368
440
|
/**
|
|
@@ -380,43 +452,89 @@ const compileTestVariable = (variable: TestVariable) => ({
|
|
|
380
452
|
*/
|
|
381
453
|
const arrayToIdMap = <T extends { id: string }, R>(
|
|
382
454
|
items: T[],
|
|
383
|
-
transform: (item: T) => R,
|
|
384
|
-
|
|
455
|
+
transform: (item: T, index: number) => R,
|
|
456
|
+
options: {
|
|
457
|
+
patternKey: EntryIdPatternKey
|
|
458
|
+
getErrorReference: (item: T, index: number) => string
|
|
459
|
+
},
|
|
460
|
+
): Record<string, R> =>
|
|
461
|
+
Object.fromEntries(
|
|
462
|
+
items.map((item, index) => {
|
|
463
|
+
const itemId = assertEntryId(
|
|
464
|
+
item.id,
|
|
465
|
+
options.patternKey,
|
|
466
|
+
options.getErrorReference(item, index),
|
|
467
|
+
)
|
|
468
|
+
return [itemId, transform(item, index)]
|
|
469
|
+
}),
|
|
470
|
+
)
|
|
385
471
|
|
|
386
472
|
/**
|
|
387
473
|
* Compile typed AutomationTest to raw format
|
|
388
474
|
*/
|
|
389
|
-
const compileAutomationTest = (
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
475
|
+
const compileAutomationTest = (
|
|
476
|
+
test: AutomationTest,
|
|
477
|
+
options: { mapId: string; testIndex: number },
|
|
478
|
+
) => {
|
|
479
|
+
const testId = assertEntryId(
|
|
480
|
+
test.id,
|
|
481
|
+
'TEST',
|
|
482
|
+
`(automation map: ${options.mapId}, test index: ${options.testIndex})`,
|
|
483
|
+
)
|
|
484
|
+
|
|
485
|
+
return {
|
|
486
|
+
id: testId,
|
|
487
|
+
title: test.title,
|
|
488
|
+
hide_short_ref: test.hideShortRef,
|
|
489
|
+
timeout: test.timeout,
|
|
490
|
+
trigger_type: test.trigger_type,
|
|
491
|
+
cron: test.cron,
|
|
492
|
+
skip_trigger_type_check: test.skip_trigger_type_check,
|
|
493
|
+
local_sync: test.local_sync,
|
|
494
|
+
meta: test.meta,
|
|
495
|
+
case_map: arrayToIdMap(test.cases, compileTestCase, {
|
|
496
|
+
patternKey: 'TEST_CASE',
|
|
497
|
+
getErrorReference: (_, index) =>
|
|
498
|
+
`(automation map: ${options.mapId}, test: ${testId}, case index: ${index})`,
|
|
499
|
+
}),
|
|
500
|
+
var_map: arrayToIdMap(test.variables, compileTestVariable, {
|
|
501
|
+
patternKey: 'TEST_VAR',
|
|
502
|
+
getErrorReference: (_, index) =>
|
|
503
|
+
`(automation map: ${options.mapId}, test: ${testId}, variable index: ${index})`,
|
|
504
|
+
}),
|
|
505
|
+
}
|
|
506
|
+
}
|
|
401
507
|
|
|
402
508
|
/**
|
|
403
509
|
* Compile typed AutomationTestMap to raw format
|
|
404
510
|
*/
|
|
405
|
-
const compileAutomationTestMap = (testMap: AutomationTestMap) =>
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
511
|
+
const compileAutomationTestMap = (testMap: AutomationTestMap, mapId: string) => {
|
|
512
|
+
assertEntryId(testMap.id, 'AUTOMATION_MAP', `(automation map id field: ${mapId})`)
|
|
513
|
+
|
|
514
|
+
return {
|
|
515
|
+
title: testMap.title,
|
|
516
|
+
hide_short_ref: testMap.hideShortRef,
|
|
517
|
+
createdAt: testMap.createdAt,
|
|
518
|
+
map: arrayToIdMap(
|
|
519
|
+
testMap.tests,
|
|
520
|
+
(test, index) => compileAutomationTest(test, { mapId, testIndex: index }),
|
|
521
|
+
{
|
|
522
|
+
patternKey: 'TEST',
|
|
523
|
+
getErrorReference: (_, index) => `(automation map: ${mapId}, test index: ${index})`,
|
|
524
|
+
},
|
|
525
|
+
),
|
|
526
|
+
}
|
|
527
|
+
}
|
|
410
528
|
|
|
411
529
|
/**
|
|
412
530
|
* Compile typed AutomationMap to raw automation_map format
|
|
413
531
|
*/
|
|
414
532
|
const compileAutomation = (automationMap: AutomationMap) =>
|
|
415
533
|
Object.fromEntries(
|
|
416
|
-
Object.entries(automationMap).map(([mapId, testMap]) =>
|
|
417
|
-
mapId,
|
|
418
|
-
compileAutomationTestMap(testMap)
|
|
419
|
-
|
|
534
|
+
Object.entries(automationMap).map(([mapId, testMap]) => {
|
|
535
|
+
const automationMapId = assertEntryId(mapId, 'AUTOMATION_MAP', '(automation map key)')
|
|
536
|
+
return [automationMapId, compileAutomationTestMap(testMap, automationMapId)]
|
|
537
|
+
}),
|
|
420
538
|
)
|
|
421
539
|
|
|
422
540
|
export const compile = async (app: Application) => {
|
|
@@ -424,16 +542,35 @@ export const compile = async (app: Application) => {
|
|
|
424
542
|
const timestamp = Date.now()
|
|
425
543
|
const config = {
|
|
426
544
|
title: `${app.name || 'Unknown'}(${timestamp})`,
|
|
427
|
-
subspace_map: app.subspaces.reduce((subspaceMap, subspace) => {
|
|
428
|
-
|
|
545
|
+
subspace_map: app.subspaces.reduce((subspaceMap, subspace, subspaceIndex) => {
|
|
546
|
+
const subspaceId = assertEntryId(
|
|
547
|
+
subspace.id,
|
|
548
|
+
'SUBSPACE',
|
|
549
|
+
`(subspace index: ${subspaceIndex})`,
|
|
550
|
+
)
|
|
551
|
+
const rootCanvasId = assertEntryId(
|
|
552
|
+
subspace.rootCanvas?.id,
|
|
553
|
+
'CANVAS',
|
|
554
|
+
`(subspace: ${subspaceId}, root canvas)`,
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
subspaceMap[subspaceId] = {
|
|
429
558
|
title: subspace.title,
|
|
430
559
|
description: subspace.description,
|
|
560
|
+
hide_short_ref: subspace.hideShortRef,
|
|
561
|
+
unused: subspace.unused,
|
|
562
|
+
portal: subspace.portal,
|
|
431
563
|
_expanded: subspace.unexpanded
|
|
432
564
|
? {
|
|
433
565
|
brick: !subspace.unexpanded.brick,
|
|
434
566
|
generator: !subspace.unexpanded.generator,
|
|
435
|
-
canvas: subspace.unexpanded.canvas?.reduce((acc, canvas) => {
|
|
436
|
-
|
|
567
|
+
canvas: subspace.unexpanded.canvas?.reduce((acc, canvas, canvasIndex) => {
|
|
568
|
+
const unexpandedCanvasId = assertEntryId(
|
|
569
|
+
canvas?.id,
|
|
570
|
+
'CANVAS',
|
|
571
|
+
`(subspace: ${subspaceId}, unexpanded canvas index: ${canvasIndex})`,
|
|
572
|
+
)
|
|
573
|
+
acc[unexpandedCanvasId] = !canvas?.id
|
|
437
574
|
return acc
|
|
438
575
|
}, {}),
|
|
439
576
|
property_bank: !subspace.unexpanded.data,
|
|
@@ -450,32 +587,42 @@ export const compile = async (app: Application) => {
|
|
|
450
587
|
change_canvas: subspace.localSyncChangeCanvas,
|
|
451
588
|
}
|
|
452
589
|
: undefined,
|
|
453
|
-
animation_map: subspace.animations.reduce((map, animation) => {
|
|
590
|
+
animation_map: subspace.animations.reduce((map, animation, animationIndex) => {
|
|
591
|
+
const animationId = assertEntryId(
|
|
592
|
+
animation?.id,
|
|
593
|
+
'ANIMATION',
|
|
594
|
+
`(animation index: ${animationIndex}, subspace: ${subspaceId})`,
|
|
595
|
+
)
|
|
596
|
+
|
|
454
597
|
if (animation.__typename === 'Animation') {
|
|
455
598
|
const animationDef = animation as AnimationDef
|
|
456
|
-
map[
|
|
599
|
+
map[animationId] = {
|
|
600
|
+
alias: animationDef.alias,
|
|
457
601
|
title: animationDef.title,
|
|
458
602
|
description: animationDef.description,
|
|
603
|
+
hide_short_ref: animationDef.hideShortRef,
|
|
459
604
|
animationRunType: animationDef.runType,
|
|
460
605
|
property: animationDef.property,
|
|
461
606
|
type: animationTypeMap[animationDef.config.__type],
|
|
462
607
|
config: compileProperty(
|
|
463
|
-
|
|
464
|
-
`(animation: ${
|
|
608
|
+
omit(animationDef.config, '__type'),
|
|
609
|
+
`(animation: ${animationId}, subspace ${subspaceId})`,
|
|
465
610
|
),
|
|
466
611
|
}
|
|
467
612
|
} else if (animation.__typename === 'AnimationCompose') {
|
|
468
613
|
const animationDef = animation as AnimationComposeDef
|
|
469
|
-
map[
|
|
614
|
+
map[animationId] = {
|
|
615
|
+
alias: animationDef.alias,
|
|
470
616
|
title: animationDef.title,
|
|
471
617
|
description: animationDef.description,
|
|
618
|
+
hide_short_ref: animationDef.hideShortRef,
|
|
472
619
|
animationRunType: animationDef.runType,
|
|
473
620
|
compose_type: animationDef.composeType,
|
|
474
621
|
item_list: animationDef.items.map((item, index) => {
|
|
475
622
|
const innerAnimation = item()
|
|
476
623
|
if (!innerAnimation?.id)
|
|
477
624
|
throw new Error(
|
|
478
|
-
`Invalid animation index: ${index} (animation: ${innerAnimation.id}, subspace ${
|
|
625
|
+
`Invalid animation index: ${index} (animation: ${innerAnimation.id}, subspace ${subspaceId})`,
|
|
479
626
|
)
|
|
480
627
|
return { animation_id: innerAnimation.id }
|
|
481
628
|
}),
|
|
@@ -483,10 +630,15 @@ export const compile = async (app: Application) => {
|
|
|
483
630
|
}
|
|
484
631
|
return map
|
|
485
632
|
}, {}),
|
|
486
|
-
brick_map: subspace.bricks.reduce((map, brick) => {
|
|
633
|
+
brick_map: subspace.bricks.reduce((map, brick, brickIndex) => {
|
|
634
|
+
const brickId = assertEntryId(
|
|
635
|
+
brick.id,
|
|
636
|
+
'BRICK',
|
|
637
|
+
`(brick index: ${brickIndex}, subspace: ${subspaceId})`,
|
|
638
|
+
)
|
|
487
639
|
const property = compileProperty(
|
|
488
640
|
brick.property || {},
|
|
489
|
-
`(brick: ${
|
|
641
|
+
`(brick: ${brickId}, subspace ${subspaceId})`,
|
|
490
642
|
)
|
|
491
643
|
if (brick.templateKey === 'BRICK_ITEMS') {
|
|
492
644
|
const brickItems = brick as BrickItems
|
|
@@ -498,25 +650,31 @@ export const compile = async (app: Application) => {
|
|
|
498
650
|
frame: itemBrick.frame,
|
|
499
651
|
property: compileProperty(
|
|
500
652
|
itemBrick.property,
|
|
501
|
-
`(brick: ${
|
|
653
|
+
`(brick: ${brickId}, ${key}: ${index}, subspace ${subspaceId})`,
|
|
502
654
|
),
|
|
503
655
|
propertyMapping: itemBrick.propertyMapping,
|
|
504
656
|
animation: compileAnimations(
|
|
505
657
|
itemBrick.templateKey,
|
|
506
658
|
itemBrick.animation || {},
|
|
507
|
-
`(brick: ${
|
|
659
|
+
`(brick: ${brickId}, ${key}: ${index}, subspace ${subspaceId})`,
|
|
508
660
|
),
|
|
509
661
|
outlet: compileOutlets(
|
|
510
662
|
itemBrick.templateKey,
|
|
511
663
|
itemBrick.outlets || {},
|
|
512
|
-
`(brick: ${
|
|
664
|
+
`(brick: ${brickId}, ${key}: ${index}, subspace ${subspaceId})`,
|
|
513
665
|
),
|
|
514
666
|
eventMap: compileEvents(itemBrick.templateKey, itemBrick.eventMap || {}, {
|
|
515
667
|
camelCase: true,
|
|
516
|
-
errorReference: `(brick: ${
|
|
668
|
+
errorReference: `(brick: ${brickId}, ${key}: ${index}, subspace ${subspaceId})`,
|
|
517
669
|
}),
|
|
518
|
-
stateGroup: itemBrick.stateGroup.reduce((acc, stateGroup) => {
|
|
519
|
-
|
|
670
|
+
stateGroup: itemBrick.stateGroup.reduce((acc, stateGroup, stateGroupIndex) => {
|
|
671
|
+
const stateGroupId = assertEntryId(
|
|
672
|
+
stateGroup.id,
|
|
673
|
+
'BRICK_STATE_GROUP',
|
|
674
|
+
`(brick: ${brickId}, ${key}: ${index}, switch index: ${stateGroupIndex}, subspace ${subspaceId})`,
|
|
675
|
+
)
|
|
676
|
+
|
|
677
|
+
acc[stateGroupId] = {
|
|
520
678
|
title: stateGroup.title,
|
|
521
679
|
description: stateGroup.description,
|
|
522
680
|
override: stateGroup.override,
|
|
@@ -525,35 +683,40 @@ export const compile = async (app: Application) => {
|
|
|
525
683
|
conds: compileSwitchConds(
|
|
526
684
|
itemBrick.templateKey,
|
|
527
685
|
stateGroup.conds || [],
|
|
528
|
-
`(brick: ${
|
|
686
|
+
`(brick: ${brickId}, ${key}: ${index}, switch: ${stateGroupId}, subspace ${subspaceId})`,
|
|
529
687
|
),
|
|
530
688
|
property: compileProperty(
|
|
531
689
|
stateGroup.property,
|
|
532
|
-
`(brick: ${
|
|
690
|
+
`(brick: ${brickId}, ${key}: ${index}, switch: ${stateGroupId}, subspace ${subspaceId})`,
|
|
533
691
|
),
|
|
534
692
|
animation: compileAnimations(
|
|
535
693
|
itemBrick.templateKey,
|
|
536
694
|
stateGroup.animation || {},
|
|
537
|
-
`(brick: ${
|
|
695
|
+
`(brick: ${brickId}, ${key}: ${index}, switch: ${stateGroupId}, subspace ${subspaceId})`,
|
|
538
696
|
),
|
|
539
697
|
outlet: compileOutlets(
|
|
540
698
|
itemBrick.templateKey,
|
|
541
699
|
stateGroup.outlets || {},
|
|
542
|
-
`(brick: ${
|
|
700
|
+
`(brick: ${brickId}, ${key}: ${index}, switch: ${stateGroupId}, subspace ${subspaceId})`,
|
|
543
701
|
),
|
|
544
702
|
eventMap: compileEvents(itemBrick.templateKey, stateGroup.eventMap || {}, {
|
|
545
703
|
camelCase: true,
|
|
546
|
-
errorReference: `(brick: ${
|
|
704
|
+
errorReference: `(brick: ${brickId}, ${key}: ${index}, switch: ${stateGroupId}, subspace ${subspaceId})`,
|
|
547
705
|
}),
|
|
548
706
|
}
|
|
549
707
|
return acc
|
|
550
708
|
}, {}),
|
|
709
|
+
show: itemBrick.show,
|
|
710
|
+
pressToOpenDetail: itemBrick.pressToOpenDetail,
|
|
711
|
+
pressToBackList: itemBrick.pressToBackList,
|
|
551
712
|
})
|
|
552
713
|
if (Array.isArray(brickItems.brickList)) {
|
|
553
714
|
const brickList = (brickItems.brickList || []).map((item, index) =>
|
|
554
715
|
buildList(item, index, 'brickList'),
|
|
555
716
|
)
|
|
556
717
|
property.brickList = brickList
|
|
718
|
+
} else if (!brickItems.brickList) {
|
|
719
|
+
property.brickList = []
|
|
557
720
|
} else {
|
|
558
721
|
// Not supported Data for brickList
|
|
559
722
|
throw new TypeError('Not supported Data for brickList directly')
|
|
@@ -563,32 +726,42 @@ export const compile = async (app: Application) => {
|
|
|
563
726
|
buildList(item, index, 'brickDetails'),
|
|
564
727
|
)
|
|
565
728
|
property.brickDetails = brickDetails
|
|
729
|
+
} else if (!brickItems.brickDetails) {
|
|
730
|
+
property.brickDetails = []
|
|
566
731
|
} else {
|
|
567
732
|
// Not supported Data for brickList
|
|
568
733
|
throw new TypeError('Not supported Data for brickList directly')
|
|
569
734
|
}
|
|
570
735
|
}
|
|
571
|
-
map[
|
|
736
|
+
map[brickId] = {
|
|
572
737
|
template_key: brick.templateKey,
|
|
738
|
+
alias: brick.alias,
|
|
573
739
|
title: brick.title,
|
|
574
740
|
description: brick.description,
|
|
741
|
+
hide_short_ref: brick.hideShortRef,
|
|
575
742
|
property,
|
|
576
743
|
animation: compileAnimations(
|
|
577
744
|
brick.templateKey,
|
|
578
745
|
brick.animation || {},
|
|
579
|
-
`(brick: ${
|
|
746
|
+
`(brick: ${brickId}, subspace ${subspaceId})`,
|
|
580
747
|
),
|
|
581
748
|
event_map: compileEvents(brick.templateKey, brick.events || {}, {
|
|
582
749
|
camelCase: false,
|
|
583
|
-
errorReference: `(brick: ${
|
|
750
|
+
errorReference: `(brick: ${brickId}, subspace ${subspaceId})`,
|
|
584
751
|
}),
|
|
585
752
|
outlet: compileOutlets(
|
|
586
753
|
brick.templateKey,
|
|
587
754
|
brick.outlets || {},
|
|
588
|
-
`(brick: ${
|
|
755
|
+
`(brick: ${brickId}, subspace ${subspaceId})`,
|
|
589
756
|
),
|
|
590
|
-
state_group: brick.switches?.reduce((acc, switchCase) => {
|
|
591
|
-
|
|
757
|
+
state_group: brick.switches?.reduce((acc, switchCase, switchIndex) => {
|
|
758
|
+
const switchId = assertEntryId(
|
|
759
|
+
switchCase.id,
|
|
760
|
+
'BRICK_STATE_GROUP',
|
|
761
|
+
`(brick: ${brickId}, switch index: ${switchIndex}, subspace ${subspaceId})`,
|
|
762
|
+
)
|
|
763
|
+
|
|
764
|
+
acc[switchId] = {
|
|
592
765
|
title: switchCase.title,
|
|
593
766
|
description: switchCase.description,
|
|
594
767
|
break: switchCase.break,
|
|
@@ -597,25 +770,25 @@ export const compile = async (app: Application) => {
|
|
|
597
770
|
conds: compileSwitchConds(
|
|
598
771
|
brick.templateKey,
|
|
599
772
|
switchCase.conds || [],
|
|
600
|
-
`(brick: ${
|
|
773
|
+
`(brick: ${brickId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
601
774
|
),
|
|
602
775
|
property: compileProperty(
|
|
603
776
|
switchCase.property,
|
|
604
|
-
`(brick: ${
|
|
777
|
+
`(brick: ${brickId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
605
778
|
),
|
|
606
779
|
outlet: compileOutlets(
|
|
607
780
|
brick.templateKey,
|
|
608
781
|
switchCase.outlets || {},
|
|
609
|
-
`(brick: ${
|
|
782
|
+
`(brick: ${brickId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
610
783
|
),
|
|
611
784
|
event_map: compileEvents(brick.templateKey, switchCase.events || {}, {
|
|
612
785
|
camelCase: false,
|
|
613
|
-
errorReference: `(brick: ${
|
|
786
|
+
errorReference: `(brick: ${brickId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
614
787
|
}),
|
|
615
788
|
animation: compileAnimations(
|
|
616
789
|
brick.templateKey,
|
|
617
790
|
switchCase.animation || {},
|
|
618
|
-
`(brick: ${
|
|
791
|
+
`(brick: ${brickId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
619
792
|
),
|
|
620
793
|
}
|
|
621
794
|
return acc
|
|
@@ -623,21 +796,35 @@ export const compile = async (app: Application) => {
|
|
|
623
796
|
}
|
|
624
797
|
return map
|
|
625
798
|
}, {}),
|
|
626
|
-
root_canvas_id:
|
|
627
|
-
canvas_map: subspace.canvases.reduce((map, canvas) => {
|
|
628
|
-
|
|
799
|
+
root_canvas_id: rootCanvasId,
|
|
800
|
+
canvas_map: subspace.canvases.reduce((map, canvas, canvasIndex) => {
|
|
801
|
+
const canvasId = assertEntryId(
|
|
802
|
+
canvas.id,
|
|
803
|
+
'CANVAS',
|
|
804
|
+
`(canvas index: ${canvasIndex}, subspace: ${subspaceId})`,
|
|
805
|
+
)
|
|
806
|
+
|
|
807
|
+
map[canvasId] = {
|
|
808
|
+
alias: canvas.alias,
|
|
629
809
|
title: canvas.title,
|
|
630
810
|
description: canvas.description,
|
|
811
|
+
hide_short_ref: canvas.hideShortRef,
|
|
631
812
|
property: compileProperty(
|
|
632
813
|
canvas.property,
|
|
633
|
-
`(canvas: ${
|
|
814
|
+
`(canvas: ${canvasId}, subspace ${subspaceId})`,
|
|
634
815
|
),
|
|
635
816
|
event_map: compileEvents('CANVAS', canvas.events || {}, {
|
|
636
817
|
camelCase: false,
|
|
637
|
-
errorReference: `(canvas: ${
|
|
818
|
+
errorReference: `(canvas: ${canvasId}, subspace ${subspaceId})`,
|
|
638
819
|
}),
|
|
639
|
-
state_group: canvas.switches?.reduce((acc, switchCase) => {
|
|
640
|
-
|
|
820
|
+
state_group: canvas.switches?.reduce((acc, switchCase, switchIndex) => {
|
|
821
|
+
const switchId = assertEntryId(
|
|
822
|
+
switchCase.id,
|
|
823
|
+
'BRICK_STATE_GROUP',
|
|
824
|
+
`(canvas: ${canvasId}, switch index: ${switchIndex}, subspace ${subspaceId})`,
|
|
825
|
+
)
|
|
826
|
+
|
|
827
|
+
acc[switchId] = {
|
|
641
828
|
title: switchCase.title,
|
|
642
829
|
description: switchCase.description,
|
|
643
830
|
break: switchCase.break,
|
|
@@ -646,20 +833,20 @@ export const compile = async (app: Application) => {
|
|
|
646
833
|
conds: compileSwitchConds(
|
|
647
834
|
'CANVAS',
|
|
648
835
|
switchCase.conds || [],
|
|
649
|
-
`(canvas: ${
|
|
836
|
+
`(canvas: ${canvasId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
650
837
|
),
|
|
651
838
|
property: compileProperty(
|
|
652
839
|
switchCase.property,
|
|
653
|
-
`(canvas: ${
|
|
840
|
+
`(canvas: ${canvasId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
654
841
|
),
|
|
655
842
|
event_map: compileEvents('CANVAS', switchCase.events || {}, {
|
|
656
843
|
camelCase: false,
|
|
657
|
-
errorReference: `(canvas: ${
|
|
844
|
+
errorReference: `(canvas: ${canvasId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
658
845
|
}),
|
|
659
846
|
animation: compileAnimations(
|
|
660
847
|
'CANVAS',
|
|
661
848
|
switchCase.animation || {},
|
|
662
|
-
`(canvas: ${
|
|
849
|
+
`(canvas: ${canvasId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
663
850
|
),
|
|
664
851
|
}
|
|
665
852
|
return acc
|
|
@@ -670,16 +857,16 @@ export const compile = async (app: Application) => {
|
|
|
670
857
|
const brick = (item.item as () => Brick)()
|
|
671
858
|
if (!brick?.id)
|
|
672
859
|
throw new Error(
|
|
673
|
-
`Invalid canvas item index: ${index}, brick not found (canvas: ${
|
|
860
|
+
`Invalid canvas item index: ${index}, brick not found (canvas: ${canvasId}, subspace ${subspaceId})`,
|
|
674
861
|
)
|
|
675
862
|
itemPayload = { brick_id: brick.id }
|
|
676
863
|
} else {
|
|
677
|
-
const
|
|
678
|
-
if (!app.subspaces.some((s) => s.id ===
|
|
864
|
+
const targetSubspaceId = item.item
|
|
865
|
+
if (!app.subspaces.some((s) => s.id === targetSubspaceId))
|
|
679
866
|
throw new Error(
|
|
680
|
-
`Invalid canvas item index: ${index}, subspace not found (canvas: ${
|
|
867
|
+
`Invalid canvas item index: ${index}, subspace not found (canvas: ${canvasId}, subspace ${subspaceId})`,
|
|
681
868
|
)
|
|
682
|
-
itemPayload = { subspace_id:
|
|
869
|
+
itemPayload = { subspace_id: targetSubspaceId }
|
|
683
870
|
}
|
|
684
871
|
return {
|
|
685
872
|
type: typeof item.item === 'function' ? 'brick' : 'subspace',
|
|
@@ -691,11 +878,19 @@ export const compile = async (app: Application) => {
|
|
|
691
878
|
}
|
|
692
879
|
return map
|
|
693
880
|
}, {}),
|
|
694
|
-
generator_map: subspace.generators.reduce((map, generator) => {
|
|
695
|
-
|
|
881
|
+
generator_map: subspace.generators.reduce((map, generator, generatorIndex) => {
|
|
882
|
+
const generatorId = assertEntryId(
|
|
883
|
+
generator.id,
|
|
884
|
+
'GENERATOR',
|
|
885
|
+
`(generator index: ${generatorIndex}, subspace: ${subspaceId})`,
|
|
886
|
+
)
|
|
887
|
+
|
|
888
|
+
map[generatorId] = {
|
|
696
889
|
template_key: generator.templateKey,
|
|
890
|
+
alias: generator.alias,
|
|
697
891
|
title: generator.title,
|
|
698
892
|
description: generator.description,
|
|
893
|
+
hide_short_ref: generator.hideShortRef,
|
|
699
894
|
local_sync: generator.localSyncRunMode
|
|
700
895
|
? {
|
|
701
896
|
run_mode: generator.localSyncRunMode,
|
|
@@ -703,19 +898,25 @@ export const compile = async (app: Application) => {
|
|
|
703
898
|
: undefined,
|
|
704
899
|
property: compileProperty(
|
|
705
900
|
generator.property || {},
|
|
706
|
-
`(generator: ${
|
|
901
|
+
`(generator: ${generatorId}, subspace ${subspaceId})`,
|
|
707
902
|
),
|
|
708
903
|
event_map: compileEvents(generator.templateKey, generator.events || {}, {
|
|
709
904
|
camelCase: false,
|
|
710
|
-
errorReference: `(generator: ${
|
|
905
|
+
errorReference: `(generator: ${generatorId}, subspace ${subspaceId})`,
|
|
711
906
|
}),
|
|
712
907
|
outlet: compileOutlets(
|
|
713
908
|
generator.templateKey,
|
|
714
909
|
generator.outlets || {},
|
|
715
|
-
`(generator: ${
|
|
910
|
+
`(generator: ${generatorId}, subspace ${subspaceId})`,
|
|
716
911
|
),
|
|
717
|
-
state_group: generator.switches?.reduce((acc, switchCase) => {
|
|
718
|
-
|
|
912
|
+
state_group: generator.switches?.reduce((acc, switchCase, switchIndex) => {
|
|
913
|
+
const switchId = assertEntryId(
|
|
914
|
+
switchCase.id,
|
|
915
|
+
'BRICK_STATE_GROUP',
|
|
916
|
+
`(generator: ${generatorId}, switch index: ${switchIndex}, subspace ${subspaceId})`,
|
|
917
|
+
)
|
|
918
|
+
|
|
919
|
+
acc[switchId] = {
|
|
719
920
|
title: switchCase.title,
|
|
720
921
|
description: switchCase.description,
|
|
721
922
|
break: switchCase.break,
|
|
@@ -724,25 +925,25 @@ export const compile = async (app: Application) => {
|
|
|
724
925
|
conds: compileSwitchConds(
|
|
725
926
|
generator.templateKey,
|
|
726
927
|
switchCase.conds || [],
|
|
727
|
-
`(generator: ${
|
|
928
|
+
`(generator: ${generatorId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
728
929
|
),
|
|
729
930
|
property: compileProperty(
|
|
730
931
|
switchCase.property,
|
|
731
|
-
`(generator: ${
|
|
932
|
+
`(generator: ${generatorId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
732
933
|
),
|
|
733
934
|
outlet: compileOutlets(
|
|
734
935
|
generator.templateKey,
|
|
735
936
|
switchCase.outlets || {},
|
|
736
|
-
`(generator: ${
|
|
937
|
+
`(generator: ${generatorId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
737
938
|
),
|
|
738
939
|
event_map: compileEvents(generator.templateKey, switchCase.events || {}, {
|
|
739
940
|
camelCase: false,
|
|
740
|
-
errorReference: `(generator: ${
|
|
941
|
+
errorReference: `(generator: ${generatorId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
741
942
|
}),
|
|
742
943
|
animation: compileAnimations(
|
|
743
944
|
generator.templateKey,
|
|
744
945
|
switchCase.animation || {},
|
|
745
|
-
`(generator: ${
|
|
946
|
+
`(generator: ${generatorId}, switch: ${switchId}, subspace ${subspaceId})`,
|
|
746
947
|
),
|
|
747
948
|
}
|
|
748
949
|
return acc
|
|
@@ -750,10 +951,18 @@ export const compile = async (app: Application) => {
|
|
|
750
951
|
}
|
|
751
952
|
return map
|
|
752
953
|
}, {}),
|
|
753
|
-
property_bank_map: subspace.data.reduce((map, data) => {
|
|
754
|
-
|
|
954
|
+
property_bank_map: subspace.data.reduce((map, data, dataIndex) => {
|
|
955
|
+
const dataId = assertEntryId(
|
|
956
|
+
data.id,
|
|
957
|
+
'PROPERTY_BANK_DATA_NODE',
|
|
958
|
+
`(data index: ${dataIndex}, subspace: ${subspaceId})`,
|
|
959
|
+
)
|
|
960
|
+
|
|
961
|
+
map[dataId] = {
|
|
962
|
+
alias: data.alias,
|
|
755
963
|
title: data.title,
|
|
756
964
|
description: data.description,
|
|
965
|
+
hide_short_ref: data.hideShortRef,
|
|
757
966
|
linked: data.metadata?.linked,
|
|
758
967
|
linkedFrom: data.metadata?.linkedFrom,
|
|
759
968
|
local_sync: data.localSyncUpdateMode
|
|
@@ -767,35 +976,72 @@ export const compile = async (app: Application) => {
|
|
|
767
976
|
schema: data.schema,
|
|
768
977
|
type: data.type,
|
|
769
978
|
...compileKind(data.kind),
|
|
770
|
-
value: compileProperty(data.value, `(data: ${
|
|
979
|
+
value: compileProperty(data.value, `(data: ${dataId}, subspace ${subspaceId})`),
|
|
771
980
|
event_map: compileEvents('PROPERTY_BANK', data.events || {}, {
|
|
772
981
|
camelCase: false,
|
|
773
|
-
errorReference: `(data: ${
|
|
982
|
+
errorReference: `(data: ${dataId}, subspace ${subspaceId})`,
|
|
774
983
|
}),
|
|
775
984
|
hit_equal: data.hit_equal,
|
|
776
985
|
hit_regex: data.hit_regex,
|
|
777
986
|
}
|
|
778
987
|
return map
|
|
779
988
|
}, {}),
|
|
780
|
-
property_bank_calc_map: subspace.dataCalculation.reduce((map, dataCalc) => {
|
|
989
|
+
property_bank_calc_map: subspace.dataCalculation.reduce((map, dataCalc, dataCalcIndex) => {
|
|
990
|
+
const dataCalcId = assertEntryId(
|
|
991
|
+
dataCalc.id,
|
|
992
|
+
'PROPERTY_BANK_COMMAND_MAP',
|
|
993
|
+
`(data calc index: ${dataCalcIndex}, subspace: ${subspaceId})`,
|
|
994
|
+
)
|
|
995
|
+
|
|
781
996
|
const calc: any = {
|
|
782
997
|
title: dataCalc.title,
|
|
783
998
|
description: dataCalc.description,
|
|
999
|
+
hide_short_ref: dataCalc.hideShortRef,
|
|
784
1000
|
}
|
|
785
1001
|
if (dataCalc.triggerMode) calc.trigger_type = dataCalc.triggerMode
|
|
786
1002
|
if (dataCalc.__typename === 'DataCalculationMap') {
|
|
787
1003
|
calc.type = 'general'
|
|
788
1004
|
const mapCalc = dataCalc as DataCalculationMap
|
|
789
1005
|
|
|
1006
|
+
const getNodeId = (
|
|
1007
|
+
node: DataCalculationData | DataCommand,
|
|
1008
|
+
reference = '',
|
|
1009
|
+
nodeIndex?: number,
|
|
1010
|
+
) => {
|
|
1011
|
+
const nodeReference = [
|
|
1012
|
+
`data calc: ${dataCalcId}`,
|
|
1013
|
+
`subspace: ${subspaceId}`,
|
|
1014
|
+
typeof nodeIndex === 'number' ? `node index: ${nodeIndex}` : undefined,
|
|
1015
|
+
reference || undefined,
|
|
1016
|
+
]
|
|
1017
|
+
.filter(Boolean)
|
|
1018
|
+
.join(', ')
|
|
1019
|
+
|
|
1020
|
+
if (node.__typename === 'DataCalculationData') {
|
|
1021
|
+
return assertEntryId(
|
|
1022
|
+
node.data()?.id,
|
|
1023
|
+
'PROPERTY_BANK_DATA_NODE',
|
|
1024
|
+
`(${nodeReference})`,
|
|
1025
|
+
)
|
|
1026
|
+
}
|
|
1027
|
+
if (node.__typename === 'DataCommand') {
|
|
1028
|
+
return assertEntryId(node.id, 'PROPERTY_BANK_COMMAND_NODE', `(${nodeReference})`)
|
|
1029
|
+
}
|
|
1030
|
+
throw new Error(`Invalid node: ${JSON.stringify(node)}`)
|
|
1031
|
+
}
|
|
1032
|
+
|
|
790
1033
|
const generateInputPorts = (inputs) =>
|
|
791
|
-
inputs.reduce((acc, port) => {
|
|
1034
|
+
inputs.reduce((acc, port, portIndex) => {
|
|
792
1035
|
if (!acc[port.key]) acc[port.key] = null
|
|
793
1036
|
|
|
794
1037
|
let sourceId
|
|
795
1038
|
const sourceNode = port.source()
|
|
796
|
-
if (
|
|
797
|
-
|
|
798
|
-
|
|
1039
|
+
if (
|
|
1040
|
+
sourceNode?.__typename === 'DataCalculationData' ||
|
|
1041
|
+
sourceNode?.__typename === 'DataCommand'
|
|
1042
|
+
) {
|
|
1043
|
+
sourceId = getNodeId(sourceNode, `input port index: ${portIndex}`)
|
|
1044
|
+
}
|
|
799
1045
|
|
|
800
1046
|
if (!sourceId) return acc
|
|
801
1047
|
if (!acc[port.key]) acc[port.key] = []
|
|
@@ -809,14 +1055,17 @@ export const compile = async (app: Application) => {
|
|
|
809
1055
|
}, {})
|
|
810
1056
|
|
|
811
1057
|
const generateOutputPorts = (outputs) =>
|
|
812
|
-
outputs.reduce((acc, port) => {
|
|
1058
|
+
outputs.reduce((acc, port, portIndex) => {
|
|
813
1059
|
if (!acc[port.key]) acc[port.key] = null
|
|
814
1060
|
|
|
815
1061
|
let targetId
|
|
816
1062
|
const targetNode = port.target()
|
|
817
|
-
if (
|
|
818
|
-
|
|
819
|
-
|
|
1063
|
+
if (
|
|
1064
|
+
targetNode?.__typename === 'DataCalculationData' ||
|
|
1065
|
+
targetNode?.__typename === 'DataCommand'
|
|
1066
|
+
) {
|
|
1067
|
+
targetId = getNodeId(targetNode, `output port index: ${portIndex}`)
|
|
1068
|
+
}
|
|
820
1069
|
|
|
821
1070
|
if (!targetId) return acc
|
|
822
1071
|
if (!acc[port.key]) acc[port.key] = []
|
|
@@ -828,18 +1077,13 @@ export const compile = async (app: Application) => {
|
|
|
828
1077
|
return acc
|
|
829
1078
|
}, {})
|
|
830
1079
|
|
|
831
|
-
|
|
832
|
-
if (node.__typename === 'DataCalculationData') return node.data().id
|
|
833
|
-
if (node.__typename === 'DataCommand') return node.id
|
|
834
|
-
throw new Error(`Invalid node: ${JSON.stringify(node)}`)
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
calc.map = mapCalc.nodes.reduce((acc, node) => {
|
|
1080
|
+
calc.map = mapCalc.nodes.reduce((acc, node, nodeIndex) => {
|
|
838
1081
|
if (node.__typename === 'DataCalculationData') {
|
|
839
1082
|
const dataNode = node as DataCalculationData
|
|
840
|
-
acc[getNodeId(dataNode)] = {
|
|
1083
|
+
acc[getNodeId(dataNode, 'data node', nodeIndex)] = {
|
|
841
1084
|
title: dataNode.title,
|
|
842
1085
|
description: dataNode.description,
|
|
1086
|
+
hide_short_ref: dataNode.hideShortRef,
|
|
843
1087
|
type: 'data-node',
|
|
844
1088
|
properties: {},
|
|
845
1089
|
in: generateInputPorts(dataNode.inputs),
|
|
@@ -862,9 +1106,10 @@ export const compile = async (app: Application) => {
|
|
|
862
1106
|
(input.source()?.__typename === 'DataCalculationData' ||
|
|
863
1107
|
input.source()?.__typename === 'DataCommand'),
|
|
864
1108
|
)
|
|
865
|
-
acc[getNodeId(commandNode)] = {
|
|
1109
|
+
acc[getNodeId(commandNode, 'command node', nodeIndex)] = {
|
|
866
1110
|
title: commandNode.title,
|
|
867
1111
|
description: commandNode.description,
|
|
1112
|
+
hide_short_ref: commandNode.hideShortRef,
|
|
868
1113
|
type: `command-node-${type}`,
|
|
869
1114
|
properties: {
|
|
870
1115
|
command: commandNode.__commandName,
|
|
@@ -880,11 +1125,11 @@ export const compile = async (app: Application) => {
|
|
|
880
1125
|
return acc
|
|
881
1126
|
}, {})
|
|
882
1127
|
calc.editor_info = mapCalc.editorInfo.reduce((acc, editorInfo) => {
|
|
883
|
-
acc[getNodeId(editorInfo.node)] = {
|
|
1128
|
+
acc[getNodeId(editorInfo.node, 'editor info node')] = {
|
|
884
1129
|
position: editorInfo.position,
|
|
885
1130
|
points: editorInfo.points.reduce((pointsAcc, point) => {
|
|
886
|
-
const sourceId = getNodeId(point.source)
|
|
887
|
-
const targetId = getNodeId(point.target)
|
|
1131
|
+
const sourceId = getNodeId(point.source, 'editor info point source')
|
|
1132
|
+
const targetId = getNodeId(point.target, 'editor info point target')
|
|
888
1133
|
const key = `${sourceId}-${point.sourceOutputKey}-${targetId}-${point.targetInputKey}`
|
|
889
1134
|
pointsAcc[key] = point.positions
|
|
890
1135
|
return pointsAcc
|
|
@@ -896,43 +1141,55 @@ export const compile = async (app: Application) => {
|
|
|
896
1141
|
const scriptCalc = dataCalc as DataCalculationScript
|
|
897
1142
|
calc.type = 'script'
|
|
898
1143
|
|
|
899
|
-
|
|
900
|
-
try {
|
|
901
|
-
const program = parseAST(scriptCalc.code, { sourceType: 'module', ecmaVersion: 2020 })
|
|
902
|
-
// export function main() { ... }
|
|
903
|
-
const declarationBody = (
|
|
904
|
-
(program.body[0] as ExportNamedDeclaration).declaration as FunctionDeclaration
|
|
905
|
-
)?.body
|
|
906
|
-
code = escodegen.generate(declarationBody, {
|
|
907
|
-
format: {
|
|
908
|
-
indent: { style: ' ' },
|
|
909
|
-
semicolons: false,
|
|
910
|
-
},
|
|
911
|
-
comment: true,
|
|
912
|
-
})
|
|
913
|
-
} catch {
|
|
914
|
-
code = scriptCalc.code || ''
|
|
915
|
-
}
|
|
1144
|
+
const code = compileScriptCalculationCode(scriptCalc.code)
|
|
916
1145
|
calc.script_config = {
|
|
917
|
-
|
|
1146
|
+
title: scriptCalc.title ?? '',
|
|
1147
|
+
note: scriptCalc.note ?? '',
|
|
918
1148
|
code,
|
|
919
1149
|
enable_async: scriptCalc.enableAsync,
|
|
920
1150
|
trigger_mode: scriptCalc.triggerMode,
|
|
921
1151
|
inputs: scriptCalc.inputs.reduce((acc, input) => {
|
|
922
|
-
|
|
1152
|
+
const inputId = assertEntryId(
|
|
1153
|
+
input.data()?.id,
|
|
1154
|
+
'PROPERTY_BANK_DATA_NODE',
|
|
1155
|
+
`(data calc: ${dataCalcId}, script input: ${input.key}, subspace: ${subspaceId})`,
|
|
1156
|
+
)
|
|
1157
|
+
acc[inputId] = input.key
|
|
923
1158
|
return acc
|
|
924
1159
|
}, {}),
|
|
925
1160
|
disabled_triggers: scriptCalc.inputs.reduce((acc, input) => {
|
|
926
|
-
|
|
1161
|
+
const inputId = assertEntryId(
|
|
1162
|
+
input.data()?.id,
|
|
1163
|
+
'PROPERTY_BANK_DATA_NODE',
|
|
1164
|
+
`(data calc: ${dataCalcId}, script trigger input: ${input.key}, subspace: ${subspaceId})`,
|
|
1165
|
+
)
|
|
1166
|
+
acc[inputId] = !input.trigger
|
|
927
1167
|
return acc
|
|
928
1168
|
}, {}),
|
|
929
|
-
output: scriptCalc.output
|
|
1169
|
+
output: scriptCalc.output
|
|
1170
|
+
? assertEntryId(
|
|
1171
|
+
scriptCalc.output()?.id,
|
|
1172
|
+
'PROPERTY_BANK_DATA_NODE',
|
|
1173
|
+
`(data calc: ${dataCalcId}, script output, subspace: ${subspaceId})`,
|
|
1174
|
+
)
|
|
1175
|
+
: null,
|
|
930
1176
|
outputs: scriptCalc.outputs.reduce((acc, output) => {
|
|
931
1177
|
if (!acc[output.key]) acc[output.key] = []
|
|
932
|
-
|
|
1178
|
+
const outputId = assertEntryId(
|
|
1179
|
+
output.data()?.id,
|
|
1180
|
+
'PROPERTY_BANK_DATA_NODE',
|
|
1181
|
+
`(data calc: ${dataCalcId}, script outputs key: ${output.key}, subspace: ${subspaceId})`,
|
|
1182
|
+
)
|
|
1183
|
+
acc[output.key].push(outputId)
|
|
933
1184
|
return acc
|
|
934
1185
|
}, {}),
|
|
935
|
-
error: scriptCalc.error
|
|
1186
|
+
error: scriptCalc.error
|
|
1187
|
+
? assertEntryId(
|
|
1188
|
+
scriptCalc.error()?.id,
|
|
1189
|
+
'PROPERTY_BANK_DATA_NODE',
|
|
1190
|
+
`(data calc: ${dataCalcId}, script error output, subspace: ${subspaceId})`,
|
|
1191
|
+
)
|
|
1192
|
+
: null,
|
|
936
1193
|
}
|
|
937
1194
|
|
|
938
1195
|
Object.assign(
|
|
@@ -942,25 +1199,32 @@ export const compile = async (app: Application) => {
|
|
|
942
1199
|
}),
|
|
943
1200
|
)
|
|
944
1201
|
}
|
|
945
|
-
map[
|
|
1202
|
+
map[dataCalcId] = calc
|
|
946
1203
|
return map
|
|
947
1204
|
}, {}),
|
|
948
1205
|
action_map: subspace.actions || undefined,
|
|
949
1206
|
event_map: compileEvents('', subspace.events || {}, {
|
|
950
1207
|
camelCase: false,
|
|
951
|
-
errorReference: `(subspace ${
|
|
1208
|
+
errorReference: `(subspace ${subspaceId})`,
|
|
952
1209
|
}),
|
|
953
1210
|
routing: subspace.dataRouting.reduce((acc, data, index) => {
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1211
|
+
const dataId = assertEntryId(
|
|
1212
|
+
data?.id,
|
|
1213
|
+
'PROPERTY_BANK_DATA_NODE',
|
|
1214
|
+
`(data routing index: ${index}, subspace ${subspaceId})`,
|
|
1215
|
+
)
|
|
1216
|
+
acc[dataId] = { enabled_routing: true }
|
|
957
1217
|
return acc
|
|
958
1218
|
}, {}),
|
|
959
1219
|
...compileModule(subspace),
|
|
960
1220
|
}
|
|
961
1221
|
return subspaceMap
|
|
962
1222
|
}, {}),
|
|
963
|
-
root_subspace_id:
|
|
1223
|
+
root_subspace_id: assertEntryId(
|
|
1224
|
+
app.rootSubspace?.id,
|
|
1225
|
+
'SUBSPACE',
|
|
1226
|
+
'(application root subspace)',
|
|
1227
|
+
),
|
|
964
1228
|
fonts: app.fonts,
|
|
965
1229
|
...compileApplicationSettings(app.settings),
|
|
966
1230
|
// Use typed automationMap if available, otherwise fall back to TEMP metadata
|
|
@@ -974,3 +1238,8 @@ export const compile = async (app: Application) => {
|
|
|
974
1238
|
}
|
|
975
1239
|
return config
|
|
976
1240
|
}
|
|
1241
|
+
|
|
1242
|
+
export const checkConfig = async (configPath: string) => {
|
|
1243
|
+
const { $ } = await import('bun')
|
|
1244
|
+
await $`bricks app check-config ${configPath}`
|
|
1245
|
+
}
|