Skip to content

feat(share): the wickchart-share plugin — the chart as one self-contained file - #90

Closed
benyblack wants to merge 2 commits into
mainfrom
feat/share-plugin
Closed

benyblack wants to merge 2 commits into
mainfrom
feat/share-plugin

Conversation

@benyblack

Copy link
Copy Markdown
Owner

Roadmap v3 PR 3 (Track 2, the zero-dep flex): exportChart() turns a live chart into ONE self-contained .html — the library's own module sources inlined, state + bars embedded — that opens offline in any browser and paints the exact chart again. Only a zero-dependency, no-build library can offer this: there is nothing else to ship.

How the file works

  • core + chart sources ride as base64 data-URL modules; the chart module's from './core.js' line is rewritten onto the core's data URL at export time, so one dynamic import() registers the element — no network, no import map.
  • The payload ({v, meta, state, bars}) sits in a JSON script block, applied via setState() then setData() (the pending-range mechanism restores the exact view).
  • < is escaped everywhere user or source text is embedded — neither a title nor a code comment can terminate a script block (unit-tested with injected </script><b> payloads).

Surface

attachShare(chart) → exportChart() / downloadChart(); the standalone builder and parseChartFile() are pure and exported (hosts read a shared file back into {bars, state, meta}). Module URLs are discovered via resource timing (any way the page loaded them); bundled hosts pass URLs or sources explicitly.

Ships as a plugin (3.0 KB gz, own 5 KB CI budget) — the main entry keeps the headroom it has left. The family is 17 packages.

Verification

  • 8 unit tests: builder/parser round-trip, script-block escaping, import-rewrite guard (fails loudly if the chart module's import line ever changes shape), attach/detach surface.
  • e2e proves the thesis end to end: the exported file, opened from a blob URL with every other request blocked, re-paints all 300 bars with the source chart's view — offline by construction.
  • npm test — 715/715 · e2e — 81 passed / 4 skipped.
  • Docs: plugins hub section + live playground, demo toolbar Share button (icon-only — the phone-layout lesson sticks), README section, roadmap rows struck with the plugin-not-core decision recorded.

…ined file

Roadmap v3 PR 3: exportChart() turns a live <wick-chart> into ONE
self-contained .html — the library's own module sources inlined, the
chart's state and bars embedded — that opens offline in any browser and
paints the exact chart again. Only a zero-dependency, no-build library
can offer this; the constraint pays off.

How the file works: core + chart sources ride as base64 data-URL
modules; the chart module's "from './core.js'" line is rewritten onto
the core's data URL at export time, so one dynamic import() registers
the element with no network and no import map. The payload
({v, meta, state, bars}) sits in a JSON script block and is applied
via setState() then setData() (the pending-range mechanism restores the
exact view). '<' is escaped everywhere user or source text is embedded,
so neither a title nor a code comment can terminate a script block.

Surface: attachShare(chart) → exportChart()/downloadChart(); the
standalone builder + parseChartFile() are pure and exported for hosts
and tests. Module URLs are discovered via resource timing (any way the
page loaded them); bundled hosts pass urls or sources explicitly.

Ships as a plugin (3.0 KB gz, own 5 KB CI budget) — the main entry
keeps the headroom it has left. e2e proves the thesis end to end: the
exported file, opened from a blob URL with everything else blocked,
re-paints all 300 bars with the source chart's view.
…oadmap strikes

The hub gains a live export playground (17 packages now), the demo
toolbar gets an icon-only Share button in the view cluster, README
documents the plugin, and the two Track-2 rows strike with the
plugin-not-core decision recorded.
@benyblack

Copy link
Copy Markdown
Owner Author

Superseded by #91 (merged) — closing with credit.

This PR and #91 are parallel implementations of the same Track-2 rows (single-file export + open), built independently six days apart. #91 is now on main with green CI, so this branch conflicts in every shared file (README, ROADMAP, demo, docs, package.json, budget test) and would ship a second, competing exporter.

What #91 kept from its own design: sources flattened into one module script (raw text — no base64's +33%), the inlining contract pinned against the real sources with node --check in every CI run instead of a guarded string rewrite, compact bar arrays (~½ payload) with maxBars, custom-theme palettes traveling with the chart, and the full round-trip (adoptShared + attachDrop) covering the 'open a shared chart' row too.

What this PR had that was genuinely clever: resource-timing module discovery (finding wick-chart.js however the page loaded it) and the offline-by-construction blob-URL e2e. The discovery fallback wasn't ported — every path it covers (script tag, ESM, CDN) is also covered by import.meta.url-relative fetch, and bundlers defeat both equally — but it's recorded here in case a real host surfaces where that stops being true.

The branch can be reopened if you'd rather salvage the data-URL embedding (e.g. for a CSP-agnostic variant) — the commits stay reachable.

@benyblack benyblack closed this Oct 8, 2026
@benyblack
benyblack deleted the feat/share-plugin branch October 8, 2026 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant