wcstack 3.2.0 → 3.4.0

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 CHANGED
@@ -11,9 +11,11 @@ Project site: **https://wcstack.github.io** · Source: **https://github.com/wcst
11
11
  This file is a complete, self-contained guide to writing a correct wcstack app. Read it top to bottom, then **verify what you wrote**:
12
12
 
13
13
  ```bash
14
- npx @wcstack/lint index.html # exit code 0 = clean. Iterate until it exits 0.
14
+ npx @wcstack/lint index.html # exit 0 = no error-severity finding. Iterate until it exits 0.
15
15
  ```
16
16
 
17
+ Exit `0` does **not** mean the file is clean: warnings and info diagnostics are printed and still exit `0`. Read what it printed, or add `--strict` to make warnings fail too.
18
+
17
19
  Do not guess at syntax that is not documented here. wcstack has little presence in training data, so invented syntax will look plausible and be wrong. Two rules cover most failures:
18
20
 
19
21
  - **Filters transform values. They never attach to event handlers.**
@@ -35,11 +37,11 @@ wcstack is buildless — load what you need from a CDN. The default is one tag p
35
37
 
36
38
  Each `/auto` script registers its custom elements and does nothing else. No initialization call, no bootstrap. Tags activate when the browser parses them. The tags fetch in parallel (every `/auto` is self-contained), so multiple tags cost requests, not a waterfall.
37
39
 
38
- For an app that uses the SPA core anyway, **this package ships the bundle**: `wcstack/auto` is `@wcstack/state` + `@wcstack/router` + `@wcstack/fetch` + `@wcstack/storage` + `@wcstack/autoloader` pre-linked by Rollup into one self-contained file (344 KB min / 99 KB gzip as of 3.2.0) — one request, and in production one `integrity` hash covering every line of the core that runs (digests ship with each GitHub Release; see `docs/sri.md`):
40
+ For an app that uses the SPA core anyway, **this package ships the bundle**: `wcstack/auto` is `@wcstack/state` + `@wcstack/router` + `@wcstack/fetch` + `@wcstack/storage` + `@wcstack/autoloader` pre-linked by Rollup into one self-contained file (368 KB min / 108 KB gzip as of 3.4.0) — one request, and in production one `integrity` hash covering every line of the core that runs (digests ship with each GitHub Release; see `docs/sri.md`):
39
41
 
40
42
  ```html
41
43
  <script type="module"
42
- src="https://cdn.jsdelivr.net/npm/wcstack@3.2.0/dist/auto.min.js"
44
+ src="https://cdn.jsdelivr.net/npm/wcstack@3.4.0/dist/auto.min.js"
43
45
  integrity="sha384-…"></script>
44
46
  ```
45
47
 
@@ -47,6 +49,8 @@ Loading the bundle alongside an individual package's `/auto` is safe: whichever
47
49
 
48
50
  If you want npm packages for local development, install the individual ones (`@wcstack/state`, `@wcstack/router`, …); this package publishes only the bundle and this guide.
49
51
 
52
+ `@wcstack/state` also ships **split entries** for a page that deliberately leaves features out: import `bootstrapState` and `installFeatures` from `@wcstack/state/core`, then `installFeatures([...])` with the features you need (`features/temporal` = `$watch` / `$scan` / `$stream`, `features/scopes` = `bind-component` / `mount=` / DCC, plus `recursion`, `ssr`, `formats`, `devtools`, `diagnostics`) **before** calling `bootstrapState()`. A declaration whose feature is missing throws `[wcs/feature-not-installed]`. Load the split files from jsDelivr's plain `/npm/…/dist/split/` paths or a bundler — **never `esm.run`**, which re-bundles a separate engine into each entry. The full-package `/auto` above needs none of this and stays the default; see `npm view @wcstack/state readme`.
53
+
50
54
  ---
51
55
 
52
56
  ## A complete working app
@@ -175,6 +179,15 @@ Multiple bindings are separated by `;`:
175
179
  | `radio` | Radio group (two-way) |
176
180
  | `checkbox` | Checkbox group bound to an array (two-way) |
177
181
  | `onclick`, `on*` | Event handler |
182
+ | `.NAME` | Explicit property (3.1) — the same binding as `NAME:`, except it is never an event |
183
+
184
+ **A property whose name starts with `on` needs the dotted form (3.1).** `online: x` is parsed as an event binding: it listens for a `"line"` event and **never writes the element's `online` property**. Put a dot in front to bind the property itself:
185
+
186
+ ```html
187
+ <my-status data-wcs=".online: isOnline; onclick: refresh"></my-status>
188
+ ```
189
+
190
+ `.value:` stays two-way like `value:`, and modifiers and filters work as usual. A namespace word after the dot (`.class`, `.attr`, `.style`, `.command`, `.eventToken`) or an empty name is rejected with `[wcs/binding-syntax]`.
178
191
 
