@wcstack/state 4.0.0-rc.9 → 4.0.1

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 (40) hide show
  1. package/README.ja.md +8 -6
  2. package/README.md +8 -6
  3. package/dist/auto.min.js +1 -1
  4. package/dist/auto.min.js.map +1 -1
  5. package/dist/index.esm.js +1 -1
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/parser.esm.js +4 -0
  8. package/dist/split/auto.js +1 -1
  9. package/dist/split/chunks/{chunk-M5SODAAE.js → chunk-6MACFEK7.js} +2 -2
  10. package/dist/split/chunks/chunk-BMGEWHCR.js +2 -0
  11. package/dist/split/chunks/chunk-BMGEWHCR.js.map +1 -0
  12. package/dist/split/chunks/{chunk-UD3AYVP2.js → chunk-DFXQ7MFW.js} +2 -2
  13. package/dist/split/chunks/{chunk-7AYOQHZH.js → chunk-EM3Y3SJS.js} +2 -2
  14. package/dist/split/chunks/chunk-LAUWEM6K.js +2 -0
  15. package/dist/split/chunks/chunk-LAUWEM6K.js.map +1 -0
  16. package/dist/split/chunks/{chunk-EIMTT5I3.js → chunk-M656SMUU.js} +1 -1
  17. package/dist/split/chunks/{chunk-EIMTT5I3.js.map → chunk-M656SMUU.js.map} +1 -1
  18. package/dist/split/chunks/{chunk-W4KOY6GT.js → chunk-PHAN6L23.js} +2 -2
  19. package/dist/split/chunks/{chunk-NOPTR2L3.js → chunk-TUQ3OPZQ.js} +2 -2
  20. package/dist/split/chunks/{chunk-55J45X6H.js → chunk-V6VVL4F3.js} +2 -2
  21. package/dist/split/core.js +1 -1
  22. package/dist/split/features/devtools.js +1 -1
  23. package/dist/split/features/diagnostics.js +1 -1
  24. package/dist/split/features/diagnostics.js.map +1 -1
  25. package/dist/split/features/formats.js +1 -1
  26. package/dist/split/features/native-commands.js +1 -1
  27. package/dist/split/features/recursion.js +1 -1
  28. package/dist/split/features/scopes.js +1 -1
  29. package/dist/split/features/ssr.js +1 -1
  30. package/package.json +1 -1
  31. package/dist/split/chunks/chunk-L3PFEJP7.js +0 -2
  32. package/dist/split/chunks/chunk-L3PFEJP7.js.map +0 -1
  33. package/dist/split/chunks/chunk-SAUVGHSB.js +0 -2
  34. package/dist/split/chunks/chunk-SAUVGHSB.js.map +0 -1
  35. /package/dist/split/chunks/{chunk-M5SODAAE.js.map → chunk-6MACFEK7.js.map} +0 -0
  36. /package/dist/split/chunks/{chunk-UD3AYVP2.js.map → chunk-DFXQ7MFW.js.map} +0 -0
  37. /package/dist/split/chunks/{chunk-7AYOQHZH.js.map → chunk-EM3Y3SJS.js.map} +0 -0
  38. /package/dist/split/chunks/{chunk-W4KOY6GT.js.map → chunk-PHAN6L23.js.map} +0 -0
  39. /package/dist/split/chunks/{chunk-NOPTR2L3.js.map → chunk-TUQ3OPZQ.js.map} +0 -0
  40. /package/dist/split/chunks/{chunk-55J45X6H.js.map → chunk-V6VVL4F3.js.map} +0 -0
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.9/dist/split/core.js",
195
- "@wcstack/state/features/temporal": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.9/dist/split/features/temporal.js",
196
- "@wcstack/state/features/scopes": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.9/dist/split/features/scopes.js"
194
+ "@wcstack/state/core": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.1/dist/split/core.js",
195
+ "@wcstack/state/features/temporal": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.1/dist/split/features/temporal.js",
196
+ "@wcstack/state/features/scopes": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.1/dist/split/features/scopes.js"
197
197
  }
198
198
  }
199
199
  </script>
@@ -253,7 +253,7 @@
253
253
  ページが名指したアドオンを、同じビルドから読み込みます。
254
254
 
