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

@ydtb/tk-scope-data-workbench

v0.24.0

Published

Saved-view-driven data workbench primitives for tk-scope tools.

Readme

@ydtb/tk-scope-data-workbench

Primitive family for saved-view-driven record exploration surfaces.

The package intentionally starts with contracts and state hooks rather than a monolithic <DataWorkbench /> component. Tools keep domain-specific APIs, row renderers, permissions, and export implementations.

Current exports

Contracts

  • WorkbenchField
  • WorkbenchFieldType
  • WorkbenchSavedView
  • WorkbenchColumnState
  • WorkbenchSortState
  • WorkbenchPaginationState
  • WorkbenchSelectionState
  • FieldManagementCapability

Saved view state

  • useWorkbenchViewState(...)
  • isWorkbenchStateDirty(...)
  • cloneWorkbenchState(...)

Use this to hydrate local working state from an active saved view, compare against a saved snapshot, expose dirty state, save, and reset.

Field registry adapters

  • adaptWorkbenchColumns(...)
  • fieldsToFilterFields(...)
  • fieldsToExportFields(...)
  • dedupeWorkbenchFields(...)
  • persistWorkbenchColumns(...)
  • normalizePersistedColumns(...)
  • defaultIconKeyForFieldType(...)

Use these to map a dataset field registry into column/filter/export surfaces. The column adapter preserves saved visibility/order, appends newly available fields hidden by default, and keeps orphaned saved columns as hidden unavailable fields.

Optional managed context

  • DataWorkbenchProvider
  • useDataWorkbench()
  • useOptionalDataWorkbench()
  • createDataWorkbenchContextValue(...)

Use this when a tool wants shared children (headers, sidebars, tables, drawers) to read the same active view, working state, dirty/save status, fields, pagination, selection, and field-management capability without prop-drilling. The lower-level hooks remain direct exports and can still be used without the provider.

Field management capability

  • FieldManagementCapability
  • canCreateWorkbenchField(...)
  • canEditWorkbenchField(...)
  • canDeleteWorkbenchField(...)
  • canCreateWorkbenchFieldOption(...)
  • disabledFieldManagementCapability()

Use this to describe whether a dataset supports user-managed fields. Contacts enables creation/options; fixed datasets like Signals can use the disabled capability.

Export panel

  • WorkbenchExportPanel
  • countWorkbenchFilterConditions(...)
  • getWorkbenchExportFilterSummary(...)
  • getWorkbenchExportTabs(...)

Use this as the shared TabbedPanel shell for contacts-style exports. Tools own the actual export form, API call, file download, and domain-specific filter visualization; the workbench shell owns canonical Export / Filters tabs, heading chrome, and filter-count summary helpers.

Filter panel

  • WorkbenchFilterPanel
  • formatWorkbenchFilterResultCount(...)

Use this to wrap the shared UI FilterPanel in a workbench-shaped layout with optional narrowing content (for example source selection), empty-fields messaging, and a result-count footer.

Column panel

  • WorkbenchColumnPanel
  • toUiColumnConfig(...)
  • toWorkbenchColumnConfig(...)
  • mergeUiColumnChanges(...)
  • WORKBENCH_COLUMN_ICON_MAP

Use this to render the shared column visibility/order/search UI from workbench column configs while preserving workbench-only metadata such as iconKey, unavailable, and dataset source.

Saved views sidebar section

  • WorkbenchSavedViewsSidebarSection
  • getSavedViewsSidebarSectionState(...)

Use this inside a tool-owned sidebar to render saved-view navigation without giving the package ownership of the entire tool sidebar. It supports active view highlighting, loading/empty/count states, optional create action, optional badges, and optional pin/favorite preference controls.

Header controls

  • WorkbenchSaveResetControls
  • getWorkbenchSaveResetDisabledState(...)

Use these inside a tool's ToolPageHeader actions to keep dirty view Save/Reset behavior consistent across workbenches.

Pagination

  • useWorkbenchOffsetPagination(...)
  • useWorkbenchCursorPagination(...)
  • offset helpers: normalizeOffsetPage, offsetForPage, totalPagesFor
  • cursor helpers: createInitialCursorPagerState, advanceCursorPager, retreatCursorPager

Default behavior for consumers:

  • pagination is session UI state, not saved-view identity
  • reset pagination when view/filter/sort/source changes
  • offset mode uses page, pageSize, and optional total
  • cursor mode tracks current cursor, next cursor, page index, and previous-page history

Selection

  • useWorkbenchSelection(...)
  • toggleSelectionId(...)
  • clearSelection(...)

Default behavior for consumers:

  • selection is page-local
  • clear selection on page/view changes
  • cross-page selection should be an explicit future capability, not default behavior

Umbrella docs

  • docs/data-workbench.md
  • docs/data-workbench-mission-control.md
  • plans/data-workbench-roadmap.md
  • plans/data-workbench-slices.md

Usage examples

Fixed/source-derived dataset (Case Scouting Signals)

const workbenchView = useWorkbenchViewState({
  viewKey: resolvedViewId,
  savedView: activeView,
  getStateFromSavedView: savedConfigFromView,
  saveState: saveWorkbenchState,
  serializeState: comparableViewConfig,
})

const pagination = useWorkbenchOffsetPagination({
  pageSize: 50,
  resetKeys: [filters, selectedSources, sorts, resolvedViewId],
})

const selection = useWorkbenchSelection({
  resetKeys: [resolvedViewId, pagination.page],
})

<WorkbenchSaveResetControls
  isDirty={workbenchView.isDirty}
  isSaving={workbenchView.isSaving}
  onSave={() => void workbenchView.save()}
  onReset={workbenchView.reset}
/>

Signals keeps source registry construction, row rendering, bulk actions, and export execution in the Case Scouting tool.

Editable-field dataset (Contacts)

const fieldManagement: FieldManagementCapability<CreateFieldInput> = {
  enabled: true,
  canCreate: true,
  createField,
}

if (canCreateWorkbenchField(fieldManagement)) {
  await fieldManagement.createField(input)
}

<WorkbenchColumnPanel
  columns={toWorkbenchColumns(columns)}
  onColumnsChange={(updated) => onColumnsChange(mergeColumns(updated, columns))}
  footer={<CreateFieldButton />}
/>

Contacts keeps custom-field creation forms, option colors, inline edits, and permissions in the Contacts tool.

Optional provider

const value = createDataWorkbenchContextValue({
  activeView,
  activeViewId,
  fields,
  viewState,
  pagination,
  selection,
  fieldManagement,
})

return <DataWorkbenchProvider value={value}>{children}</DataWorkbenchProvider>

The provider is optional. Direct hooks/adapters remain first-class.