@fugood/bricks-ctor 2.25.0-beta.60 → 2.25.0-beta.61
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/package.json +4 -28
- package/tools/deploy.ts +19 -176
- package/tools/mcp-server.ts +16 -33
- package/tools/postinstall.ts +21 -292
- package/tools/pull.ts +15 -195
- package/tools/push-config.ts +18 -113
- package/tools/simulator.ts +19 -148
- package/compile/__tests__/config-diff.test.js +0 -100
- package/compile/__tests__/index.test.js +0 -461
- package/compile/__tests__/util.test.js +0 -450
- package/compile/action-name-map.ts +0 -1079
- package/compile/config-diff.ts +0 -155
- package/compile/index.ts +0 -1594
- package/compile/util.ts +0 -482
- package/index.ts +0 -6
- package/skills/bricks-ctor/SKILL.md +0 -38
- package/skills/bricks-ctor/references/animation.md +0 -160
- package/skills/bricks-ctor/references/architecture-patterns.md +0 -88
- package/skills/bricks-ctor/references/automations.md +0 -232
- package/skills/bricks-ctor/references/buttress.md +0 -245
- package/skills/bricks-ctor/references/data-calculation.md +0 -252
- package/skills/bricks-ctor/references/local-sync.md +0 -129
- package/skills/bricks-ctor/references/media-flow.md +0 -165
- package/skills/bricks-ctor/references/remote-data-bank.md +0 -196
- package/skills/bricks-ctor/references/simulator.md +0 -132
- package/skills/bricks-ctor/references/source-editing-tools.md +0 -81
- package/skills/bricks-ctor/references/standby-transition.md +0 -124
- package/skills/bricks-ctor/references/verification-toolchain.md +0 -200
- package/skills/bricks-design/SKILL.md +0 -171
- package/skills/bricks-design/references/architecture-truths.md +0 -132
- package/skills/bricks-design/references/avoiding-complexity.md +0 -91
- package/skills/bricks-design/references/design-critique.md +0 -195
- package/skills/bricks-design/references/design-languages.md +0 -265
- package/skills/bricks-design/references/performance.md +0 -116
- package/skills/bricks-design/references/presentation-and-slideshow.md +0 -137
- package/skills/bricks-design/references/translating-inputs.md +0 -152
- package/skills/bricks-design/references/variations-and-tweaks.md +0 -124
- package/skills/bricks-design/references/when-the-brief-is-branded.md +0 -284
- package/skills/bricks-design/references/when-the-brief-is-vague.md +0 -85
- package/skills/bricks-design/references/workflow.md +0 -134
- package/skills/bricks-ux/SKILL.md +0 -114
- package/skills/bricks-ux/references/accessibility.md +0 -162
- package/skills/bricks-ux/references/flow-states.md +0 -175
- package/skills/bricks-ux/references/interaction-archetypes.md +0 -189
- package/skills/bricks-ux/references/monitoring-screens.md +0 -153
- package/skills/bricks-ux/references/pressable-composition.md +0 -126
- package/skills/bricks-ux/references/user-journey.md +0 -168
- package/skills/bricks-ux/references/ux-critique.md +0 -256
- package/skills/rive-marketplace/SKILL.md +0 -99
- package/tools/__tests__/_cli-error.test.ts +0 -35
- package/tools/__tests__/_mcp-config.test.ts +0 -67
- package/tools/__tests__/pull.test.ts +0 -108
- package/tools/_cli-error.ts +0 -17
- package/tools/_edits-log.ts +0 -41
- package/tools/_git-author.ts +0 -37
- package/tools/_last-pushed-commit.ts +0 -28
- package/tools/_mcp-config.ts +0 -42
- package/tools/_shell.ts +0 -180
- package/tools/icons/.gitattributes +0 -1
- package/tools/icons/fa6pro-glyphmap.json +0 -4686
- package/tools/icons/fa6pro-meta.json +0 -1
- package/tools/mcp-env.ts +0 -13
- package/tools/mcp-tools/__tests__/data-calc-editing.test.js +0 -516
- package/tools/mcp-tools/__tests__/entry-editing.test.js +0 -866
- package/tools/mcp-tools/__tests__/huggingface.test.ts +0 -49
- package/tools/mcp-tools/__tests__/icons.test.ts +0 -21
- package/tools/mcp-tools/__tests__/mcp-env.test.js +0 -19
- package/tools/mcp-tools/_editing-helpers.ts +0 -98
- package/tools/mcp-tools/_verify.ts +0 -50
- package/tools/mcp-tools/compile.ts +0 -104
- package/tools/mcp-tools/data-calc-editing.ts +0 -1311
- package/tools/mcp-tools/entry-editing.ts +0 -2297
- package/tools/mcp-tools/huggingface.ts +0 -772
- package/tools/mcp-tools/icons.ts +0 -97
- package/tools/mcp-tools/lottie.ts +0 -102
- package/tools/mcp-tools/media.ts +0 -113
- package/tools/simulator-main.mjs +0 -488
- package/tools/simulator-preload.cjs +0 -16
- package/types/animation.d.ts +0 -116
- package/types/automation.d.ts +0 -231
- package/types/brick-base.d.ts +0 -80
- package/types/bricks/Camera.d.ts +0 -246
- package/types/bricks/Chart.d.ts +0 -372
- package/types/bricks/GenerativeMedia.d.ts +0 -290
- package/types/bricks/Icon.d.ts +0 -98
- package/types/bricks/Image.d.ts +0 -126
- package/types/bricks/Items.d.ts +0 -480
- package/types/bricks/Lottie.d.ts +0 -168
- package/types/bricks/Maps.d.ts +0 -262
- package/types/bricks/QrCode.d.ts +0 -117
- package/types/bricks/Rect.d.ts +0 -150
- package/types/bricks/RichText.d.ts +0 -131
- package/types/bricks/Rive.d.ts +0 -220
- package/types/bricks/Scene3D.d.ts +0 -676
- package/types/bricks/Sketch.d.ts +0 -256
- package/types/bricks/Slideshow.d.ts +0 -201
- package/types/bricks/Svg.d.ts +0 -99
- package/types/bricks/Text.d.ts +0 -148
- package/types/bricks/TextInput.d.ts +0 -242
- package/types/bricks/Video.d.ts +0 -242
- package/types/bricks/VideoStreaming.d.ts +0 -112
- package/types/bricks/WebRtcStream.d.ts +0 -65
- package/types/bricks/WebView.d.ts +0 -168
- package/types/bricks/index.d.ts +0 -23
- package/types/canvas.d.ts +0 -82
- package/types/common.d.ts +0 -141
- package/types/data-calc-command/base.d.ts +0 -57
- package/types/data-calc-command/collection.d.ts +0 -418
- package/types/data-calc-command/color.d.ts +0 -432
- package/types/data-calc-command/constant.d.ts +0 -50
- package/types/data-calc-command/datetime.d.ts +0 -147
- package/types/data-calc-command/file.d.ts +0 -129
- package/types/data-calc-command/index.d.ts +0 -13
- package/types/data-calc-command/iteratee.d.ts +0 -23
- package/types/data-calc-command/logictype.d.ts +0 -190
- package/types/data-calc-command/math.d.ts +0 -275
- package/types/data-calc-command/object.d.ts +0 -119
- package/types/data-calc-command/sandbox.d.ts +0 -66
- package/types/data-calc-command/string.d.ts +0 -407
- package/types/data-calc-script.d.ts +0 -21
- package/types/data-calc.d.ts +0 -12
- package/types/data.d.ts +0 -97
- package/types/generators/AlarmClock.d.ts +0 -110
- package/types/generators/Assistant.d.ts +0 -640
- package/types/generators/BleCentral.d.ts +0 -247
- package/types/generators/BlePeripheral.d.ts +0 -208
- package/types/generators/CanvasMap.d.ts +0 -74
- package/types/generators/CastlesPay.d.ts +0 -87
- package/types/generators/DataBank.d.ts +0 -160
- package/types/generators/File.d.ts +0 -432
- package/types/generators/GraphQl.d.ts +0 -132
- package/types/generators/Http.d.ts +0 -222
- package/types/generators/HttpServer.d.ts +0 -230
- package/types/generators/Information.d.ts +0 -103
- package/types/generators/Intent.d.ts +0 -168
- package/types/generators/Iterator.d.ts +0 -108
- package/types/generators/Keyboard.d.ts +0 -105
- package/types/generators/LlmAnthropicCompat.d.ts +0 -212
- package/types/generators/LlmAppleBuiltin.d.ts +0 -159
- package/types/generators/LlmGgml.d.ts +0 -903
- package/types/generators/LlmMediaTekNeuroPilot.d.ts +0 -235
- package/types/generators/LlmMlx.d.ts +0 -228
- package/types/generators/LlmOnnx.d.ts +0 -213
- package/types/generators/LlmOpenAiCompat.d.ts +0 -312
- package/types/generators/LlmQualcommAiEngine.d.ts +0 -247
- package/types/generators/Mcp.d.ts +0 -637
- package/types/generators/McpServer.d.ts +0 -289
- package/types/generators/MediaFlow.d.ts +0 -170
- package/types/generators/MqttBroker.d.ts +0 -141
- package/types/generators/MqttClient.d.ts +0 -141
- package/types/generators/Question.d.ts +0 -408
- package/types/generators/RealtimeTranscription.d.ts +0 -287
- package/types/generators/RerankerGgml.d.ts +0 -195
- package/types/generators/SerialPort.d.ts +0 -151
- package/types/generators/SoundPlayer.d.ts +0 -94
- package/types/generators/SoundRecorder.d.ts +0 -139
- package/types/generators/SpeechToTextGgml.d.ts +0 -424
- package/types/generators/SpeechToTextOnnx.d.ts +0 -236
- package/types/generators/SpeechToTextPlatform.d.ts +0 -85
- package/types/generators/SqLite.d.ts +0 -159
- package/types/generators/Step.d.ts +0 -107
- package/types/generators/SttAppleBuiltin.d.ts +0 -153
- package/types/generators/Tcp.d.ts +0 -126
- package/types/generators/TcpServer.d.ts +0 -147
- package/types/generators/TextToSpeechAppleBuiltin.d.ts +0 -127
- package/types/generators/TextToSpeechGgml.d.ts +0 -221
- package/types/generators/TextToSpeechOnnx.d.ts +0 -178
- package/types/generators/TextToSpeechOpenAiLike.d.ts +0 -121
- package/types/generators/ThermalPrinter.d.ts +0 -193
- package/types/generators/Tick.d.ts +0 -83
- package/types/generators/Udp.d.ts +0 -120
- package/types/generators/VadGgml.d.ts +0 -260
- package/types/generators/VadOnnx.d.ts +0 -231
- package/types/generators/VadTraditional.d.ts +0 -138
- package/types/generators/VectorStore.d.ts +0 -257
- package/types/generators/Watchdog.d.ts +0 -107
- package/types/generators/WebCrawler.d.ts +0 -103
- package/types/generators/WebRtc.d.ts +0 -181
- package/types/generators/WebSocket.d.ts +0 -148
- package/types/generators/index.d.ts +0 -57
- package/types/index.d.ts +0 -13
- package/types/subspace.d.ts +0 -60
- package/types/switch.d.ts +0 -51
- package/types/system.d.ts +0 -707
- package/utils/__tests__/calc.test.js +0 -25
- package/utils/__tests__/id.test.js +0 -154
- package/utils/calc.ts +0 -130
- package/utils/data.ts +0 -495
- package/utils/event-props.ts +0 -912
- package/utils/id.ts +0 -133
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
# Data Calculation (JS Sandbox)
|
|
2
|
-
|
|
3
|
-
Transform and compute Data Bank values using JavaScript scripts. Calcs are for **pure data transformation only** — see [Architecture Patterns](architecture-patterns.md) for the pattern selection guide.
|
|
4
|
-
|
|
5
|
-
| If you need to... | Use instead |
|
|
6
|
-
|---|---|
|
|
7
|
-
| Call an LLM / AI model | Generator (Assistant, LLM, HTTP) |
|
|
8
|
-
| Sequence multiple actions | Event Action Chain |
|
|
9
|
-
| Set a data value directly | PROPERTY_BANK system action |
|
|
10
|
-
| Compute a simple expression | PROPERTY_BANK_EXPRESSION |
|
|
11
|
-
| Transform/format/parse data | Data Calculation (correct use) |
|
|
12
|
-
|
|
13
|
-
## Authoring Contract
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
import { makeId } from 'bricks-ctor'
|
|
17
|
-
import { readFile } from 'node:fs/promises'
|
|
18
|
-
|
|
19
|
-
const calculation: DataCalculationScript = {
|
|
20
|
-
__typename: 'DataCalculationScript',
|
|
21
|
-
id: makeId('property_bank_calc'),
|
|
22
|
-
title: 'Format Price',
|
|
23
|
-
description: 'Formats price with currency symbol',
|
|
24
|
-
note: '',
|
|
25
|
-
triggerMode: 'auto', // 'auto' (default) | 'manual'
|
|
26
|
-
enableAsync: false,
|
|
27
|
-
// Inline code for short scripts...
|
|
28
|
-
code: `
|
|
29
|
-
const price = inputs.price || 0
|
|
30
|
-
const currency = inputs.currency || 'USD'
|
|
31
|
-
return new Intl.NumberFormat('en-US', {
|
|
32
|
-
style: 'currency',
|
|
33
|
-
currency,
|
|
34
|
-
}).format(price)
|
|
35
|
-
`,
|
|
36
|
-
// ...or load from a file (preferred for longer scripts):
|
|
37
|
-
// code: await readFile(new URL('./format-price.sandbox.js', import.meta.url), 'utf8'),
|
|
38
|
-
inputs: [
|
|
39
|
-
{ key: 'price', data: () => priceData, trigger: true },
|
|
40
|
-
{ key: 'currency', data: () => currencyData, trigger: false },
|
|
41
|
-
],
|
|
42
|
-
output: () => formattedPriceData,
|
|
43
|
-
outputs: [], // Additional named outputs (see Multiple Outputs)
|
|
44
|
-
error: null, // or () => errorData for error handling
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Field Rules (defaults and constraints)
|
|
49
|
-
|
|
50
|
-
- `trigger` **defaults to `false` when omitted** — always set it explicitly. A calc whose inputs are all non-trigger never auto-runs.
|
|
51
|
-
- `triggerMode` defaults to `'auto'` when omitted.
|
|
52
|
-
- `output` receives the **whole return value**. `outputs` entries extract fields by key from a returned object — `key` is a lodash-get path, so deep paths like `'user.name'` work. `output`, `outputs`, and `error` can be combined.
|
|
53
|
-
- `error` receives the error **message string** when the script throws. Both extraction steps run on every execution: a success overwrites the error Data, a failure overwrites the output Data(s) — don't expect stale values to persist.
|
|
54
|
-
- **Auto mode rejects the same Data in both `inputs` and `output`/`outputs`/`error`** — compile fails with `Not allow duplicate set property id between inputs / outputs / output / error`. Manual mode allows the overlap (self-referential updates, see Recipes).
|
|
55
|
-
- `.sandbox.js` files use an `export function main() { ... }` wrapper — compile unwraps it. Raw statements also work, but the wrapper keeps linters happy since script bodies use top-level `return`.
|
|
56
|
-
|
|
57
|
-
## Trigger Modes
|
|
58
|
-
|
|
59
|
-
| Mode | Description |
|
|
60
|
-
|------|-------------|
|
|
61
|
-
| `auto` | Run on every write to a `trigger: true` input (even if the value is unchanged) |
|
|
62
|
-
| `manual` | Never auto-runs; only via `PROPERTY_BANK_COMMAND` action. Allows the same Data as both input and output |
|
|
63
|
-
|
|
64
|
-
Use `manual` to prevent circular dependencies, for explicit control, or when an output must feed back into an input.
|
|
65
|
-
|
|
66
|
-
## Triggering via PROPERTY_BANK_COMMAND
|
|
67
|
-
|
|
68
|
-
`input` references a Data that is an input of the target calc — the system runs the calc(s) that data feeds into. It does NOT reference the DataCalculation itself.
|
|
69
|
-
|
|
70
|
-
- **Manual calc**: ANY input works — `trigger` flags are ignored for manual-mode calcs.
|
|
71
|
-
- **Auto calc**: only `trigger: true` inputs work; commanding a `trigger: false` input is a silent no-op.
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
const triggerCalc: EventAction = {
|
|
75
|
-
handler: 'system',
|
|
76
|
-
action: {
|
|
77
|
-
__actionName: 'PROPERTY_BANK_COMMAND',
|
|
78
|
-
parent: 'System',
|
|
79
|
-
dataParams: [
|
|
80
|
-
{ input: () => priceData }, // Reference to an input Data of the calc
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
- When the same chain **writes a calc input first** (e.g. `PROPERTY_BANK` setting `dLastButton`) then issues `PROPERTY_BANK_COMMAND`, set `waitAsync: true` on the write so the calc reads the new value rather than the pre-chain snapshot. See [Event Action Chains](architecture-patterns.md#event-action-chains-priority-2).
|
|
87
|
-
- When a **later action reads the calc's outputs**, set `waitAsync: true` on the `PROPERTY_BANK_COMMAND` action itself — it awaits the full calc chain including output writes.
|
|
88
|
-
- A dataParam's `value` acts as an execution gate: `{ input: () => d, value: false }` skips that trigger (combine with `mapping` for conditional runs).
|
|
89
|
-
|
|
90
|
-
## One trigger source per result panel
|
|
91
|
-
|
|
92
|
-
A panel that shows the result of an async action (Generator HTTP/LLM response, request telemetry) reads from a calc whose **trigger should come from a single source**: either the live async outlet, or a completion marker the action chain writes — not both.
|
|
93
|
-
|
|
94
|
-
- **Outlet-triggered** (`{ data: () => dResponse, trigger: true }`): the calc reruns as outlets land. Use when each outlet is only written once its value is final.
|
|
95
|
-
- **Marker-triggered**: run the generator with `waitAsync: true`, then write a `done` Data the calc triggers on. Use when several outlets settle separately and the panel must wait for all of them.
|
|
96
|
-
|
|
97
|
-
Wiring both at once — triggering on the live outlet _and_ gating on a separately-written marker — lets the calc run before the outlets have settled (it renders `undefined`/stale) while the marker path masks it intermittently. A panel that updates "sometimes" usually has two competing triggers: pick one, and order it with `waitAsync` so the trigger fires after the values it reads are written.
|
|
98
|
-
|
|
99
|
-
Scope the panel's calc to the **single value it derives** (the formatted display string), and write sibling status labels — running/done, progress, selected route — imperatively in the event chain with `PROPERTY_BANK`. A calc rewrites _every_ one of its outputs on each run, so a return that omits a key writes `undefined` to that output Data (see [Field Rules](#field-rules-defaults-and-constraints)): folding status labels into a multi-output result calc resets them to `undefined` on any run that returns only the derived value. If a calc genuinely must drive several outputs, return all of their keys every run.
|
|
100
|
-
|
|
101
|
-
## Script Sandbox
|
|
102
|
-
|
|
103
|
-
Scripts run in `use strict` mode as a function body — top-level `return` returns the calc result. No `fetch`, `XMLHttpRequest`, or `require` in any mode: I/O belongs to Generators.
|
|
104
|
-
|
|
105
|
-
### Built-in Globals
|
|
106
|
-
|
|
107
|
-
| Global | Description |
|
|
108
|
-
|--------|-------------|
|
|
109
|
-
| `inputs` | Object with input values (keyed by input `key`) |
|
|
110
|
-
| `console` | `{ log, error, warn, info }` — output is only visible in DevTools debug sessions; production is a no-op |
|
|
111
|
-
| `Platform` | `{ OS, isTV, isPad, isVision, isElectron }` |
|
|
112
|
-
| `TextEncoder`, `TextDecoder` | Text encoding/decoding |
|
|
113
|
-
| `Buffer` | Node.js Buffer (without `allocUnsafe`/`allocUnsafeSlow`) |
|
|
114
|
-
| `btoa`, `atob` | Base64 encoding/decoding |
|
|
115
|
-
|
|
116
|
-
### Async Mode
|
|
117
|
-
|
|
118
|
-
Sync mode (default) has **no `Promise`, timers, or `await`**. Enable `enableAsync: true` to unlock:
|
|
119
|
-
|
|
120
|
-
- `Promise`, `setTimeout`, `setInterval`, `setImmediate`, `clearTimeout`, `clearInterval`, `clearImmediate`, `requestAnimationFrame`
|
|
121
|
-
- Full lodash (sync mode omits `debounce`, `delay`, `defer`)
|
|
122
|
-
- `await` at the top level of the script
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
code: `
|
|
126
|
-
const result = await new Promise((resolve) => {
|
|
127
|
-
setTimeout(() => resolve(inputs.value * 2), 100)
|
|
128
|
-
})
|
|
129
|
-
return result
|
|
130
|
-
`,
|
|
131
|
-
enableAsync: true,
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Runtime Environment
|
|
135
|
-
|
|
136
|
-
| Platform | Engine |
|
|
137
|
-
|----------|--------|
|
|
138
|
-
| Android | Hermes engine sandbox |
|
|
139
|
-
| iOS | JavaScriptCore sandbox |
|
|
140
|
-
| Electron desktop | Web Worker (V8) |
|
|
141
|
-
| Web preview / Simulator | Web Worker (V8) |
|
|
142
|
-
|
|
143
|
-
Simulator (Path 1) runs scripts on V8 while devices run Hermes/JSC — engine-sensitive code (date parsing, Intl, regex features) can pass in the Simulator and fail on device.
|
|
144
|
-
|
|
145
|
-
### Available Libraries
|
|
146
|
-
|
|
147
|
-
All exposed as globals. No network/file-download capability in any of them.
|
|
148
|
-
|
|
149
|
-
| Global | Library | Notes |
|
|
150
|
-
|--------|---------|-------|
|
|
151
|
-
| `_`, `lodash` | lodash | Sync mode omits `debounce`/`delay`/`defer` |
|
|
152
|
-
| `voca` | voca | String manipulation |
|
|
153
|
-
| `invariant` | invariant | Assertions |
|
|
154
|
-
| `json5` | json5 | JSON5 parsing |
|
|
155
|
-
| `qs` | qs | Query string parsing |
|
|
156
|
-
| `url` | node-url | URL parsing |
|
|
157
|
-
| `bytes` | bytes | Byte parsing/formatting |
|
|
158
|
-
| `ms` | ms | Millisecond conversion |
|
|
159
|
-
| `base45` | base45 | Base45 encoding |
|
|
160
|
-
| `iconv` | iconv-lite | Character encoding |
|
|
161
|
-
| `math`, `mathjs` | mathjs | Math library |
|
|
162
|
-
| `chroma` | chroma-js | Color manipulation |
|
|
163
|
-
| `moment` | moment | Date/time; auto parseFormat for string args |
|
|
164
|
-
| `nanoid` | nanoid | Unique ID generation |
|
|
165
|
-
| `md5` | md5 | MD5 hashing |
|
|
166
|
-
| `crypto` | crypto-browserify | Crypto functions |
|
|
167
|
-
| `kjurJWS` | jsrsasign | JWT/JWS signing (`KJUR.jws.JWS`) |
|
|
168
|
-
| `coseVerify` | cose-js | COSE verification (sync) |
|
|
169
|
-
| `fflate` | fflate | `{ zlibSync, unzlibSync, gzipSync, gunzipSync, compressSync, decompressSync, strFromU8 }` |
|
|
170
|
-
| `cbor` | cbor | `{ encode, decode, decodeFirstSync, decodeAllSync, addSemanticType }` |
|
|
171
|
-
| `fs` | (in-repo fs-compat) | File system; no download/upload methods |
|
|
172
|
-
| `parseDocument` | officeparser (in-repo fork) | Office document parsing (async) |
|
|
173
|
-
| `TurndownService` | turndown | HTML to Markdown |
|
|
174
|
-
| `OpenCC` | opencc-js | Chinese conversion `{ Converter, ConverterFactory, CustomConverter, Locale }` |
|
|
175
|
-
| `TOON` | @toon-format/toon | TOON format parsing |
|
|
176
|
-
|
|
177
|
-
## Recipes
|
|
178
|
-
|
|
179
|
-
### Multiple Outputs
|
|
180
|
-
|
|
181
|
-
Return an object; each `outputs` entry extracts its `key`:
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
outputs: [
|
|
185
|
-
{ key: 'total', data: () => totalData },
|
|
186
|
-
{ key: 'tax', data: () => taxData },
|
|
187
|
-
{ key: 'subtotal', data: () => subtotalData },
|
|
188
|
-
],
|
|
189
|
-
output: null,
|
|
190
|
-
error: null,
|
|
191
|
-
code: `
|
|
192
|
-
const subtotal = inputs.price * inputs.quantity
|
|
193
|
-
const tax = subtotal * 0.1
|
|
194
|
-
const total = subtotal + tax
|
|
195
|
-
return { total, tax, subtotal }
|
|
196
|
-
`,
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
### Manual Self-Referential Update
|
|
200
|
-
|
|
201
|
-
When an update is too complex for `PROPERTY_BANK_EXPRESSION` and must read its own previous value — manual mode allows the same Data as input and output:
|
|
202
|
-
|
|
203
|
-
```typescript
|
|
204
|
-
const appendHistory: DataCalculationScript = {
|
|
205
|
-
__typename: 'DataCalculationScript',
|
|
206
|
-
id: makeId('property_bank_calc'),
|
|
207
|
-
title: 'Append History Entry',
|
|
208
|
-
triggerMode: 'manual',
|
|
209
|
-
enableAsync: false,
|
|
210
|
-
code: `
|
|
211
|
-
const history = Array.isArray(inputs.history) ? inputs.history : []
|
|
212
|
-
return [...history, { entry: inputs.entry, at: moment().toISOString() }].slice(-50)
|
|
213
|
-
`,
|
|
214
|
-
inputs: [
|
|
215
|
-
{ key: 'history', data: () => historyData, trigger: true },
|
|
216
|
-
{ key: 'entry', data: () => entryData, trigger: true },
|
|
217
|
-
],
|
|
218
|
-
output: () => historyData, // same Data as input — manual mode only
|
|
219
|
-
outputs: [],
|
|
220
|
-
error: null,
|
|
221
|
-
}
|
|
222
|
-
// Run it from an event chain: PROPERTY_BANK writes entryData (waitAsync: true),
|
|
223
|
-
// then PROPERTY_BANK_COMMAND with input: () => entryData.
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
## Failure Modes
|
|
227
|
-
|
|
228
|
-
| Symptom | Cause | Fix |
|
|
229
|
-
|---------|-------|-----|
|
|
230
|
-
| Calc never auto-runs | `trigger` omitted on inputs (defaults to `false`) | Set `trigger: true` explicitly |
|
|
231
|
-
| `PROPERTY_BANK_COMMAND` does nothing | Auto calc + `trigger: false` input, or `input` doesn't reference an input Data of the calc | Command a `trigger: true` input (auto) or any input (manual) |
|
|
232
|
-
| Compile error `Not allow duplicate set property id...` | Auto mode with same Data as input and output | Use `triggerMode: 'manual'`, or split into separate Data |
|
|
233
|
-
| Calc reads stale value written earlier in the same chain | Missing `waitAsync: true` on the preceding write | Set `waitAsync: true` on the write action |
|
|
234
|
-
| Result/telemetry panel shows `undefined` or stale data intermittently | Calc triggered by two sources at once (live outlet + a separately-written marker) | Trigger from one source — see [One trigger source per result panel](#one-trigger-source-per-result-panel) |
|
|
235
|
-
| Sibling status Data (selected/progress) resets to `undefined` after a calc runs | Multi-output result calc whose return omitted those keys on that run | Scope the calc to one output and write status labels imperatively, or return every output key each run — see [One trigger source per result panel](#one-trigger-source-per-result-panel) |
|
|
236
|
-
| Works in Simulator, fails on device | V8 vs Hermes/JSC engine difference | Verify on device (Path 2); avoid engine-sensitive parsing |
|
|
237
|
-
| `console.log` shows nothing | Console only emits during DevTools debug sessions | Attach DevTools, or write debug values to an output Data |
|
|
238
|
-
| `Promise`/`setTimeout` undefined, or `Async mode is required` error | `enableAsync: false` | Set `enableAsync: true` |
|
|
239
|
-
|
|
240
|
-
## Best Practices
|
|
241
|
-
|
|
242
|
-
1. **Avoid circular deps**: Set non-triggering inputs (`trigger: false`) or use `manual` mode
|
|
243
|
-
2. **Error handling**: Always set `error` output for scripts that might fail
|
|
244
|
-
3. **Keep scripts pure**: Avoid side effects, return computed values
|
|
245
|
-
4. **Debounce rapid updates**: Use `manual` mode + timer for high-frequency inputs (auto calcs re-run on every write, even unchanged)
|
|
246
|
-
|
|
247
|
-
## Anti-Patterns (AVOID)
|
|
248
|
-
|
|
249
|
-
See [Architecture Patterns](architecture-patterns.md) for the full pattern selection guide.
|
|
250
|
-
|
|
251
|
-
### Using Data Calc as an orchestrator
|
|
252
|
-
Scripts that manage state machines, control UI flow, or coordinate multi-step processes belong in Event Action Chains. Symptoms: if/else on "what happens next", mirror `dFooResult` outputs that copy back to `dFoo` via `valueChange`, or a `dLastInput` field set-then-cleared to force an auto calc. See the "user-driven state machine" recipe in [Architecture Patterns](architecture-patterns.md).
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# Local Sync
|
|
2
|
-
|
|
3
|
-
Synchronize data between devices on a Local Area Network (LAN) without remote server storage. High synchronization rate for real-time multi-device experiences.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Update Data**: Sync Data Bank values across local devices
|
|
8
|
-
- **Execute Data Calculation**: Trigger calculations on other devices
|
|
9
|
-
- **No Remote Storage**: Direct device-to-device communication
|
|
10
|
-
|
|
11
|
-
## Main / Minor Device Model
|
|
12
|
-
|
|
13
|
-
| Role | Description |
|
|
14
|
-
|------|-------------|
|
|
15
|
-
| Main | Manages Data Bank if enabled, first device to start |
|
|
16
|
-
| Minor | Follows main device, subsequent devices |
|
|
17
|
-
|
|
18
|
-
### Role Determination
|
|
19
|
-
|
|
20
|
-
1. First device to start becomes Main
|
|
21
|
-
2. If simultaneous start: `Priority as Main Device` (0-9, set in Device Page) + random number determines Main
|
|
22
|
-
|
|
23
|
-
## Configuration
|
|
24
|
-
|
|
25
|
-
### Run Mode Options
|
|
26
|
-
|
|
27
|
-
| Mode | Description |
|
|
28
|
-
|------|-------------|
|
|
29
|
-
| `all` | Run on all devices |
|
|
30
|
-
| `main-only` | Only run on Main device |
|
|
31
|
-
| `minor-only` | Only run on Minor devices |
|
|
32
|
-
|
|
33
|
-
Apply run mode to:
|
|
34
|
-
- Data properties
|
|
35
|
-
- Generators
|
|
36
|
-
- Data Calculations
|
|
37
|
-
|
|
38
|
-
### Subspace Local Sync Settings
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
const subspace: Subspace = {
|
|
42
|
-
__typename: 'Subspace',
|
|
43
|
-
id: 'main',
|
|
44
|
-
localSyncChangeCanvas: 'all', // 'all' | 'main-only' | 'minor-only' | 'none'
|
|
45
|
-
// ...
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Data Local Sync
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
import { makeId } from 'bricks-ctor'
|
|
53
|
-
|
|
54
|
-
const data: Data = {
|
|
55
|
-
__typename: 'Data',
|
|
56
|
-
id: makeId('data'),
|
|
57
|
-
title: 'Shared Counter',
|
|
58
|
-
type: 'number',
|
|
59
|
-
value: 0,
|
|
60
|
-
localSyncUpdateMode: 'main-only', // 'main-only' | 'minor-only' | undefined (all)
|
|
61
|
-
events: {},
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Generator Local Sync
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
import { makeId } from 'bricks-ctor'
|
|
69
|
-
|
|
70
|
-
const generator: GeneratorTimer = {
|
|
71
|
-
__typename: 'Generator',
|
|
72
|
-
templateKey: 'Timer',
|
|
73
|
-
id: makeId('generator'),
|
|
74
|
-
title: 'Sync Timer',
|
|
75
|
-
description: '',
|
|
76
|
-
localSyncRunMode: 'main-only', // Timer only runs on main device
|
|
77
|
-
property: {},
|
|
78
|
-
events: {},
|
|
79
|
-
switches: [],
|
|
80
|
-
}
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Use Cases
|
|
84
|
-
|
|
85
|
-
### Synchronized Displays
|
|
86
|
-
Multiple screens showing coordinated content:
|
|
87
|
-
- Main device controls timing/state
|
|
88
|
-
- Minor devices follow state changes
|
|
89
|
-
|
|
90
|
-
### Interactive Kiosks
|
|
91
|
-
Touch on one device, update all:
|
|
92
|
-
- User interacts with input device (Minor)
|
|
93
|
-
- Main device processes and broadcasts result
|
|
94
|
-
- All devices update simultaneously
|
|
95
|
-
|
|
96
|
-
### Video Walls
|
|
97
|
-
Coordinated multi-screen layouts:
|
|
98
|
-
- Main device manages playback state
|
|
99
|
-
- Minor devices sync position/frame
|
|
100
|
-
|
|
101
|
-
## System Data
|
|
102
|
-
|
|
103
|
-
Access local sync status via System Data:
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
// Is current device the main device?
|
|
107
|
-
systemData.isLocalSyncMainDevice // boolean
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Important Notes
|
|
111
|
-
|
|
112
|
-
1. **Version Matching**: All devices must use same BRICKS Foundation minor version
|
|
113
|
-
- ✅ v2.11.0 matches v2.11.1
|
|
114
|
-
- ❌ v2.11.0 does NOT match v2.10.8
|
|
115
|
-
|
|
116
|
-
2. **Network Requirements**:
|
|
117
|
-
- All devices on same LAN
|
|
118
|
-
- mDNS/Bonjour enabled
|
|
119
|
-
- Firewall allows local discovery
|
|
120
|
-
|
|
121
|
-
3. **Startup Order**: Consider device startup sequence when Main role matters
|
|
122
|
-
|
|
123
|
-
## Best Practices
|
|
124
|
-
|
|
125
|
-
1. **Designate Main explicitly**: Set high `Priority as Main Device` on intended main
|
|
126
|
-
2. **Idempotent logic**: Design for eventual consistency, not strict ordering
|
|
127
|
-
3. **Minimal sync scope**: Only enable local sync for data that truly needs it
|
|
128
|
-
4. **Test multi-device**: Validate behavior with actual device count
|
|
129
|
-
5. **Handle disconnection**: Design for graceful degradation if devices disconnect
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
# Media Flow
|
|
2
|
-
|
|
3
|
-
Centralized media asset management for BRICKS applications. Store, organize, and reference images, videos, and audio files.
|
|
4
|
-
|
|
5
|
-
## Enable Media Workspace
|
|
6
|
-
|
|
7
|
-
1. Visit `Media` tab in workspace page
|
|
8
|
-
2. Enable media workspace for your workspace
|
|
9
|
-
|
|
10
|
-
## Media Box
|
|
11
|
-
|
|
12
|
-
Organize assets into boxes (folders). Each box can contain files of various types.
|
|
13
|
-
|
|
14
|
-
### Generator Media Flow
|
|
15
|
-
|
|
16
|
-
Use `Generator Media Flow` to:
|
|
17
|
-
- Get file list from a box
|
|
18
|
-
- Download files
|
|
19
|
-
- Subscribe to box changes
|
|
20
|
-
|
|
21
|
-
Quick setup: Create new Property with `As Media Resource file list?` option.
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
import { makeId } from 'bricks-ctor'
|
|
25
|
-
|
|
26
|
-
const mediaListGenerator: GeneratorMediaFlow = {
|
|
27
|
-
__typename: 'Generator',
|
|
28
|
-
templateKey: 'MediaFlow',
|
|
29
|
-
id: makeId('generator'),
|
|
30
|
-
title: 'Promo Images',
|
|
31
|
-
description: '',
|
|
32
|
-
property: {
|
|
33
|
-
boxId: 'promo-box-id',
|
|
34
|
-
passcode: 'box-read-only-passcode',
|
|
35
|
-
},
|
|
36
|
-
outlets: {
|
|
37
|
-
files: () => promoFilesData, // Array of file objects
|
|
38
|
-
},
|
|
39
|
-
events: {},
|
|
40
|
-
switches: [],
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
When hand-writing `GENERATOR_MEDIA_FLOW`, do not use a bare `boxId`. The editor
|
|
45
|
-
flow creates the required authorization, but manual config must include either
|
|
46
|
-
`property.passcode` from a Media Box passcode or `property.accessToken`.
|
|
47
|
-
Without one, devices cannot read the box and the generator will report an
|
|
48
|
-
authorization error.
|
|
49
|
-
|
|
50
|
-
## Property Kinds for Media
|
|
51
|
-
|
|
52
|
-
Link Data properties to Media Flow for asset selection:
|
|
53
|
-
|
|
54
|
-
| Kind | Description |
|
|
55
|
-
|------|-------------|
|
|
56
|
-
| `media-resource-image` | Image asset selector |
|
|
57
|
-
| `media-resource-video` | Video asset selector |
|
|
58
|
-
| `media-resource-audio` | Audio asset selector |
|
|
59
|
-
| `lottie-file-uri` | Lottie animation selector |
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
import { makeId } from 'bricks-ctor'
|
|
63
|
-
|
|
64
|
-
const backgroundImage: Data = {
|
|
65
|
-
__typename: 'Data',
|
|
66
|
-
id: makeId('data'),
|
|
67
|
-
title: 'Background Image',
|
|
68
|
-
type: 'string',
|
|
69
|
-
kind: { type: 'media-resource-image' },
|
|
70
|
-
value: '',
|
|
71
|
-
events: {},
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Assets with these kinds are **preloaded** during application launch.
|
|
76
|
-
|
|
77
|
-
## Compatible Bricks & Generators
|
|
78
|
-
|
|
79
|
-
### Bricks
|
|
80
|
-
- **Brick Image**: Display images from Media Flow
|
|
81
|
-
- **Brick Video**: Play videos from Media Flow
|
|
82
|
-
- **Brick Lottie**: Render Lottie animations
|
|
83
|
-
- **Brick Slideshow**: Cycle through Media Flow file list
|
|
84
|
-
|
|
85
|
-
### Generators
|
|
86
|
-
- **Generator Sound Player**: Play audio files
|
|
87
|
-
- **Generator File Reader**: Read file contents
|
|
88
|
-
|
|
89
|
-
## Slideshow with Media Flow
|
|
90
|
-
|
|
91
|
-
Connect Generator Media Flow output to Brick Slideshow:
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
import { makeId, linkData } from 'bricks-ctor'
|
|
95
|
-
|
|
96
|
-
const slideshow: BrickSlideshow = {
|
|
97
|
-
__typename: 'Brick',
|
|
98
|
-
templateKey: 'Slideshow',
|
|
99
|
-
id: makeId('brick'),
|
|
100
|
-
title: 'Promo Slideshow',
|
|
101
|
-
description: '',
|
|
102
|
-
property: {
|
|
103
|
-
images: linkData(() => promoFilesData),
|
|
104
|
-
interval: 5000, // ms between slides
|
|
105
|
-
transition: 'fade',
|
|
106
|
-
},
|
|
107
|
-
events: {},
|
|
108
|
-
switches: [],
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## File Object Structure
|
|
113
|
-
|
|
114
|
-
Files from Media Flow include:
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
interface MediaFile {
|
|
118
|
-
id: string
|
|
119
|
-
name: string
|
|
120
|
-
url: string
|
|
121
|
-
thumbnailUrl?: string
|
|
122
|
-
mimeType: string
|
|
123
|
-
size: number
|
|
124
|
-
width?: number // For images/videos
|
|
125
|
-
height?: number
|
|
126
|
-
duration?: number // For videos/audio
|
|
127
|
-
createdAt: string
|
|
128
|
-
updatedAt: string
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Upload & Management
|
|
133
|
-
|
|
134
|
-
### Via Editor
|
|
135
|
-
1. Open Media tab in BRICKS Editor
|
|
136
|
-
2. Select or create a box
|
|
137
|
-
3. Drag & drop files or use upload button
|
|
138
|
-
|
|
139
|
-
### Via CLI
|
|
140
|
-
```bash
|
|
141
|
-
bricks media boxes # List media boxes
|
|
142
|
-
bricks media box <box-id> # Box details
|
|
143
|
-
bricks media files <box-id> # List files in box
|
|
144
|
-
bricks media file <file-id> # File details
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
> Note: CLI currently supports read-only operations. Upload is not yet supported.
|
|
148
|
-
|
|
149
|
-
### Via API
|
|
150
|
-
Use BRICKS API for programmatic upload and management.
|
|
151
|
-
|
|
152
|
-
## Screenshot Storage
|
|
153
|
-
|
|
154
|
-
Automation `Match Screenshot` can save screenshots to Media Flow workspace:
|
|
155
|
-
- Baseline images stored in specified box
|
|
156
|
-
- Easy visual comparison and management
|
|
157
|
-
|
|
158
|
-
## Best Practices
|
|
159
|
-
|
|
160
|
-
1. **Organize by purpose**: Create boxes for different content types (backgrounds, icons, videos)
|
|
161
|
-
2. **Optimize assets**: Compress images/videos before upload
|
|
162
|
-
3. **Preload critical assets**: Use `media-resource-*` kinds for important visuals
|
|
163
|
-
4. **Slideshow performance**: Limit file count and resolution for smooth playback
|
|
164
|
-
5. **Version control**: Use box naming conventions for content versions
|
|
165
|
-
6. **CDN benefit**: Media Flow URLs are CDN-backed for fast delivery
|