on_the_money 0.5.2 → 0.7.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/CHANGELOG.md +74 -0
- package/README.md +272 -69
- package/dist/on_the_money.min.js +1 -1
- package/package.json +13 -5
- package/src/clipboard/index.js +20 -0
- package/src/core/On.js +3 -0
- package/src/core/Select.js +18 -0
- package/src/core/The.js +184 -54
- package/src/core/index.js +2 -0
- package/src/eslint/config.js +11 -0
- package/src/eslint/plugin.js +31 -3
- package/src/linter/Linter.js +265 -13
- package/src/linter/cli.js +41 -8
- package/src/live/Live.js +176 -0
- package/src/live/Sse.js +35 -0
- package/src/live/index.js +21 -0
- package/src/test/index.js +68 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,80 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.7.0] — 2026-07-19
|
|
8
|
+
|
|
9
|
+
The boundary release. OTM's mandate extends to the browser side of live data — batteries for the platform's gaps, contracts instead of server code, and the lint stack grown into a drift wall — under a ratified constitution: a battery ships only if it wraps a platform *absence*, rides an existing standard or published machine-readable convention, lands with lint + doctest on day one, lives in a subpath the core never pays for, and carries an explicit NOT-list. Issues #84, #86–#89, #115–#120; PRs #121–#131.
|
|
10
|
+
|
|
11
|
+
### Breaking
|
|
12
|
+
|
|
13
|
+
- **`_t` currency must be explicit.** The hardcoded USD default is gone: `options.currency` / `data-i18n-currency` (ISO 4217), throw without one, platform `RangeError` on invalid codes. New HTML-025 catches the missing declarative code at lint time. Constitutional principle: directive attributes mirror Intl option names verbatim — OTM invents no formatting vocabulary. (#118)
|
|
14
|
+
- **New error-tier lint rules** fail runs that previously passed: `otm/no-raw-websocket` (use `live()`), HTML-107 reveal-key parity. (#86, #117)
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`on_the_money/live`** — WebSocket battery harvested from four production implementations of the same lifecycle: `live(pathOrState, { onMessage, onDown, onUp, signal })` → `{ send, request }`; jittered backoff with stable-timer reset and guarded dial; `close(1000)` terminal; `req_id` correlation that resolves `null` and never rejects; `takeLatest` supersession; server-advertised channels via body state. Wire conventions ship as `examples/live/asyncapi.yaml` + reference server — contract-as-document, no server code in the package. (#86)
|
|
19
|
+
- **`sse()`** — EventSource adapter in the live subpath: named-event subscription, JSON-or-raw-text decode, the same handler contract; reconnection stays the platform's. Streaming-into-slot discipline documented (accumulate + whole-value projection, idempotent under `Last-Event-ID` replay). (#115)
|
|
20
|
+
- **`on_the_money/clipboard`** — copy affordances via the capability-declaration pattern: `body[data-clipboard="available"]` reveals server-rendered-hidden `[data-copy]` buttons; `data-copied` pulse for the CSS flash; no dead controls without JS or a secure context. (#116)
|
|
21
|
+
- **`data-bind="attr:key"`** — attribute projection, the `[data-text]` sibling: state into `href`/`src`/`datetime`/any plain attribute; `null` removes; HTML-104/106 aware. (#87)
|
|
22
|
+
- **`$.cloneEach(parent, selector, items, fill)`** — list rendering with replace-children semantics; deliberately not reactive array-binding; HTML-101 recognizes the shape. (#88)
|
|
23
|
+
- **`route(cb, { match })`** — selective enhancement: intercept only opted-in links, everything else navigates natively. (#89)
|
|
24
|
+
- **HTML-107** — reveal-key parity wall: `data-K-key="V"` spans ↔ `[data-K="V"]` state-CSS rules, both directions. (#117)
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- `otm/prefer-on` states its DOM boundary and names the sanctioned alternatives (handler properties; `live()` for sockets). (#84)
|
|
29
|
+
- Test harness `location` stub gained `host`/`protocol`.
|
|
30
|
+
|
|
31
|
+
### Documentation
|
|
32
|
+
|
|
33
|
+
- **Substrate contract** replaces the named-stylesheet coupling: four clauses (classless semantic styling, ARIA state response, token custom properties, data-attribute theme switch); vendor a pinned copy as `-vendor.css`. The four-layer CSS architecture (`-vendor`/`-structure`/`-style`/`-state`) is canon, with `-state.css` as the only OTM-aware layer. (#119)
|
|
34
|
+
- **The enhancement ladder** (rungs 0–4) with the module-form deletion test; **capability declaration** named as a pattern; **battery admission rule** published. (#119)
|
|
35
|
+
|
|
36
|
+
## [0.6.0] — 2026-07-19
|
|
37
|
+
|
|
38
|
+
The alignment release. A full-repo audit (theory, specification, documentation, implementation) surfaced probe-confirmed contradictions between the README's contracts and the runtime; 0.6.0 resolves every one against a ratified doctrine (AGENTS.md §0.6.0) and adds CI enforcement so spec/implementation drift becomes a red build. Issues #91–#102, PRs #103–#114.
|
|
39
|
+
|
|
40
|
+
### Breaking
|
|
41
|
+
|
|
42
|
+
- **`the(key, null)` now deletes** — removes the attribute, clears `[data-text]` mirrors, removes the persisted `localStorage` entry for `persistKeys` members. Previously wrote the literal string `"null"`. `undefined` still throws. (#94)
|
|
43
|
+
- **ariaMap is element-scoped only.** Global writes always produce `data-*`; `the("hidden", true)` no longer sets `aria-hidden` on `<body>` (which hid the whole app from screen readers). (#94)
|
|
44
|
+
- **`the.form`**: `[]` names yield arrays at every cardinality (was string at 1, array at 2+); multi-`<select>` yields all selected values; file inputs skipped. (#95)
|
|
45
|
+
- **`route()`** returns an unsubscribe and throws on double-registration while one is active (previously stacked listeners and corrupted history). (#93)
|
|
46
|
+
- **HTML-004** reimplemented: rendered text must live inside a `data-i18n` or `data-text` carrier, kept as source-language fallback. `data-text` parents are exempt now; the "wrap in a semantic tag" guidance (which the implementation never honored) is gone. (#96)
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- `_t()` element hydration preserves existing `textContent` on missing dictionary keys — as the README always claimed. Interpolation replaces every `{token}` occurrence and is inert to `$`-patterns in values. (#91)
|
|
51
|
+
- `the.boot({ dictionary })` loads unconditionally; the locale short-circuit governs only the fetch and hydration pass (the quickstart's dictionary was previously discarded silently). Failed dictionary fetches warn and retry the `data-fallback` file. Locale default unified to `"en"`. (#92)
|
|
52
|
+
- Router guards modified clicks (meta/ctrl/shift/alt, non-primary button) and `[download]` links; same-URL clicks no-op. (#93)
|
|
53
|
+
- `on()` throws a named contract error when a string parent matches nothing. (#95)
|
|
54
|
+
- otm-lint detects `<meta name="i18n">` via parse5 — attribute order no longer silently disables HTML-024/102/103. (#96)
|
|
55
|
+
- Latent `Linter.#traverse` bug: parse5 template content was never walked; HTML rules now inspect template subtrees. (#97)
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- `route.go(path)` — programmatic navigation (`pushState` never fires `popstate`; redirects had no sanctioned path). (#93)
|
|
60
|
+
- **HTML-104**: global `the()` write keys colliding with `data-text` slots in `<template>` subtrees. (#97)
|
|
61
|
+
- **HTML-105**: `data-action` ↔ `on()` selector cross-check, both directions (dead controls, orphan handlers); generic `[data-action]` dispatch waives, `data-otm-dynamic` opts out. (#97)
|
|
62
|
+
- **HTML-106** (warn tier — reported, never fails the run): the deletion test as lint — globally written keys nothing consumes. otm-lint now scans `.css`. (#97)
|
|
63
|
+
- **`on_the_money/test`** subpath: the `setupDOM` linkedom harness consumers need to test OTM apps; the repo's own suite dogfoods it. `linkedom` is an optional peer. Shipped eslint config exempts `**/*.test.*` from `no-server-dom`/`no-document-query`. (#98)
|
|
64
|
+
- **Dogfooding**: `eslint.config.js`/`stylelint.config.js` consume the shipped configs via package self-reference; `npm run lint:examples` wired into the `check` gate. (#99)
|
|
65
|
+
- **README doctest harness**: every fenced HTML block linted, the quickstart cross-file-scanned and executed end-to-end, every JS block parsed, every CSS block stylelinted — in CI. (#101)
|
|
66
|
+
|
|
67
|
+
### Documentation
|
|
68
|
+
|
|
69
|
+
- README rewritten against the doctrine: lint-clean quickstart that teaches real boot behavior, opt-in persistence stated once and correctly, reactivity reframed as delegated-to-platform, all new contracts documented, Testing-your-app section, fetch-intake + `replaceChildren()` recipes, hot-swap pattern persists the language. Size claims and the (incorrect) PurgeCSS section removed. (#100, #102)
|
|
70
|
+
|
|
71
|
+
## [0.5.3] — 2026-05-28
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- **`the.boot()` locale resolution now prefers `<html lang>` over `navigator.language`.** When a server deliberately renders `<html lang="es">`, that's an explicit signal about the document's language — the server may have already considered the visitor's cookies, URL path, or preferences when choosing it. `navigator.language` was previously winning and overriding the server's render with the browser's passive default, causing OTM to flash server-rendered Spanish text back to English on every navigation. Resolution chain is now: `?lang=` → `localStorage["${prefix}lang"]` → `document.documentElement.lang` → `navigator.language` → `"en"`. (#82)
|
|
76
|
+
|
|
77
|
+
### Behavior change worth noting
|
|
78
|
+
|
|
79
|
+
Static SPAs that hardcoded `<html lang="en">` and relied on the framework to detect the visitor's browser language are affected. The framework now treats the `lang` attribute as authoritative. Consumers wanting navigator-driven detection should leave `<html lang>` empty or omit the attribute — then the chain falls through to navigator. This was always the more honest setup; the previous behavior papered over the SPA author's hardcoded `lang` claim.
|
|
80
|
+
|
|
7
81
|
## [0.5.2] — 2026-05-23
|
|
8
82
|
|
|
9
83
|
### Documentation
|