@contractspec/lib.contracts-runtime-client-react 3.7.5 → 3.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,156 +1,63 @@
1
1
  # @contractspec/lib.contracts-runtime-client-react
2
2
 
3
- React runtime adapters for rendering ContractSpec forms and feature presentations.
3
+ **React runtime adapters for ContractSpec contracts.**
4
4
 
5
- Website: https://contractspec.io/
5
+ ## What It Provides
6
6
 
7
- ## Why this package exists
8
-
9
- This package is the React client runtime layer extracted from `@contractspec/lib.contracts`.
10
-
11
- It keeps rendering concerns separate from core contract definitions, while still preserving contract-first behavior:
12
-
13
- - render presentation specs through a transform engine
14
- - render form specs through pluggable UI driver slots
15
- - keep UI toolkit choice external (shadcn, RN reusable components, custom)
16
-
17
- ## Package boundary (important)
18
-
19
- Use this package for:
20
-
21
- - Rendering `PresentationSpec` targets in React workflows.
22
- - Rendering `FormSpec` with `react-hook-form` and Zod resolver integration.
23
- - Bridging contract fields to your design-system components via `DriverSlots`.
24
-
25
- Do not use this package for:
26
-
27
- - Defining contracts (use `@contractspec/lib.contracts-spec`).
28
- - Owning your design-system components themselves.
7
+ - **Layer**: lib.
8
+ - **Consumers**: design-system, presentation-runtime-react, bundles.
9
+ - Related ContractSpec packages include `@contractspec/lib.contracts-spec`, `@contractspec/lib.schema`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
10
+ - Related ContractSpec packages include `@contractspec/lib.contracts-spec`, `@contractspec/lib.schema`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
29
11
 
30
12
  ## Installation
31
13
 
32
- ```bash
33
- npm install @contractspec/lib.contracts-runtime-client-react @contractspec/lib.contracts-spec
34
- # or
35
- bun add @contractspec/lib.contracts-runtime-client-react @contractspec/lib.contracts-spec
36
- ```
37
-
38
- Required peer dependencies:
39
-
40
- - `react`
41
- - `react-dom`
42
- - `react-hook-form`
43
- - `@hookform/resolvers`
44
- - `@blocknote/core`
45
-
46
- ## Export map
47
-
48
- - Presentation helpers:
49
- - `createEngineWithDefaults`
50
- - `renderFeaturePresentation`
51
- - `createFeatureModule`
52
- - `registerFeature`
53
- - Form helpers:
54
- - `createFormRenderer`
55
- - `DriverSlots` (type)
56
- - Driver wrappers:
57
- - `shadcnDriver`
58
- - `rnReusablesDriver`
59
-
60
- ## Quick start
61
-
62
- ### Presentation rendering
63
-
64
- ```ts
65
- import {
66
- createEngineWithDefaults,
67
- renderFeaturePresentation,
68
- } from "@contractspec/lib.contracts-runtime-client-react";
69
- import type { PresentationSpec } from "@contractspec/lib.contracts-spec/presentations";
70
-
71
- declare const presentation: PresentationSpec;
72
-
73
- const engine = createEngineWithDefaults();
74
-
75
- const markdownOutput = await renderFeaturePresentation(
76
- engine,
77
- "markdown",
78
- presentation
79
- );
80
-
81
- console.log(markdownOutput);
82
- ```
83
-
84
- ### Form rendering with driver slots
85
-
86
- ```tsx
87
- import {
88
- createFormRenderer,
89
- shadcnDriver,
90
- type DriverSlots,
91
- } from "@contractspec/lib.contracts-runtime-client-react";
92
- import type { FormSpec } from "@contractspec/lib.contracts-spec/forms";
93
-
94
- declare const slots: DriverSlots;
95
- declare const formSpec: FormSpec;
96
-
97
- const renderer = createFormRenderer({
98
- driver: shadcnDriver(slots),
99
- onSubmitOverride: async (values, actionKey) => {
100
- console.log("submit", actionKey, values);
101
- },
102
- });
103
-
104
- export function ContractForm() {
105
- return renderer.render(formSpec);
106
- }
107
- ```
108
-
109
- ## Driver model (key concept)
110
-
111
- `createFormRenderer` is UI-library agnostic.
112
-
113
- You provide a `DriverSlots` object (Field, Input, Select, Checkbox, RadioGroup, Switch, Button, etc.), and the runtime maps form contract field kinds (`text`, `textarea`, `select`, `group`, `array`, ...) to your components.
114
-
115
- This allows:
14
+ `npm install @contractspec/lib.contracts-runtime-client-react`
116
15
 
