on_the_money 0.7.0 → 0.7.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.
- package/CHANGELOG.md +15 -0
- package/README.md +4 -2
- package/package.json +4 -5
- package/src/eslint/plugin.js +8 -3
- package/src/linter/Linter.js +4 -1
- package/src/linter/cli.js +13 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ 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.1] — 2026-07-19
|
|
8
|
+
|
|
9
|
+
Port feedback, same day: the first downstream migrations onto the 0.7.0 batteries surfaced three regressions. Issues #132–#135, #137; PRs #138–#142.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **`otm/no-raw-websocket` flags only the browser global.** Scope-resolved: an imported or locally declared `WebSocket` (a Node `ws`-package client) passes — the hand-rolled-lifecycle slop vector the rule targets doesn't exist there. (#132)
|
|
14
|
+
- **`.ejs` joins otm-lint's markup universe** for cross-file rules (reveal spans, slots, actions); per-file rules stay `.html`-only so template syntax never trips HTML-004. HTML-107's css→span direction is silent when zero reveal spans were found anywhere — an empty universe is blindness, not dead wiring. Kills 46 false errors on server-templated projects. (#133)
|
|
15
|
+
- **src-first entry — the core singleton unforked.** `exports "."` (and `main`/`module`) resolve to `src/core/index.js`, the same graph every battery subpath imports; previously `.` pointed at the dist bundle, so importing the entry plus any battery loaded two `The` singletons and `boot()` configured one while batteries read the other. The redundant `./src` alias is gone; `dist/` demotes to a CDN/script-tag artifact. Reverses the 0.2.0 dist-entry decision — deliberately, no legacy. (#134)
|
|
16
|
+
- Test-runner IPC flake (`Unable to deserialize cloned data`) starved at the source: the CLI's console chatter is mocked in its tests. (#30 lineage)
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Blog example modernized to 0.7.0 idioms: `$.cloneEach` + `data-bind` replace the manual clone loop and per-clone `setAttribute`. (#135)
|
|
21
|
+
|
|
7
22
|
## [0.7.0] — 2026-07-19
|
|
8
23
|
|
|
9
24
|
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.
|
package/README.md
CHANGED
|
@@ -766,7 +766,7 @@ npx otm-lint --check ./src
|
|
|
766
766
|
| **HTML-106** *(warn)* | A globally written state key nothing consumes | The deletion test as lint: no CSS attribute selector, `[data-text]` slot, `"data-key"` JS string literal (e.g. MutationObserver `attributeFilter`), or `the("key")` read touches it — dead state or a missing CSS rule. Warn-level: reported, never fails the run. |
|
|
767
767
|
| **HTML-107** | A `data-K-key="V"` reveal span with no `[data-K="V"]` state-CSS rule, or a CSS `[data-K-key="V"]` reference with no span | Either half missing means the message silently never shows (or the rule is dead wiring). Add the missing half or delete the orphan; `data-otm-dynamic` opts a span out of the span→CSS direction. |
|
|
768
768
|
|
|
769
|
-
`otm-lint` walks `.html`, `.js`, `.css`, and locale `.json` files. HTML files get the per-file rules above (template content included); `.js` files contribute `$.clone` references, `the()` write/read keys, and `data-action` selectors; `.css` files contribute attribute-selector consumption for HTML-106; locale dicts get loaded per HTML file's `<meta name="i18n">` for HTML-102/103. Default excludes: `node_modules`, `dist`, `.git`, dotdirs. Exit code is nonzero when error-level violations are found.
|
|
769
|
+
`otm-lint` walks `.html`, `.ejs` (cross-file rules only — per-file rules stay `.html`), `.js`, `.css`, and locale `.json` files. HTML files get the per-file rules above (template content included); `.js` files contribute `$.clone` references, `the()` write/read keys, and `data-action` selectors; `.css` files contribute attribute-selector consumption for HTML-106; locale dicts get loaded per HTML file's `<meta name="i18n">` for HTML-102/103. Default excludes: `node_modules`, `dist`, `.git`, dotdirs. Exit code is nonzero when error-level violations are found.
|
|
770
770
|
|
|
771
771
|
### Lint-rule scope
|
|
772
772
|
|
|
@@ -849,9 +849,11 @@ src/
|
|
|
849
849
|
test/
|
|
850
850
|
└── integration.test.js # cross-module integration suite
|
|
851
851
|
dist/
|
|
852
|
-
└── on_the_money.min.js #
|
|
852
|
+
└── on_the_money.min.js # CDN/script-tag artifact only — npm resolves "." to src
|
|
853
853
|
```
|
|
854
854
|
|
|
855
|
+
**One module graph.** The npm entry (`.`) and every battery subpath resolve into the same `src/` graph, so `The`'s statics (`dictionary`, `locale`, `prefix`, `persistKeys`) are one singleton everywhere. `dist/on_the_money.min.js` exists solely for `<script type="module">` hotlinking — importing it *alongside* npm subpaths would fork the core, which is exactly the bug this arrangement removes.
|
|
856
|
+
|
|
855
857
|
Unit tests are co-located with source: `src/core/On.test.js`, etc.
|
|
856
858
|
|
|
857
859
|
## Commands
|
package/package.json
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "on_the_money",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Opinionated, attribute-driven, standards-oriented modern framework. Native browser APIs only. See README.md for the authoring context.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "
|
|
7
|
-
"module": "
|
|
6
|
+
"main": "src/core/index.js",
|
|
7
|
+
"module": "src/core/index.js",
|
|
8
8
|
"bin": {
|
|
9
9
|
"otm-lint": "./src/linter/main.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
|
-
".": "./
|
|
13
|
-
"./src": "./src/core/index.js",
|
|
12
|
+
".": "./src/core/index.js",
|
|
14
13
|
"./live": "./src/live/index.js",
|
|
15
14
|
"./clipboard": "./src/clipboard/index.js",
|
|
16
15
|
"./test": "./src/test/index.js",
|
package/src/eslint/plugin.js
CHANGED
|
@@ -293,9 +293,14 @@ const noRawWebsocket = {
|
|
|
293
293
|
create(context) {
|
|
294
294
|
return {
|
|
295
295
|
NewExpression(node) {
|
|
296
|
-
if (node.callee?.name
|
|
297
|
-
|
|
298
|
-
|
|
296
|
+
if (node.callee?.name !== "WebSocket") return;
|
|
297
|
+
// Only the browser GLOBAL is banned. An imported or locally
|
|
298
|
+
// declared WebSocket (a Node ws-package client) resolves to a
|
|
299
|
+
// definition and is outside live()'s reach — let it pass.
|
|
300
|
+
const scope = context.sourceCode.getScope(node);
|
|
301
|
+
const ref = scope.references.find((r) => r.identifier === node.callee);
|
|
302
|
+
if (ref?.resolved?.defs.length) return;
|
|
303
|
+
context.report({ node, messageId: "useLive" });
|
|
299
304
|
},
|
|
300
305
|
};
|
|
301
306
|
},
|
package/src/linter/Linter.js
CHANGED
|
@@ -437,7 +437,10 @@ export default class Linter {
|
|
|
437
437
|
);
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
-
|
|
440
|
+
// An empty span universe is evidence of blindness (markup living in
|
|
441
|
+
// templates the scan can't see), not of dead wiring — the css→span
|
|
442
|
+
// direction only fires when at least one reveal span was found.
|
|
443
|
+
for (const ref of spanPairs.size > 0 ? spanRefs : []) {
|
|
441
444
|
if (spanPairs.has(`${ref.group} ${ref.value}`)) continue;
|
|
442
445
|
Linter.#addViolation(
|
|
443
446
|
violations,
|
package/src/linter/cli.js
CHANGED
|
@@ -62,8 +62,19 @@ export default class Cli {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
static async scan(dir) {
|
|
65
|
-
const allFiles = await Cli.getFiles(dir, [
|
|
66
|
-
|
|
65
|
+
const allFiles = await Cli.getFiles(dir, [
|
|
66
|
+
".html",
|
|
67
|
+
".ejs",
|
|
68
|
+
".js",
|
|
69
|
+
".json",
|
|
70
|
+
".css",
|
|
71
|
+
]);
|
|
72
|
+
// .ejs joins the markup universe for cross-file rules (reveal spans,
|
|
73
|
+
// slots, actions); per-file rules stay .html-only — Linter.check
|
|
74
|
+
// skips non-.html, so template syntax never false-positives HTML-004.
|
|
75
|
+
const htmlPaths = allFiles.filter(
|
|
76
|
+
(f) => f.endsWith(".html") || f.endsWith(".ejs"),
|
|
77
|
+
);
|
|
67
78
|
const jsPaths = allFiles.filter((f) => f.endsWith(".js"));
|
|
68
79
|
const cssPaths = allFiles.filter((f) => f.endsWith(".css"));
|
|
69
80
|
let totalViolations = 0;
|