Bump all @json-render/* packages to 0.19.0, add changelog entry for
custom directives API and @json-render/directives package, and update
the web app changelog page.
* feat: add custom directives API and @json-render/directives package
Add a `defineDirective` API that lets users register custom `$`-prefixed
dynamic values with schemas, resolvers, and prompt instructions — extending
the spec language without forking core.
* fixes
* perf(core): optimize findDirective to iterate registry instead of object keys
Flip the loop from O(object-keys) to O(registry-size) by iterating
the directive registry and checking `key in value` rather than scanning
all object keys with Object.keys() and startsWith("$").
* fix(core): reject directive names that conflict with built-in keys
defineDirective now throws at registration time if the name collides
with a built-in prop expression key ($state, $cond, etc.), making the
precedence contract explicit rather than relying on check ordering in
resolvePropValue.
* fix(directives): handle future dates in $format and warn on $math NaN coercion
$format relative dates now support future timestamps ("2h from now")
and return "just now" for zero diff. $math emits a console.warn in
dev mode when a non-numeric value is silently coerced to 0.
* fix(directives): remove process.env check that breaks DTS build
The directives package doesn't include @types/node, so referencing
process.env fails during tsup's DTS generation. The console.warn is
unconditional now — it only fires on actual misuse (non-numeric input)
so the cost is negligible.
* feat(directives): rename prompt to description, auto-describe schemas in prompt, add docs
- Rename `prompt` to `description` on DirectiveDefinition — a short
behavioral label rather than the full AI prompt blob
- Auto-generate directive schema signatures in the system prompt using
formatZodType, so the AI always sees every field, type, and optionality
- Add docs: guide page, API reference page, nav/title entries, docs-chat
* feat(directives): add standardDirectives export and composition hint
Export a pre-assembled standardDirectives array (all 7 non-factory
directives) for convenience. Add a composition hint to the generated
AI prompt so agents know directives can nest inside each other.
* docs: add directives skill, README entry, and docs-chat listing
- Add skills/directives/SKILL.md with full directive API reference
- Add @json-render/directives row to root README packages table
- Add "directives" to the Available skills list in docs-chat prompt
* perf(core): skip Zod parse in directive hot path
Resolvers are already defensive (coercion, fallbacks, switch defaults),
so runtime validation on every render adds overhead without safety.
The schema remains used for prompt generation and TypeScript inference.
- `@json-render/react` barrel-imports React contexts that call `createContext`, which crashes in Next.js App Router API routes (RSC runtime strips `createContext`)
- Updated all docs, READMEs, examples, and skills to import `schema` from `@json-render/react/schema` instead of `@json-render/react`
- For combined imports, split into separate `schema` (subpath) and client API (main entry) lines
Fixes#123
* external store adapter for state management
Introduces a `StateStore` interface that lets users plug in their own state management (Redux, Zustand, XState, etc.) instead of being locked into the internal `useState`-based store.
- Added `StateStore` interface and `createStateStore()` factory to `@json-render/core`
- `StateProvider`, `JSONUIProvider`, and `createRenderer` now accept an optional `store` prop for controlled mode
- When `store` is provided, it becomes the single source of truth (`initialState`/`onStateChange` are ignored)
- When `store` is omitted, everything works exactly as before (fully backward compatible)
- Applied across all platform packages: react, react-native, react-pdf
* improvements
* update docs
* improvements
* fixes
* fix CI
* add store adapters
* fixes
* fixes
* fixes
* fixes
* e2e tests
* improvements
* fixes
* fixes
* fixes
* fixes
* update lockfile for widened react peer deps
* fix dashboard build
When form inputs lack `$bindState` bindings (like in the homepage contact form simulation), `useFieldValidation` was called with `bindings?.value ?? ""` as the path. All three inputs registered at the same `""` path but with different validation configs. Each `registerField` call overwrote the previous one, triggering a re-render where the other inputs would see a mismatched config and re-register -- creating an infinite loop.
- Fix infinite re-render loop caused by multiple unbound form inputs (Input, Textarea, Select) all registering field validation at path `""` with different `checks` configs, causing them to overwrite each other endlessly
- Stabilize context values in ActionProvider, ValidationProvider, and useUIStream by using refs for state/callbacks, preventing unnecessary re-render cascades on every state update
* add rate limits
* fix lint
* better
generate prompt
update examples
* fixes
* fixes
* new api
* update docs
* fixes
* fixes
* generated prompt
* Add tests for catalog validation and prompt generation
- Test generateSystemPrompt with components, actions, custom rules
- Test new defineCatalog API from schema system
- Test catalog.prompt() method with custom rules
- Test catalog.validate() for valid and invalid specs
- Test catalog.zodSchema() for custom validation
- Test catalog.jsonSchema() for structured outputs
- Add tests for nested specs with children
- Add tests for rejecting invalid component types
* Fix lint: pass children as nested elements in renderer
Change from children={...} prop to nested children pattern
to satisfy react/no-children-prop rule.
* Fix lint errors in dashboard and web apps
- Disable react/prop-types in both eslint configs (TypeScript handles this)
- Allow styled-jsx 'jsx' property in dashboard
- Add DATABASE_URL to turbo env allowlist
- Remove unused drizzle-orm imports (and, sql)
- Suppress unused variable warnings where intentional
* Add server entry point for @json-render/remotion
The main package entry includes React components that require
client-side context (React.createContext). This causes build
failures when importing in server-side API routes.
Added `@json-render/remotion/server` entry point that exports
only schema and catalog definitions without React dependencies:
- schema, RemotionSchema, RemotionSpec
- standardComponentDefinitions, standardTransitionDefinitions
- standardEffectDefinitions
- Type exports for catalogs
Updated remotion example to import from /server in catalog.ts
* Make dashboard database connection lazy-initialized
The database connection threw an error at module load time if
DATABASE_URL was not set, causing builds to fail in CI where
the database is not available.
Changed to lazy initialization using a Proxy so the error only
occurs when the database is actually used at runtime, not at
build time.
* Fix previousSpec property name and lazy rate limiting
- Fix property name mismatch: playground now passes previousSpec
instead of previousTree to match what useUIStream hook expects
- Make rate limiting lazy-initialized to avoid runtime errors when
Redis env vars (KV_REST_API_URL, KV_REST_API_TOKEN) are not set
- Rate limiting gracefully becomes a no-op when Redis is unavailable