117
- - shared form contract logic
118
- - custom visual identity per app
119
- - lower coupling between schema contracts and specific UI component libraries
16
+ or
120
17
 
121
- ## Runtime behavior details
18
+ `bun add @contractspec/lib.contracts-runtime-client-react`
122
19
 
123
- - Entry point is client-oriented (`"use client"`).
124
- - Form renderer integrates with `react-hook-form` + Zod resolver.
125
- - Supports conditional visibility/enablement and relation predicates from form specs.
126
- - Supports static and resolver-based options for select/radio fields.
127
- - Supports array fields and nested/grouped field rendering.
20
+ ## Usage
128
21
 
129
- ## AI assistant guidance
22
+ Import the root entrypoint from `@contractspec/lib.contracts-runtime-client-react`, or choose a documented subpath when you only need one part of the package surface.
130
23
 
131
- When generating code:
24
+ ## Architecture
132
25
 
133
- - Use this package when task asks to render contract-defined forms or presentations in React.
134
- - Keep `DriverSlots` in app code so generated components stay design-system aligned.
135
- - For non-React targets, do not use this package; use transport/runtime packages that match the target.
26
+ - `src/drivers` is part of the package's public or composition surface.
27
+ - `src/feature-render.ts` is part of the package's public or composition surface.
28
+ - `src/form-render.impl.tsx` is part of the package's public or composition surface.
29
+ - `src/form-render.ts` is part of the package's public or composition surface.
30
+ - `src/index.ts` is the root public barrel and package entrypoint.
136
31
 
137
- When debugging:
32
+ ## Public Entry Points
138
33
 
139
- - If form fields do not render, verify driver slot coverage for the field kind.
140
- - If resolver options stay empty, verify `resolverKey` and dependency paths in form contract.
34
+ - Export `.` resolves through `./src/index.ts`.
35
+ - Export `./drivers/rn-reusables` resolves through `./src/drivers/rn-reusables.ts`.
36
+ - Export `./drivers/shadcn` resolves through `./src/drivers/shadcn.ts`.
37
+ - Export `./feature-render` resolves through `./src/feature-render.ts`.
38
+ - Export `./form-render` resolves through `./src/form-render.ts`.
39
+ - Export `./form-render.impl` resolves through `./src/form-render.impl.tsx`.
141
40
 
142
- ## Surface-runtime slot integration
41
+ ## Local Commands
143
42
 
144
- When using `@contractspec/lib.surface-runtime`, feature and form renderers can fill slots (e.g. `entity-section`, `form`, `entity-field`):
43
+ - `bun run dev` contractspec-bun-build dev
44
+ - `bun run build` — bun run prebuild && bun run build:bundle && bun run build:types
45
+ - `bun run lint` — bun run lint:fix
46
+ - `bun run lint:check` — biome check .
47
+ - `bun run lint:fix` — biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .
48
+ - `bun run typecheck` — tsc --noEmit
49
+ - `bun run publish:pkg` — bun publish --tolerate-republish --ignore-scripts --verbose
50
+ - `bun run publish:pkg:canary` — bun publish:pkg --tag canary
51
+ - `bun run clean` — rm -rf dist
52
+ - `bun run build:bundle` — contractspec-bun-build transpile
53
+ - `bun run build:types` — contractspec-bun-build types
54
+ - `bun run prebuild` — contractspec-bun-build prebuild
145
55
 