179
192
  ### Modifiers
180
193
 
@@ -184,9 +197,10 @@ Multiple bindings are separated by `;`:
184
197
  | `#prevent` | `event.preventDefault()` on handlers |
185
198
  | `#stop` | `event.stopPropagation()` on handlers |
186
199
  | `#onchange` | Use `change` instead of `input` for two-way binding |
187
- | `#init=element` | The element owns the initial value (use with `<wcs-storage>` and monitors) |
200
+ | `#init=<authority>` | Who wins the **initial** sync: `element` (the element's own value seeds the state — use with `<wcs-storage>` and monitors), `state`, `auto`, `none`. Without it the default comes from the member's `wcBindable` declaration |
201
+ | `#sync=<timing>` | When an element-authority binding reads the element: `call` (default — when the binding attaches) or `connect` (once the element is in the document) |
188
202
 
189
- Combine after one `#`, comma separated: `value#ro,init=none: path`.
203
+ Combine after one `#`, comma separated: `value#ro,init=none: path`, `value#init=element,sync=connect: path`. A second `#` is a parse error.
190
204
 
191
205
  ### Paths
192
206
 
@@ -197,6 +211,16 @@ Combine after one `#`, comma separated: `value#ro,init=none: path`.
197
211
  | `.price` | Shorthand for the current row's property inside a loop |
198
212
  | `cart.path` | Read a mounted volume (`<wcs-state mount="cart">`) by its path prefix — one tree per root, extended by mounts (`name=` / `path@name` were removed in v2) |
199
213
 
214
+ ### Splitting state across files (`mount=`)
215
+
216
+ A second `<wcs-state mount="cart" src="./cart.js">` grafts its module onto the root tree at `cart`; the page then reads `cart.total`. When the volume's own code needs a path from outside its subtree, inject it on that element (3.1):
217
+
218
+ ```html
219
+ <wcs-state mount="cart" src="./cart.js" data-wcs="state.taxRate: settings.taxRate"></wcs-state>
220
+ ```
221
+
222
+ Inside `cart.js`, `this.taxRate` reads and writes the root's `settings.taxRate` (add `#ro` for read-only). One `state.<key>` per injection; the right side must be a static path — no wildcard, no `$`, no filter. The injected name exists only inside the volume: the page still reads `settings.taxRate`, and there is no `cart.taxRate`.
223
+
200
224
  ### Structural directives
201
225
 
202
226
  Always on a `<template>` element:
@@ -270,6 +294,25 @@ this.items = this.items.map(t => t.id === id ? { ...t, done: true } : t);
270
294
 
271
295
  ---
272
296
 
297
+ ## Names that changed in 3.2
298
+
299
+ Older names appear all over the training data. They still work through 3.x and are removed in 4.0, but `@wcstack/lint` and the VS Code extension flag each one (`wcs/name-alias`, info severity — it does **not** change the exit code, so it is easy to miss). Write the canonical name.
300
+
301
+ | Canonical | Old name |
302
+ |---|---|
303
+ | `upper` · `lower` · `capitalize` | `uc` · `lc` · `cap` |
304
+ | `add` · `sub` | `inc` · `dec` |
305
+ | `toFixed` · `padStart` | `fix` · `pad` |
306
+ | `repeat` · `reverse` | `rep` · `rev` |
307
+ | `nullIfEmpty` | `null` |
308
+ | `$stream` (async producer → state) | `$streams` |
309
+ | `$renderedCallback` (hook) | `$updatedCallback` |
310
+ | `this.$dependOn(path)` · `this.$untracked(fn)` | `$trackDependency` · `$untrackDependency` |
311
+
312
+ Declaring both spellings of a state key fails with `[wcs/declaration-alias]`. `$renderedCallback` reports the **bindings that were applied**, not every state change — use `$watch` for those.
313
+
314
+ ---
315
+
273
316
  ## Verify before you finish
274
317
 
275
318
  ```bash
@@ -280,7 +323,7 @@ npx @wcstack/lint index.html
280
323
  npx @wcstack/lint --errors-only index.html
281
324
  ```
282
325
 
283
- Exit code `0` means clean, `1` means at least one error-severity finding, `2` means a usage or read failure. Diagnostics carry stable `wcs/*` codes and `source:line:col` ranges.
326
+ Exit code `0` means no error-severity finding, `1` means at least one, `2` means a usage or read failure. **Warnings and info diagnostics do not change the exit code** — `0` is not the same as "no findings", so read the output too (or pass `--strict`, which makes warnings exit `1` as well). Diagnostics carry stable `wcs/*` codes and `source:line:col` ranges.
284
327
 
285
328
  ---
286
329