@weasel-js/core 0.7.0 → 0.7.2

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 CHANGED
@@ -1,5 +1,131 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 8bc719a: Every package now declares `engines.node: ">=22"`, up from `">=20"`. Node 20
8
+ reached end of life on 2026-04-30, so the old floor advertised support for a
9
+ runtime that no longer receives security patches — a claim in each published
10
+ tarball that had quietly stopped being true. `@weasel-js/labkit` had no `engines`
11
+ field at all and now matches its siblings.
12
+
13
+ Nothing in the kit required a Node 20 feature, so this changes what is promised
14
+ rather than what runs. CI tests both ends of the range: the 22 floor and the 24
15
+ Active LTS the release and docs workflows build on.
16
+
17
+ - a19124d: `VERSION` reports the right number again. `@weasel-js/core@0.7.1` was published
18
+ from a working tree whose `dist/` predated the version bump, so the constant
19
+ baked into that tarball reads `0.7.0` while the package it ships in is `0.7.1` —
20
+ the one export whose entire job is to say what you are running, saying the wrong
21
+ thing. Nothing else in 0.7.1 is affected: the value is stamped at build time by
22
+ `tsup`'s `define`, so only a stale build can desync it, and only `core` bakes it.
23
+
24
+ npm tarballs are immutable, so 0.7.1 cannot be corrected in place. Anything
25
+ pinned there should move to this release; `0.7.1` is deprecated on npm pointing
26
+ here.
27
+
28
+ - Updated dependencies [8bc719a]
29
+ - @weasel-js/font@0.7.2
30
+ - @weasel-js/geom@0.7.2
31
+ - @weasel-js/gestures@0.7.2
32
+ - @weasel-js/history@0.7.2
33
+ - @weasel-js/modes@0.7.2
34
+
35
+ ## 0.7.1
36
+
37
+ ### Patch Changes
38
+
39
+ - a3af158: Gestures are now keyed per pointer. `gestureIdFor` returned the literal string
40
+ `pointer-mouse` with nothing interpolated — despite its own docs promising
41
+ `pointer-<pointerId>` — so every pointer shared one in-flight handle slot and
42
+ two pointer gestures could not coexist. Pointer events carry `pointerId` now
43
+ and the id interpolates; events without one (synthetic probes, most tests)
44
+ still key to `pointer-mouse`.
45
+
46
+ That removes an accident the pinch path was relying on, so the multitouch
47
+ policy is stated rather than implied: when a second pointer lands, the
48
+ multitouch channel claims every pointer that hasn't already committed to a
49
+ gesture, suppressing both drags and taps from those pointers. A drag already in
50
+ flight keeps running — yanking a gesture away from someone who rested a palm is
51
+ worse than letting it finish.
52
+
53
+ `useTools` also reports routing conflicts now. `findConflicts` had been
54
+ written, tested, and never called, so the kit could detect its one class of
55
+ genuine routing ambiguity and never looked. It runs at registry assembly under
56
+ a dev guard and warns each conflict in the grammar the route was written in. It
57
+ warns and never throws: a consumer tool colliding with a kit tool can be
58
+ deliberate, since the loser may still take the gesture by declining through
59
+ `enabled()`.
60
+
61
+ - a3af158: Scenes with many shapes or much text draw far less work per frame. Two caches
62
+ the kit already had were missing on essentially every node of every frame,
63
+ because the values they key on were rebuilt each time.
64
+
65
+ The tessellation cache (`WeakMap<Path, Mesh>`) keys on `Path` identity, but
66
+ `kit:shape` allocated a fresh path for every ellipse, polygon and star on every
67
+ draw. Painters now memoize `paint` against the node, so the same path comes
68
+ back and the cache does its job: 1000 shape nodes went from 6.69 to 0.20
69
+ ms/frame through paint and tessellation.
70
+
71
+ Text layout is the larger one. `layoutRuns` — which walks every codepoint,
72
+ resolves a face per run, measures, wraps and places each glyph — ran per text
73
+ command per frame. It is now cached in the renderer, keyed on the resolved
74
+ runs. 200 wrapped paragraphs went from 31.8 to 0.06 ms/frame, 1000 short
75
+ labels from 12.5 to 0.42. The cache drops itself when a font becomes
76
+ available, so text still reflows the moment the real face lands.
77
+
78
+ Two contracts follow from this, for anyone writing a custom painter or calling
79
+ these directly:
80
+
81
+ - The array a painter's `paint` returns belongs to the painter. Treat it as
82
+ immutable and copy before appending — `defaultDrawOne` now does, for its
83
+ label overlay.
84
+ - `registerFont` now notifies `subscribeGlyphReady` when a family finishes
85
+ registering, so a font loaded mid-session repaints without waiting for an
86
+ unrelated redraw. `glyphGeneration()` is a new pull-based companion to that
87
+ signal, for caches that can't hold a subscription.
88
+
89
+ - 6af4806: Reorder: `Cmd/Ctrl+Shift+]` and `Cmd/Ctrl+Shift+[` now bring-to-front and
90
+ send-to-back. The shortcut every drawing app uses could never fire — modifier
91
+ matching is strict, so a binding without `shift` in its spec cannot match a
92
+ keystroke that holds it, which also made the shifted `'}'` / `'{'` characters
93
+ in those key lists unreachable. `Cmd+Alt+]` / `Cmd+Alt+[` remain as the
94
+ fallback for browsers that reserve `Cmd+Shift+[`/`]` for tab switching.
95
+
96
+ `BUNDLE_TOOLS.standard` no longer includes `pencil`. Freehand is a specialist
97
+ instrument rather than part of the everyday shape-drawing set; it is still in
98
+ `exhaustive`. Consumers wanting it back can pass `tools={{ pencil: true }}`
99
+ alongside the bundle.
100
+
101
+ - a3af158: Clicks now land on the shape a node actually paints, not on its bounding box.
102
+ The pose rect is the wrong answer for anything that isn't a rectangle: a click
103
+ in a star's notch, in the corner outside an ellipse, or in the blank half of a
104
+ text box went to the node that merely bounds that point, burying whatever was
105
+ really underneath. `picking: 'shape'` had been available since it shipped and
106
+ was opt-in only because flipping it changes what a click selects.
107
+
108
+ Ink counts too, not just the boundary. A shape whose interior isn't filled —
109
+ an outlined rect, a pencil stroke, a bare line — is now grabbable along its
110
+ outline and not through its empty middle, which is the opposite of what a fill
111
+ test alone answers. Painters declare this through the new `NodeShapeEntry.ink`;
112
+ one that declares none is treated as filled, the previous behavior.
113
+
114
+ Pass `geometry={{ picking: 'pose' }}` to `SceneCanvas` for the old rect
115
+ behavior. Painters with no silhouette are unaffected either way, so nothing
116
+ becomes unreachable.
117
+
118
+ - 2003597: Export `VERSION` — the kit version a build was compiled from, baked in at
119
+ build time. Apps can pair it with their own compile timestamp to report what
120
+ they're running (WeaselDraw now shows `0.7.0 · Jul 30` in its status bar).
121
+ - Updated dependencies [6af4806]
122
+ - Updated dependencies [a3af158]
123
+ - @weasel-js/font@0.7.1
124
+ - @weasel-js/geom@0.7.1
125
+ - @weasel-js/gestures@0.7.1
126
+ - @weasel-js/history@0.7.1
127
+ - @weasel-js/modes@0.7.1
128
+
3
129
  ## 0.7.0
4
130
 
5
131
  ### Minor Changes