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

@object-ui/core

v17.6.0

Published

Core logic, types, and validation for Object UI. Zero React dependencies.

Readme

@object-ui/core

Core logic, types, and validation for Object UI. Zero React dependencies.

Features

  • 🎯 Type Definitions - Re-exported runtime types; the component schema vocabulary itself is @object-ui/types
  • 🔍 Component Registry - Framework-agnostic component registration system
  • 📊 Data Scope - Data scope management and expression evaluation
  • Validation - Zod-based schema validation
  • 🚀 Zero React - Can run in Node.js or any JavaScript environment

Installation

npm install @object-ui/core

Usage

Type Definitions

The component schema vocabulary lives in @object-ui/types. Core depends on that package and does not re-export it, so import the types from there. The page node type is PageNodeSchema — the SDUI node, as distinct from the authored page document.

import type {
  PageNodeSchema,
  FormSchema,
  InputSchema,
  BaseSchema
} from '@object-ui/types'

const mySchema: PageNodeSchema = {
  type: 'page',
  title: 'My Page',
  body: []
}

Component Registry

import { ComponentRegistry } from '@object-ui/core'

ComponentRegistry.register('button', buttonMetadata)
const metadata = ComponentRegistry.get('button')

ComponentRegistry is a process-level singleton exported by @object-ui/core; SchemaRenderer resolves every type against it, so a component registered here is renderable from schema anywhere in the app.

Data Scope

DataScopeManager owns the named scopes a component tree reads from, and evaluateExpression evaluates a ${...} expression against a context. They are separate exports: a scope holds data, it does not evaluate.

import { DataScopeManager, evaluateExpression } from '@object-ui/core'

const manager = new DataScopeManager()
manager.registerScope('user', { data: { name: 'John', role: 'admin' } })

const userName = manager.getScope('user')?.data.name // 'John'
const isAdmin = evaluateExpression('${user.role === "admin"}', {
  user: { name: 'John', role: 'admin' },
}) // true

Server Action Dispatch (createServerActionHandler)

ActionSchema.body (L1 expression / L2 sandboxed JS) executes server-sidePOST /api/v1/actions/{object}/{action} → the runtime sandbox. The client dispatches; it never interprets a body. Build the dispatch handler with the factory and register it — core stays opinion-free about auth, origin and object scope, which are injected:

import { createServerActionHandler } from '@object-ui/core'

const script = createServerActionHandler({
  fetch: myAuthenticatedFetch,          // your auth wrapper (Bearer/cookies/...)
  baseUrl: 'https://api.example.com',   // '' or omitted = same-origin
  resolveObject: () => currentObject,   // fallback when the action has no objectName
  onRefresh: () => refetchData(),       // called per the action's refreshAfter
})

// Registered handlers beat the built-in executors:
runner.registerHandler('script', script)
// (React hosts: <ActionProvider handlers={{ script }} ... />)

The factory owns the protocol so consumers cannot drift on it: name-based action identity (ADR-0110), the record-id resolution dance (_rowRecord, recordIdField, selection fallback, aggregate _selectedIds), a re-entrancy guard, and the /actions response-envelope rule (interpretActionResponse / readActionPayload, also exported).

System Views (defineSystemView)

Schemas authored in source code are part of the product contract and must not be mutated at runtime. Wrap them with defineSystemView() to deep-freeze the graph and tag it as a System View.

import { defineSystemView, cloneAsOverride, isSystemView } from '@object-ui/core'

export const userListView = defineSystemView({
  type: 'list',
  data: { object: 'User' },
  columns: [{ name: 'email' }],
})

userListView.columns.push({ name: 'name' }) // ❌ TypeError (strict mode)
isSystemView(userListView)                   // ✅ true

// To produce a Tenant- or User-level override, derive a mutable copy:
const draft = cloneAsOverride(userListView)
draft.columns.push({ name: 'name' })         // ✅ allowed
isSystemView(draft)                          // false — clone is no longer System

View tiers (recommended layering):

| Tier | Source | Mutable? | API | | ----------- | --------------------- | -------- | --------------------------- | | System View | code (import / as const) | ❌ frozen | defineSystemView() | | Tenant View | backend / DB | ⚠️ admin only | cloneAsOverride() + persist | | User View | localStorage / API | ✅ user-editable | cloneAsOverride() + persist |

Date, RegExp, Map, Set, and class instances passed via props are intentionally not frozen so infrastructure objects keep working.

Philosophy

This package is designed to be framework-agnostic. It contains:

  • ✅ Pure TypeScript types and interfaces
  • ✅ Core logic and utilities
  • ✅ Validation schemas
  • ❌ NO React components
  • ❌ NO UI rendering logic
  • ❌ NO framework dependencies

This allows the core types and logic to be used in:

  • Build tools and CLI utilities
  • Backend validation
  • Code generators
  • Alternative framework adapters (Vue, Svelte, etc.)

API Reference

See full documentation for detailed API reference.

Links

License

MIT — see LICENSE.