mythik 0.1.3 → 0.1.5
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/README.md +87 -65
- package/dist/actions/dispatcher.d.ts.map +1 -1
- package/dist/actions/dispatcher.js +19 -3
- package/dist/actions/dispatcher.js.map +1 -1
- package/dist/design/background/patterns/resolver.d.ts.map +1 -1
- package/dist/design/background/patterns/resolver.js +5 -1
- package/dist/design/background/patterns/resolver.js.map +1 -1
- package/dist/design/background/sanitizer.d.ts.map +1 -1
- package/dist/design/background/sanitizer.js +64 -16
- package/dist/design/background/sanitizer.js.map +1 -1
- package/dist/renderer/deps.d.ts.map +1 -1
- package/dist/renderer/deps.js +4 -0
- package/dist/renderer/deps.js.map +1 -1
- package/dist/renderer/prop-schemas.js +1 -1
- package/dist/renderer/prop-schemas.js.map +1 -1
- package/dist/sql/drivers/mysql.d.ts.map +1 -1
- package/dist/sql/drivers/mysql.js +7 -5
- package/dist/sql/drivers/mysql.js.map +1 -1
- package/dist/sql/drivers/postgres.d.ts.map +1 -1
- package/dist/sql/drivers/postgres.js +7 -5
- package/dist/sql/drivers/postgres.js.map +1 -1
- package/dist/sql/drivers/sqlite.d.ts.map +1 -1
- package/dist/sql/drivers/sqlite.js +7 -5
- package/dist/sql/drivers/sqlite.js.map +1 -1
- package/dist/sql/drivers/sqlserver.d.ts.map +1 -1
- package/dist/sql/drivers/sqlserver.js +7 -5
- package/dist/sql/drivers/sqlserver.js.map +1 -1
- package/dist/sql/errors.d.ts +10 -0
- package/dist/sql/errors.d.ts.map +1 -1
- package/dist/sql/errors.js +14 -0
- package/dist/sql/errors.js.map +1 -1
- package/docs/consumer/WHERE-TO-LOOK.md +1 -1
- package/docs/consumer/ai-context-primitives.md +3 -0
- package/docs/consumer/ai-context-runtime-semantics.md +11 -9
- package/docs/consumer/ai-context.md +53 -34
- package/docs/consumer/reference-doc.md +43 -36
- package/docs/wiki/compiled/README.md +6 -6
- package/docs/wiki/compiled/action-fetch.md +7 -2
- package/docs/wiki/compiled/concept-background-layer-kinds.md +1 -1
- package/docs/wiki/compiled/concept-package-layout.md +11 -11
- package/docs/wiki/compiled/concept-pattern-primitives.md +2 -2
- package/docs/wiki/compiled/concept-public-package-names.md +24 -15
- package/docs/wiki/compiled/expression-platform.md +14 -6
- package/docs/wiki/compiled/path-ui-loading-error.md +5 -0
- package/docs/wiki/compiled/pattern-fetch-vs-datasources.md +5 -0
- package/docs/wiki/compiled/pattern-loading-content-empty.md +3 -2
- package/docs/wiki/compiled/primitive-screen.md +9 -3
- package/docs/wiki/compiled/primitive-select.md +16 -2
- package/package.json +22 -5
|
@@ -24,14 +24,17 @@ Use `npm install mythik mythik-react` for a React app, `npm install -D mythik-cl
|
|
|
24
24
|
|
|
25
25
|
Server-side SQL helpers, SQL drivers, and SQL-backed spec stores are imported from `mythik/server`, not from the browser-safe `mythik` entry. Supported SQL dialects are `sqlserver`, `postgres`, `mysql`, and `sqlite`.
|
|
26
26
|
|
|
27
|
-
Database runtime dependencies: SQL adapters (`mssql`, `pg`, `mysql2`, and `better-sqlite3`) are optional dependencies
|
|
27
|
+
Database runtime dependencies: SQL adapters (`mssql`, `pg`, `mysql2`, and `better-sqlite3`) are optional peer dependencies. Browser-only installs do not need them. SQL-backed stores and servers must install exactly the adapter for the selected database:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
+
npm install mssql # SQL Server
|
|
30
31
|
npm install pg # PostgreSQL
|
|
31
32
|
npm install mysql2 # MySQL
|
|
32
33
|
npm install better-sqlite3 # SQLite
|
|
33
34
|
```
|
|
34
35
|
|
|
36
|
+
SQLite uses the native `better-sqlite3` adapter. npm warnings from that adapter's transitive native-build helpers are adapter-level install noise, not a Mythik runtime failure. Missing SQL adapter errors include the package name and exact install command for the selected dialect.
|
|
37
|
+
|
|
35
38
|
MySQL support targets MySQL 8.0.19+ for generated upsert SQL. Older MySQL deployments need an explicit custom SQL path or another supported dialect.
|
|
36
39
|
|
|
37
40
|
## Spec Structure
|
|
@@ -268,18 +271,26 @@ Resolves by current platform. `"native"` alias matches ios and android. Specific
|
|
|
268
271
|
- `$breakpoint`: Layout adaptation (columns, gaps, padding, direction) — same component, different sizing
|
|
269
272
|
- `$platform`: Platform-specific techniques (CSS blur vs native BlurView, hover vs press, web sidebar vs native tabs) — different implementation, same feature
|
|
270
273
|
|
|
271
|
-
**
|
|
274
|
+
**Keep `root` stable.** The top-level `root` value is a string element id. Do not put `$platform` directly in `root`. For platform differences, branch at localized props/children/style points, or create separate screen specs when the platform experience is fundamentally different:
|
|
272
275
|
```json
|
|
273
276
|
{
|
|
274
|
-
"root":
|
|
277
|
+
"root": "layout",
|
|
275
278
|
"elements": {
|
|
276
|
-
"layout
|
|
277
|
-
|
|
279
|
+
"layout": {
|
|
280
|
+
"type": "stack",
|
|
281
|
+
"props": {
|
|
282
|
+
"direction": { "$platform": { "web": "horizontal", "native": "vertical" } }
|
|
283
|
+
},
|
|
284
|
+
"style": {
|
|
285
|
+
"backdropFilter": { "$platform": { "web": "blur(24px)", "native": null } }
|
|
286
|
+
},
|
|
287
|
+
"children": ["shared-form"]
|
|
288
|
+
},
|
|
278
289
|
"shared-form": { "type": "stack", "children": ["..."] }
|
|
279
290
|
}
|
|
280
291
|
}
|
|
281
292
|
```
|
|
282
|
-
State, initialActions, and forms
|
|
293
|
+
State, initialActions, and forms stay shared while only the presentation technique branches per platform.
|
|
283
294
|
|
|
284
295
|
### Math & Data
|
|
285
296
|
|
|
@@ -342,19 +353,19 @@ Extended: `locale`, `notation` (compact/scientific), `signDisplay` (always/excep
|
|
|
342
353
|
|
|
343
354
|
### Named Bindings
|
|
344
355
|
|
|
345
|
-
`$let` / `$ref` — define once, use many times:
|
|
346
|
-
```json
|
|
347
|
-
{ "$let": { "total": { "$array": "count", "source": { "$state": "/items" } } }, "$in": { "$ref": "total" } }
|
|
348
|
-
```
|
|
349
|
-
`$ref` may also read nested values from an object binding with dot notation:
|
|
350
|
-
```json
|
|
351
|
-
{ "$let": { "user": { "$state": "/auth/user" } }, "$in": { "$ref": "user.name" } }
|
|
352
|
-
```
|
|
353
|
-
Inside the same `$let`, `$template` placeholders can read the same dotted binding paths, for example `${user.name}`.
|
|
354
|
-
**JSONB array format** (when stored in DB, order matters):
|
|
355
|
-
```json
|
|
356
|
-
{ "$let": [["filtered", { "$array": "filter", "source": { "$state": "/items" }, "where": { "field": "status", "eq": "active" } }], ["count", { "$array": "count", "source": { "$ref": "filtered" } }]], "$in": { "$ref": "count" } }
|
|
357
|
-
```
|
|
356
|
+
`$let` / `$ref` — define once, use many times:
|
|
357
|
+
```json
|
|
358
|
+
{ "$let": { "total": { "$array": "count", "source": { "$state": "/items" } } }, "$in": { "$ref": "total" } }
|
|
359
|
+
```
|
|
360
|
+
`$ref` may also read nested values from an object binding with dot notation:
|
|
361
|
+
```json
|
|
362
|
+
{ "$let": { "user": { "$state": "/auth/user" } }, "$in": { "$ref": "user.name" } }
|
|
363
|
+
```
|
|
364
|
+
Inside the same `$let`, `$template` placeholders can read the same dotted binding paths, for example `${user.name}`.
|
|
365
|
+
**JSONB array format** (when stored in DB, order matters):
|
|
366
|
+
```json
|
|
367
|
+
{ "$let": [["filtered", { "$array": "filter", "source": { "$state": "/items" }, "where": { "field": "status", "eq": "active" } }], ["count", { "$array": "count", "source": { "$ref": "filtered" } }]], "$in": { "$ref": "count" } }
|
|
368
|
+
```
|
|
358
369
|
|
|
359
370
|
### Group & Selection (inside repeat)
|
|
360
371
|
|
|
@@ -391,15 +402,15 @@ All primitives accept `style`, `visible`, and `permission`. Tokens are project-d
|
|
|
391
402
|
|
|
392
403
|
Wire to events with `on`: `{ "on": { "press": { "action": "...", "params": {...} } } }`
|
|
393
404
|
|
|
394
|
-
Arrays execute sequentially: `"press": [action1, action2, action3]`. Arrays may mix normal action bindings and transaction bindings; each entry runs in order and transactions are awaited before the next entry.
|
|
405
|
+
Arrays execute sequentially: `"press": [action1, action2, action3]`. Arrays may mix normal action bindings and transaction bindings; each entry runs in order and transactions are awaited before the next entry.
|
|
395
406
|
|
|
396
407
|
**Trap:** Action chains don't stop on failure — `validateForm` marks errors but does NOT halt the chain. Use `submitForm` with `formId` instead (validates + blocks if invalid). See [ai-context-patterns.md](ai-context-patterns.md).
|
|
397
408
|
|
|
398
|
-
Add `"fireAndForget": true` to dispatch without waiting (background re-fetch after closing modal).
|
|
399
|
-
|
|
400
|
-
Any action binding may include `params.skipIf`. Mythik resolves `skipIf` at dispatch time before resolving the rest of the params; when truthy, that action is skipped and the surrounding action chain continues.
|
|
401
|
-
|
|
402
|
-
### Action Reference
|
|
409
|
+
Add `"fireAndForget": true` to dispatch without waiting (background re-fetch after closing modal).
|
|
410
|
+
|
|
411
|
+
Any action binding may include `params.skipIf`. Mythik resolves `skipIf` at dispatch time before resolving the rest of the params; when truthy, that action is skipped and the surrounding action chain continues.
|
|
412
|
+
|
|
413
|
+
### Action Reference
|
|
403
414
|
|
|
404
415
|
| Action | Params | Purpose |
|
|
405
416
|
|--------|--------|---------|
|
|
@@ -438,6 +449,7 @@ Any action binding may include `params.skipIf`. Mythik resolves `skipIf` at disp
|
|
|
438
449
|
- Empty strings in body → `null` (prevents DB errors)
|
|
439
450
|
- Sets `/ui/loading` while in flight
|
|
440
451
|
- On error: sets `/ui/lastError` with status and message
|
|
452
|
+
- Optional `errorTarget` writes the same structured error to a screen-owned path and clears that path on success. Use it for critical screen-load fetches instead of relying only on global `/ui/lastError`
|
|
441
453
|
- Auth headers auto-injected for `authDomains` URLs
|
|
442
454
|
|
|
443
455
|
### Transactions (Optimistic Updates)
|
|
@@ -591,14 +603,16 @@ Inside: `{ "$selection": "selected" }` (boolean), `{ "$selection": "count" }`. T
|
|
|
591
603
|
|
|
592
604
|
**Rule:** Don't mix both for the same data target. Pick one pattern per data source.
|
|
593
605
|
|
|
606
|
+
For critical `initialActions` fetches, set `params.errorTarget` to a screen-owned path (for example `/ui/loadErrors/orderForm`) and render a visible error state from that path. `/ui/lastError` is global and can be overwritten by unrelated fetches.
|
|
607
|
+
|
|
594
608
|
### Loading/Content/Empty Pattern
|
|
595
609
|
|
|
596
|
-
**With `initialActions` fetch** (uses `/ui/loading
|
|
610
|
+
**With `initialActions` fetch** (uses `/ui/loading`; critical loads should set `errorTarget`):
|
|
597
611
|
```json
|
|
598
612
|
"loading": { "visible": { "$and": [{ "$state": "/ui/loading" }, { "$not": { "$array": "count", "source": { "$state": "/items" } } }] } },
|
|
599
613
|
"content": { "visible": { "$array": "count", "source": { "$state": "/items" } } },
|
|
600
614
|
"empty": { "visible": { "$and": [{ "$not": { "$state": "/ui/loading" } }, { "$not": { "$array": "count", "source": { "$state": "/items" } } }] } },
|
|
601
|
-
"error": { "visible": { "$state": "/ui/
|
|
615
|
+
"error": { "visible": { "$state": "/ui/loadErrors/items" } }
|
|
602
616
|
```
|
|
603
617
|
|
|
604
618
|
**With `dataSources`** (uses auto-generated `/{target}Loading` and `/{target}Error`):
|
|
@@ -1347,7 +1361,7 @@ If a consumer overrides any name, AI applies the same schema under the consumer-
|
|
|
1347
1361
|
|
|
1348
1362
|
### Canonical reference
|
|
1349
1363
|
|
|
1350
|
-
The canonical SQL store DDL ships in the installed package. Use `mythik init-store --dialect <sqlserver|postgres|mysql|sqlite> --dry-run` or `getSqlStoreDdl(dialect)` from `mythik/server` to inspect it. Do not copy DDL from unrelated local artifacts.
|
|
1364
|
+
The canonical SQL store DDL ships in the installed package. Use `mythik init-store --dialect <sqlserver|postgres|mysql|sqlite> --dry-run` or `getSqlStoreDdl(dialect)` from `mythik/server` to inspect it. Do not copy DDL from unrelated local artifacts.
|
|
1351
1365
|
|
|
1352
1366
|
### Schema evolution
|
|
1353
1367
|
|
|
@@ -1445,9 +1459,14 @@ When the framework changes the schema in a future version, this section will gai
|
|
|
1445
1459
|
85. For existing spec edits, the required AI loop is `mythik manifest` -> `mythik elements` -> `mythik patch --from-file` -> verify. Manifest tells you the structure; elements gives the exact JSON you are changing; patch is the validated write path. Do not skip directly to full-spec `pull`/rewrite/push for a local change, do not mutate DB rows manually, and do not call `SpecStore.save()` from app code. Use `push` for new specs or intentional full replacement only.
|
|
1446
1460
|
86. Mythik's AI documentation ships with the `mythik` npm package. Before generating or modifying specs, locate it with `mythik docs path` and start from `docs/llms.txt`, `docs/consumer/ai-context.md`, and `docs/wiki/compiled/README.md`. Use `mythik docs copy ./mythik-docs` when a project-local copy is easier to hand to an AI agent.
|
|
1447
1461
|
87. DNA numeric seeds (`roundness`, `density`, `depth`, `formality`) are canonical `0–1` values. Generate `0.7`, not `70`. The runtime tolerates legacy `0–100` values by normalizing any numeric seed greater than `1` with `/100` during DNA derivation, including initial AppSpec load and runtime `updateTokens`.
|
|
1448
|
-
88. API query endpoints can combine `pagination: "offset"` with `scopeFilter`. For generated counts, Mythik applies the scope filter to the source query before `COUNT(*)`, so paginated totals remain tenant-scoped. Prefer generated counts. If a custom `endpoint.count` is truly needed with `scopeFilter`, include `{{scopeWhere[:alias]}}` or `{{scopeAnd[:alias]}}`; Mythik expands the macro to the correct scope predicate and removes it for bypass roles. Other custom count SQL is left verbatim. Use `:alias` for JOIN/subquery counts, and do not reference internal scope params directly.
|
|
1449
|
-
89. Transaction `confirm` failures from `fetch` preserve backend error details for `onError`. Read `/tx/error/message` for the best available message; when the backend returns `{ error: { code, message } }`, Mythik keeps that message, `code`, HTTP `status`, and raw `data` after rollback. Do not parse `/ui/lastError` from transaction specs.
|
|
1450
|
-
90. For SQL-backed stores and servers, use the generic `mythik/server` SQL boundary. Initialize tables with `mythik init-store --dialect <sqlserver|postgres|mysql|sqlite>` or inspect DDL with `--dry-run`; configure the CLI with `--store`, `--url`/`--filename`/SQL Server flags, or `MYTHIK_*` environment variables; and keep spec edits on the required `manifest -> elements -> patch --from-file -> validate` loop. Write custom API SQL in the selected dialect with Mythik named params (`@name`); Mythik does not translate custom SQL between dialects.
|
|
1451
|
-
91. Event arrays may mix normal actions and transaction bindings. Mythik executes them sequentially and awaits each transaction before continuing. Use this when a flow needs a small action before or after an optimistic transaction; do not wrap a transaction inside another transaction phase.
|
|
1452
|
-
92. `$ref` and `$template` placeholders can read nested values from `$let` object bindings with dot notation, for example `{ "$ref": "user.name" }` or `${user.name}`. If a dotted `$ref` segment is missing, runtime throws an unknown `$ref` error rather than silently returning undefined.
|
|
1453
|
-
93. Use `params.skipIf` for a dispatch-time action guard when an action should be skipped but the surrounding action chain should continue. `skipIf` is resolved before other params and is removed before the action handler runs. Do not use `skipIf` as a substitute for form validation or transaction rollback.
|
|
1462
|
+
88. API query endpoints can combine `pagination: "offset"` with `scopeFilter`. For generated counts, Mythik applies the scope filter to the source query before `COUNT(*)`, so paginated totals remain tenant-scoped. Prefer generated counts. If a custom `endpoint.count` is truly needed with `scopeFilter`, include `{{scopeWhere[:alias]}}` or `{{scopeAnd[:alias]}}`; Mythik expands the macro to the correct scope predicate and removes it for bypass roles. Other custom count SQL is left verbatim. Use `:alias` for JOIN/subquery counts, and do not reference internal scope params directly.
|
|
1463
|
+
89. Transaction `confirm` failures from `fetch` preserve backend error details for `onError`. Read `/tx/error/message` for the best available message; when the backend returns `{ error: { code, message } }`, Mythik keeps that message, `code`, HTTP `status`, and raw `data` after rollback. Do not parse `/ui/lastError` from transaction specs.
|
|
1464
|
+
90. For SQL-backed stores and servers, use the generic `mythik/server` SQL boundary. Initialize tables with `mythik init-store --dialect <sqlserver|postgres|mysql|sqlite>` or inspect DDL with `--dry-run`; configure the CLI with `--store`, `--url`/`--filename`/SQL Server flags, or `MYTHIK_*` environment variables; and keep spec edits on the required `manifest -> elements -> patch --from-file -> validate` loop. Write custom API SQL in the selected dialect with Mythik named params (`@name`); Mythik does not translate custom SQL between dialects.
|
|
1465
|
+
91. Event arrays may mix normal actions and transaction bindings. Mythik executes them sequentially and awaits each transaction before continuing. Use this when a flow needs a small action before or after an optimistic transaction; do not wrap a transaction inside another transaction phase.
|
|
1466
|
+
92. `$ref` and `$template` placeholders can read nested values from `$let` object bindings with dot notation, for example `{ "$ref": "user.name" }` or `${user.name}`. If a dotted `$ref` segment is missing, runtime throws an unknown `$ref` error rather than silently returning undefined.
|
|
1467
|
+
93. Use `params.skipIf` for a dispatch-time action guard when an action should be skipped but the surrounding action chain should continue. `skipIf` is resolved before other params and is removed before the action handler runs. Do not use `skipIf` as a substitute for form validation or transaction rollback.
|
|
1468
|
+
94. For critical direct `fetch` actions, especially `initialActions` screen loads, set `params.errorTarget` to a screen-owned `/ui/...` path and render that path visibly. The fetch action still writes global `/ui/lastError`, but `/ui/lastError` is shared and can be overwritten by unrelated fetches. On success, Mythik clears the provided `errorTarget`.
|
|
1469
|
+
95. `select.options` accepts strings, `{ label, value }` objects, or catalog-shaped objects when `labelKey` and `valueKey` are provided. Example: `{ "options": { "$state": "/cat/services/data" }, "labelKey": "name", "valueKey": "id" }`. Values are emitted as strings from `on.change`; malformed option data renders disabled diagnostics instead of blank clickable rows or crashes.
|
|
1470
|
+
96. SQL adapters are optional peer dependencies, not installed-by-default runtime payload. Browser-only apps install `mythik mythik-react` without database drivers. SQL-backed stores/servers must install exactly one selected adapter: `mssql`, `pg`, `mysql2`, or `better-sqlite3`. SQLite uses native `better-sqlite3`; native-build helper warnings from that adapter are not Mythik runtime failures.
|
|
1471
|
+
97. Missing SQL adapter errors are actionable. The thrown `SqlDriverError` includes `packageName`, `installCommand`, and a message with the exact `npm install ...` command for the selected dialect.
|
|
1472
|
+
98. For native Expo apps, install renderer peer packages with `npx expo install react-native-svg react-native-reanimated react-native-worklets ...` before installing `mythik mythik-react-native`, so Expo selects native module versions that match the app SDK. Keep `react-native-reanimated/plugin` last in the app Babel config. Keep `root` as a stable string element id; use `$platform` only inside localized props, style, children, or values. `$platform` matches exact platform keys first, then falls back from `ios`/`android` to `native`; it has no `default` key. Before using a primitive in native specs, check `REACT_NATIVE_PRIMITIVE_SUPPORT` or `getReactNativePrimitiveSupport` from `mythik-react-native`; native-milestone primitives should fail visibly instead of being treated as supported.
|
|
@@ -309,9 +309,9 @@ Nested conditionals for multi-branch logic:
|
|
|
309
309
|
```json
|
|
310
310
|
{ "$template": "Hello, ${/user/name}! You have ${/inbox/count} messages." }
|
|
311
311
|
```
|
|
312
|
-
Interpolates values into a string. Supports two reference types:
|
|
313
|
-
- State paths: `${/user/name}` — reads from application state
|
|
314
|
-
- `$let` bindings: `${age}` or `${user.name}` — reads from a named binding defined with `$let`
|
|
312
|
+
Interpolates values into a string. Supports two reference types:
|
|
313
|
+
- State paths: `${/user/name}` — reads from application state
|
|
314
|
+
- `$let` bindings: `${age}` or `${user.name}` — reads from a named binding defined with `$let`
|
|
315
315
|
|
|
316
316
|
### `$computed` — Registered function
|
|
317
317
|
```json
|
|
@@ -326,20 +326,20 @@ Calls a registered function with resolved arguments. **Prefer `$math`, `$array`,
|
|
|
326
326
|
"$in": { "$ref": "bmi" }
|
|
327
327
|
}
|
|
328
328
|
```
|
|
329
|
-
Define a named value once, reference it multiple times. Avoids repetition.
|
|
330
|
-
|
|
331
|
-
`$ref` can read nested values from an object binding with dot notation:
|
|
332
|
-
```json
|
|
333
|
-
{
|
|
334
|
-
"$let": { "user": { "$state": "/auth/user" } },
|
|
335
|
-
"$in": { "$ref": "user.name" }
|
|
336
|
-
}
|
|
337
|
-
```
|
|
338
|
-
The same dotted binding lookup is available inside `$template` placeholders, for example `${user.name}`.
|
|
339
|
-
|
|
340
|
-
**Later bindings can reference earlier ones:**
|
|
341
|
-
```json
|
|
342
|
-
{
|
|
329
|
+
Define a named value once, reference it multiple times. Avoids repetition.
|
|
330
|
+
|
|
331
|
+
`$ref` can read nested values from an object binding with dot notation:
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"$let": { "user": { "$state": "/auth/user" } },
|
|
335
|
+
"$in": { "$ref": "user.name" }
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
The same dotted binding lookup is available inside `$template` placeholders, for example `${user.name}`.
|
|
339
|
+
|
|
340
|
+
**Later bindings can reference earlier ones:**
|
|
341
|
+
```json
|
|
342
|
+
{
|
|
343
343
|
"$let": {
|
|
344
344
|
"total": { "$array": "count", "source": { "$state": "/items" } },
|
|
345
345
|
"label": { "$template": "${total} items" }
|
|
@@ -386,6 +386,7 @@ Resolves to different values based on the current platform (`web`, `ios`, `andro
|
|
|
386
386
|
{ "$platform": { "web": "layout-web", "native": "layout-native" } }
|
|
387
387
|
{ "$platform": { "web": "hover-card", "ios": "ios-card", "android": "android-card" } }
|
|
388
388
|
```
|
|
389
|
+
If no key matches, `$platform` resolves to `undefined`; it does not support a `default` key. Keep top-level `root` as a stable string element id and use `$platform` only in localized props, style, children, or values.
|
|
389
390
|
|
|
390
391
|
**Use with `$breakpoint`** — `$breakpoint` handles responsive layout (viewport width), `$platform` handles platform-specific techniques (CSS vs native components). They are complementary, not alternatives.
|
|
391
392
|
|
|
@@ -862,9 +863,9 @@ Wire actions to events with the `on` property:
|
|
|
862
863
|
}
|
|
863
864
|
```
|
|
864
865
|
|
|
865
|
-
### Multiple Actions (Sequential)
|
|
866
|
-
|
|
867
|
-
Actions in an array execute sequentially — each async action (like `fetch`) completes before the next one starts:
|
|
866
|
+
### Multiple Actions (Sequential)
|
|
867
|
+
|
|
868
|
+
Actions in an array execute sequentially — each async action (like `fetch`) completes before the next one starts:
|
|
868
869
|
```json
|
|
869
870
|
{
|
|
870
871
|
"on": {
|
|
@@ -931,6 +932,7 @@ The `fetch` action supports:
|
|
|
931
932
|
- **Empty string sanitization:** Empty strings in body are automatically converted to `null` (prevents database errors for typed columns)
|
|
932
933
|
- **Loading state:** Sets `/ui/loading` to true while in flight, false when done
|
|
933
934
|
- **Error handling:** On failure, sets `/ui/lastError` with status and message
|
|
935
|
+
- **Screen-owned errors:** Optional `errorTarget` receives the same structured error and is cleared on success; use it for critical `initialActions` loads
|
|
934
936
|
|
|
935
937
|
```json
|
|
936
938
|
{
|
|
@@ -946,14 +948,14 @@ The `fetch` action supports:
|
|
|
946
948
|
},
|
|
947
949
|
"target": "/lastResult"
|
|
948
950
|
}
|
|
949
|
-
}
|
|
950
|
-
```
|
|
951
|
-
|
|
952
|
-
Action arrays may also mix normal action bindings and transaction bindings. Mythik runs each entry in order and waits for a transaction to finish before dispatching the next entry.
|
|
953
|
-
|
|
954
|
-
Any action binding can include `params.skipIf`. Mythik resolves `skipIf` at dispatch time before the rest of the params; if it is truthy, that action is skipped and the surrounding action chain continues.
|
|
955
|
-
|
|
956
|
-
### Transactions (Optimistic Updates)
|
|
951
|
+
}
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
Action arrays may also mix normal action bindings and transaction bindings. Mythik runs each entry in order and waits for a transaction to finish before dispatching the next entry.
|
|
955
|
+
|
|
956
|
+
Any action binding can include `params.skipIf`. Mythik resolves `skipIf` at dispatch time before the rest of the params; if it is truthy, that action is skipped and the surrounding action chain continues.
|
|
957
|
+
|
|
958
|
+
### Transactions (Optimistic Updates)
|
|
957
959
|
|
|
958
960
|
Use `transaction` for CRUD operations that need instant UI feedback. The framework takes a state snapshot, applies your changes instantly, then confirms with the server. On failure, it rolls back automatically.
|
|
959
961
|
|
|
@@ -2972,7 +2974,7 @@ Mythik backgrounds use a structured `LayerBackground` model. Apps declare `token
|
|
|
2972
2974
|
|
|
2973
2975
|
178. **`BackgroundLayer` + `BackgroundStack` components shipped for web and RN** — Web: `packages/react/src/background/` using CSS for solid/gradient/image + inline SVG for pattern/grain. RN: `packages/react-native/src/background/` using `react-native-svg` `SvgXml` for all layers + View for solid + Image for image. Accepts `LayerBackground` config OR recipe string name
|
|
2974
2976
|
|
|
2975
|
-
179. **`custom-svg` sanitized escape hatch** — When built-in patterns aren't enough, consumers pass SVG shape fragments via `{ kind: 'custom-svg', shapes: '<circle.../>', tileSize: 20 }`. `sanitizeSVGShapes` uses regex pre-strip
|
|
2977
|
+
179. **`custom-svg` sanitized escape hatch** — When built-in patterns aren't enough, consumers pass SVG shape fragments via `{ kind: 'custom-svg', shapes: '<circle.../>', tileSize: 20 }`. `sanitizeSVGShapes` uses a platform-safe regex pre-strip plus a strict SVG tag/attribute allowlist, without DOM-only sanitizer dependencies. Only circle/rect/path/line/polygon/polyline/ellipse/g/defs/gradients plus geometric attrs survive.
|
|
2976
2978
|
|
|
2977
2979
|
---
|
|
2978
2980
|
|
|
@@ -3056,7 +3058,7 @@ The current background and motion stack combines app-level `LayerBackground`, an
|
|
|
3056
3058
|
|
|
3057
3059
|
211. **`useShapeAnimations(ref, animations, options)` — Layer 3 web runner** — Exported from `mythik-react` via `packages/react/src/animation/useShapeAnimations.ts`. React hook for SVG-child animations (`<path>`/`<circle>`/`<rect>`/`<g>`…). Consumes the same `ElementAnimations` contract as `useElementAnimations` but narrowed to the `ambient` trigger ONLY; shape children have no hover/focus/active contract and no distinct mount ceremony. Attaches CSS animations via `el.style.animation` (surgical, preserves other inline styles); keyframes register once through the CSSOM singleton (zero `dangerouslySetInnerHTML`) and dedupe by hash so multiple shape instances with the same recipe share one CSS rule. Dev mode warns when non-ambient triggers are passed. Production silently ignores them. `options.recipes` SHOULD be stable for useMemo performance.
|
|
3058
3060
|
|
|
3059
|
-
212. **`useShapeAnimations(animations, options)` — Layer 3 RN runner** —
|
|
3061
|
+
212. **`useShapeAnimations(animations, options)` — Layer 3 RN runner** — Published through `mythik-react-native` from `packages/react-native/src/animation/useShapeAnimations.ts`. Reanimated parity of rule 211: returns `{ animatedProps }` that the consumer spreads onto `Animated.createAnimatedComponent(Path)` from `react-native-svg`. Uses the `HARD_PER_TRIGGER` (=6) fixed-pool `useSharedValue` pattern (`useSharedValueArray` helper, also exported) so React Hook count stays stable. Reuses `composeRNStyle(contributions, interpolate, interpolateColor)` shared with `useElementAnimations` — single composition pipeline for View-style and animated SVG props. Relies on `react-native-svg` v13+ auto-translating the transform array into SVG `transform="..."` strings. Same dev-mode non-ambient-trigger warning as the web hook.
|
|
3060
3062
|
|
|
3061
3063
|
213. **Cross-platform Layer 3 parity pins** — `buildCSSKeyframes` (web) and `buildReanimatedSpec` (RN) interpret the same resolved `AnimationSpec` identically on load-bearing invariants: duration agreement (ms count matches regardless of input form `'28s'`/`'28000'`), keyframe stop count (web `%` markers match RN `inputRange` length), direction semantic (`'alternate'` token ⇔ `timing.reverse=true`), iterations `'infinite'`/numeric count, animated-prop enumeration (`translateX/Y`/`rotateDeg`/`scale`).
|
|
3062
3064
|
|
|
@@ -3215,9 +3217,14 @@ See `ai-context.md` for spec-gen anti-patterns the AI must NOT generate.
|
|
|
3215
3217
|
282. **Existing spec edits must use the CLI inspection-then-patch loop** - For an existing screen/app/api spec, AI agents should run `mythik manifest <id>` first, inspect only the target nodes with `mythik elements <id> <ids>`, apply a small RFC 6902 patch with `mythik patch <id> --from-file patch.json`, and verify with `manifest` or `elements`. This keeps edits surgical, validated, versionable, and reviewable. `pull` is for backup, migration, review, or full-document work; `push` is for new specs or intentional full replacement. Direct database edits and direct `SpecStore.save()` calls bypass validation and are not approved spec-write paths.
|
|
3216
3218
|
283. **Bundled AI docs are part of the install surface** - The `mythik` package includes `docs/llms.txt`, `docs/consumer/*`, and `docs/wiki/compiled/*`. Agents should run `mythik docs path` before spec generation and read the bundled docs rather than guessing from package source. Use `mythik docs copy ./mythik-docs` to create a project-local copy when the host workflow needs explicit files.
|
|
3217
3219
|
284. **DNA numeric seeds are canonical `0–1`, with legacy `0–100` normalization** - Generate `tokens.dna.roundness`, `density`, `depth`, and `formality` as `0–1` numbers (`0.7`, not `70`). The runtime normalizes numeric seed values greater than `1` by dividing by `100` inside DNA derivation, so initial AppSpec load and runtime `updateTokens` share the same backward-compatible behavior.
|
|
3218
|
-
285. **Scoped pagination counts filter before aggregation** - Query endpoints may combine `pagination: "offset"` with `scopeFilter`. For generated counts, the server applies the scope filter to the query source first and then counts the scoped source, so the response `total` matches the same tenant/role slice as `data`. Prefer generated counts. If custom `endpoint.count` is truly needed with `scopeFilter`, it must include `{{scopeWhere[:alias]}}` or `{{scopeAnd[:alias]}}`; Mythik expands the macro to the correct scope predicate and removes it for bypass roles. Other custom count SQL is left verbatim. Specs should use `:alias` for JOIN/subquery counts and should not reference internal scope parameter names directly.
|
|
3219
|
-
286. **Transaction fetch failures preserve backend error details** - When a transaction `confirm` uses `fetch` and the backend returns an HTTP error payload such as `{ error: { code, message } }`, `/tx/error` is written after rollback with the best backend message plus `code`, HTTP `status`, and raw `data`. `onError` should read `/tx/error/message`; transaction specs should not read global `/ui/lastError`.
|
|
3220
|
-
287. **SQL-backed stores and servers use one dialect-aware `mythik/server` boundary** - Import `createSqlDriver`, `SqlSpecStore`, `SqlVersionedSpecStore`, `SqlEnvironmentStore`, and `getSqlStoreDdl` from `mythik/server` for Node-side SQL work. Supported dialects are `sqlserver`, `postgres`, `mysql`, and `sqlite`. Initialize store tables with `mythik init-store --dialect <dialect>` for reachable SQL stores, `--target` for SQLite, or `--dry-run` for review/apply through a deployment process. SQL Server `init-store` accepts explicit `--server`, `--database`, `--user`, `--password`, `--encrypt`, and `--trust-server-certificate` flags. CLI commands share the same store flags/env vars and must keep existing-spec edits on the `manifest -> elements -> patch --from-file -> validate` loop. ApiSpec `dialect` controls generated CRUD/catalog/pagination/scope SQL; custom SQL remains dialect-native with Mythik named params (`@name`) and is not translated between dialects.
|
|
3221
|
-
288. **Event arrays may mix actions and transactions** - Event bindings can be a single action, a single transaction, or an array containing both normal action bindings and transaction bindings. Mythik executes the array sequentially and awaits each transaction before continuing. Transaction phases cannot contain nested transactions.
|
|
3222
|
-
289. **`$let` dotted references read nested binding values** - A `$ref` may target an object binding path such as `{ "$ref": "user.name" }`, and `$template` placeholders may read the same path as `${user.name}`. Use this for object values produced by `$let`; missing dotted `$ref` segments are invalid references and should be fixed instead of treated as optional data.
|
|
3223
|
-
290. **`params.skipIf` is a dispatch-time action guard** - Any action binding may include `params.skipIf`. Mythik resolves it before resolving the rest of the params; when truthy, the action is skipped and the action chain continues. The action handler never receives `skipIf`.
|
|
3220
|
+
285. **Scoped pagination counts filter before aggregation** - Query endpoints may combine `pagination: "offset"` with `scopeFilter`. For generated counts, the server applies the scope filter to the query source first and then counts the scoped source, so the response `total` matches the same tenant/role slice as `data`. Prefer generated counts. If custom `endpoint.count` is truly needed with `scopeFilter`, it must include `{{scopeWhere[:alias]}}` or `{{scopeAnd[:alias]}}`; Mythik expands the macro to the correct scope predicate and removes it for bypass roles. Other custom count SQL is left verbatim. Specs should use `:alias` for JOIN/subquery counts and should not reference internal scope parameter names directly.
|
|
3221
|
+
286. **Transaction fetch failures preserve backend error details** - When a transaction `confirm` uses `fetch` and the backend returns an HTTP error payload such as `{ error: { code, message } }`, `/tx/error` is written after rollback with the best backend message plus `code`, HTTP `status`, and raw `data`. `onError` should read `/tx/error/message`; transaction specs should not read global `/ui/lastError`.
|
|
3222
|
+
287. **SQL-backed stores and servers use one dialect-aware `mythik/server` boundary** - Import `createSqlDriver`, `SqlSpecStore`, `SqlVersionedSpecStore`, `SqlEnvironmentStore`, and `getSqlStoreDdl` from `mythik/server` for Node-side SQL work. Supported dialects are `sqlserver`, `postgres`, `mysql`, and `sqlite`. Initialize store tables with `mythik init-store --dialect <dialect>` for reachable SQL stores, `--target` for SQLite, or `--dry-run` for review/apply through a deployment process. SQL Server `init-store` accepts explicit `--server`, `--database`, `--user`, `--password`, `--encrypt`, and `--trust-server-certificate` flags. CLI commands share the same store flags/env vars and must keep existing-spec edits on the `manifest -> elements -> patch --from-file -> validate` loop. ApiSpec `dialect` controls generated CRUD/catalog/pagination/scope SQL; custom SQL remains dialect-native with Mythik named params (`@name`) and is not translated between dialects.
|
|
3223
|
+
288. **Event arrays may mix actions and transactions** - Event bindings can be a single action, a single transaction, or an array containing both normal action bindings and transaction bindings. Mythik executes the array sequentially and awaits each transaction before continuing. Transaction phases cannot contain nested transactions.
|
|
3224
|
+
289. **`$let` dotted references read nested binding values** - A `$ref` may target an object binding path such as `{ "$ref": "user.name" }`, and `$template` placeholders may read the same path as `${user.name}`. Use this for object values produced by `$let`; missing dotted `$ref` segments are invalid references and should be fixed instead of treated as optional data.
|
|
3225
|
+
290. **`params.skipIf` is a dispatch-time action guard** - Any action binding may include `params.skipIf`. Mythik resolves it before resolving the rest of the params; when truthy, the action is skipped and the action chain continues. The action handler never receives `skipIf`.
|
|
3226
|
+
291. **Direct `fetch` supports `errorTarget` for visible screen-load failures** - `fetch.params.errorTarget` writes HTTP/network errors to a consumer-owned state path and clears it on success. Use it for critical `initialActions` loads so the screen can render a local banner/empty state; `/ui/lastError` remains global compatibility state and can be overwritten by unrelated fetches.
|
|
3227
|
+
292. **`select` supports catalog keys and invalid-option diagnostics** - `select.options` may be strings, `{ label, value }`, or catalog-shaped objects when `labelKey`/`valueKey` are provided. Values emitted from the primitive are strings. Malformed option data renders as disabled diagnostics instead of blank clickable options or crashes, so AI-generated catalog bindings fail visibly.
|
|
3228
|
+
293. **SQL adapters are optional peer dependencies** - `mythik` does not install SQL drivers by default. Browser-only apps install `mythik mythik-react`. SQL-backed stores/servers must install exactly the selected adapter (`mssql`, `pg`, `mysql2`, or `better-sqlite3`). SQLite uses native `better-sqlite3`; warnings from its transitive native-build helpers are adapter-level install warnings, not Mythik runtime failures.
|
|
3229
|
+
294. **Missing SQL adapter errors are actionable** - If a SQL-backed store or server uses a dialect whose adapter package is not installed, Mythik throws `SqlDriverError` with `code: "SQL_DRIVER_DEPENDENCY_MISSING"`, `packageName`, `installCommand`, and a message containing the exact `npm install ...` command.
|
|
3230
|
+
295. **`mythik-react-native` publishes an explicit native support contract** - Expo apps should install React Native/Expo peer packages with `npx expo install ...`, including `react-native-reanimated` and its Expo-matched `react-native-worklets` peer, before installing `mythik mythik-react-native`, so Expo selects native module versions that match the app SDK. Keep `react-native-reanimated/plugin` last in the app Babel config. The package exports `REACT_NATIVE_PRIMITIVE_SUPPORT` and `getReactNativePrimitiveSupport(name)`. Supported native primitives are `box`, `stack`, `grid`, `scroll`, `divider`, `spacer`, `text`, `image`, `icon`, `input`, `textarea`, `select`, `checkbox`, `toggle`, `slider`, `button`, `touchable`, `list`, `modal`, `drawer`, `tabs`, `accordion`, `wizard`, `screen`, `screen-outlet`, `toast-container`, and `skeleton`. Native-milestone primitives are `bar-chart`, `line-chart`, `pie-chart`, `area-chart`, `table`, `kanban-board`, `spatial-map`, `file-upload`, `camera`, `signature`, and `audio-player`; they should surface diagnostics instead of silently rendering broken UI. Keep `root` as a stable string and use `$platform` only in localized props/style/children/value branches.
|
|
@@ -12,12 +12,12 @@ Compiled from `docs/consumer/` into **327 atomic articles**. The wiki is optimiz
|
|
|
12
12
|
6. [cli-existing-spec-edit-loop](cli-existing-spec-edit-loop.md) - required loop for modifying existing persisted specs.
|
|
13
13
|
7. [cli-docs](cli-docs.md) - locate or copy the bundled AI documentation after `npm install`.
|
|
14
14
|
|
|
15
|
-
## Publish notes
|
|
16
|
-
|
|
17
|
-
- Public package names are unscoped: `mythik`, `mythik-react`, `mythik-cli`, `mythik-server`.
|
|
18
|
-
-
|
|
19
|
-
- The wiki metadata folder is not publish content.
|
|
20
|
-
- `docs/consumer` remains the canonical source.
|
|
15
|
+
## Publish notes
|
|
16
|
+
|
|
17
|
+
- Public package names are unscoped: `mythik`, `mythik-react`, `mythik-cli`, `mythik-server`, `mythik-react-native`.
|
|
18
|
+
- `mythik-react-native` is a public preview release line with an explicit support matrix.
|
|
19
|
+
- The wiki metadata folder is not publish content.
|
|
20
|
+
- `docs/consumer` remains the canonical source.
|
|
21
21
|
|
|
22
22
|
## Catalog
|
|
23
23
|
|
|
@@ -20,7 +20,8 @@ transactions, `GET` in `initialActions`). For reactive GETs, prefer
|
|
|
20
20
|
"method"?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
|
|
21
21
|
"headers"?: <object-or-$state>,
|
|
22
22
|
"body"?: <object-with-expressions>,
|
|
23
|
-
"target"?: "/state/path"
|
|
23
|
+
"target"?: "/state/path",
|
|
24
|
+
"errorTarget"?: "/ui/screen-owned-error-path"
|
|
24
25
|
}}
|
|
25
26
|
```
|
|
26
27
|
|
|
@@ -30,6 +31,9 @@ transactions, `GET` in `initialActions`). For reactive GETs, prefer
|
|
|
30
31
|
- **Empty strings in body → `null`** (prevents DB errors on typed columns).
|
|
31
32
|
- Sets `/ui/loading` to `true` while in flight; `false` when done.
|
|
32
33
|
- On error: writes `/ui/lastError` with status and message.
|
|
34
|
+
- If `errorTarget` is provided, writes the same structured error there and
|
|
35
|
+
clears it on success. Use this for critical `initialActions` screen loads
|
|
36
|
+
instead of relying only on global `/ui/lastError`.
|
|
33
37
|
- **Auth headers auto-injected** for URLs whose hostname matches
|
|
34
38
|
`auth.authDomains` — see [[@concept-auth-domains]].
|
|
35
39
|
|
|
@@ -50,7 +54,8 @@ POST with body:
|
|
|
50
54
|
"title": { "$state": "/form/title" },
|
|
51
55
|
"description": { "$state": "/form/description" }
|
|
52
56
|
},
|
|
53
|
-
"target": "/lastResult"
|
|
57
|
+
"target": "/lastResult",
|
|
58
|
+
"errorTarget": "/ui/loadErrors/taskCreate"
|
|
54
59
|
}}
|
|
55
60
|
```
|
|
56
61
|
|
|
@@ -62,7 +62,7 @@ desaturated grain).
|
|
|
62
62
|
{ "kind": "custom-svg", "shapes": "<circle.../>", "tileSize": 20 }
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
`sanitizeSVGShapes` uses regex pre-strip
|
|
65
|
+
`sanitizeSVGShapes` uses platform-safe regex pre-strip plus a strict SVG tag and attribute allowlist. Only
|
|
66
66
|
circle/rect/path/line/polygon/polyline/ellipse/g/defs/gradients +
|
|
67
67
|
geometric attrs survive. Rejects `<script>`, `<foreignObject>`,
|
|
68
68
|
`<use href>`, `on*` events, `javascript:` URLs.
|
|
@@ -11,20 +11,20 @@ sources: [docs/consumer/ai-context.md, docs/consumer/WHERE-TO-LOOK.md]
|
|
|
11
11
|
|
|
12
12
|
| Package | Purpose |
|
|
13
13
|
|---|---|
|
|
14
|
-
| `mythik` | Browser-safe core. State, expressions, validation, renderer engine, design, auth, data, security, and browser-safe spec stores |
|
|
15
|
-
| `mythik/server` | Node-only spec stores, SQL drivers, and SQL DDL helpers: `FileSpecStore`, `SqlSpecStore`, `SqlVersionedSpecStore`, `SqlEnvironmentStore`, `createSqlDriver`, `getSqlStoreDdl`, and SQL Server compatibility stores |
|
|
16
|
-
| `mythik-react` | React host, renderer, and web primitives |
|
|
17
|
-
| `mythik-cli` | CLI package; installs the `mythik` command |
|
|
18
|
-
| `mythik-cli/api` | Programmatic CLI API: `runPush`, `runPatch`, `runLint`, `parsePatchInput`, and types |
|
|
19
|
-
| `mythik-server` | Express server runtime for ApiSpecs |
|
|
20
|
-
|
|
21
|
-
React Native work lives in the repository as a preview track and is not part of the supported npm publish surface yet.
|
|
14
|
+
| `mythik` | Browser-safe core. State, expressions, validation, renderer engine, design, auth, data, security, and browser-safe spec stores |
|
|
15
|
+
| `mythik/server` | Node-only spec stores, SQL drivers, and SQL DDL helpers: `FileSpecStore`, `SqlSpecStore`, `SqlVersionedSpecStore`, `SqlEnvironmentStore`, `createSqlDriver`, `getSqlStoreDdl`, and SQL Server compatibility stores |
|
|
16
|
+
| `mythik-react` | React host, renderer, and web primitives |
|
|
17
|
+
| `mythik-cli` | CLI package; installs the `mythik` command |
|
|
18
|
+
| `mythik-cli/api` | Programmatic CLI API: `runPush`, `runPatch`, `runLint`, `parsePatchInput`, and types |
|
|
19
|
+
| `mythik-server` | Express server runtime for ApiSpecs |
|
|
20
|
+
|
|
21
|
+
React Native work lives in the repository as a preview track and is not part of the supported npm publish surface yet.
|
|
22
22
|
|
|
23
23
|
## Browser vs server core entries
|
|
24
24
|
|
|
25
|
-
The default `mythik` entry is browser-safe by construction. Node-only stores and SQL drivers live behind the `mythik/server` subpath so browser bundles do not pull `fs`, SQL adapters, or other Node-only dependencies.
|
|
26
|
-
|
|
27
|
-
SQL adapters (`mssql`, `pg`, `mysql2`, `better-sqlite3`) are optional dependencies
|
|
25
|
+
The default `mythik` entry is browser-safe by construction. Node-only stores and SQL drivers live behind the `mythik/server` subpath so browser bundles do not pull `fs`, SQL adapters, or other Node-only dependencies.
|
|
26
|
+
|
|
27
|
+
SQL adapters (`mssql`, `pg`, `mysql2`, `better-sqlite3`) are optional peer dependencies. Browser-only apps do not install database drivers by default; SQL-backed stores and servers must install exactly the adapter for the selected database. SQLite uses native `better-sqlite3`, so warnings from its transitive native-build helpers belong to that adapter install path. Missing SQL adapter errors include the package name and exact install command.
|
|
28
28
|
|
|
29
29
|
## Programmatic CLI API
|
|
30
30
|
|
|
@@ -30,13 +30,13 @@ sources: [docs/consumer/reference-doc.md#rules-174-179]
|
|
|
30
30
|
{ "kind": "custom-svg", "shapes": "<circle cx=\"5\" cy=\"5\" r=\"2\"/>", "tileSize": 10 }
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
`sanitizeSVGShapes` uses regex pre-strip
|
|
33
|
+
`sanitizeSVGShapes` uses platform-safe regex pre-strip plus a strict SVG tag and attribute allowlist:
|
|
34
34
|
- **Allowed**: circle, rect, path, line, polygon, polyline, ellipse,
|
|
35
35
|
g, defs, gradients + geometric attrs.
|
|
36
36
|
- **Rejected**: `<script>`, `<foreignObject>`, `<use href>`, `on*` events,
|
|
37
37
|
`javascript:` URLs.
|
|
38
38
|
|
|
39
|
-
Cross-platform safe
|
|
39
|
+
Cross-platform safe without DOM-only sanitizer dependencies.
|
|
40
40
|
|
|
41
41
|
## Example
|
|
42
42
|
|
|
@@ -7,29 +7,38 @@ sources: [docs/consumer/ai-context.md, docs/consumer/WHERE-TO-LOOK.md]
|
|
|
7
7
|
|
|
8
8
|
# Public package names
|
|
9
9
|
|
|
10
|
-
Mythik publishes unscoped npm packages. Do not generate scoped package imports for public npm consumers.
|
|
10
|
+
Mythik publishes unscoped npm packages. Do not generate scoped package imports for public npm consumers.
|
|
11
11
|
|
|
12
12
|
| Public package | Use |
|
|
13
13
|
|---|---|
|
|
14
14
|
| `mythik` | Browser-safe core runtime, state, expressions, validation, browser-safe stores |
|
|
15
|
-
| `mythik/server` | Node-only stores, SQL drivers, and SQL DDL helpers exported from the core package subpath |
|
|
16
|
-
| `mythik-react` | React host, renderer, and web primitives |
|
|
17
|
-
| `mythik-cli` | CLI package; installs the `mythik` binary |
|
|
18
|
-
| `mythik-cli/api` | Programmatic CLI API: `runPush`, `runPatch`, `runLint`, and related types |
|
|
19
|
-
| `mythik-server` | Express server runtime for ApiSpecs |
|
|
20
|
-
|
|
21
|
-
The `mythik` package also ships the AI documentation under `node_modules/mythik/docs`.
|
|
22
|
-
Use [[@cli-docs]] to locate or copy it after install.
|
|
23
|
-
|
|
24
|
-
Typical React install:
|
|
15
|
+
| `mythik/server` | Node-only stores, SQL drivers, and SQL DDL helpers exported from the core package subpath |
|
|
16
|
+
| `mythik-react` | React host, renderer, and web primitives |
|
|
17
|
+
| `mythik-cli` | CLI package; installs the `mythik` binary |
|
|
18
|
+
| `mythik-cli/api` | Programmatic CLI API: `runPush`, `runPatch`, `runLint`, and related types |
|
|
19
|
+
| `mythik-server` | Express server runtime for ApiSpecs |
|
|
20
|
+
|
|
21
|
+
The `mythik` package also ships the AI documentation under `node_modules/mythik/docs`.
|
|
22
|
+
Use [[@cli-docs]] to locate or copy it after install.
|
|
23
|
+
|
|
24
|
+
Typical React install:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
npm install mythik mythik-react
|
|
28
28
|
npm install -D mythik-cli
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Add `mythik-server` only when building a Mythik-backed Node server. React Native work is a repository preview track, not part of the supported npm publish surface yet.
|
|
32
|
-
|
|
33
|
-
SQL adapters (`mssql`, `pg`, `mysql2`, `better-sqlite3`) are optional dependencies
|
|
31
|
+
Add `mythik-server` only when building a Mythik-backed Node server. React Native work is a repository preview track, not part of the supported npm publish surface yet.
|
|
32
|
+
|
|
33
|
+
SQL adapters (`mssql`, `pg`, `mysql2`, `better-sqlite3`) are optional peer dependencies. Install only the selected database adapter:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install pg # PostgreSQL
|
|
37
|
+
npm install mysql2 # MySQL
|
|
38
|
+
npm install mssql # SQL Server
|
|
39
|
+
npm install better-sqlite3 # SQLite
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
SQLite uses native `better-sqlite3`; warnings from its transitive native-build helpers are adapter-level install warnings, not Mythik runtime failures. Missing SQL adapter errors include the package name and exact install command for the selected dialect.
|
|
34
43
|
|
|
35
|
-
Related: [[@cli-docs]], [[@cli-programmatic-api]], [[@concept-spec-stores-catalog]], [[@concept-where-to-look]].
|
|
44
|
+
Related: [[@cli-docs]], [[@cli-programmatic-api]], [[@concept-spec-stores-catalog]], [[@concept-where-to-look]].
|
|
@@ -25,13 +25,21 @@ Platform-specific styling:
|
|
|
25
25
|
"style": { "backdropFilter": { "$platform": { "web": "blur(24px)", "native": null } } }
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Localized platform-specific presentation:
|
|
29
29
|
```json
|
|
30
30
|
{
|
|
31
|
-
"root":
|
|
31
|
+
"root": "layout",
|
|
32
32
|
"elements": {
|
|
33
|
-
"layout
|
|
34
|
-
|
|
33
|
+
"layout": {
|
|
34
|
+
"type": "stack",
|
|
35
|
+
"props": {
|
|
36
|
+
"direction": { "$platform": { "web": "horizontal", "native": "vertical" } }
|
|
37
|
+
},
|
|
38
|
+
"style": {
|
|
39
|
+
"backdropFilter": { "$platform": { "web": "blur(24px)", "native": null } }
|
|
40
|
+
},
|
|
41
|
+
"children": ["shared-form"]
|
|
42
|
+
},
|
|
35
43
|
"shared-form": { "type": "stack", "children": ["..."] }
|
|
36
44
|
}
|
|
37
45
|
}
|
|
@@ -53,8 +61,8 @@ Platform-specific overrides for ios:
|
|
|
53
61
|
|
|
54
62
|
- **If no key matches, resolves to `undefined`.** Always provide keys for
|
|
55
63
|
all target platforms (or include `native` as fallback).
|
|
56
|
-
-
|
|
57
|
-
|
|
64
|
+
- Keep top-level `root` as a stable string element id. Do not put `$platform`
|
|
65
|
+
directly in `root`; branch at localized props, styles, children, or values.
|
|
58
66
|
|
|
59
67
|
## Related concepts
|
|
60
68
|
|
|
@@ -16,6 +16,11 @@ Auto-managed by `fetch` action.
|
|
|
16
16
|
| `/ui/loading` | boolean | Set `true` at request start, `false` at resolve. **Shared across all fetch actions.** |
|
|
17
17
|
| `/ui/lastError` | object | Error message on failure; cleared on next successful fetch. |
|
|
18
18
|
|
|
19
|
+
`/ui/lastError` is global compatibility state. For critical screen loads,
|
|
20
|
+
set `fetch.params.errorTarget` to a screen-owned `/ui/...` path and render
|
|
21
|
+
that path visibly; `fetch` writes the same structured error there and clears
|
|
22
|
+
it on success.
|
|
23
|
+
|
|
19
24
|
## Use in visibility
|
|
20
25
|
|
|
21
26
|
```json
|
|
@@ -19,6 +19,11 @@ Both load data into state. Pick **one pattern per data target**.
|
|
|
19
19
|
| **Re-fetch** | Manual (call fetch again) | Automatic on param change, or `refreshDataSource` |
|
|
20
20
|
| **Use for** | Static initial data, POST/PUT/DELETE | Lists with filters, search, pagination |
|
|
21
21
|
|
|
22
|
+
For critical `initialActions + fetch` screen loads, set `errorTarget` to a
|
|
23
|
+
screen-owned path (for example `/ui/loadErrors/orderForm`) and render that
|
|
24
|
+
path visibly. `/ui/lastError` is shared global state and can be overwritten
|
|
25
|
+
by unrelated fetches.
|
|
26
|
+
|
|
22
27
|
## Rule
|
|
23
28
|
|
|
24
29
|
**Don't mix both for the same data target.** They write to different
|
|
@@ -12,7 +12,8 @@ state paths differ between `initialActions + fetch` vs `dataSources`.
|
|
|
12
12
|
|
|
13
13
|
## With `initialActions + fetch`
|
|
14
14
|
|
|
15
|
-
Uses `/ui/loading` and
|
|
15
|
+
Uses `/ui/loading`; critical loads should set `errorTarget` and render the
|
|
16
|
+
screen-owned error path:
|
|
16
17
|
|
|
17
18
|
```json
|
|
18
19
|
"loading": { "visible": { "$and": [
|
|
@@ -24,7 +25,7 @@ Uses `/ui/loading` and `/ui/lastError`:
|
|
|
24
25
|
{ "$not": { "$state": "/ui/loading" } },
|
|
25
26
|
{ "$not": { "$array": "count", "source": { "$state": "/items" } } }
|
|
26
27
|
]}},
|
|
27
|
-
"error": { "visible": { "$state": "/ui/
|
|
28
|
+
"error": { "visible": { "$state": "/ui/loadErrors/items" } }
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
## With `dataSources`
|
|
@@ -22,12 +22,18 @@ chrome (title bar, navigation integration).
|
|
|
22
22
|
{ "type": "screen", "props": { "title": "Dashboard" }, "children": [...] }
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
Used
|
|
25
|
+
Used from a stable root:
|
|
26
26
|
```json
|
|
27
27
|
{
|
|
28
|
-
"root":
|
|
28
|
+
"root": "layout",
|
|
29
29
|
"elements": {
|
|
30
|
-
"layout
|
|
30
|
+
"layout": {
|
|
31
|
+
"type": "screen",
|
|
32
|
+
"props": {
|
|
33
|
+
"title": { "$platform": { "web": "Dashboard", "native": "Mobile dashboard" } }
|
|
34
|
+
},
|
|
35
|
+
"children": [...]
|
|
36
|
+
}
|
|
31
37
|
}
|
|
32
38
|
}
|
|
33
39
|
```
|