255
255
  ```html
256
- <script type="module" src="https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.9/dist/split/auto.js"></script>
256
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.1/dist/split/auto.js"></script>
257
257
  <wcs-state features="scopes diagnostics">
258
258
  <script type="module">
259
259
  export default {
@@ -543,7 +543,7 @@ property[#modifier]: path[|filter[|filter(args)...]]
543
543
 
544
544
  修飾子は束縛の種別を変えません: `radio#ro:` と `checkbox#ro:` は radio / checkbox の束縛のままです。その束縛が使わない修飾子は無視されます(プロパティ束縛の `#direct`、未知の `#foo`)。未知の `key=value` 形式の修飾子(`#foo=1`)は throw します。
545
545
 
546
- パーサは次の書き方を `[wcs/binding-syntax]` で拒否します: 2 つ目の `#`(`value#ro#wo` ではなく `value#ro,wo` と書く)、`else:` の後ろの値(`else:` と書く)、`for` / `if` / `elseif` / `else` / `...` の左辺の修飾子やフィルタ、`for:` の出力フィルタ(`#121` — [ループ](#ループ-for) 参照)、`__proto__` や `prototype` というパスセグメント(`#120` — 書き込み・`$resolve`・`$setAll`、そして `this.__proto__` のような読み取りでも拒否される)、フィルタ引数の閉じていない引用符。
546
+ パーサは次の書き方を `[wcs/binding-syntax]` で拒否します: 2 つ目の `#`(`value#ro#wo` ではなく `value#ro,wo` と書く)、`else:` の後ろの値(`else:` と書く)、`for` / `if` / `elseif` / `else` / `...` の左辺の修飾子やフィルタ、`for:` の出力フィルタ(`#121` — [ループ](#ループ-for) 参照)、名前の無い `class:` と `attr:`(`#122` — `class.NAME:` / `attr.NAME:` と書く。名前の無い `class:` は要素の `class` というプロパティに書くだけで何も起きない。属性全体なら `className:` をバインドする)、`__proto__` や `prototype` というパスセグメント(`#120` — 書き込み・`$resolve`・`$setAll`、そして `this.__proto__` のような読み取りでも拒否される)、フィルタ引数の閉じていない引用符。
547
547
 
548
548
  ### 双方向バインディング
549
549
 
@@ -1281,6 +1281,8 @@ export default {
1281
1281
 
1282
1282
  ネストループでは、`$1` が外側のインデックス、`$2` が内側のインデックスです。
1283
1283
 
1284
+ 段はテンプレートの入れ子ではなくパスで決まります。行の中でトップレベルの一覧を回す `for:`(`for: groups` の中の `for: tags` で、どの行にも同じタグを並べる形)が描くのは、深さ 1 の一覧 `tags` の行です。そこでは `$1` がタグのインデックスで、`$2` は(エラーなしで)空になり、イベントハンドラにもタグのインデックスだけが渡ります。内側の行から外側の行が要るときは、行 getter で外側の行ごとに一覧を持たせ、それを回してください —— `get "groups.*.tagsHere"() { return this.tags; }` と `for: .tagsHere` にすると、`$1` がグループ、`$2` がタグになります。
1285
+
1284
1286
  テンプレート内でループインデックスを直接表示することもできます:
1285
1287
 
1286
1288
  ```html
@@ -1408,7 +1410,7 @@ export default {
1408
1410
  };
1409
1411
  ```
1410
1412
 
1411
- **同じオブジェクトが 2 つの位置にあるとき。** 1 つのリストの 2 つの位置に同じオブジェクトがあると(`items: [o, o, …]`)、片方の行の下のキーへの書き込み(`this["items.0.name"] = "z"`)でオブジェクトは変わりますが、もう片方の行のバインディングと行 getter は古い値を表示し続けます: 1 つのリストの中では、書き込みはそれを通した行にしか届かないためです。素の読み取り・ルートの getter・`$getAll` には新しい値が見えます。普通のキーの 2 つの配列が同じオブジェクトを持つ場合(`backup = items; items = items.filter(…)` で両方を描画する形)も同じです。こうした書き込みの後に `$postUpdate("items")` を呼ぶと、そのリストのすべての行がオブジェクトを表示し直します。これはこのバージョンの既知の制約です。getter が配列を結び付ける場合 —— TodoMVC 風の絞り込み(`todos` を絞り込んだコピーを返す `get shown()` を `for: shown` で描画する形)、並べ替え、切り出し —— は、どちら側から書いても、オブジェクトを持つすべての行と `todos.*` を読むものに届き、そのオブジェクトを配列に持つ getter は評価し直されます(チェックした行は未完了の絞り込みから抜け、名前を変えた行は並べ替えた表示で動きます)。書いたオブジェクトを配列に持たない getter は評価し直しません: 配列を読んだのであって、オブジェクトは読んでいないためです —— どの行にも追従させるには、その中で `$getAll("todos.*.done")` を読んでください。
1413
+ **同じオブジェクトが 2 つの位置にあるとき。** 1 つのリストの 2 つの位置に同じオブジェクトがあると(`items: [o, o, …]`)、片方の行の下のキーへの書き込み(`this["items.0.name"] = "z"`)でオブジェクトは変わりますが、もう片方の行のバインディングと行 getter は古い値を表示し続けます: 1 つのリストの中では、書き込みはそれを通した行にしか届かないためです。素の読み取り・ルートの getter・`$getAll` には新しい値が見えます。普通のキーの 2 つの配列が同じオブジェクトを持つ場合(`backup = items; items = items.filter(…)` で両方を描画する形)も同じです。こうした書き込みの後に `$postUpdate("items")` を呼ぶと、そのリストのすべての行がオブジェクトを表示し直します。外側の 2 つの行が、同じオブジェクトを持つ別々の配列を持つ場合(`groups: [{ items: a }, { items: [...a] }]`)も同じで、もう片方の一覧(`"groups.1.items"`)か外側の一覧(`"groups"`)の `$postUpdate` を呼んでください。これはこのバージョンの既知の制約です。getter が配列を結び付ける場合 —— TodoMVC 風の絞り込み(`todos` を絞り込んだコピーを返す `get shown()` を `for: shown` で描画する形)、並べ替え、切り出し —— は、どちら側から書いても、オブジェクトを持つすべての行と `todos.*` を読むものに届き、そのオブジェクトを配列に持つ getter は評価し直されます(チェックした行は未完了の絞り込みから抜け、名前を変えた行は並べ替えた表示で動きます)。書いたオブジェクトを配列に持たない getter は評価し直しません: 配列を読んだのであって、オブジェクトは読んでいないためです —— どの行にも追従させるには、その中で `$getAll("todos.*.done")` を読んでください。
1412
1414
 
1413
1415
  ## 再帰パス(`$recursion`)
1414
1416
 
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.9/dist/split/core.js",
196
- "@wcstack/state/features/temporal": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.9/dist/split/features/temporal.js",
197
- "@wcstack/state/features/scopes": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.9/dist/split/features/scopes.js"
195
+ "@wcstack/state/core": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.1/dist/split/core.js",
196
+ "@wcstack/state/features/temporal": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.1/dist/split/features/temporal.js",
197
+ "@wcstack/state/features/scopes": "https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.1/dist/split/features/scopes.js"
198
198
  }
199
199
  }
200
200
  </script>
@@ -254,7 +254,7 @@ receptacle the owning add-on fills on install).
254
254
  core, and the add-ons the page names from the same build.
255
255
 
256
256
  ```html
257
- <script type="module" src="https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.0-rc.9/dist/split/auto.js"></script>
257
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@wcstack/state@4.0.1/dist/split/auto.js"></script>
258
258
  <wcs-state features="scopes diagnostics">
259
259
  <script type="module">
260
260
  export default {
@@ -549,7 +549,7 @@ Multiple modifiers are comma-separated after a single `#`: `value#ro,init=none:
549
549
 
550
550
  A modifier never changes the kind of binding: `radio#ro:` and `checkbox#ro:` stay radio / checkbox bindings. A modifier the binding does not use is ignored (`#direct` on a property binding, an unknown `#foo`); an unknown `key=value` modifier (`#foo=1`) throws.
551
551
 
552
- The parser rejects, with `[wcs/binding-syntax]`: a second `#` (write `value#ro,wo`, not `value#ro#wo`), a value after `else:` (write `else:`), modifiers or left-side filters on `for` / `if` / `elseif` / `else` / `...`, output filters on `for:` (`#121` — see [Loop](#loop-for)), a path segment `__proto__` or `prototype` (`#120` — refused in writes, `$resolve`, `$setAll` and reads such as `this.__proto__` too), and an unterminated quote in filter arguments.
552
+ The parser rejects, with `[wcs/binding-syntax]`: a second `#` (write `value#ro,wo`, not `value#ro#wo`), a value after `else:` (write `else:`), modifiers or left-side filters on `for` / `if` / `elseif` / `else` / `...`, output filters on `for:` (`#121` — see [Loop](#loop-for)), `class:` and `attr:` without a name (`#122` — write `class.NAME:` / `attr.NAME:`; a bare `class:` would only set an element property named `class`, which does nothing — bind `className:` for the whole attribute), a path segment `__proto__` or `prototype` (`#120` — refused in writes, `$resolve`, `$setAll` and reads such as `this.__proto__` too), and an unterminated quote in filter arguments.
553
553
 
554
554
  ### Two-Way Binding
555
555
 
@@ -1287,6 +1287,8 @@ export default {
1287
1287
 
1288
1288
  For nested loops, `$1` is the outer index and `$2` is the inner index.
1289
1289
 
1290
+ The levels follow the paths, not the template nesting. A `for:` inside a row that loops over a top-level list (`for: tags` inside `for: groups`, each row showing the same tags) renders rows of `tags`, a list of depth 1: there `$1` is the tag's index, `$2` is empty (no error), and event handlers receive the tag's index only. When the inner rows need the outer row, give each outer row the list through a row getter and loop over that — `get "groups.*.tagsHere"() { return this.tags; }` with `for: .tagsHere` — so that `$1` is the group and `$2` the tag.
1291
+
1290
1292
  You can also display the loop index directly in templates:
1291
1293
 
1292
1294
  ```html
@@ -1414,7 +1416,7 @@ export default {
1414
1416
  };
1415
1417
  ```
1416
1418
 
1417
- **One object at two positions.** When the same object sits at two positions of one list (`items: [o, o, …]`), a write to a key below one of those rows (`this["items.0.name"] = "z"`) changes the object, but the other row's bindings and row getters keep showing the old value: within one list, a write reaches only the row it was made through. Plain reads, root getters and `$getAll` see the new value. The same holds for two arrays at plain keys that share an object (`backup = items; items = items.filter(…)`, both rendered). Call `$postUpdate("items")` after such a write, and every row of that list shows the object again. This is a known limitation of this version. When a getter relates the arrays — a TodoMVC-style filter (`get shown()` returning a filtered copy of `todos`, rendered with `for: shown`), a sort, a slice — a write from either side reaches every row holding the object and the `todos.*` readers, and the getters whose array holds it are evaluated again (a checked row leaves an "active" filter, a renamed row moves in a sorted view). A getter whose array does not hold the written object is not evaluated again: it read the array, not the object — read `$getAll("todos.*.done")` in it to follow every row.
1419
+ **One object at two positions.** When the same object sits at two positions of one list (`items: [o, o, …]`), a write to a key below one of those rows (`this["items.0.name"] = "z"`) changes the object, but the other row's bindings and row getters keep showing the old value: within one list, a write reaches only the row it was made through. Plain reads, root getters and `$getAll` see the new value. The same holds for two arrays at plain keys that share an object (`backup = items; items = items.filter(…)`, both rendered). Call `$postUpdate("items")` after such a write, and every row of that list shows the object again. So do two outer rows holding different arrays that share an object (`groups: [{ items: a }, { items: [...a] }]`): call `$postUpdate` on the other list (`"groups.1.items"`) or on the outer one (`"groups"`). This is a known limitation of this version. When a getter relates the arrays — a TodoMVC-style filter (`get shown()` returning a filtered copy of `todos`, rendered with `for: shown`), a sort, a slice — a write from either side reaches every row holding the object and the `todos.*` readers, and the getters whose array holds it are evaluated again (a checked row leaves an "active" filter, a renamed row moves in a sorted view). A getter whose array does not hold the written object is not evaluated again: it read the array, not the object — read `$getAll("todos.*.done")` in it to follow every row.
1418
1420
 
1419
1421
  ## Recursive Paths (`$recursion`)
1420
1422