Skip to content

v2.0.0

Latest

Choose a tag to compare

@frobnitzem frobnitzem released this 17 Oct 18:39
· 2 commits to main since this release
283e4be

2.0.0 (2026-10-17)

Published to npm as pocketview and @pocketview/view (the embeddable viewer),
@pocketview/core (the layout engine), @pocketview/typeset (line
breaking) and @pocketview/markdown (the Markdown plugin). Breaking
changes from 1.0: Planner.plan(spec, viewport) takes a LayoutSpec, the
outermost frame's slot is "", and the viewer moved from the demo into
@pocketview/view.

  • Packages ship compiled ES modules with type declarations (dist/); the
    view package also ships its single-file bundle (bundle/) for use from
    a CDN. A GitHub release publishes them (.github/workflows/release.yml).

  • @pocketview/view: the viewer as an embeddable package. mount(element, value, options) fills a fixed-size element and returns a Viewer
    (show, on, setTheme, configure, destroy). A
    single-file bundle (pocketview.js and pocketview.css, with the Latin
    font subsets inlined) is built and served from the demo site at lib/,
    with an example page, embed.html. The demo uses the same API.

  • The viewer's colour schemes apply to the viewer element only, never to
    the embedding page.

  • Targeting a container no longer re-plans or drops expansions.

  • The viewer is a Viewer object owning the document, the layout spec
    and the target. Every click goes through pure rules (rules.ts), then
    one plan and one redraw, then one event: viewer.on(type, listener)
    reports target, open, expand, minify, page and refuse, with
    the node's JSON Pointer.

  • Viewer API calls run the same actions as clicks: target, open,
    expand, minify, page and refuse. Each returns whether it
    succeeded, and notifies listeners only when asked to. The current layout
    spec and target are read from viewer.state.

  • viewer.update(path, value) replaces part of the document (or all of
    it) and keeps the navigation; nodes with unchanged content keep their
    cached sizes (core: Planner.update, replaceAt). viewer.isShown(path)
    says whether a node is drawn itself; viewer.value is the current
    document. Updates are reported as update events when asked.

  • A minified node hides everything inside it: the outermost choice wins.
    Minifying keeps the expanded nodes inside it on the list, so expanding
    it again restores them; expanding a node un-minifies its ancestors.
    Expanding or minifying a node twice is idempotent.

  • Solarized: body text is the other mode's panel tone (midnight blue on
    light, cream on dark), for more contrast.

  • Untargeted, a key or a nested title toggles its node: shown or expanded
    nodes are minified (collapsed even when there is room), minified ones
    expanded. Minified nodes are a new list in the layout spec.

  • Core: Planner.plan(spec, viewport) takes a LayoutSpec (views,
    expanded, minified, windows, offsets); the outermost frame is
    the slot "" in views, so re-rooting is opening into it. Re-rooting
    keeps the annotations inside the new root.

  • Sizes are cached per document node, keyed by the layout spec inside the
    node's subtree: navigating in one container keeps every other
    container's sizes. Text and Markdown measurements are cached per viewer
    and recomputed when a node's text changes (two viewers on a page no
    longer share Markdown heights).