146
- 1. **Slot content**: Pass `FeatureRender` output or form components as `slotContent` to `BundleRenderer` for slots that `accepts` include `form` or `entity-section`.
147
- 2. **Field renderer registry**: Register custom field renderers via `@contractspec/lib.surface-runtime/runtime/field-renderer-registry` so entity fields render correctly in surface slots.
148
- 3. **Widget registry**: For `custom-widget` slots, wire your form or feature components through the widget registry.
56
+ ## Recent Updates
149
57
 
150
- Example: a slot with `accepts: ['form', 'entity-section']` can render `createFormRenderer(...).render(formSpec)` or `renderFeaturePresentation` output as its content.
58
+ - Replace eslint+prettier by biomejs to optimize speed.
151
59
 
152
- ## Split migration from deprecated monolith
60
+ ## Notes
153
61
 
154
- - `@contractspec/lib.contracts/client/react/feature-render` -> `@contractspec/lib.contracts-runtime-client-react/feature-render`
155
- - `@contractspec/lib.contracts/client/react/form-render` -> `@contractspec/lib.contracts-runtime-client-react/form-render`
156
- - `@contractspec/lib.contracts/client/react/drivers/*` -> `@contractspec/lib.contracts-runtime-client-react/drivers/*`
62
+ - Driver interface must stay compatible with both shadcn and RN Reusables.
63
+ - Form rendering pipeline is a critical path; test thoroughly before changing.
@@ -1,10 +1,10 @@
1
1
  // src/feature-render.ts
2
- import React from "react";
3
2
  import {
4
3
  createDefaultTransformEngine,
5
4
  registerBasicValidation,
6
5
  registerDefaultReactRenderer
7
6
  } from "@contractspec/lib.contracts-spec/presentations/transform-engine";
7
+ import React from "react";
8
8
  function createEngineWithDefaults() {
9
9
  return registerBasicValidation(registerDefaultReactRenderer(createDefaultTransformEngine()));
10
10
  }
@@ -1,15 +1,15 @@
1
1
  // src/form-render.impl.tsx
2
+ import {
3
+ buildZodWithRelations,
4
+ evalPredicate
5
+ } from "@contractspec/lib.contracts-spec/forms";
6
+ import { zodResolver } from "@hookform/resolvers/zod";
2
7
  import React, { useEffect, useMemo, useState } from "react";
3
8
  import {
4
9
  Controller,
5
10
  useFieldArray,
6
11
  useForm
7
12
  } from "react-hook-form";
8
- import { zodResolver } from "@hookform/resolvers/zod";
9
- import {
10
- buildZodWithRelations,
11
- evalPredicate
12
- } from "@contractspec/lib.contracts-spec/forms";
13
13
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
14
14
  "use client";
