main
v0.2.0
v0.1.0
v0.1.1
${ noResults }
2 Commits (f9c07a263d9d27b0874be3c3924e32ea80c1c0a7)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
f9c07a263d |
refactor: split element classes from customElements.define
Every component is now two modules sharing a basename: - src/elements/leaflet-foo.ts -- `export default class LeafletFooElement extends WithProps(...)`, the class only, no customElements.define, no side effects. src/elements/index.ts is an order-free barrel. - src/components/leaflet-foo.ts -- three lines: import the class, define the tag, re-export. Importing this (or src/index.ts) registers the tag. Plugin authors can now import a class without triggering the built-in define, to subclass it or register it under a different tag name. Package subpath exports `leaflet-components/elements`, `leaflet-components/elements/leaflet-foo.js`, and `leaflet-components/components/leaflet-foo.js` map onto dist/; jsr.json gains an `./elements` entry. The load-bearing ordering moves from the export statements in src/index.ts to its `./components/*` side-effect imports (the elements barrel carries no define, so its order is free). Classes are renamed LeafletFoo -> LeafletFooElement, including in the HTMLElementTagNameMap augmentation. Docs (CLAUDE.md, docs/, README.md) updated for the new layout. |
2 weeks ago |
|
|
3845e53329 |
fix: remove parent-reaches-into-child patterns, fix a real load-order bug
Two parent-looks-for-child patterns found and removed, per the child-emits-events-parent-never-reaches-in principle: - leaflet-control-layers: #childLayers() queried children directly via querySelectorAll + reading their leafletObject/attributes, in two call sites. Verified empirically that a parent's connectedCallback always completes before a freshly-connected child's does (even for an already-built subtree attached in one shot), which means both call sites always ran against unpopulated children -- dead code. Deleted; #onChildRegister (already event-driven) was doing all the real work. - leaflet-polygon/leaflet-polyline: #coords() queried <leaflet-line> children via querySelectorAll + read their .latlng property directly, using a MutationObserver + a payload-less event only as a "something changed, rescan everyone" signal. Rewritten to be purely event-driven: <leaflet-line> now fires leaflet-line-sync (connect + every lat/lng change, carrying its own position) and leaflet-line-remove (disconnect) on itself; a new shared VertexTracker (src/core/vertex-tracker.ts) turns that event stream into an ordered coordinate list, using compareDocumentPosition only to place a newly-registered vertex at its real document position rather than assuming registration order matches DOM order. No querySelectorAll, no MutationObserver, no reading a child's property. Testing the polygon rewrite in an actual browser (not jsdom) surfaced two real bugs, both fixed: 1. disconnectedCallback fires *after* a node is already detached from its parent, so leaflet-line's removal event had nowhere to bubble to. Fixed by caching parentNode while still connected and dispatching from that cached reference instead of from the (by-then-detached) node. 2. A load-order hazard affecting every "parent listens for a specific child tag's announcement" relationship in this codebase: customElements.define() upgrades every matching element already parsed into the page immediately and synchronously, so whichever tag gets defined first wins a race -- a child tag defined before its listening parent fires its one-shot connect-time announcement into a parent that doesn't exist yet, and it's lost for good. This broke polygon/polyline (introduced by this rewrite, since leaflet-line was exported before leaflet-polygon) and, independently, was already silently broken for leaflet-control-layers (a base/overlay layer leaked directly onto the map, bypassing the control entirely) and latently for leaflet-layer-group/leaflet-feature-group. src/index.ts's export order now encodes and documents the real dependency hierarchy (map -> containers that listen for child announcements -> concrete layer types -> their own children). Added test/load-order.test.ts, which is structurally different from every other test file: it never statically imports a component module, building the DOM with plain undefined elements first and only dynamically import()ing src/index.ts afterward -- reproducing a real page's actual load order, which every other test's "define everything first" pattern cannot catch. Confirmed it fails against the old ordering and passes against the fix. |
4 weeks ago |