wcstack 3.2.0 → 3.3.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 +49 -6
- package/dist/auto.min.js +1 -1
- package/dist/auto.min.js.map +1 -1
- package/package.json +1 -1
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
|
|
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 (
|
|
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 (352 KB min / 102 KB gzip as of 3.3.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.
|
|
44
|
+
src="https://cdn.jsdelivr.net/npm/wcstack@3.3.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
|
|
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
|
|
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
|
|