mythik 0.1.2 → 0.1.3
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 +47 -23
- package/dist/actions/dispatcher.d.ts.map +1 -1
- package/dist/actions/dispatcher.js +10 -0
- package/dist/actions/dispatcher.js.map +1 -1
- package/dist/expressions/handlers/let.d.ts +6 -0
- package/dist/expressions/handlers/let.d.ts.map +1 -1
- package/dist/expressions/handlers/let.js +29 -4
- package/dist/expressions/handlers/let.js.map +1 -1
- package/dist/expressions/handlers/template.d.ts.map +1 -1
- package/dist/expressions/handlers/template.js +2 -1
- package/dist/expressions/handlers/template.js.map +1 -1
- package/dist/security/api-spec-validator.d.ts.map +1 -1
- package/dist/security/api-spec-validator.js +4 -0
- package/dist/security/api-spec-validator.js.map +1 -1
- package/dist/security/spec-validator.d.ts.map +1 -1
- package/dist/security/spec-validator.js +43 -31
- package/dist/security/spec-validator.js.map +1 -1
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -0
- package/dist/server.js.map +1 -1
- package/dist/spec-stores/sql-versioned.d.ts +38 -0
- package/dist/spec-stores/sql-versioned.d.ts.map +1 -0
- package/dist/spec-stores/sql-versioned.js +186 -0
- package/dist/spec-stores/sql-versioned.js.map +1 -0
- package/dist/spec-stores/sql.d.ts +21 -0
- package/dist/spec-stores/sql.d.ts.map +1 -0
- package/dist/spec-stores/sql.js +65 -0
- package/dist/spec-stores/sql.js.map +1 -0
- package/dist/spec-stores/sqlserver-versioned.d.ts +5 -30
- package/dist/spec-stores/sqlserver-versioned.d.ts.map +1 -1
- package/dist/spec-stores/sqlserver-versioned.js +16 -245
- package/dist/spec-stores/sqlserver-versioned.js.map +1 -1
- package/dist/spec-stores/sqlserver.d.ts +4 -11
- package/dist/spec-stores/sqlserver.d.ts.map +1 -1
- package/dist/spec-stores/sqlserver.js +16 -66
- package/dist/spec-stores/sqlserver.js.map +1 -1
- package/dist/sql/ddl.d.ts +7 -0
- package/dist/sql/ddl.d.ts.map +1 -0
- package/dist/sql/ddl.js +134 -0
- package/dist/sql/ddl.js.map +1 -0
- package/dist/sql/drivers/mysql.d.ts +25 -0
- package/dist/sql/drivers/mysql.d.ts.map +1 -0
- package/dist/sql/drivers/mysql.js +327 -0
- package/dist/sql/drivers/mysql.js.map +1 -0
- package/dist/sql/drivers/postgres.d.ts +30 -0
- package/dist/sql/drivers/postgres.d.ts.map +1 -0
- package/dist/sql/drivers/postgres.js +319 -0
- package/dist/sql/drivers/postgres.js.map +1 -0
- package/dist/sql/drivers/sqlite.d.ts +28 -0
- package/dist/sql/drivers/sqlite.d.ts.map +1 -0
- package/dist/sql/drivers/sqlite.js +367 -0
- package/dist/sql/drivers/sqlite.js.map +1 -0
- package/dist/sql/drivers/sqlserver.d.ts +46 -0
- package/dist/sql/drivers/sqlserver.d.ts.map +1 -0
- package/dist/sql/drivers/sqlserver.js +403 -0
- package/dist/sql/drivers/sqlserver.js.map +1 -0
- package/dist/sql/errors.d.ts +12 -0
- package/dist/sql/errors.d.ts.map +1 -0
- package/dist/sql/errors.js +13 -0
- package/dist/sql/errors.js.map +1 -0
- package/dist/sql/factory.d.ts +3 -0
- package/dist/sql/factory.d.ts.map +1 -0
- package/dist/sql/factory.js +24 -0
- package/dist/sql/factory.js.map +1 -0
- package/dist/sql/index.d.ts +17 -0
- package/dist/sql/index.d.ts.map +1 -0
- package/dist/sql/index.js +9 -0
- package/dist/sql/index.js.map +1 -0
- package/dist/sql/named-params.d.ts +8 -0
- package/dist/sql/named-params.d.ts.map +1 -0
- package/dist/sql/named-params.js +182 -0
- package/dist/sql/named-params.js.map +1 -0
- package/dist/sql/types.d.ts +49 -0
- package/dist/sql/types.d.ts.map +1 -0
- package/dist/sql/types.js +2 -0
- package/dist/sql/types.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/docs/consumer/README.md +1 -1
- package/docs/consumer/WHERE-TO-LOOK.md +4 -4
- package/docs/consumer/ai-context-api.md +44 -0
- package/docs/consumer/ai-context-runtime-semantics.md +12 -9
- package/docs/consumer/ai-context.md +124 -50
- package/docs/consumer/reference-doc.md +41 -24
- package/docs/wiki/compiled/README.md +1 -1
- package/docs/wiki/compiled/_lint.md +13 -8
- package/docs/wiki/compiled/concept-action-chains.md +62 -24
- package/docs/wiki/compiled/concept-package-layout.md +5 -3
- package/docs/wiki/compiled/concept-public-package-names.md +4 -2
- package/docs/wiki/compiled/concept-shape-animations.md +1 -1
- package/docs/wiki/compiled/concept-spec-stores-catalog.md +28 -16
- package/docs/wiki/compiled/concept-transactions.md +20 -12
- package/docs/wiki/compiled/expression-let-ref.md +36 -18
- package/docs/wiki/compiled/expression-template.md +28 -17
- package/package.json +7 -2
|
@@ -7,15 +7,15 @@ sources: [docs/consumer/ai-context.md#actions, docs/consumer/ai-context-patterns
|
|
|
7
7
|
|
|
8
8
|
# Action chains — sequential execution
|
|
9
9
|
|
|
10
|
-
Wire multiple actions to one event by passing an array. **Each
|
|
11
|
-
completes before the next starts** — sequential dispatch with state commit
|
|
12
|
-
between steps.
|
|
10
|
+
Wire multiple actions to one event by passing an array. **Each entry
|
|
11
|
+
completes before the next starts** — sequential dispatch with state commit
|
|
12
|
+
between steps. Entries can be normal action bindings or transaction bindings.
|
|
13
13
|
|
|
14
14
|
## Shape / Signature
|
|
15
15
|
|
|
16
|
-
```json
|
|
17
|
-
{ "on": { "press": [<action>, <action
|
|
18
|
-
```
|
|
16
|
+
```json
|
|
17
|
+
{ "on": { "press": [<action-or-transaction>, <action-or-transaction>] } }
|
|
18
|
+
```
|
|
19
19
|
|
|
20
20
|
## Examples
|
|
21
21
|
|
|
@@ -28,27 +28,65 @@ Save then close + refresh:
|
|
|
28
28
|
]
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Set state then navigate (the navigated screen sees the new state):
|
|
32
|
-
```json
|
|
33
|
-
"press": [
|
|
34
|
-
{ "action": "setState", "params": { "statePath": "/draft", "value": { "$state": "/form" } } },
|
|
35
|
-
{ "action": "navigateScreen", "params": { "screen": "review" } }
|
|
36
|
-
]
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
Set state then navigate (the navigated screen sees the new state):
|
|
32
|
+
```json
|
|
33
|
+
"press": [
|
|
34
|
+
{ "action": "setState", "params": { "statePath": "/draft", "value": { "$state": "/form" } } },
|
|
35
|
+
{ "action": "navigateScreen", "params": { "screen": "review" } }
|
|
36
|
+
]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Action before a transaction:
|
|
40
|
+
```json
|
|
41
|
+
"press": [
|
|
42
|
+
{ "action": "setState", "params": { "statePath": "/ui/saving", "value": true } },
|
|
43
|
+
{
|
|
44
|
+
"transaction": {
|
|
45
|
+
"optimistic": [{ "action": "setState", "params": { "statePath": "/items", "value": { "$array": "append", "source": { "$state": "/items" }, "item": { "$state": "/draft" } } } }],
|
|
46
|
+
"confirm": [{ "action": "fetch", "params": { "url": "/api/items", "method": "POST", "body": { "$state": "/draft" } } }],
|
|
47
|
+
"onError": [{ "action": "showNotification", "params": { "type": "error", "message": { "$state": "/tx/error/message" } } }]
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{ "action": "setState", "params": { "statePath": "/ui/saving", "value": false } }
|
|
51
|
+
]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Conditional action guard:
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"action": "fetch",
|
|
58
|
+
"params": {
|
|
59
|
+
"skipIf": { "$not": { "$state": "/form/isDirty" } },
|
|
60
|
+
"url": "/api/save",
|
|
61
|
+
"method": "POST",
|
|
62
|
+
"body": { "$state": "/form" }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Commit semantics
|
|
68
|
+
|
|
69
|
+
Each entry in a sequential chain commits state before the next runs.
|
|
70
|
+
`[setState, navigateScreen]` works — the navigated screen sees the state
|
|
71
|
+
written by `setState`.
|
|
72
|
+
|
|
73
|
+
For a transaction entry, Mythik waits for the transaction to finish before the
|
|
74
|
+
next event-array entry runs. Transaction phases themselves still follow the
|
|
75
|
+
transaction timing rules.
|
|
44
76
|
|
|
45
77
|
## Constraints / Anti-patterns
|
|
46
78
|
|
|
47
|
-
- **Chains do NOT stop on failure.** `validateForm` marks errors but does
|
|
48
|
-
NOT halt subsequent actions. Use `submitForm` with `formId` instead. See
|
|
49
|
-
[[@antipattern-action-chain-no-stop]].
|
|
50
|
-
-
|
|
51
|
-
|
|
79
|
+
- **Chains do NOT stop on failure.** `validateForm` marks errors but does
|
|
80
|
+
NOT halt subsequent actions. Use `submitForm` with `formId` instead. See
|
|
81
|
+
[[@antipattern-action-chain-no-stop]].
|
|
82
|
+
- **`skipIf` skips one action, not the whole chain.** It is resolved at
|
|
83
|
+
dispatch time before other params and removed before the action handler
|
|
84
|
+
runs. Use it for small dispatch-time guards, not for form validation or
|
|
85
|
+
transaction rollback.
|
|
86
|
+
- **Do not nest transactions.** An event array may contain a transaction, but
|
|
87
|
+
transaction phases cannot contain another transaction binding.
|
|
88
|
+
- For background dispatch (next action immediately), use
|
|
89
|
+
[[@concept-fire-and-forget]].
|
|
52
90
|
- For optimistic CRUD UX, prefer [[@concept-transactions]] over plain chains.
|
|
53
91
|
|
|
54
92
|
## Related concepts
|
|
@@ -12,17 +12,19 @@ sources: [docs/consumer/ai-context.md, docs/consumer/WHERE-TO-LOOK.md]
|
|
|
12
12
|
| Package | Purpose |
|
|
13
13
|
|---|---|
|
|
14
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: `FileSpecStore`, `
|
|
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
16
|
| `mythik-react` | React host, renderer, and web primitives |
|
|
17
17
|
| `mythik-cli` | CLI package; installs the `mythik` command |
|
|
18
18
|
| `mythik-cli/api` | Programmatic CLI API: `runPush`, `runPatch`, `runLint`, `parsePatchInput`, and types |
|
|
19
19
|
| `mythik-server` | Express server runtime for ApiSpecs |
|
|
20
20
|
|
|
21
|
-
React Native work lives in the repository as a preview track and is not part of the
|
|
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 live behind the `mythik/server` subpath so browser bundles do not pull `fs`,
|
|
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 of `mythik`. npm/pnpm install optional dependencies by default; if optional dependencies are omitted, install the adapter for the database in use.
|
|
26
28
|
|
|
27
29
|
## Programmatic CLI API
|
|
28
30
|
|
|
@@ -12,7 +12,7 @@ Mythik publishes unscoped npm packages. Do not generate scoped package imports f
|
|
|
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 exported from the core package subpath |
|
|
15
|
+
| `mythik/server` | Node-only stores, SQL drivers, and SQL DDL helpers exported from the core package subpath |
|
|
16
16
|
| `mythik-react` | React host, renderer, and web primitives |
|
|
17
17
|
| `mythik-cli` | CLI package; installs the `mythik` binary |
|
|
18
18
|
| `mythik-cli/api` | Programmatic CLI API: `runPush`, `runPatch`, `runLint`, and related types |
|
|
@@ -28,6 +28,8 @@ 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
|
|
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 of `mythik`. They install by default with npm/pnpm unless optional dependencies are omitted.
|
|
32
34
|
|
|
33
35
|
Related: [[@cli-docs]], [[@cli-programmatic-api]], [[@concept-spec-stores-catalog]], [[@concept-where-to-look]].
|
|
@@ -30,7 +30,7 @@ useShapeAnimations(ref, animations, options)
|
|
|
30
30
|
## RN variant
|
|
31
31
|
|
|
32
32
|
`packages/react-native/src/animation/useShapeAnimations.ts` — repository
|
|
33
|
-
preview implementation. It is not part of the
|
|
33
|
+
preview implementation. It is not part of the supported npm publish surface yet.
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
36
|
useShapeAnimations(animations, options) → { animatedProps }
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: concept-spec-stores-catalog
|
|
3
3
|
title: Spec stores catalog
|
|
4
4
|
kind: concept
|
|
5
|
-
sources: [docs/consumer/ai-context-runtime-semantics.md#54-specstore-layering--save-vs-saveversion-vs-cli-patch]
|
|
5
|
+
sources: [docs/consumer/ai-context-runtime-semantics.md#54-specstore-layering--save-vs-saveversion-vs-cli-patch]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Spec stores catalog
|
|
@@ -20,18 +20,23 @@ sources: [docs/consumer/ai-context-runtime-semantics.md#54-specstore-layering--s
|
|
|
20
20
|
|
|
21
21
|
## Node-only (`mythik/server`)
|
|
22
22
|
|
|
23
|
-
| Store | Purpose |
|
|
24
|
-
|---|---|
|
|
25
|
-
| `FileSpecStore` | Local filesystem (`fs`) |
|
|
26
|
-
| `
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
23
|
+
| Store | Purpose |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `FileSpecStore` | Local filesystem (`fs`) |
|
|
26
|
+
| `SqlSpecStore` | Generic SQL store over a `SqlDriver` |
|
|
27
|
+
| `SqlVersionedSpecStore` | Generic SQL store + version history |
|
|
28
|
+
| `SqlEnvironmentStore` | Generic SQL store + env promotions |
|
|
29
|
+
| `SqlServerSpecStore` | SQL Server compatibility wrapper |
|
|
30
|
+
| `SqlServerVersionedSpecStore` | SQL Server compatibility wrapper + version history |
|
|
31
|
+
| `SqlServerEnvironmentStore` | SQL Server compatibility wrapper + env promotions |
|
|
32
|
+
|
|
33
|
+
Supported SQL driver dialects: SQL Server, PostgreSQL, MySQL, and SQLite.
|
|
29
34
|
|
|
30
35
|
## Why split
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`mythik`
|
|
37
|
+
The structural split keeps `mythik` browser-safe **by construction**:
|
|
38
|
+
browser bundles import the default entry, while Node hosts import
|
|
39
|
+
`mythik/server` for filesystem stores, SQL stores, and SQL adapters.
|
|
35
40
|
|
|
36
41
|
## Imports
|
|
37
42
|
|
|
@@ -39,9 +44,16 @@ bundle that imported `mythik`. v0.1.0 structural split makes
|
|
|
39
44
|
// Browser-safe
|
|
40
45
|
import { SupabaseSpecStore, MemorySpecStore } from 'mythik';
|
|
41
46
|
|
|
42
|
-
// Node-only
|
|
43
|
-
import {
|
|
44
|
-
|
|
47
|
+
// Node-only
|
|
48
|
+
import { FileSpecStore, SqlSpecStore, createSqlDriver } from 'mythik/server';
|
|
49
|
+
|
|
50
|
+
const driver = createSqlDriver({
|
|
51
|
+
dialect: 'postgres',
|
|
52
|
+
connection: process.env.DATABASE_URL!,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const store = new SqlSpecStore({ driver });
|
|
56
|
+
```
|
|
45
57
|
|
|
46
58
|
## Configurable table names
|
|
47
59
|
|
|
@@ -49,9 +61,9 @@ Default `'screens'`. Override via constructor — see
|
|
|
49
61
|
[[@concept-storage-custom-names]].
|
|
50
62
|
|
|
51
63
|
```ts
|
|
52
|
-
new
|
|
53
|
-
new SupabaseSpecStore({ ..., table: 'api_specs' })
|
|
54
|
-
```
|
|
64
|
+
new SqlSpecStore({ driver, table: 'api_specs' })
|
|
65
|
+
new SupabaseSpecStore({ ..., table: 'api_specs' })
|
|
66
|
+
```
|
|
55
67
|
|
|
56
68
|
## Related concepts
|
|
57
69
|
|
|
@@ -7,10 +7,14 @@ sources: [docs/consumer/ai-context.md#transactions-optimistic-updates, docs/cons
|
|
|
7
7
|
|
|
8
8
|
# Transactions — optimistic CRUD with rollback
|
|
9
9
|
|
|
10
|
-
Use `transaction` for CRUD operations that need instant UI feedback. The
|
|
11
|
-
framework takes a state snapshot before `optimistic`, applies your changes
|
|
12
|
-
instantly, then confirms with the server. **On failure, it rolls back
|
|
13
|
-
automatically.**
|
|
10
|
+
Use `transaction` for CRUD operations that need instant UI feedback. The
|
|
11
|
+
framework takes a state snapshot before `optimistic`, applies your changes
|
|
12
|
+
instantly, then confirms with the server. **On failure, it rolls back
|
|
13
|
+
automatically.**
|
|
14
|
+
|
|
15
|
+
A transaction can be used directly as an event binding or as one entry inside
|
|
16
|
+
an event action array. When mixed with normal actions in an event array,
|
|
17
|
+
Mythik awaits the transaction before running the next entry.
|
|
14
18
|
|
|
15
19
|
## Shape / Signature
|
|
16
20
|
|
|
@@ -55,17 +59,21 @@ Default 10 seconds. Override:
|
|
|
55
59
|
|
|
56
60
|
## Constraints / Anti-patterns
|
|
57
61
|
|
|
58
|
-
- **`submitForm` in `confirm` is NOT recommended.** It has its own validation
|
|
59
|
-
gate that conflicts with the transaction engine. Use `fetch` in `confirm`
|
|
60
|
-
instead. See [[@antipattern-submit-form-in-tx-confirm]].
|
|
61
|
-
- **
|
|
62
|
-
|
|
62
|
+
- **`submitForm` in `confirm` is NOT recommended.** It has its own validation
|
|
63
|
+
gate that conflicts with the transaction engine. Use `fetch` in `confirm`
|
|
64
|
+
instead. See [[@antipattern-submit-form-in-tx-confirm]].
|
|
65
|
+
- **Do not nest transactions.** An event array may contain transaction
|
|
66
|
+
bindings, but `before`, `optimistic`, `confirm`, `onSuccess`, and `onError`
|
|
67
|
+
phases contain normal action bindings only.
|
|
68
|
+
- **UPDATE transactions don't need `onSuccess`** — re-fetch causes flash.
|
|
69
|
+
See [[@pattern-tx-update]].
|
|
63
70
|
|
|
64
71
|
## Related concepts
|
|
65
72
|
|
|
66
|
-
- [[@concept-transaction-phase-timing]]
|
|
67
|
-
- [[@concept-transaction-rollback]]
|
|
68
|
-
- [[@concept-transaction-snapshot]]
|
|
73
|
+
- [[@concept-transaction-phase-timing]]
|
|
74
|
+
- [[@concept-transaction-rollback]]
|
|
75
|
+
- [[@concept-transaction-snapshot]]
|
|
76
|
+
- [[@concept-action-chains]]
|
|
69
77
|
- [[@pattern-tx-create]] / [[@pattern-tx-update]] / [[@pattern-tx-delete]] / [[@pattern-tx-toggle]]
|
|
70
78
|
- [[@path-tx-result-error]]
|
|
71
79
|
|
|
@@ -8,9 +8,12 @@ sources: [docs/consumer/ai-context.md#named-bindings, docs/consumer/reference-do
|
|
|
8
8
|
# `$let` / `$ref` — named bindings
|
|
9
9
|
|
|
10
10
|
`$let` defines named bindings; `$in` is the expression that uses them.
|
|
11
|
-
References use `$ref`. Use to define a value once and reference it multiple
|
|
12
|
-
times — particularly useful when `$item` or a complex expression must be
|
|
13
|
-
captured for use in `$template`.
|
|
11
|
+
References use `$ref`. Use to define a value once and reference it multiple
|
|
12
|
+
times — particularly useful when `$item` or a complex expression must be
|
|
13
|
+
captured for use in `$template`.
|
|
14
|
+
|
|
15
|
+
`$ref` can read nested values from an object binding with dot notation. The
|
|
16
|
+
same dotted binding lookup is available inside `$template` placeholders.
|
|
14
17
|
|
|
15
18
|
## Shape / Signature
|
|
16
19
|
|
|
@@ -35,17 +38,28 @@ Array form (preserves order — use when stored in JSONB):
|
|
|
35
38
|
|
|
36
39
|
## Examples
|
|
37
40
|
|
|
38
|
-
Capture `$item` for `$template` (the most common use):
|
|
39
|
-
```json
|
|
40
|
-
{
|
|
41
|
-
"$let": { "x": { "$item": "name" } },
|
|
42
|
-
"$in": { "$template": "Editing: ${x}" }
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
41
|
+
Capture `$item` for `$template` (the most common use):
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"$let": { "x": { "$item": "name" } },
|
|
45
|
+
"$in": { "$template": "Editing: ${x}" }
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Read nested object fields:
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"$let": { "user": { "$state": "/auth/user" } },
|
|
53
|
+
"$in": {
|
|
54
|
+
"label": { "$ref": "user.name" },
|
|
55
|
+
"message": { "$template": "Welcome, ${user.name}" }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Multi-step computation:
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
49
63
|
"$let": {
|
|
50
64
|
"total": { "$array": "count", "source": { "$state": "/items" } },
|
|
51
65
|
"label": { "$template": "${total} items" }
|
|
@@ -70,10 +84,14 @@ In a composite template:
|
|
|
70
84
|
|
|
71
85
|
## Constraints / Anti-patterns
|
|
72
86
|
|
|
73
|
-
- **Use array form when storing in JSONB.** Object key order is not
|
|
74
|
-
preserved by JSONB — if bindings reference each other via `$ref`, use
|
|
75
|
-
the array form to guarantee evaluation order. See rule 4.
|
|
76
|
-
-
|
|
87
|
+
- **Use array form when storing in JSONB.** Object key order is not
|
|
88
|
+
preserved by JSONB — if bindings reference each other via `$ref`, use
|
|
89
|
+
the array form to guarantee evaluation order. See rule 4.
|
|
90
|
+
- **Fix missing dotted `$ref` segments.** A path such as
|
|
91
|
+
`{ "$ref": "user.name" }` expects `user` to exist as a binding and `name`
|
|
92
|
+
to exist on that object. Missing dotted segments are invalid references,
|
|
93
|
+
not optional data.
|
|
94
|
+
- Object form is fine when bindings don't reference each other.
|
|
77
95
|
|
|
78
96
|
## Related concepts
|
|
79
97
|
|
|
@@ -7,8 +7,9 @@ sources: [docs/consumer/ai-context.md#values--formatting, docs/consumer/ai-conte
|
|
|
7
7
|
|
|
8
8
|
# `$template` — string interpolation
|
|
9
9
|
|
|
10
|
-
`$template` interpolates values into a string. Two reference forms:
|
|
11
|
-
`${/state/path}` reads from state, `${name}` reads from a
|
|
10
|
+
`$template` interpolates values into a string. Two reference forms:
|
|
11
|
+
`${/state/path}` reads from state, `${name}` or `${user.name}` reads from a
|
|
12
|
+
`$let` binding.
|
|
12
13
|
Resolves at the consumption site — at render in element props, at dispatch in
|
|
13
14
|
action params.
|
|
14
15
|
|
|
@@ -30,21 +31,31 @@ URL with state:
|
|
|
30
31
|
{ "$template": "${/config/apiUrl}/rest/v1/items?id=eq.${/form/editId}" }
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
Combined with `$let` (when `$item` is needed inside `$template`):
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"$let": { "x": { "$item": "name" } },
|
|
37
|
-
"$in": { "$template": "Editing: ${x}" }
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
Combined with `$let` (when `$item` is needed inside `$template`):
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"$let": { "x": { "$item": "name" } },
|
|
38
|
+
"$in": { "$template": "Editing: ${x}" }
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Nested `$let` binding:
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"$let": { "user": { "$state": "/auth/user" } },
|
|
46
|
+
"$in": { "$template": "Welcome, ${user.name}" }
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Constraints / Anti-patterns
|
|
51
|
+
|
|
52
|
+
- **`$template` does NOT resolve `$item` directly.** `$item` is a JSON
|
|
53
|
+
expression, not a string token. Capture in `$let` first (see example
|
|
54
|
+
above) — see also [[@concept-expression-contexts]].
|
|
55
|
+
- **Dotted `$let` binding placeholders require the binding path to exist.**
|
|
56
|
+
Use them for known object bindings, not optional deep probing.
|
|
57
|
+
- **`$template` does NOT resolve in transaction phases.** Capture row data
|
|
58
|
+
via `setState` before the transaction fires.
|
|
48
59
|
- **Plain strings containing `${...}` are LITERAL** in `DataSourceConfig.url`.
|
|
49
60
|
Wrap in `$template` to enable templating — the validator catches plain
|
|
50
61
|
strings with `${...}` and points to the fix. See
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mythik",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Spec-driven core runtime for validated JSON applications, APIs, editor sessions, state, actions, validation, and versioning.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"isomorphic-dompurify": "^3.9.0",
|
|
47
|
-
"mssql": "^12.2.1",
|
|
48
47
|
"zustand": "^5.0.0"
|
|
49
48
|
},
|
|
50
49
|
"devDependencies": {
|
|
@@ -52,6 +51,12 @@
|
|
|
52
51
|
"es-module-lexer": "^2.0.0",
|
|
53
52
|
"typescript": "^5.7.0"
|
|
54
53
|
},
|
|
54
|
+
"optionalDependencies": {
|
|
55
|
+
"better-sqlite3": "^12.9.0",
|
|
56
|
+
"mssql": "^12.2.1",
|
|
57
|
+
"mysql2": "^3.22.3",
|
|
58
|
+
"pg": "^8.20.0"
|
|
59
|
+
},
|
|
55
60
|
"scripts": {
|
|
56
61
|
"build": "node ../../node_modules/typescript/bin/tsc",
|
|
57
62
|
"typecheck": "node ../../node_modules/typescript/bin/tsc --noEmit"
|