@quillmark/registry
v0.11.0
Published
Unified API for discovering, loading, packaging, and registering Quills with the WASM engine
Maintainers
Readme
@quillmark/registry
Unified API for discovering, loading, and registering Quills with the Quillmark WASM engine. Works in both browser and Node.js environments.
Install
npm install @quillmark/registryPeer dependency: Requires @quillmark/wasm@>=0.39.0 — you provide the engine instance.
Quick Start
Browser (HTTP source)
import { Quillmark, init } from '@quillmark/wasm';
import { QuillRegistry, HttpSource } from '@quillmark/registry';
const source = new HttpSource({ baseUrl: 'https://cdn.example.com/quills/' });
const registry = new QuillRegistry({ source });
// Start fetching while @quillmark/wasm initializes
const fetched = registry.fetch('[email protected]');
init();
const engine = new Quillmark();
registry.setEngine(engine);
await fetched;
// Resolve a quill — fetches, caches, and registers with the engine
const bundle = await registry.resolve('usaf_memo'); // or await registry.resolve('[email protected]')
// Engine is now ready to render
const parsed = Quillmark.parseMarkdown(myMarkdown);
const result = engine.render(parsed, { quill: 'usaf_memo' });Node.js (filesystem source)
import { Quillmark } from '@quillmark/wasm';
import { QuillRegistry, FileSystemSource } from '@quillmark/registry';
const engine = new Quillmark();
const source = new FileSystemSource('/path/to/quills');
const registry = new QuillRegistry({ source, engine });
const bundle = await registry.resolve('usaf_memo');API
QuillRegistry
Orchestrates sources, resolves versions, caches loaded quills, and registers them with the engine. Loading is lazy — quills are fetched on first resolve() call, not at construction time.
const registry = new QuillRegistry({ source, engine });| Method | Description |
|---|---|
| fetch(canonicalRef) | Fetches a quill bundle by canonical ref (name@version, full semver) and caches it. Does not register with the engine. |
| resolve(ref) | Resolves a quill reference (name, name@version, or semver selector like name@1 / [email protected]). Reuses fetched bundles when present, otherwise fetches on demand, then registers with the engine. Returns a QuillBundle. |
| setEngine(engine) | Attaches or replaces the engine used by resolve(). Useful when fetching before @quillmark/wasm initialization completes. |
| getManifest() | Returns the full QuillManifest from the source. |
| getAvailableQuills() | Returns QuillMetadata[] for all quills in the source. |
| isLoaded(name) | Returns true if the quill is registered in the engine. |
HttpSource
Fetches quill zips and manifest from any HTTP endpoint. Works in browser and Node.js.
const source = new HttpSource({
baseUrl: 'https://cdn.example.com/quills/',
manifest: preloadedManifest, // optional — skip initial manifest fetch (useful for SSR)
fetch: customFetch, // optional — custom fetch function
});Zip URLs use the format {baseUrl}{name}@{version}.zip?v={version} for cache-busting.
FileSystemSource
Node.js-only source that reads quill directories from disk. Each version directory must contain a Quill.yaml file; name and version are derived from the directory structure.
const source = new FileSystemSource('/path/to/quills');Packaging for static hosting
await source.packageForHttp('/path/to/output');
// Writes: output/manifest.json, output/[email protected], ...QuillSource interface
Implement this to create custom sources:
interface QuillSource {
getManifest(): Promise<QuillManifest>;
loadQuill(name: string, version: string): Promise<QuillBundle>;
}Error Handling
All errors are thrown as RegistryError with a typed code:
| Code | Meaning |
|---|---|
| quill_not_found | No quill with that name exists in the source |
| version_not_found | Quill exists but the requested version doesn't |
| load_error | Source failed to fetch or parse quill data |
| source_unavailable | Network failure, filesystem error, etc. |
import { RegistryError } from '@quillmark/registry';
try {
await registry.resolve('nonexistent');
} catch (err) {
if (err instanceof RegistryError) {
console.error(err.code, err.quillName);
}
}Version Resolution
fetch() requires a canonical ref (name@version) using full semver (for example, [email protected]). resolve() accepts name, canonical name@version, or semver selectors with missing segments (for example, usaf_memo@1 or [email protected]) and picks the highest matching version from a manifest that is loaded eagerly when the registry is constructed. Fetches are deduplicated in-memory to prevent duplicate source loads under races.
License
Apache-2.0
