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.
Files changed (96) hide show
  1. package/README.md +47 -23
  2. package/dist/actions/dispatcher.d.ts.map +1 -1
  3. package/dist/actions/dispatcher.js +10 -0
  4. package/dist/actions/dispatcher.js.map +1 -1
  5. package/dist/expressions/handlers/let.d.ts +6 -0
  6. package/dist/expressions/handlers/let.d.ts.map +1 -1
  7. package/dist/expressions/handlers/let.js +29 -4
  8. package/dist/expressions/handlers/let.js.map +1 -1
  9. package/dist/expressions/handlers/template.d.ts.map +1 -1
  10. package/dist/expressions/handlers/template.js +2 -1
  11. package/dist/expressions/handlers/template.js.map +1 -1
  12. package/dist/security/api-spec-validator.d.ts.map +1 -1
  13. package/dist/security/api-spec-validator.js +4 -0
  14. package/dist/security/api-spec-validator.js.map +1 -1
  15. package/dist/security/spec-validator.d.ts.map +1 -1
  16. package/dist/security/spec-validator.js +43 -31
  17. package/dist/security/spec-validator.js.map +1 -1
  18. package/dist/server.d.ts +7 -0
  19. package/dist/server.d.ts.map +1 -1
  20. package/dist/server.js +3 -0
  21. package/dist/server.js.map +1 -1
  22. package/dist/spec-stores/sql-versioned.d.ts +38 -0
  23. package/dist/spec-stores/sql-versioned.d.ts.map +1 -0
  24. package/dist/spec-stores/sql-versioned.js +186 -0
  25. package/dist/spec-stores/sql-versioned.js.map +1 -0
  26. package/dist/spec-stores/sql.d.ts +21 -0
  27. package/dist/spec-stores/sql.d.ts.map +1 -0
  28. package/dist/spec-stores/sql.js +65 -0
  29. package/dist/spec-stores/sql.js.map +1 -0
  30. package/dist/spec-stores/sqlserver-versioned.d.ts +5 -30
  31. package/dist/spec-stores/sqlserver-versioned.d.ts.map +1 -1
  32. package/dist/spec-stores/sqlserver-versioned.js +16 -245
  33. package/dist/spec-stores/sqlserver-versioned.js.map +1 -1
  34. package/dist/spec-stores/sqlserver.d.ts +4 -11
  35. package/dist/spec-stores/sqlserver.d.ts.map +1 -1
  36. package/dist/spec-stores/sqlserver.js +16 -66
  37. package/dist/spec-stores/sqlserver.js.map +1 -1
  38. package/dist/sql/ddl.d.ts +7 -0
  39. package/dist/sql/ddl.d.ts.map +1 -0
  40. package/dist/sql/ddl.js +134 -0
  41. package/dist/sql/ddl.js.map +1 -0
  42. package/dist/sql/drivers/mysql.d.ts +25 -0
  43. package/dist/sql/drivers/mysql.d.ts.map +1 -0
  44. package/dist/sql/drivers/mysql.js +327 -0
  45. package/dist/sql/drivers/mysql.js.map +1 -0
  46. package/dist/sql/drivers/postgres.d.ts +30 -0
  47. package/dist/sql/drivers/postgres.d.ts.map +1 -0
  48. package/dist/sql/drivers/postgres.js +319 -0
  49. package/dist/sql/drivers/postgres.js.map +1 -0
  50. package/dist/sql/drivers/sqlite.d.ts +28 -0
  51. package/dist/sql/drivers/sqlite.d.ts.map +1 -0
  52. package/dist/sql/drivers/sqlite.js +367 -0
  53. package/dist/sql/drivers/sqlite.js.map +1 -0
  54. package/dist/sql/drivers/sqlserver.d.ts +46 -0
  55. package/dist/sql/drivers/sqlserver.d.ts.map +1 -0
  56. package/dist/sql/drivers/sqlserver.js +403 -0
  57. package/dist/sql/drivers/sqlserver.js.map +1 -0
  58. package/dist/sql/errors.d.ts +12 -0
  59. package/dist/sql/errors.d.ts.map +1 -0
  60. package/dist/sql/errors.js +13 -0
  61. package/dist/sql/errors.js.map +1 -0
  62. package/dist/sql/factory.d.ts +3 -0
  63. package/dist/sql/factory.d.ts.map +1 -0
  64. package/dist/sql/factory.js +24 -0
  65. package/dist/sql/factory.js.map +1 -0
  66. package/dist/sql/index.d.ts +17 -0
  67. package/dist/sql/index.d.ts.map +1 -0
  68. package/dist/sql/index.js +9 -0
  69. package/dist/sql/index.js.map +1 -0
  70. package/dist/sql/named-params.d.ts +8 -0
  71. package/dist/sql/named-params.d.ts.map +1 -0
  72. package/dist/sql/named-params.js +182 -0
  73. package/dist/sql/named-params.js.map +1 -0
  74. package/dist/sql/types.d.ts +49 -0
  75. package/dist/sql/types.d.ts.map +1 -0
  76. package/dist/sql/types.js +2 -0
  77. package/dist/sql/types.js.map +1 -0
  78. package/dist/types.d.ts +1 -1
  79. package/dist/types.d.ts.map +1 -1
  80. package/docs/consumer/README.md +1 -1
  81. package/docs/consumer/WHERE-TO-LOOK.md +4 -4
  82. package/docs/consumer/ai-context-api.md +44 -0
  83. package/docs/consumer/ai-context-runtime-semantics.md +12 -9
  84. package/docs/consumer/ai-context.md +124 -50
  85. package/docs/consumer/reference-doc.md +41 -24
  86. package/docs/wiki/compiled/README.md +1 -1
  87. package/docs/wiki/compiled/_lint.md +13 -8
  88. package/docs/wiki/compiled/concept-action-chains.md +62 -24
  89. package/docs/wiki/compiled/concept-package-layout.md +5 -3
  90. package/docs/wiki/compiled/concept-public-package-names.md +4 -2
  91. package/docs/wiki/compiled/concept-shape-animations.md +1 -1
  92. package/docs/wiki/compiled/concept-spec-stores-catalog.md +28 -16
  93. package/docs/wiki/compiled/concept-transactions.md +20 -12
  94. package/docs/wiki/compiled/expression-let-ref.md +36 -18
  95. package/docs/wiki/compiled/expression-template.md +28 -17
  96. 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 action
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>, <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
- ## Commit semantics
40
-
41
- Each action in a sequential chain commits state before the next runs.
42
- `[setState, navigateScreen]` works the navigated screen sees the state
43
- written by `setState`.
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
- - For background dispatch (next action immediately), use
51
- [[@concept-fire-and-forget]].
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`, `SqlServerSpecStore`, and versioned/environment variants |
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 initial npm publish surface.
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`, `mssql`, or other Node-only 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 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 initial npm publish surface.
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 initial npm publish surface.
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
- | `SqlServerSpecStore` | SQL Server (via `mssql`) |
27
- | `SqlServerVersionedSpecStore` | + version history |
28
- | `SqlServerEnvironmentStore` | + env promotions |
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
- Pre-v0.1.0 shape pulled `mssql` (Node-only) and `fs` into any browser
33
- bundle that imported `mythik`. v0.1.0 structural split makes
34
- `mythik` browser-safe **by construction** no bundler stubs
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 { SqlServerSpecStore, FileSpecStore } from 'mythik/server';
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 SqlServerSpecStore({ ..., table: 'api_specs' })
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
- - **UPDATE transactions don't need `onSuccess`** re-fetch causes flash.
62
- See [[@pattern-tx-update]].
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
- Multi-step computation:
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
- - Object form is fine when bindings don't reference each other.
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 `$let` binding.
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
- ## Constraints / Anti-patterns
42
-
43
- - **`$template` does NOT resolve `$item` directly.** `$item` is a JSON
44
- expression, not a string token. Capture in `$let` first (see example
45
- above) see also [[@concept-expression-contexts]].
46
- - **`$template` does NOT resolve in transaction phases.** Capture row data
47
- via `setState` before the transaction fires.
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.2",
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"