15
15
  function toOptionsArray(src) {
@@ -1,15 +1,15 @@
1
1
  // src/form-render.impl.tsx
2
+ import {
3
+ buildZodWithRelations,
4
+ evalPredicate
5
+ } from "@contractspec/lib.contracts-spec/forms";
6
+ import { zodResolver } from "@hookform/resolvers/zod";
2
7
  import React, { useEffect, useMemo, useState } from "react";
3
8
  import {
4
9
  Controller,
5
10
  useFieldArray,
6
11
  useForm
7
12
  } from "react-hook-form";
8
- import { zodResolver } from "@hookform/resolvers/zod";
9
- import {
10
- buildZodWithRelations,
11
- evalPredicate
12
- } from "@contractspec/lib.contracts-spec/forms";
13
13
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
14
14
  "use client";
15
15
  function toOptionsArray(src) {
@@ -9,12 +9,12 @@ function shadcnDriver(slots) {
9
9
  }
10
10
 
11
11
  // src/feature-render.ts
12
- import React from "react";
13
12
  import {
14
13
  createDefaultTransformEngine,
15
14
  registerBasicValidation,
16
15
  registerDefaultReactRenderer
17
16
  } from "@contractspec/lib.contracts-spec/presentations/transform-engine";
17
+ import React from "react";
18
18
  function createEngineWithDefaults() {
19
19
  return registerBasicValidation(registerDefaultReactRenderer(createDefaultTransformEngine()));
20
20
  }
@@ -56,17 +56,17 @@ function registerFeature(registry, feature) {
56
56
  }
57
57
 
58
58
  // src/form-render.impl.tsx
59
+ import {
60
+ buildZodWithRelations,
61
+ evalPredicate
62
+ } from "@contractspec/lib.contracts-spec/forms";
63
+ import { zodResolver } from "@hookform/resolvers/zod";
59
64
  import React2, { useEffect, useMemo, useState } from "react";
60
65
  import {
61
66
  Controller,
62
67
  useFieldArray,
63
68
  useForm
64
69
  } from "react-hook-form";
65
- import { zodResolver } from "@hookform/resolvers/zod";
66
- import {
67
- buildZodWithRelations,
68
- evalPredicate
69
- } from "@contractspec/lib.contracts-spec/forms";
70
70
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
71
71
  "use client";
72
72
  function toOptionsArray(src) {
@@ -1,8 +1,8 @@
1
- import React from 'react';
1
+ import type { BlockConfig } from '@blocknote/core';
2
+ import { type FeatureModuleSpec, FeatureRegistry } from '@contractspec/lib.contracts-spec/features';
2
3
  import type { PresentationSpec, PresentationTarget } from '@contractspec/lib.contracts-spec/presentations';
3
4
  import { type ComponentMap, TransformEngine } from '@contractspec/lib.contracts-spec/presentations/transform-engine';
4
- import { type FeatureModuleSpec, FeatureRegistry } from '@contractspec/lib.contracts-spec/features';
5
- import type { BlockConfig } from '@blocknote/core';
5
+ import React from 'react';
6
6
  export declare function createEngineWithDefaults(): TransformEngine;
7
7
  export declare function renderFeaturePresentation(engine: TransformEngine, target: PresentationTarget, desc: PresentationSpec, options?: {
8
8
  componentMap?: ComponentMap;
@@ -1,11 +1,11 @@
1
1
  // @bun
2
2
  // src/feature-render.ts
3
- import React from "react";
4
3
  import {
5
4
  createDefaultTransformEngine,
6
5
  registerBasicValidation,
7
6
  registerDefaultReactRenderer
8
7
  } from "@contractspec/lib.contracts-spec/presentations/transform-engine";
8
+ import React from "react";
9
9
  function createEngineWithDefaults() {
10
10
  return registerBasicValidation(registerDefaultReactRenderer(createDefaultTransformEngine()));
11
11
  }
@@ -1,6 +1,6 @@
1
- import React from 'react';
2
1
  import type { FormOption, FormSpec, FormValuesFor } from '@contractspec/lib.contracts-spec/forms';
3
2
  import type { AnySchemaModel } from '@contractspec/lib.schema';
3
+ import React from 'react';
4
4
  export interface DriverSlots {
5
5
  Field: React.ComponentType<React.PropsWithChildren<{
6
6
  'data-invalid'?: boolean;
@@ -1,16 +1,16 @@
1
1
  // @bun
2
2
  // src/form-render.impl.tsx
3
+ import {
4
+ buildZodWithRelations,
5
+ evalPredicate
6
+ } from "@contractspec/lib.contracts-spec/forms";
7
+ import { zodResolver } from "@hookform/resolvers/zod";
3
8
  import React, { useEffect, useMemo, useState } from "react";
4
9
  import {
5
10
  Controller,
6
11
  useFieldArray,
7
12
  useForm
8
13
  } from "react-hook-form";
9
- import { zodResolver } from "@hookform/resolvers/zod";
10
- import {
11
- buildZodWithRelations,
12
- evalPredicate
13
- } from "@contractspec/lib.contracts-spec/forms";
14
14
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
15
15
  "use client";
16
16
  function toOptionsArray(src) {
@@ -1,16 +1,16 @@
1
1
  // @bun
2
2
  // src/form-render.impl.tsx
3
+ import {
4
+ buildZodWithRelations,
5
+ evalPredicate
6
+ } from "@contractspec/lib.contracts-spec/forms";
7
+ import { zodResolver } from "@hookform/resolvers/zod";
3
8
  import React, { useEffect, useMemo, useState } from "react";
4
9
  import {
5
10
  Controller,
6
11
  useFieldArray,
7
12
  useForm
8
13
  } from "react-hook-form";
9
- import { zodResolver } from "@hookform/resolvers/zod";
10
- import {
11
- buildZodWithRelations,
12
- evalPredicate
13
- } from "@contractspec/lib.contracts-spec/forms";
14
14
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
15
15
  "use client";
16
16
  function toOptionsArray(src) {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
+ export * from './drivers/rn-reusables';
2
+ export * from './drivers/shadcn';
1
3
  export * from './feature-render';
2
4
  export * from './form-render';
3
- export * from './drivers/shadcn';
4
- export * from './drivers/rn-reusables';
package/dist/index.js CHANGED
@@ -10,12 +10,12 @@ function shadcnDriver(slots) {
10
10
  }
11
11
 
12
12
  // src/feature-render.ts
13
- import React from "react";
14
13
  import {
15
14
  createDefaultTransformEngine,
16
15
  registerBasicValidation,
17
16
  registerDefaultReactRenderer
18
17
  } from "@contractspec/lib.contracts-spec/presentations/transform-engine";
18
+ import React from "react";
19
19
  function createEngineWithDefaults() {
20
20
  return registerBasicValidation(registerDefaultReactRenderer(createDefaultTransformEngine()));
21
21
  }
@@ -57,17 +57,17 @@ function registerFeature(registry, feature) {
57
57
  }
58
58
 
59
59
  // src/form-render.impl.tsx
60
+ import {
61
+ buildZodWithRelations,
62
+ evalPredicate
63
+ } from "@contractspec/lib.contracts-spec/forms";
64
+ import { zodResolver } from "@hookform/resolvers/zod";
60
65
  import React2, { useEffect, useMemo, useState } from "react";
61
66
  import {
62
67
  Controller,
63
68
  useFieldArray,
64
69
  useForm
65
70
  } from "react-hook-form";
66
- import { zodResolver } from "@hookform/resolvers/zod";
67
- import {
68
- buildZodWithRelations,
69
- evalPredicate
70
- } from "@contractspec/lib.contracts-spec/forms";
71
71
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
72
72
  "use client";
73
73
  function toOptionsArray(src) {
@@ -1,10 +1,10 @@
1
1
  // src/feature-render.ts
2
- import React from "react";
3
2
  import {
4
3
  createDefaultTransformEngine,
5
4
  registerBasicValidation,
6
5
  registerDefaultReactRenderer
7
6
  } from "@contractspec/lib.contracts-spec/presentations/transform-engine";
7
+ import React from "react";
8
8
  function createEngineWithDefaults() {
9
9
  return registerBasicValidation(registerDefaultReactRenderer(createDefaultTransformEngine()));
10
10
  }
@@ -1,15 +1,15 @@
1
1
  // src/form-render.impl.tsx
2
+ import {
3
+ buildZodWithRelations,
4
+ evalPredicate
5
+ } from "@contractspec/lib.contracts-spec/forms";
6
+ import { zodResolver } from "@hookform/resolvers/zod";
2
7
  import React, { useEffect, useMemo, useState } from "react";
3
8
  import {
4
9
  Controller,
5
10
  useFieldArray,
6
11
  useForm
7
12
  } from "react-hook-form";
8
- import { zodResolver } from "@hookform/resolvers/zod";
9
- import {
10
- buildZodWithRelations,
11
- evalPredicate
12
- } from "@contractspec/lib.contracts-spec/forms";
13
13
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
14
14
  "use client";
15
15
  function toOptionsArray(src) {
@@ -1,15 +1,15 @@
1
1
  // src/form-render.impl.tsx
2
+ import {
3
+ buildZodWithRelations,
4
+ evalPredicate
5
+ } from "@contractspec/lib.contracts-spec/forms";
6
+ import { zodResolver } from "@hookform/resolvers/zod";
2
7
  import React, { useEffect, useMemo, useState } from "react";
3
8
  import {
4
9
  Controller,
5
10
  useFieldArray,
6
11
  useForm
7
12
  } from "react-hook-form";
8
- import { zodResolver } from "@hookform/resolvers/zod";
9
- import {
10
- buildZodWithRelations,
11
- evalPredicate
12
- } from "@contractspec/lib.contracts-spec/forms";
13
13
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
14
14
  "use client";
15
15
  function toOptionsArray(src) {
@@ -9,12 +9,12 @@ function shadcnDriver(slots) {
9
9
  }
10
10
 
11
11
  // src/feature-render.ts
12
- import React from "react";
13
12
  import {
14
13
  createDefaultTransformEngine,
15
14
  registerBasicValidation,
16
15
  registerDefaultReactRenderer
17
16
  } from "@contractspec/lib.contracts-spec/presentations/transform-engine";
17
+ import React from "react";
18
18
  function createEngineWithDefaults() {
19
19
  return registerBasicValidation(registerDefaultReactRenderer(createDefaultTransformEngine()));
20
20
  }
@@ -56,17 +56,17 @@ function registerFeature(registry, feature) {
56
56
  }
57
57
 
58
58
  // src/form-render.impl.tsx
59
+ import {
60
+ buildZodWithRelations,
61
+ evalPredicate
62
+ } from "@contractspec/lib.contracts-spec/forms";
63
+ import { zodResolver } from "@hookform/resolvers/zod";
59
64
  import React2, { useEffect, useMemo, useState } from "react";
60
65
  import {
61
66
  Controller,
62
67
  useFieldArray,
63
68
  useForm
64
69
  } from "react-hook-form";
65
- import { zodResolver } from "@hookform/resolvers/zod";
66
- import {
67
- buildZodWithRelations,
68
- evalPredicate
69
- } from "@contractspec/lib.contracts-spec/forms";
70
70
  import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
71
71
  "use client";
72
72
  function toOptionsArray(src) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/lib.contracts-runtime-client-react",
3
- "version": "3.7.5",
3
+ "version": "3.7.7",
4
4
  "description": "React runtime adapters for ContractSpec contracts",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -9,8 +9,8 @@
9
9
  "publish:pkg:canary": "bun publish:pkg --tag canary",
10
10
  "clean": "rm -rf dist",
11
11
  "lint": "bun run lint:fix",
12
- "lint:fix": "eslint src --fix",
13
- "lint:check": "eslint src",
12
+ "lint:fix": "biome check --write --unsafe --only=nursery/useSortedClasses . && biome check --write .",
13
+ "lint:check": "biome check .",
14
14
  "build": "bun run prebuild && bun run build:bundle && bun run build:types",
15
15
  "build:bundle": "contractspec-bun-build transpile",
16
16
  "build:types": "contractspec-bun-build types",
@@ -31,13 +31,13 @@
31
31
  "react-hook-form": "^7.70.0"
32
32
  },
33
33
  "dependencies": {
34
- "@contractspec/lib.contracts-spec": "3.7.5",
35
- "@contractspec/lib.schema": "3.7.5"
34
+ "@contractspec/lib.contracts-spec": "4.0.0",
35
+ "@contractspec/lib.schema": "3.7.6"
36
36
  },
37
37
  "devDependencies": {
38
- "@contractspec/tool.typescript": "3.7.5",
38
+ "@contractspec/tool.typescript": "3.7.6",
39
39
  "typescript": "^5.9.3",
40
- "@contractspec/tool.bun": "3.7.5"
40
+ "@contractspec/tool.bun": "3.7.6"
41
41
  },
42
42
  "files": [
43
43
  "dist",