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

@bendyline/docblocks

v2.0.0

Published

Core data structures and filesystem abstractions for DocBlocks

Readme

@bendyline/docblocks

Core types and abstractions for DocBlocks — the single source of truth for everything that crosses a process or storage boundary (filesystem providers, workspace management, and the Electron host contract).

Installation

npm install @bendyline/docblocks

Exports

The package exposes focused subpath modules. Filesystem, document, workspace, and host APIs are also re-exported from the package root; boundary-specific wire protocols stay isolated in their own entry points.

Filesystem (@bendyline/docblocks/filesystem)

Correctness-first, byte-authoritative filesystem abstraction — the single seam for user-document storage. UI code never touches indexedDB, node:fs, or electron directly; it goes through a provider.

  • FileSystemProviderV2 — canonical branded paths, typed errors, explicit mutation modes, opaque versions, capabilities, snapshots, watches, and disposal
  • WorkspacePath / parseWorkspacePath() — the portable logical path representation ('' is workspace root)
  • FsError — stable error codes that survive IPC/structured clone boundaries
  • IndexedDBFileSystemProvider — browser-local persistent storage (site, VS Code webview fallback)
  • NativeFileSystemProvider — real folders in the browser via the File System Access API
  • ElectronFileSystemProvider — bridges to the desktop main process over the host API
  • MemoryFileSystemProvider — authoritative in-memory v2 storage for transient loose-file and DBK workspaces
  • IndexedDBContentContainer / FileSystemContentContainer — content-container layer for media alongside documents
  • createFileMediaProvider — media provider wired to a filesystem provider
import { IndexedDBFileSystemProvider, parseWorkspacePath } from '@bendyline/docblocks/filesystem';

const fs = new IndexedDBFileSystemProvider('my-workspace', 'My workspace');
const path = parseWorkspacePath('/doc.md');
await fs.v2.writeFile(path, new TextEncoder().encode('# Hello'), {
  mode: 'create',
  createParents: true,
});
const content = await fs.v2.readFile(path);

FileSystemProvider remains as a deprecated text compatibility facade during the v2 migration. New code should discover provider.v2 with getFileSystemProviderV2() and use v1 only as an explicit compatibility fallback. Every new backend must pass the shared v2 conformance suite.

Provider families also have isolated entry points so a browser or desktop surface can load only the backend it selects:

  • @bendyline/docblocks/filesystem/indexeddb
  • @bendyline/docblocks/filesystem/memory
  • @bendyline/docblocks/filesystem/native
  • @bendyline/docblocks/filesystem/electron

Use literal dynamic imports of those subpaths in multi-surface shells. The compatibility filesystem barrel still re-exports every provider, but eagerly constructing from that barrel puts mutually exclusive backends in one startup bundle.

Mutation behavior is explicit: writeFile requires a create, replace, or upsert mode; remove distinguishes an empty-directory removal from a recursive tree removal; and move never overwrites its destination. Missing entries are returned as null only by stat and readFile. Permission, wrong-kind, conflict, quota, and I/O failures remain typed FsErrors.

Capability declarations are conservative promises, not marketing labels:

| Provider | Write | Move | Snapshot | Conditional write | Watch | Durability | | ------------------------- | ------------- | ------------- | ------------- | ----------------- | ----- | ----------- | | Memory | process | process | process | process | yes | volatile | | IndexedDB | cross-context | cross-context | cross-context | storage-atomic | no | best-effort | | Native File System Access | none | none | none | process | no | best-effort | | Electron workspace | process | process | process | process | yes | best-effort |

Versions are opaque equality tokens scoped to their issuing provider. A consumer must never parse them or compare tokens from different providers. When a watch reports overflow, discard incremental assumptions and reload or snapshot the relevant state.

IndexedDB workspaces migrate the legacy fs:* text/binary namespace in one transaction and then use v2 records as their sole authority. Divergent legacy or pre-release v2 data is retained as an explicit recovery candidate instead of being guessed away. If an obsolete tab recreates legacy keys, a bounded prefix probe quarantines that branch before the requested operation retries; ordinary operations do not scan or deserialize the complete workspace.

Document (@bendyline/docblocks/document)

Framework-neutral document transaction/session primitives: serialized latest-write commits, monotonic revisions, explicit transitions/retarget/delete/close, conflict state, and crash-recovery journals.

Workspace (@bendyline/docblocks/workspace)

Workspace registry — how DocBlocks tracks the document collections a user has opened.

  • WorkspaceDescriptor — the workspace record type
  • listWorkspaces / getWorkspace / saveWorkspace / removeWorkspace — registry CRUD
  • touchWorkspace — update the last-opened timestamp
  • ensureDefaultWorkspace — create a default workspace if none exist
import { listWorkspaces, ensureDefaultWorkspace } from '@bendyline/docblocks/workspace';

const workspaces = await listWorkspaces();

Host (@bendyline/docblocks/host)

The canonical contract for what the Electron desktop shell exposes to its renderer (fsV2, legacy fs, workspaces, shell, ffmpeg, updater, menu, open-file requests).

  • DocBlocksHostAPI — the contract type (implemented by desktop/main/ipc-*.ts, exposed by desktop/preload/preload.ts)
  • isElectronHost() — feature-detect the desktop shell
  • getDocBlocksHost() — get the host API (throws outside Electron)
  • maybeGetDocBlocksHost() — get the host API or null, for code that degrades gracefully in the browser
import { isElectronHost, maybeGetDocBlocksHost } from '@bendyline/docblocks/host';

const host = maybeGetDocBlocksHost();
if (host) {
  await host.shell.revealInFolder(workspaceId, path);
}

VS Code protocol (@bendyline/docblocks/vscode)

The canonical bidirectional postMessage contract for the VS Code extension host and editor webview. Both sides consume the same discriminated unions and must parse incoming unknown values with parseWebviewToExtensionMessage() or parseExtensionToWebviewMessage() before dispatch.

Conventions

Anything that crosses IPC, postMessage, HTTP, or MCP boundaries belongs in this package — surface packages must not define their own copies of wire types.

Wire types document shape; they do not grant authority. Privileged hosts must parse runtime values as unknown, apply HOST_WIRE_LIMITS, use parseExternalHttpUrl for external navigation, and accept workspace IDs or owner-scoped opaque grants instead of renderer-provided absolute paths.

License

MIT