npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

exemplara-core

v0.1.1

Published

Framework-independent Exemplara document engine, renderer and Nano Stores editor sessions

Readme

Exemplara Core

MIT-licensed, framework-independent document model, command engine, HTML/CSS renderer, shared authoring utilities, and editor sessions backed by Nano Stores. No Svelte runtime or types are required by exemplara-core, /core, /renderer, /shared, or /editor.

import { EditorSession, createFullEditorPreset } from 'exemplara-core/editor';
import { render } from 'exemplara-core/renderer';

const editor = new EditorSession({ composition: createFullEditorPreset() });
const stop = editor.stores.selectedNode.subscribe(node => console.log(node?.id));
editor.addComponent('text', editor.activePage!.regions.body.id);
const output = render(editor.snapshot());
stop();
editor.destroy();

Each session owns its document engine, history, selection, clipboard, tabs, zoom, previews, drag state, component registry, render runtime, capability policy, and plugin services. The engine's canonical store owns document/history state; the session exposes that same store. session.ui owns typed Nano Store models for all component and private-feature state: drafts, filters, confirmations, sidebar geometry, ruler/toolbar placement, preview measurements, disclosures, upload/import progress, and version-history progress/counters. Use one session per editor/request. Subscribe to the read-only store API and change state through session methods. Store values remain the existing document model: make edits through commands rather than mutating document objects. snapshot() returns an independent clone.

A synchronous editing action batches store notifications and reconciles selection. Replacing a document increments documentEpoch, resets history, clears editing/drag targets, and fences pending persistence results. destroy() is idempotent and stops subscriptions and plugin hooks. Detaching a view does not destroy an externally owned session. A view may register reveal/viewport callbacks and inline caret insertion; the core does not retain DOM nodes.

Component models are scoped by profile and optional node/source/path identity:

const model = editor.ui.get('data');
model.set('query', 'invoice');
const stopDraft = model.store.subscribe(draft => console.log(draft.pasteText));
const textDraft = editor.ui.get('richText', nodeId);
textDraft.set('draftHtml', '<strong>Pending edit</strong>');
editor.ui.commitRichText(nodeId);
stopDraft();

Detaching a view preserves drafts/preferences and clears view scheduling/drag handles. Replacing a document resets its UI models and invalidates pending imports/uploads/clipboard work. Capture a model's capture() before awaiting a platform operation; begin(channel) also fences older intent on that channel. Use immutable replacements for nested fields. DOM elements, observers, animation frame/timer handles, caret ranges, and view registrations remain platform resources.

EditorApplication owns the host application's view mode, settings, feature flags, session lifetime, and computed document/JSON/statistics. Supply composition and seed-document factories; feature changes validate the replacement before disposing the previous session. This owner can run without any view mounted.

Portable plugins use composeEditor({ plugins, services, policy }); their setup(api) registers commands, menus, keybindings, block factories, renderers, transforms, style fields, autocomplete providers, and framework-independent panel metadata. api.onSession(session => disposer) starts a service once, after initialization. Core presets provide the structural metadata and editing commands. Proprietary features remain in the separate exemplara-plugins/core package.

session.extensions.install(plugin) and api.installCore(plugin) install portable behavior once per plugin ID, with cleanup when the session is destroyed. Wrappers use session.extensions.attach(...extensions) for view behavior; its returned disposer removes those registrations and releases view resources. A replacement attachment uses fresh callbacks. Failed setup restores managed registrations and permits retry, including portable plugins installed during that attempt. Plugins must clean up resources acquired before their setup throws; the registry can only invoke disposers that setup returned.

The shared barrel contains pure utilities. Browser utilities such as /shared/html-import, /shared/preview, /shared/dom, and measurement helpers are explicit opt-in leaves and require their platform APIs when called. PDF execution belongs to exemplara-plugins/pdf and Node/Chromium, not this package.

Development from the sibling checkouts:

pnpm install
pnpm build
pnpm check
pnpm test:run

The Svelte package's pnpm check:state audits the complete wrapper/private-plugin/playground source graph and rejects application Rune state, local component state, state constructors outside core, and disclosures without a core owner. pnpm test:packages builds and packs all three packages, installs isolated consumers, checks headless declarations and browser bundles, builds and runs two isolated Svelte editors, and generates a PDF from the headless tarballs. pnpm test:browser verifies editing and view reattachment in the sibling playground. Both certification scripts require Chrome (/usr/bin/google-chrome or EXEMPLARA_CHROMIUM_PATH). Publish [email protected] before [email protected]; the wrapper requires the new attachment API. The private plugins depend on the public core but are never re-exported from it.