@wcstack/state 4.0.0-rc.3 → 4.0.0-rc.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.ja.md +80 -21
- package/README.md +81 -22
- package/dist/auto.min.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +1 -1
- package/dist/manifest.d.ts +4 -2
- package/dist/manifest.esm.js +84 -80
- package/dist/parser.esm.js +43 -27
- package/dist/split/auto.js +1 -1
- package/dist/split/chunks/{chunk-I2V4DGEI.js → chunk-5D34CGCF.js} +1 -1
- package/dist/split/chunks/chunk-5MLEMVL3.js +1 -0
- package/dist/split/chunks/{chunk-YZ4LWPXN.js → chunk-ACYOJ3NW.js} +1 -1
- package/dist/split/chunks/chunk-C3UYMJRT.js +1 -0
- package/dist/split/chunks/chunk-COJU24UI.js +1 -0
- package/dist/split/chunks/chunk-FVHQWDF4.js +1 -0
- package/dist/split/chunks/chunk-FZJY4CF3.js +1 -0
- package/dist/split/chunks/chunk-HSMALJSW.js +1 -0
- package/dist/split/chunks/chunk-L2BZD5DU.js +1 -0
- package/dist/split/chunks/{chunk-Z3EEGBYA.js → chunk-SA2LYPN7.js} +1 -1
- package/dist/split/chunks/chunk-VY2XLPFM.js +1 -0
- package/dist/split/core.js +1 -1
- package/dist/split/features/devtools.js +1 -1
- package/dist/split/features/diagnostics.d.ts +3 -3
- package/dist/split/features/diagnostics.js +1 -1
- package/dist/split/features/formats.d.ts +4 -1
- package/dist/split/features/formats.js +1 -1
- package/dist/split/features/list-keys.js +1 -1
- package/dist/split/features/native-commands.d.ts +31 -0
- package/dist/split/features/native-commands.js +1 -0
- package/dist/split/features/recursion.js +1 -1
- package/dist/split/features/scopes.js +1 -1
- package/dist/split/features/ssr.js +1 -1
- package/dist/split/features/temporal.js +1 -1
- package/dist/wcs-manifest.json +71 -17
- package/package.json +1 -1
- package/dist/split/chunks/chunk-2PWEFKRB.js +0 -1
- package/dist/split/chunks/chunk-5PWMZ75N.js +0 -1
- package/dist/split/chunks/chunk-FED2DM4X.js +0 -1
- package/dist/split/chunks/chunk-HYEQWIFX.js +0 -1
- package/dist/split/chunks/chunk-NPPWJBGJ.js +0 -1
- package/dist/split/chunks/chunk-WPSUT5QQ.js +0 -1
- package/dist/split/chunks/chunk-YPD4YBJO.js +0 -1
- package/dist/split/chunks/chunk-YZUTVCIH.js +0 -1
package/README.ja.md
CHANGED
|
@@ -191,9 +191,9 @@
|
|
|
191
191
|
<script type="importmap">
|
|
192
192
|
{
|
|
193
193
|
"imports": {
|
|
194
|
-
"@wcstack/state/core": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.
|
|
195
|
-
"@wcstack/state/features/temporal": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.
|
|
196
|
-
"@wcstack/state/features/scopes": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.
|
|
194
|
+
"@wcstack/state/core": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.5/dist/split/core.js",
|
|
195
|
+
"@wcstack/state/features/temporal": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.5/dist/split/features/temporal.js",
|
|
196
|
+
"@wcstack/state/features/scopes": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.5/dist/split/features/scopes.js"
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
</script>
|
|
@@ -226,21 +226,22 @@
|
|
|
226
226
|
|
|
227
227
|
| エントリ | 足されるもの |
|
|
228
228
|
|---|---|
|
|
229
|
-
| `@wcstack/state/core` | バインディングの本体: `data-wcs`・`{{ }}` とコメントバインディング・`for` / `if`・パス getter・イベント・`$command` / `$on
|
|
229
|
+
| `@wcstack/state/core` | バインディングの本体: `data-wcs`・`{{ }}` とコメントバインディング・`for` / `if`・パス getter・イベント・`$command` / `$on`・条件の 10 個のフィルタ(`eq` `ne` `not` `lt` `le` `gt` `ge` `truthy` `falsy` `boolean`)・`bootstrapState`・`installFeatures` |
|
|
230
230
|
| `@wcstack/state/features/temporal` | `$watch`・`$stream` |
|
|
231
231
|
| `@wcstack/state/features/list-keys` | `$listKeys` |
|
|
232
|
+
| `@wcstack/state/features/native-commands` | ネイティブ要素の `command.<method>:`(`<dialog>` の `showModal()`・`<input>` の `focus()`・`<video>` の `play()` など)—— [ネイティブ要素のコマンド](#ネイティブ要素のコマンド) |
|
|
232
233
|
| `@wcstack/state/features/scopes` | `bind-component`・`mount=` のボリューム・オーバーレイの公開 getter・DCC(`data-wc-definition`) |
|
|
233
234
|
| `@wcstack/state/features/recursion` | `$recursion` と `**` パス |
|
|
234
235
|
| `@wcstack/state/features/ssr` | `enable-ssr`: サーバー描画とハイドレーション |
|
|
235
|
-
| `@wcstack/state/features/formats` |
|
|
236
|
+
| `@wcstack/state/features/formats` | 残りの 37 個のフィルタ: 算術・型変換・デフォルト(`add`・`int`・`coalesce` …)と書式(`upper`・`date`・`round`・`truncate` …) |
|
|
236
237
|
| `@wcstack/state/features/devtools` | DevTools Hook Protocol への source 登録 |
|
|
237
|
-
| `@wcstack/state/features/diagnostics` | エラーメッセージの文章(did-you-mean と lint への案内を含む)と、開発時の警告(束縛や `$watch` のパスが解決しない、`wcs/default-getter-mismatch
|
|
238
|
+
| `@wcstack/state/features/diagnostics` | エラーメッセージの文章(did-you-mean と lint への案内を含む)と、開発時の警告(束縛や `$watch` のパスが解決しない、`wcs/default-getter-mismatch`)。入れなければ、メッセージは番号と値だけになり([エラーメッセージ](#エラーメッセージと番号))、これらの警告は出ず、4.0 で外した 3.x の名前(`$scan`・`$streams`・`$updatedCallback`・`$trackDependency`・`$untrackDependency`)も見つけない |
|
|
238
239
|
| `@wcstack/state/define` | `defineState` と型だけ — ランタイムは 0 |
|
|
239
240
|
|
|
240
241
|
アドオンが入っていない宣言は黙って無視されません。state の読み込み時に
|
|
241
242
|
`[wcs/feature-not-installed] $watch needs the add-on @wcstack/state/features/temporal` を throw し
|
|
242
243
|
(`mount=`・`bind-component`・`data-wc-definition` は同じ形で `scopes` を、`enable-ssr` は `ssr` を
|
|
243
|
-
名指します)、`formats`
|
|
244
|
+
名指します)、`formats` なしの `formats` のフィルタは束縛計画の段で、アドオン名を挙げた `[wcs/filter-unknown]`
|
|
244
245
|
を throw します。install は冪等で — 2 回目の install は読み飛ばされます — どのエントリも core の
|
|
245
246
|
チャンクを 1 つだけ共有します。アドオンがエンジンの 2 つ目のコピーを抱えることも、**別のアドオン**の
|
|
246
247
|
コピーを抱えることもありません(アドオンをまたぐ呼び出しは、持ち主のアドオンが install 時に埋める
|
|
@@ -252,7 +253,7 @@
|
|
|
252
253
|
ページが名指したアドオンを、同じビルドから読み込みます。
|
|
253
254
|
|
|
254
255
|
```html
|
|
255
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.
|
|
256
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.5/dist/split/auto.js"></script>
|
|
256
257
|
<wcs-state features="scopes diagnostics">
|
|
257
258
|
<script type="module">
|
|
258
259
|
export default {
|
|
@@ -274,7 +275,7 @@
|
|
|
274
275
|
| 何のためか | どの `<wcs-state>` が動き出すよりも前に揃っているべきもの — `mount=` / `bind-component` / DCC の要素が何であるかを決める `scopes` — と、ページの開発補助(`diagnostics`・`devtools`) | その state が必要とするアドオン(`$watch` のための `temporal`、フィルタのための `formats`) |
|
|
275
276
|
| 誰が読むか | 分割版の auto エントリだけ | すべてのエントリ: 分割版の auto エントリは足りないアドオンを読み込み、それ以外のエントリは入っているかを確かめ、入っていなければその state を `[wcs/feature-not-installed]` で失敗させる |
|
|
276
277
|
|
|
277
|
-
名前は `formats`・`diagnostics`・`temporal`・`list-keys`・`scopes`・`recursion`・`ssr`・`devtools` です。
|
|
278
|
+
名前は `formats`・`diagnostics`・`temporal`・`list-keys`・`scopes`・`recursion`・`ssr`・`devtools`・`native-commands` です。
|
|
278
279
|
`features=` にそれ以外の名前があると、分割版の auto エントリは `<wcs-state>` を定義する前に
|
|
279
280
|
`[wcs/feature-unknown]` で失敗します。`$features` にあれば、その state が失敗します(分割版の auto
|
|
280
281
|
エントリでは `[wcs/feature-unknown]`、それ以外では `[wcs/feature-not-installed]`)。配列でない
|
|
@@ -1671,7 +1672,7 @@ export default {
|
|
|
1671
1672
|
|
|
1672
1673
|
## フィルタ
|
|
1673
1674
|
|
|
1674
|
-
47 種類の組み込みフィルタが入力(DOM → 状態)と出力(状態 → DOM)の両方向で利用できます: core
|
|
1675
|
+
47 種類の組み込みフィルタが入力(DOM → 状態)と出力(状態 → DOM)の両方向で利用できます: core に条件の 10 個のフィルタ(`eq`・`ne`・`not`・`lt`・`le`・`gt`・`ge`・`truthy`・`falsy`・`boolean`)、`formats` アドオンに残りの 37 個(算術・数値フォーマット・文字列・型変換・日付 / 時刻・デフォルト)があり、全部入りのエントリには両方が含まれます。`formats` なしの `/core` で `formats` のフィルタを使うと、束縛計画の段でアドオン名を挙げて失敗します。
|
|
1675
1676
|
|
|
1676
1677
|
3.x が 3.2 の改名の別名として残していた名前(`inc`・`dec`・`fix`・`uc`・`lc`・`cap`・`rep`・`rev`・`pad`・`null`)と `substr` フィルタは存在しません: 未知の名前と同じく失敗し、メッセージが代わりに書くものを示します(`"uc" was renamed "upper" in 3.2 and removed in 4.0 — write "upper".`。`substr(start, length)` は `slice(start, start + length)`)。
|
|
1677
1678
|
|
|
@@ -2104,7 +2105,7 @@ export default {
|
|
|
2104
2105
|
| 部位 | 説明 |
|
|
2105
2106
|
|---|---|
|
|
2106
2107
|
| `command.` | 固定の prefix |
|
|
2107
|
-
| `<methodName>` | 起動する要素のメソッド。名前は `static wcBindable.commands` に `{ name: "<methodName>" }` として現れること |
|
|
2108
|
+
| `<methodName>` | 起動する要素のメソッド。名前は `static wcBindable.commands` に `{ name: "<methodName>" }` として現れること —— ネイティブ要素では [ネイティブ要素のコマンド](#ネイティブ要素のコマンド) の表にあること |
|
|
2108
2109
|
| `$command.<tokenName>` | `CommandToken` に解決される明示的な名前空間パス。`<tokenName>` は `$commandTokens` で宣言された名前であること |
|
|
2109
2110
|
|
|
2110
2111
|
右辺は `$command.<tokenName>` と書く必要があります —— ベア名の省略形(`fetchUsers`)は非対応です。`$command.` 名前空間を経由することでバインディングの意図が HTML 上で明示され、トップレベルの state 名前空間を token 名で汚さずに済みます。
|
|
@@ -2130,11 +2131,11 @@ class MyFetcher extends HTMLElement {
|
|
|
2130
2131
|
|
|
2131
2132
|
検証ルール(バインディング時に強制):
|
|
2132
2133
|
|
|
2133
|
-
- 要素は `protocol: "wc-bindable"` かつ整数 `version` が `1` 以上(現行プロトコルは `1`。1 以上のすべてのバージョンが core 互換)の `static wcBindable` を公開するカスタム要素であること
|
|
2134
|
-
- `methodName` は `wcBindable.commands` に(`name`
|
|
2134
|
+
- 要素は `protocol: "wc-bindable"` かつ整数 `version` が `1` 以上(現行プロトコルは `1`。1 以上のすべてのバージョンが core 互換)の `static wcBindable` を公開するカスタム要素であること —— または、`native-commands` アドオンがあればネイティブ要素([ネイティブ要素のコマンド](#ネイティブ要素のコマンド))
|
|
2135
|
+
- `methodName` は `wcBindable.commands` に(`name` で)現れること(ネイティブ要素では [ネイティブ要素のコマンド](#ネイティブ要素のコマンド) の表にあること)
|
|
2135
2136
|
- `<tokenName>` は `$commandTokens` で宣言されていること(`$command.typo` は `[wcs/token-undeclared]` を throw する)
|
|
2136
2137
|
|
|
2137
|
-
|
|
2138
|
+
カスタム要素はクラスが定義された時点で検査され、ネイティブ要素はその場で検査されます —— アドオンが入っていれば(`@wcstack/state` と `/auto` には含まれています)[native-commands](#ネイティブ要素のコマンド) の表と照合し、入っていなければ拒否します(`[wcs/token-misconfigured]` `#1202`)。ページのバインド中に見つかった違反は `<wcs-state>` の初期化を失敗させます。`for:` / `if:` の行の中で見つかった違反や、ページのバインド後にクラスが定義されて見つかった違反は、そのバインディング 1 本の失敗として `$errorCallback` に届き、行はそのまま構築されます([初期化の失敗](#初期化の失敗))。
|
|
2138
2139
|
|
|
2139
2140
|
### Token API
|
|
2140
2141
|
|
|
@@ -2192,6 +2193,64 @@ command token は state コードから emit する必要はありません。DO
|
|
|
2192
2193
|
<my-list data-wcs="command.reset: $command.reset"></my-list>
|
|
2193
2194
|
```
|
|
2194
2195
|
|
|
2196
|
+
### ネイティブ要素のコマンド
|
|
2197
|
+
|
|
2198
|
+
`native-commands` アドオン(`@wcstack/state` と `/auto` には含まれています。`/core` のページは `@wcstack/state/features/native-commands` を入れます)があると、`command.<method>:` は**ネイティブ**要素のメソッドも購読します。ダイアログを開く・入力欄にフォーカスする・動画を再生するといった操作が「state が emit する token」になり、state のコードは要素に手を伸ばしません:
|
|
2199
|
+
|
|
2200
|
+
```html
|
|
2201
|
+
<button data-wcs="onclick: $command.openEditor">編集</button>
|
|
2202
|
+
<dialog data-wcs="command.showModal: $command.openEditor; command.close: $command.closeEditor">
|
|
2203
|
+
<input data-wcs="value: title">
|
|
2204
|
+
<button data-wcs="onclick: save">保存</button>
|
|
2205
|
+
</dialog>
|
|
2206
|
+
```
|
|
2207
|
+
|
|
2208
|
+
```javascript
|
|
2209
|
+
export default {
|
|
2210
|
+
title: "",
|
|
2211
|
+
$commandTokens: ["openEditor", "closeEditor"],
|
|
2212
|
+
async save() {
|
|
2213
|
+
await saveTitle(this.title);
|
|
2214
|
+
this.$command.closeEditor.emit("saved"); // → dialog.close("saved")
|
|
2215
|
+
},
|
|
2216
|
+
};
|
|
2217
|
+
```
|
|
2218
|
+
|
|
2219
|
+
ネイティブ要素が呼べるのは次の表のメソッドだけです。それ以外のメソッドは、カスタム要素の宣言に無いコマンドと同じく、バインディングの取り付け時に `[wcs/token-misconfigured]`(`#1205`。その要素が呼べるメソッドを列挙する)を throw します:
|
|
2220
|
+
|
|
2221
|
+
| 要素 | メソッド |
|
|
2222
|
+
|---|---|
|
|
2223
|
+
| すべての要素 | `focus` `blur` `click` `scrollIntoView` `showPopover` `hidePopover` `togglePopover` |
|
|
2224
|
+
| `<dialog>` | `show` `showModal` `close` `requestClose` |
|
|
2225
|
+
| `<form>` | `requestSubmit` `checkValidity` `reportValidity` |
|
|
2226
|
+
| `<input>` | `select` `setSelectionRange` `showPicker` `setCustomValidity` `checkValidity` `reportValidity` |
|
|
2227
|
+
| `<textarea>` | `select` `setSelectionRange` `setCustomValidity` `checkValidity` `reportValidity` |
|
|
2228
|
+
| `<select>` | `showPicker` `setCustomValidity` `checkValidity` `reportValidity` |
|
|
2229
|
+
| `<audio>` `<video>` | `play` `pause` `load` |
|
|
2230
|
+
|
|
2231
|
+
意図して入れていないもの: HTML・属性・木を書き換えるメソッド(`insertAdjacentHTML`・`setAttribute`・`remove` など —— `html:` / `attr.` で束縛してください)、`input` イベント無しでコントロールの値を変えるため state が変化を知らないもの(`form.reset()`・`stepUp()`・`stepDown()`・`setRangeText()` —— state を書き換えてください)、入力検証と `submit` イベントを飛ばす `form.submit()`(`requestSubmit` はどちらも飛ばしません)、そして状態の出力も持つ `@wcstack/fullscreen`・`@wcstack/pointer-lock`・`@wcstack/picture-in-picture` が扱うフルスクリーン / ポインタロック / ピクチャーインピクチャーの要求です。
|
|
2232
|
+
|
|
2233
|
+
- **引数。** ネイティブのメソッドは `emit` の引数を受け取ります。ただし第 1 引数が `Event` なら引数なしで呼びます。`on…: $command.x` のバインディングは `(event, ...listIndexes)` を emit しますが、これを受け取るネイティブメソッドはありません —— `close(event)` は dialog の `returnValue` を `"[object PointerEvent]"` にし、`requestSubmit(event)` は throw します。state からの `emit("saved")`・`emit({ preventScroll: true })`・`emit({ block: "center" })` はそのまま渡ります。カスタム要素のメソッドは従来どおりすべてを受け取ります。
|
|
2234
|
+
- **決めるのは表で、ブラウザではありません。** 表にあるメソッドはどのブラウザでも(サーバーでも)束縛できます。そのメソッドを持たないブラウザ(古いブラウザの `requestClose` など)では、token が emit されたときに呼び出しが失敗し、throw した購読者と同じく報告されます。
|
|
2235
|
+
- **戻り値と例外**はカスタム要素と同じです: `emit` は `checkValidity()` の真偽値や `play()` の `Promise` を返します。throw したメソッド(非モーダルで開いている dialog への `showModal()`、`popover` の無い要素への `showPopover()`)は `console.error` で報告され、ほかの購読者には届きます。reject した `Promise` は捕捉しません: 自動再生の拒否を扱うには、state から `await Promise.all(this.$command.play.emit())` してください。
|
|
2236
|
+
- **描画は後から走ります。** 書き込みはマイクロタスクで描画されるので、`this.editing = true; this.$command.focusTitle.emit();` の emit は、まだ表示されていない入力欄に —— `if:` の中なら、まだ作られていない入力欄に —— 届きます。描かれてから `$renderedCallback` で emit してください:
|
|
2237
|
+
|
|
2238
|
+
```html
|
|
2239
|
+
<template data-wcs="if: editing">
|
|
2240
|
+
<input data-wcs="value: title; command.focus: $command.focusTitle">
|
|
2241
|
+
</template>
|
|
2242
|
+
```
|
|
2243
|
+
|
|
2244
|
+
```javascript
|
|
2245
|
+
$renderedCallback(paths) {
|
|
2246
|
+
if (paths.includes("editing") && this.editing) this.$command.focusTitle.emit();
|
|
2247
|
+
},
|
|
2248
|
+
```
|
|
2249
|
+
|
|
2250
|
+
- **ユーザー操作。** `showPicker()` と音声つきの `play()` は直前のユーザー操作を必要とします。`on…: $command.x` はイベントの処理の中でメソッドを呼びますが、`await` の後の `emit` では間に合わないことがあります。
|
|
2251
|
+
- **カスタム要素は変わりません**: コマンドは `wcBindable` で宣言し、宣言の無いものは従来どおり `#1202` を throw します。カスタマイズ済み組み込み要素(`<button is="…">`)はネイティブ要素です。
|
|
2252
|
+
- **ボタンだけで開閉が済むなら**、プラットフォームの invoker commands は state を必要としません: `<button commandfor="dlg" command="show-modal">`。state が決めるとき(fetch の後、検証の後)や、invoker commands に無い操作(`focus`・`play`・`scrollIntoView`)に `command.` を使ってください。
|
|
2253
|
+
|
|
2195
2254
|
## Event Token(イベントバインディング)
|
|
2196
2255
|
|
|
2197
2256
|
command token はコンポーネントへ *押し込み* ます(state がメソッドを起動)。**event token** はその正確な双対 —— コンポーネントから *引き出し* ます(要素がイベントを dispatch し、state が受信)。両者で要素 ↔ state 境界の双方向をカバーし、どちらの側も相手への参照を一切持ちません。共有されるのは token のみです。
|
|
@@ -2353,7 +2412,7 @@ event token は command token と同じ `Token` pub/sub プリミティブを共
|
|
|
2353
2412
|
|
|
2354
2413
|
## Stream(`$stream`)
|
|
2355
2414
|
|
|
2356
|
-
command token / event token が運ぶのは離散的なやり取りです。**`$stream`** は残る形 —— 連続的なフローをカバーします。非同期 producer(async iterable / async generator / `ReadableStream`)を宣言すると、フレームワークがそれを **fold して単一の reactive プロパティに畳み込みます** —— 各チャンクは通常のパス代入を通るため、バインディング・パス getter・`$renderedCallback` は自分で値を代入した場合とまったく同じように反応します。`args` 関数が読んだ state パスが変化すると、実行中の producer は abort され、新しい引数で source が張り直されます(switchMap 型の依存駆動 restart)。stream は `$connectedCallback` 完了後に eager に起動し、要素の disconnect で abort されます。`$stream` は `temporal` アドオンです(全部入りのエントリに含まれる)。3.x の名前 `$streams`
|
|
2415
|
+
command token / event token が運ぶのは離散的なやり取りです。**`$stream`** は残る形 —— 連続的なフローをカバーします。非同期 producer(async iterable / async generator / `ReadableStream`)を宣言すると、フレームワークがそれを **fold して単一の reactive プロパティに畳み込みます** —— 各チャンクは通常のパス代入を通るため、バインディング・パス getter・`$renderedCallback` は自分で値を代入した場合とまったく同じように反応します。`args` 関数が読んだ state パスが変化すると、実行中の producer は abort され、新しい引数で source が張り直されます(switchMap 型の依存駆動 restart)。stream は `$connectedCallback` 完了後に eager に起動し、要素の disconnect で abort されます。`$stream` は `temporal` アドオンです(全部入りのエントリに含まれる)。3.x の名前 `$streams` は、`diagnostics` アドオンが入っていれば(`@wcstack/state`・`/auto`)`[wcs/declaration-alias] $streams was removed: write $stream.`(`#1601`)を throw します。入っていなければ、その宣言は無視されます。
|
|
2357
2416
|
|
|
2358
2417
|
`$renderedCallback` は引き続き binding 駆動です。stream 宣言だけでは headless な購読にならず、その value/status/error の live DOM binding が実際に適用されたときだけ callback の path に現れます。描画せずに stream の値へ反応したい場合は、そのパスに [`$watch`](#watchwatch) を宣言してください。観測契約は [stream リファレンス](docs/streams.md) を参照してください。
|
|
2359
2418
|
|
|
@@ -2754,7 +2813,7 @@ export default {
|
|
|
2754
2813
|
|
|
2755
2814
|
状態オブジェクトに `$connectedCallback` / `$disconnectedCallback` / `$renderedCallback` / `$errorCallback` を定義すると、初期化・クリーンアップ・更新時・バインディング失敗時のフックとして利用できます。
|
|
2756
2815
|
|
|
2757
|
-
> `$renderedCallback` が受けるのは**適用されたバインディング**の更新で、state の更新全体ではありません(それには `$watch`)。3.x の名前 `$updatedCallback`
|
|
2816
|
+
> `$renderedCallback` が受けるのは**適用されたバインディング**の更新で、state の更新全体ではありません(それには `$watch`)。3.x の名前 `$updatedCallback` は、`diagnostics` アドオンが入っていれば(`@wcstack/state`・`/auto`)`[wcs/declaration-alias] $updatedCallback was removed: write $renderedCallback.`(`#1601`)を throw します。入っていなければ、その宣言は無視されます。
|
|
2758
2817
|
|
|
2759
2818
|
```html
|
|
2760
2819
|
<wcs-state>
|
|
@@ -2836,16 +2895,16 @@ li {
|
|
|
2836
2895
|
|
|
2837
2896
|
### エラーメッセージと番号
|
|
2838
2897
|
|
|
2839
|
-
メッセージはすべて `[@wcstack/state]`
|
|
2898
|
+
メッセージはすべて `[@wcstack/state]` で始まります。ほとんどのメッセージは番号(`#501`)を持ち、`@wcstack/lint` と VS Code 拡張も検査する事柄についてのメッセージは同じ診断 code(`[wcs/filter-unknown]`)を持ちます。番号の百の位がその code を表します —— 1xx `binding-syntax`、2xx `template-syntax`、3xx `binding-path-missing`、4xx `binding-type-expectation`、5xx `filter-unknown`、6xx `filter-arity`、7xx `getter-cycle`、8xx `getter-depth-exceeded`、9xx `index-arity`、10xx `index-param-range`、11xx `recursion-unsupported`、12xx `token-misconfigured`、13xx `token-undeclared`、14xx `wildcard-rank`、15xx `spread-no-bindable`、16xx `declaration-alias`、17xx `name-alias`。1〜99 は code を持ちません。番号は追加されるだけなので、番号の意味はバージョンをまたいで変わりません。
|
|
2840
2899
|
|
|
2841
|
-
|
|
2900
|
+
番号付きメッセージの code と文章 —— いちばん近い名前(lint と同じ規則による did-you-mean)、直し方、そして lint が検出できる場合は lint への案内 —— は、`@wcstack/state` と `/auto` に含まれる `diagnostics` アドオンが出します。それを入れていない `/core` のページでは、メッセージは番号と表示するはずだった値だけになります:
|
|
2842
2901
|
|
|
2843
2902
|
```
|
|
2844
2903
|
[@wcstack/state] [wcs/filter-unknown] filter not found: uc. "uc" was renamed "upper" in 3.2 and removed in 4.0 — write "upper". Validate statically: npx @wcstack/lint <file>.
|
|
2845
|
-
[@wcstack/state]
|
|
2904
|
+
[@wcstack/state] #501 "uc"
|
|
2846
2905
|
```
|
|
2847
2906
|
|
|
2848
|
-
1 行目が `@wcstack/state` と `/auto` の出力、2 行目が `features/diagnostics` なしの `/core` の出力です。`/core` で開発するときは `diagnostics`
|
|
2907
|
+
1 行目が `@wcstack/state` と `/auto` の出力、2 行目が `features/diagnostics` なしの `/core` の出力です。`/core` で開発するときは `diagnostics` を入れてください: 4.0 で外した 3.x の名前(#1・#1601・#1701)を見つけるのもこのアドオンで、入れていないページはそれらを無視します(その名前の宣言は何もせず、読むと `undefined`)。アドオンなしのページが意図して突き当たる障壁(`[wcs/feature-not-installed]`、`formats` なしの `formats` のフィルタ)は、core の中でも完全な文章です。
|
|
2849
2908
|
|
|
2850
2909
|
<details>
|
|
2851
2910
|
<summary>番号付きメッセージ</summary>
|
|
@@ -3029,7 +3088,7 @@ this.$getAll("matrix.*.*", [row]);
|
|
|
3029
3088
|
初期化を失敗させるもの:
|
|
3030
3089
|
|
|
3031
3090
|
- 読めないソース([状態の初期化](#状態の初期化))。
|
|
3032
|
-
- 不正な宣言: 削除された名前(`$scan`・`$streams`・`$updatedCallback
|
|
3091
|
+
- 不正な宣言: 削除された名前(`$scan`・`$streams`・`$updatedCallback`。`diagnostics` アドオンがあるとき)、形の誤った `$behavior` / `$features` / `$commandTokens` / `$eventTokens` / `$on`、アドオンが入っていない宣言(`[wcs/feature-not-installed]`)。
|
|
3033
3092
|
- ページのバインド中に見つかったマークアップの誤り: 構文エラー、未知のフィルタや誤った引数の個数、wildcard-rank のエラー、フィルタ付きの `for:`、テンプレートの中の `outerHTML:`、クラスが定義済みの要素での wc-bindable の設定ミス。走査はそのエラーで止まります: 文書順でそれより前はバインドされ、後はバインドされません。デプロイの前に `npx @wcstack/lint` を実行してください。
|
|
3034
3093
|
- 別の `<wcs-state>` がすでにバインドしているルートの上の、2 つ目のルート `<wcs-state>`(`#47`)。state ツリーはルートごとに 1 本です。部分木は `mount=` で接ぎ木してください。
|
|
3035
3094
|
|
package/README.md
CHANGED
|
@@ -192,9 +192,9 @@ leaves features out, it can compose them instead:
|
|
|
192
192
|
<script type="importmap">
|
|
193
193
|
{
|
|
194
194
|
"imports": {
|
|
195
|
-
"@wcstack/state/core": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.
|
|
196
|
-
"@wcstack/state/features/temporal": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.
|
|
197
|
-
"@wcstack/state/features/scopes": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.
|
|
195
|
+
"@wcstack/state/core": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.5/dist/split/core.js",
|
|
196
|
+
"@wcstack/state/features/temporal": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.5/dist/split/features/temporal.js",
|
|
197
|
+
"@wcstack/state/features/scopes": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.5/dist/split/features/scopes.js"
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
</script>
|
|
@@ -227,21 +227,22 @@ The file names under `dist/split/chunks/` carry a content hash: if you list chun
|
|
|
227
227
|
|
|
228
228
|
| Entry | What it adds |
|
|
229
229
|
|---|---|
|
|
230
|
-
| `@wcstack/state/core` | The binding engine: `data-wcs`, `{{ }}` and comment bindings, `for` / `if`, path getters, events, `$command` / `$on`, the
|
|
230
|
+
| `@wcstack/state/core` | The binding engine: `data-wcs`, `{{ }}` and comment bindings, `for` / `if`, path getters, events, `$command` / `$on`, the 10 condition filters (`eq` `ne` `not` `lt` `le` `gt` `ge` `truthy` `falsy` `boolean`), `bootstrapState`, `installFeatures` |
|
|
231
231
|
| `@wcstack/state/features/temporal` | `$watch`, `$stream` |
|
|
232
232
|
| `@wcstack/state/features/list-keys` | `$listKeys` |
|
|
233
|
+
| `@wcstack/state/features/native-commands` | `command.<method>:` on native elements (`<dialog>`.`showModal()`, `<input>`.`focus()`, `<video>`.`play()`, …) — [Native Element Commands](#native-element-commands) |
|
|
233
234
|
| `@wcstack/state/features/scopes` | `bind-component`, `mount=` volumes, overlay exports, DCC (`data-wc-definition`) |
|
|
234
235
|
| `@wcstack/state/features/recursion` | `$recursion` and `**` paths |
|
|
235
236
|
| `@wcstack/state/features/ssr` | `enable-ssr`: server rendering and hydration |
|
|
236
|
-
| `@wcstack/state/features/formats` | The
|
|
237
|
+
| `@wcstack/state/features/formats` | The other 37 filters: arithmetic, conversion and defaults (`add`, `int`, `coalesce`, …) and formatting (`upper`, `date`, `round`, `truncate`, …) |
|
|
237
238
|
| `@wcstack/state/features/devtools` | The DevTools hook protocol source |
|
|
238
|
-
| `@wcstack/state/features/diagnostics` | The sentences of error messages, with the did-you-mean and the pointer to lint, and the development-time warnings (a bound or `$watch` path that does not resolve, `wcs/default-getter-mismatch`). Without it a message is its
|
|
239
|
+
| `@wcstack/state/features/diagnostics` | The sentences of error messages, with the did-you-mean and the pointer to lint, and the development-time warnings (a bound or `$watch` path that does not resolve, `wcs/default-getter-mismatch`). Without it a message is its number and its values ([Error messages](#error-messages-and-numbers)), those warnings are not printed, and the 3.x names 4.0 removed (`$scan`, `$streams`, `$updatedCallback`, `$trackDependency`, `$untrackDependency`) are not detected |
|
|
239
240
|
| `@wcstack/state/define` | `defineState` and the types only — no runtime at all |
|
|
240
241
|
|
|
241
242
|
A declaration whose add-on is missing does not fail quietly: it throws
|
|
242
243
|
`[wcs/feature-not-installed] $watch needs the add-on @wcstack/state/features/temporal` when the state
|
|
243
244
|
is loaded (`mount=`, `bind-component` and `data-wc-definition` name `scopes` the same way, and
|
|
244
|
-
`enable-ssr` names `ssr`), and a
|
|
245
|
+
`enable-ssr` names `ssr`), and a filter of `formats` without it throws `[wcs/filter-unknown]`
|
|
245
246
|
naming the add-on when the bindings are planned. Installing is idempotent — an add-on installed
|
|
246
247
|
again is skipped — and every entry shares one core chunk: an add-on never carries a second copy of
|
|
247
248
|
the engine, and never a copy of another add-on either (a call across that seam goes through a
|
|
@@ -253,7 +254,7 @@ receptacle the owning add-on fills on install).
|
|
|
253
254
|
core, and the add-ons the page names from the same build.
|
|
254
255
|
|
|
255
256
|
```html
|
|
256
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.
|
|
257
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.5/dist/split/auto.js"></script>
|
|
257
258
|
<wcs-state features="scopes diagnostics">
|
|
258
259
|
<script type="module">
|
|
259
260
|
export default {
|
|
@@ -275,8 +276,8 @@ The add-ons are named in two places, for two different reasons:
|
|
|
275
276
|
| What it is for | What must be there before any `<wcs-state>` starts — `scopes`, which decides what a `mount=` / `bind-component` / DCC element is — and the page's development aids (`diagnostics`, `devtools`) | The add-ons that state needs (`temporal` for its `$watch`, `formats` for its filters) |
|
|
276
277
|
| Who reads it | Only the split auto entry | Every entry: the split auto entry loads the missing add-ons; the other entries check that they are installed and fail the state with `[wcs/feature-not-installed]` otherwise |
|
|
277
278
|
|
|
278
|
-
The names are `formats`, `diagnostics`, `temporal`, `list-keys`, `scopes`, `recursion`, `ssr
|
|
279
|
-
`devtools`. Any other name in `features=` makes the split auto entry fail with `[wcs/feature-unknown]`
|
|
279
|
+
The names are `formats`, `diagnostics`, `temporal`, `list-keys`, `scopes`, `recursion`, `ssr`,
|
|
280
|
+
`devtools` and `native-commands`. Any other name in `features=` makes the split auto entry fail with `[wcs/feature-unknown]`
|
|
280
281
|
before it defines `<wcs-state>`; in `$features` it fails that state (`[wcs/feature-unknown]` on the
|
|
281
282
|
split auto entry, `[wcs/feature-not-installed]` elsewhere). A `$features` that is not an array throws
|
|
282
283
|
`#46`, and a volume may not declare one.
|
|
@@ -1677,7 +1678,7 @@ Handlers run where the DOM puts them. An outer `#direct` handler runs **before**
|
|
|
1677
1678
|
|
|
1678
1679
|
## Filters
|
|
1679
1680
|
|
|
1680
|
-
47 built-in filters are available for both input (DOM → state) and output (state → DOM) directions:
|
|
1681
|
+
47 built-in filters are available for both input (DOM → state) and output (state → DOM) directions: the 10 condition filters in the core (`eq`, `ne`, `not`, `lt`, `le`, `gt`, `ge`, `truthy`, `falsy`, `boolean`) and the other 37 in the `formats` add-on (arithmetic, number formatting, string, type conversion, date / time, defaults), which the full entries include. On `/core` without `formats`, a filter of `formats` fails when the bindings are planned, naming the add-on.
|
|
1681
1682
|
|
|
1682
1683
|
The names 3.x kept as aliases of the 3.2 renames (`inc`, `dec`, `fix`, `uc`, `lc`, `cap`, `rep`, `rev`, `pad`, `null`) and the `substr` filter do not exist: they fail like any unknown name, and the message names what to write instead (`"uc" was renamed "upper" in 3.2 and removed in 4.0 — write "upper".`; `substr(start, length)` is `slice(start, start + length)`).
|
|
1683
1684
|
|
|
@@ -2114,7 +2115,7 @@ export default {
|
|
|
2114
2115
|
| Part | Description |
|
|
2115
2116
|
|---|---|
|
|
2116
2117
|
| `command.` | Fixed prefix |
|
|
2117
|
-
| `<methodName>` | The element's method to invoke. The name must appear as `{ name: "<methodName>" }` in `static wcBindable.commands` |
|
|
2118
|
+
| `<methodName>` | The element's method to invoke. The name must appear as `{ name: "<methodName>" }` in `static wcBindable.commands` — on a native element, in the table of [Native Element Commands](#native-element-commands) |
|
|
2118
2119
|
| `$command.<tokenName>` | Explicit namespace path that resolves to a `CommandToken`. `<tokenName>` must be a name declared in `$commandTokens` |
|
|
2119
2120
|
|
|
2120
2121
|
The right-hand side must be written as `$command.<tokenName>` — the bare-name shorthand (`fetchUsers`) is not supported. Going through the `$command.` namespace makes the binding's intent explicit in the HTML and keeps the top-level state namespace free of token names.
|
|
@@ -2140,11 +2141,11 @@ class MyFetcher extends HTMLElement {
|
|
|
2140
2141
|
|
|
2141
2142
|
Validation rules (enforced at binding time):
|
|
2142
2143
|
|
|
2143
|
-
- The element must be a custom element exposing `static wcBindable` with `protocol: "wc-bindable"` and an integer `version` of `1` or later (the current protocol version is `1`; all versions ≥ 1 are core-compatible)
|
|
2144
|
-
- `methodName` must appear (by `name`) in `wcBindable.commands`
|
|
2144
|
+
- The element must be a custom element exposing `static wcBindable` with `protocol: "wc-bindable"` and an integer `version` of `1` or later (the current protocol version is `1`; all versions ≥ 1 are core-compatible) — or a native element, with the `native-commands` add-on ([Native Element Commands](#native-element-commands))
|
|
2145
|
+
- `methodName` must appear (by `name`) in `wcBindable.commands` (on a native element: in the table of [Native Element Commands](#native-element-commands))
|
|
2145
2146
|
- `<tokenName>` must be declared in `$commandTokens` (`$command.typo` throws `[wcs/token-undeclared]`)
|
|
2146
2147
|
|
|
2147
|
-
A custom element is checked once its class is defined; a native element is refused
|
|
2148
|
+
A custom element is checked once its class is defined; a native element at once — against the [native-commands](#native-element-commands) table where the add-on is installed (`@wcstack/state` and `/auto` include it), and refused otherwise (`[wcs/token-misconfigured]` `#1202`). A violation found while the page is bound fails the `<wcs-state>`'s initialization; one found inside a `for:` / `if:` row, or when a class is defined after the page was bound, fails that one binding, which goes to `$errorCallback`, and the row is still built ([Initialization failures](#initialization-failures)).
|
|
2148
2149
|
|
|
2149
2150
|
### Token API
|
|
2150
2151
|
|
|
@@ -2202,6 +2203,64 @@ This is pure wiring: the event endpoint is connected to a command-token endpoint
|
|
|
2202
2203
|
<my-list data-wcs="command.reset: $command.reset"></my-list>
|
|
2203
2204
|
```
|
|
2204
2205
|
|
|
2206
|
+
### Native Element Commands
|
|
2207
|
+
|
|
2208
|
+
With the `native-commands` add-on (`@wcstack/state` and `/auto` include it; a `/core` page installs `@wcstack/state/features/native-commands`), `command.<method>:` also subscribes a **native** element's method. Opening a dialog, focusing an input or playing a video becomes a token the state emits — the state code never reaches for the element:
|
|
2209
|
+
|
|
2210
|
+
```html
|
|
2211
|
+
<button data-wcs="onclick: $command.openEditor">Edit</button>
|
|
2212
|
+
<dialog data-wcs="command.showModal: $command.openEditor; command.close: $command.closeEditor">
|
|
2213
|
+
<input data-wcs="value: title">
|
|
2214
|
+
<button data-wcs="onclick: save">Save</button>
|
|
2215
|
+
</dialog>
|
|
2216
|
+
```
|
|
2217
|
+
|
|
2218
|
+
```javascript
|
|
2219
|
+
export default {
|
|
2220
|
+
title: "",
|
|
2221
|
+
$commandTokens: ["openEditor", "closeEditor"],
|
|
2222
|
+
async save() {
|
|
2223
|
+
await saveTitle(this.title);
|
|
2224
|
+
this.$command.closeEditor.emit("saved"); // → dialog.close("saved")
|
|
2225
|
+
},
|
|
2226
|
+
};
|
|
2227
|
+
```
|
|
2228
|
+
|
|
2229
|
+
A native element may run only the methods of this table. Any other method throws `[wcs/token-misconfigured]` (`#1205`, naming the methods that element may run) when the binding is attached — like an undeclared command of a custom element:
|
|
2230
|
+
|
|
2231
|
+
| Element | Methods |
|
|
2232
|
+
|---|---|
|
|
2233
|
+
| any element | `focus` `blur` `click` `scrollIntoView` `showPopover` `hidePopover` `togglePopover` |
|
|
2234
|
+
| `<dialog>` | `show` `showModal` `close` `requestClose` |
|
|
2235
|
+
| `<form>` | `requestSubmit` `checkValidity` `reportValidity` |
|
|
2236
|
+
| `<input>` | `select` `setSelectionRange` `showPicker` `setCustomValidity` `checkValidity` `reportValidity` |
|
|
2237
|
+
| `<textarea>` | `select` `setSelectionRange` `setCustomValidity` `checkValidity` `reportValidity` |
|
|
2238
|
+
| `<select>` | `showPicker` `setCustomValidity` `checkValidity` `reportValidity` |
|
|
2239
|
+
| `<audio>` `<video>` | `play` `pause` `load` |
|
|
2240
|
+
|
|
2241
|
+
Left out on purpose: the methods that write HTML, an attribute or the tree (`insertAdjacentHTML`, `setAttribute`, `remove`, … — bind `html:` / `attr.` instead); those that change a control's value without an `input` event, so the state would not see it (`form.reset()`, `stepUp()`, `stepDown()`, `setRangeText()` — write the state instead); `form.submit()`, which skips validation and the `submit` event (`requestSubmit` does neither); and the fullscreen / pointer-lock / picture-in-picture requests, which `@wcstack/fullscreen`, `@wcstack/pointer-lock` and `@wcstack/picture-in-picture` cover along with their state.
|
|
2242
|
+
|
|
2243
|
+
- **Arguments.** A native method receives the `emit` arguments unless the first one is an `Event`. An `on…: $command.x` binding emits `(event, ...listIndexes)`, which no native method takes — `close(event)` would set the dialog's `returnValue` to `"[object PointerEvent]"`, `requestSubmit(event)` would throw — so it is called with none. From the state, `emit("saved")`, `emit({ preventScroll: true })` or `emit({ block: "center" })` pass through. A custom element's method still receives everything.
|
|
2244
|
+
- **The table decides, not the browser.** A method in the table binds in every browser (and on the server). Where a browser lacks it (`requestClose` in an older one), the call fails when the token is emitted and is reported like any subscriber that throws.
|
|
2245
|
+
- **Return values and errors** follow the custom elements': `emit` returns `checkValidity()`'s boolean or `play()`'s `Promise`. A method that throws (`showModal()` on a dialog already open non-modally, `showPopover()` on an element without `popover`) is reported with `console.error`, and the other subscribers still run. A rejected `Promise` is not caught: `await Promise.all(this.$command.play.emit())` from the state to handle an autoplay refusal.
|
|
2246
|
+
- **Rendering comes later.** Writes render in a microtask, so `this.editing = true; this.$command.focusTitle.emit();` reaches an input that is still hidden — or, inside `if:`, not built yet. Emit once it is drawn, from `$renderedCallback`:
|
|
2247
|
+
|
|
2248
|
+
```html
|
|
2249
|
+
<template data-wcs="if: editing">
|
|
2250
|
+
<input data-wcs="value: title; command.focus: $command.focusTitle">
|
|
2251
|
+
</template>
|
|
2252
|
+
```
|
|
2253
|
+
|
|
2254
|
+
```javascript
|
|
2255
|
+
$renderedCallback(paths) {
|
|
2256
|
+
if (paths.includes("editing") && this.editing) this.$command.focusTitle.emit();
|
|
2257
|
+
},
|
|
2258
|
+
```
|
|
2259
|
+
|
|
2260
|
+
- **User activation.** `showPicker()` and `play()` with sound need a recent user gesture. `on…: $command.x` calls the method inside the event; an `emit` after an `await` may come too late.
|
|
2261
|
+
- **Custom elements are unchanged**: they declare their commands in `wcBindable`, and one without a declaration still throws `#1202`. A customized built-in (`<button is="…">`) is a native element.
|
|
2262
|
+
- **When a button alone opens or closes it**, the platform's invoker commands need no state at all: `<button commandfor="dlg" command="show-modal">`. Use `command.` when the state decides (after a fetch, after validation), or for what invoker commands do not cover (`focus`, `play`, `scrollIntoView`).
|
|
2263
|
+
|
|
2205
2264
|
## Event Token (Event Binding)
|
|
2206
2265
|
|
|
2207
2266
|
Command tokens push *into* a component (state invokes a method). **Event tokens** are the exact dual — they pull *out* of a component (an element dispatches an event, state receives it). Together they cover both directions of the element ↔ state boundary, and neither side ever holds a reference to the other — the token is the only shared object.
|
|
@@ -2363,7 +2422,7 @@ Two rules cut most of the confusion:
|
|
|
2363
2422
|
|
|
2364
2423
|
## Streams (`$stream`)
|
|
2365
2424
|
|
|
2366
|
-
Command tokens and event tokens carry discrete interactions. **`$stream`** covers the remaining shape: a continuous flow. Declare an async producer (async iterable / async generator / `ReadableStream`) and the framework **folds it into a single reactive property** — each chunk goes through normal path assignment, so bindings, path getters, and `$renderedCallback` react exactly as if you had assigned the value yourself. When a state path read by the `args` function changes, the running producer is aborted and the source is restarted with the new arguments (switchMap-style dependency-driven restart). Streams start eagerly after `$connectedCallback` completes and are aborted when the element disconnects. `$stream` is the `temporal` add-on (in the full entries). The 3.x name `$streams` throws `[wcs/declaration-alias] $streams was removed: write $stream.` (`#1601`).
|
|
2425
|
+
Command tokens and event tokens carry discrete interactions. **`$stream`** covers the remaining shape: a continuous flow. Declare an async producer (async iterable / async generator / `ReadableStream`) and the framework **folds it into a single reactive property** — each chunk goes through normal path assignment, so bindings, path getters, and `$renderedCallback` react exactly as if you had assigned the value yourself. When a state path read by the `args` function changes, the running producer is aborted and the source is restarted with the new arguments (switchMap-style dependency-driven restart). Streams start eagerly after `$connectedCallback` completes and are aborted when the element disconnects. `$stream` is the `temporal` add-on (in the full entries). The 3.x name `$streams` throws `[wcs/declaration-alias] $streams was removed: write $stream.` (`#1601`) where the `diagnostics` add-on is installed (`@wcstack/state`, `/auto`); without it the declaration is ignored.
|
|
2367
2426
|
|
|
2368
2427
|
`$renderedCallback` remains binding-driven: a stream declaration alone is not a headless subscription. Its path appears in the callback only when a live DOM binding for that value/status/error is actually applied. To react to a stream's value without rendering it, declare [`$watch`](#watch-watch) on that path; see the [stream reference](docs/streams.md) for the observation contract.
|
|
2369
2428
|
|
|
@@ -2764,7 +2823,7 @@ All bindings work inside `<svg>` elements. Use `attr.*` for SVG attributes:
|
|
|
2764
2823
|
|
|
2765
2824
|
State objects can define `$connectedCallback`, `$disconnectedCallback`, `$renderedCallback`, and `$errorCallback` for initialization, cleanup, update, and binding-failure handling.
|
|
2766
2825
|
|
|
2767
|
-
> `$renderedCallback` receives updates of **applied bindings**, not every state update (use `$watch` for those). The 3.x name `$updatedCallback` throws `[wcs/declaration-alias] $updatedCallback was removed: write $renderedCallback.` (`#1601`).
|
|
2826
|
+
> `$renderedCallback` receives updates of **applied bindings**, not every state update (use `$watch` for those). The 3.x name `$updatedCallback` throws `[wcs/declaration-alias] $updatedCallback was removed: write $renderedCallback.` (`#1601`) where the `diagnostics` add-on is installed (`@wcstack/state`, `/auto`); without it the declaration is ignored.
|
|
2768
2827
|
|
|
2769
2828
|
```html
|
|
2770
2829
|
<wcs-state>
|
|
@@ -2846,16 +2905,16 @@ Only a batch that actually has bindings to apply is handed to the tag, so a writ
|
|
|
2846
2905
|
|
|
2847
2906
|
### Error messages and numbers
|
|
2848
2907
|
|
|
2849
|
-
Every message starts with `[@wcstack/state]`.
|
|
2908
|
+
Every message starts with `[@wcstack/state]`. Most messages have a number (`#501`), and a message about something `@wcstack/lint` and the VS Code extension also check has the same code (`[wcs/filter-unknown]`). The hundreds of a number name its code — 1xx `binding-syntax`, 2xx `template-syntax`, 3xx `binding-path-missing`, 4xx `binding-type-expectation`, 5xx `filter-unknown`, 6xx `filter-arity`, 7xx `getter-cycle`, 8xx `getter-depth-exceeded`, 9xx `index-arity`, 10xx `index-param-range`, 11xx `recursion-unsupported`, 12xx `token-misconfigured`, 13xx `token-undeclared`, 14xx `wildcard-rank`, 15xx `spread-no-bindable`, 16xx `declaration-alias`, 17xx `name-alias`; 1–99 carry no code. Numbers are only ever added, so a number keeps its meaning across versions.
|
|
2850
2909
|
|
|
2851
|
-
The sentence of a numbered message — with the nearest name (did-you-mean, by the same rule as the lint), how to fix it, and a pointer to the lint where the lint detects the case —
|
|
2910
|
+
The code and the sentence of a numbered message — with the nearest name (did-you-mean, by the same rule as the lint), how to fix it, and a pointer to the lint where the lint detects the case — come from the `diagnostics` add-on, which `@wcstack/state` and `/auto` include. On a `/core` page without it, a message is its number and the values it would show:
|
|
2852
2911
|
|
|
2853
2912
|
```
|
|
2854
2913
|
[@wcstack/state] [wcs/filter-unknown] filter not found: uc. "uc" was renamed "upper" in 3.2 and removed in 4.0 — write "upper". Validate statically: npx @wcstack/lint <file>.
|
|
2855
|
-
[@wcstack/state]
|
|
2914
|
+
[@wcstack/state] #501 "uc"
|
|
2856
2915
|
```
|
|
2857
2916
|
|
|
2858
|
-
The first line is what `@wcstack/state` and `/auto` print, the second what `/core` without `features/diagnostics` prints. Install `diagnostics` while developing on `/core
|
|
2917
|
+
The first line is what `@wcstack/state` and `/auto` print, the second what `/core` without `features/diagnostics` prints. Install `diagnostics` while developing on `/core`: it also detects the 3.x names 4.0 removed (#1, #1601, #1701), which a page without it ignores (a declaration under one does nothing, reading one gives `undefined`). The barriers a page without add-ons meets on purpose (`[wcs/feature-not-installed]`, a filter of `formats` without it) are full sentences in the core.
|
|
2859
2918
|
|
|
2860
2919
|
<details>
|
|
2861
2920
|
<summary>The numbered messages</summary>
|
|
@@ -3039,7 +3098,7 @@ The header (`#49`) names `mount=`, `bind-component=`, `state=` and `src=` when t
|
|
|
3039
3098
|
What fails initialization:
|
|
3040
3099
|
|
|
3041
3100
|
- A source that cannot be read ([State Initialization](#state-initialization)).
|
|
3042
|
-
- An invalid declaration: a removed name (`$scan`, `$streams`, `$updatedCallback`), a `$behavior` / `$features` / `$commandTokens` / `$eventTokens` / `$on` of the wrong shape, a declaration whose add-on is not installed (`[wcs/feature-not-installed]`).
|
|
3101
|
+
- An invalid declaration: a removed name (`$scan`, `$streams`, `$updatedCallback`; with the `diagnostics` add-on), a `$behavior` / `$features` / `$commandTokens` / `$eventTokens` / `$on` of the wrong shape, a declaration whose add-on is not installed (`[wcs/feature-not-installed]`).
|
|
3043
3102
|
- A markup error found while the page is bound: a syntax error, an unknown filter or a wrong argument count, a wildcard-rank error, `for:` with filters, `outerHTML:` in a template, a wc-bindable misconfiguration on an element whose class is already defined. The walk stops at the error: what comes before it in document order is bound, what comes after it is not. Run `npx @wcstack/lint` before you deploy.
|
|
3044
3103
|
- A second root `<wcs-state>` on a root that another one already binds (`#47`). There is one state tree per root; graft a subtree with `mount=`.
|
|
3045
3104
|
|