@servlyadmin/runtime-react 0.1.8 → 0.1.10

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 ADDED
@@ -0,0 +1,292 @@
1
+ # @servlyadmin/runtime-react
2
+
3
+ React wrapper for Servly runtime renderer. Render Servly components in your React applications with full support for props, slots, and event handling.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @servlyadmin/runtime-react @servlyadmin/runtime-core
9
+ # or
10
+ yarn add @servlyadmin/runtime-react @servlyadmin/runtime-core
11
+ # or
12
+ pnpm add @servlyadmin/runtime-react @servlyadmin/runtime-core
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```tsx
18
+ import { ServlyComponent } from '@servlyadmin/runtime-react';
19
+
20
+ function App() {
21
+ return (
22
+ <ServlyComponent
23
+ id="my-component"
24
+ version="latest"
25
+ props={{ title: 'Hello World' }}
26
+ />
27
+ );
28
+ }
29
+ ```
30
+
31
+ ## Props
32
+
33
+ | Prop | Type | Default | Description |
34
+ |------|------|---------|-------------|
35
+ | `id` | `string` | required | Component ID from the registry |
36
+ | `version` | `string` | `'latest'` | Version specifier |
37
+ | `props` | `object` | `{}` | Props to pass to the component |
38
+ | `slots` | `Record<string, ReactNode>` | - | Slot content |
39
+ | `fallback` | `ReactNode` | - | Loading/error fallback |
40
+ | `onError` | `(error: Error) => void` | - | Error callback |
41
+ | `onLoad` | `() => void` | - | Load complete callback |
42
+ | `className` | `string` | - | Wrapper class name |
43
+ | `style` | `CSSProperties` | - | Wrapper styles |
44
+ | `showSkeleton` | `boolean` | `true` | Show loading skeleton |
45
+ | `cacheStrategy` | `CacheStrategy` | `'memory'` | Cache strategy |
46
+ | `eventHandlers` | `object` | - | Event handlers by element ID |
47
+ | `children` | `ReactNode` | - | Default slot content |
48
+
49
+ ## Usage Examples
50
+
51
+ ### Basic Usage
52
+
53
+ ```tsx
54
+ import { ServlyComponent } from '@servlyadmin/runtime-react';
55
+
56
+ function MyPage() {
57
+ return (
58
+ <ServlyComponent
59
+ id="hero-section"
60
+ props={{
61
+ title: 'Welcome',
62
+ subtitle: 'Get started today',
63
+ }}
64
+ />
65
+ );
66
+ }
67
+ ```
68
+
69
+ ### With Slots
70
+
71
+ ```tsx
72
+ function CardExample() {
73
+ return (
74
+ <ServlyComponent
75
+ id="card-component"
76
+ slots={{
77
+ header: <h2>Card Title</h2>,
78
+ footer: <button>Learn More</button>,
79
+ }}
80
+ >
81
+ {/* Children go to default slot */}
82
+ <p>This is the card content.</p>
83
+ </ServlyComponent>
84
+ );
85
+ }
86
+ ```
87
+
88
+ ### With Event Handlers
89
+
90
+ ```tsx
91
+ function InteractiveExample() {
92
+ const [count, setCount] = useState(0);
93
+
94
+ return (
95
+ <ServlyComponent
96
+ id="counter-component"
97
+ props={{ count }}
98
+ eventHandlers={{
99
+ 'increment-btn': {
100
+ click: () => setCount(c => c + 1),
101
+ },
102
+ 'decrement-btn': {
103
+ click: () => setCount(c => c - 1),
104
+ },
105
+ }}
106
+ />
107
+ );
108
+ }
109
+ ```
110
+
111
+ ### Loading States
112
+
113
+ ```tsx
114
+ function WithLoadingState() {
115
+ return (
116
+ <ServlyComponent
117
+ id="data-component"
118
+ fallback={<div>Loading...</div>}
119
+ onLoad={() => console.log('Component loaded!')}
120
+ onError={(error) => console.error('Failed to load:', error)}
121
+ />
122
+ );
123
+ }
124
+ ```
125
+
126
+ ### Custom Loading Skeleton
127
+
128
+ ```tsx
129
+ function WithCustomSkeleton() {
130
+ return (
131
+ <ServlyComponent
132
+ id="profile-card"
133
+ showSkeleton={false}
134
+ fallback={
135
+ <div className="animate-pulse">
136
+ <div className="h-32 bg-gray-200 rounded" />
137
+ <div className="h-4 bg-gray-200 rounded mt-4 w-3/4" />
138
+ </div>
139
+ }
140
+ />
141
+ );
142
+ }
143
+ ```
144
+
145
+ ### Version Pinning
146
+
147
+ ```tsx
148
+ function VersionedComponent() {
149
+ return (
150
+ <>
151
+ {/* Exact version */}
152
+ <ServlyComponent id="my-component" version="1.2.3" />
153
+
154
+ {/* Version range */}
155
+ <ServlyComponent id="my-component" version="^1.0.0" />
156
+
157
+ {/* Latest */}
158
+ <ServlyComponent id="my-component" version="latest" />
159
+ </>
160
+ );
161
+ }
162
+ ```
163
+
164
+ ### Cache Control
165
+
166
+ ```tsx
167
+ function CacheExample() {
168
+ return (
169
+ <>
170
+ {/* Memory cache (default) */}
171
+ <ServlyComponent id="comp1" cacheStrategy="memory" />
172
+
173
+ {/* Persist to localStorage */}
174
+ <ServlyComponent id="comp2" cacheStrategy="localStorage" />
175
+
176
+ {/* No caching */}
177
+ <ServlyComponent id="comp3" cacheStrategy="none" />
178
+ </>
179
+ );
180
+ }
181
+ ```
182
+
183
+ ### Dynamic Props
184
+
185
+ ```tsx
186
+ function DynamicPropsExample() {
187
+ const [theme, setTheme] = useState('light');
188
+ const [user, setUser] = useState({ name: 'Guest' });
189
+
190
+ return (
191
+ <ServlyComponent
192
+ id="themed-component"
193
+ props={{
194
+ theme,
195
+ userName: user.name,
196
+ timestamp: Date.now(),
197
+ }}
198
+ />
199
+ );
200
+ }
201
+ ```
202
+
203
+ ### Error Boundary Integration
204
+
205
+ ```tsx
206
+ import { ErrorBoundary } from 'react-error-boundary';
207
+
208
+ function SafeComponent() {
209
+ return (
210
+ <ErrorBoundary fallback={<div>Something went wrong</div>}>
211
+ <ServlyComponent
212
+ id="risky-component"
213
+ onError={(error) => {
214
+ // Log to error tracking service
215
+ logError(error);
216
+ }}
217
+ />
218
+ </ErrorBoundary>
219
+ );
220
+ }
221
+ ```
222
+
223
+ ## TypeScript
224
+
225
+ Full TypeScript support:
226
+
227
+ ```tsx
228
+ import { ServlyComponent, type ServlyComponentProps } from '@servlyadmin/runtime-react';
229
+
230
+ interface MyComponentProps {
231
+ title: string;
232
+ count: number;
233
+ }
234
+
235
+ function TypedExample() {
236
+ return (
237
+ <ServlyComponent<MyComponentProps>
238
+ id="typed-component"
239
+ props={{
240
+ title: 'Hello',
241
+ count: 42,
242
+ }}
243
+ />
244
+ );
245
+ }
246
+ ```
247
+
248
+ ## Server-Side Rendering
249
+
250
+ The component handles SSR gracefully by rendering the fallback on the server and hydrating on the client.
251
+
252
+ ```tsx
253
+ // Works with Next.js, Remix, etc.
254
+ function SSRPage() {
255
+ return (
256
+ <ServlyComponent
257
+ id="ssr-component"
258
+ fallback={<div>Loading component...</div>}
259
+ />
260
+ );
261
+ }
262
+ ```
263
+
264
+ ## Performance Tips
265
+
266
+ 1. **Use version pinning** in production to leverage caching
267
+ 2. **Prefetch components** that will be needed soon
268
+ 3. **Use `cacheStrategy="localStorage"`** for components that rarely change
269
+ 4. **Memoize event handlers** to prevent unnecessary re-renders
270
+
271
+ ```tsx
272
+ import { useMemo, useCallback } from 'react';
273
+
274
+ function OptimizedExample() {
275
+ const eventHandlers = useMemo(() => ({
276
+ 'btn': {
277
+ click: () => console.log('clicked'),
278
+ },
279
+ }), []);
280
+
281
+ return (
282
+ <ServlyComponent
283
+ id="optimized"
284
+ eventHandlers={eventHandlers}
285
+ />
286
+ );
287
+ }
288
+ ```
289
+
290
+ ## License
291
+
292
+ MIT
package/dist/index.cjs CHANGED
@@ -163,7 +163,9 @@ function ServlyComponent({
163
163
  setState({
164
164
  loading: false,
165
165
  error: null,
166
- data: result.data
166
+ data: result.data,
167
+ views: result.views,
168
+ registry: result.registry
167
169
  });
168
170
  onLoad?.();
169
171
  } catch (error) {
@@ -172,7 +174,9 @@ function ServlyComponent({
172
174
  setState({
173
175
  loading: false,
174
176
  error: err,
175
- data: null
177
+ data: null,
178
+ views: void 0,
179
+ registry: void 0
176
180
  });
177
181
  onError?.(err);
178
182
  }
@@ -200,7 +204,9 @@ function ServlyComponent({
200
204
  container: containerRef.current,
201
205
  elements: state.data.layout,
202
206
  context,
203
- eventHandlers
207
+ eventHandlers,
208
+ views: state.views,
209
+ componentRegistry: state.registry
204
210
  });
205
211
  setIsRendered(true);
206
212
  return () => {
package/dist/index.js CHANGED
@@ -128,7 +128,9 @@ function ServlyComponent({
128
128
  setState({
129
129
  loading: false,
130
130
  error: null,
131
- data: result.data
131
+ data: result.data,
132
+ views: result.views,
133
+ registry: result.registry
132
134
  });
133
135
  onLoad?.();
134
136
  } catch (error) {
@@ -137,7 +139,9 @@ function ServlyComponent({
137
139
  setState({
138
140
  loading: false,
139
141
  error: err,
140
- data: null
142
+ data: null,
143
+ views: void 0,
144
+ registry: void 0
141
145
  });
142
146
  onError?.(err);
143
147
  }
@@ -165,7 +169,9 @@ function ServlyComponent({
165
169
  container: containerRef.current,
166
170
  elements: state.data.layout,
167
171
  context,
168
- eventHandlers
172
+ eventHandlers,
173
+ views: state.views,
174
+ componentRegistry: state.registry
169
175
  });
170
176
  setIsRendered(true);
171
177
  return () => {
package/package.json CHANGED
@@ -1,16 +1,14 @@
1
1
  {
2
2
  "name": "@servlyadmin/runtime-react",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "React wrapper for Servly runtime renderer",
5
5
  "type": "module",
6
- "main": "./dist/index.cjs",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
9
8
  "exports": {
10
9
  ".": {
11
- "import": "./dist/index.js",
12
- "require": "./dist/index.cjs",
13
- "types": "./dist/index.d.ts"
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js"
14
12
  }
15
13
  },
16
14
  "files": [
@@ -18,6 +16,7 @@
18
16
  ],
19
17
  "sideEffects": false,
20
18
  "scripts": {
19
+ "build:pkg": "tsup src/index.ts --format esm,cjs --clean --external react",
21
20
  "build": "tsup src/index.ts --format esm,cjs --dts --clean --external react",
22
21
  "dev": "tsup src/index.ts --format esm,cjs --dts --watch --external react"
23
22
  },
@@ -34,7 +33,7 @@
34
33
  "react-dom": ">=17.0.0"
35
34
  },
36
35
  "dependencies": {
37
- "@servlyadmin/runtime-core": "^0.1.8"
36
+ "@servlyadmin/runtime-core": "^0.1.10"
38
37
  },
39
38
  "devDependencies": {
40
39
  "@types/react": "^18.2.0",
@@ -42,7 +41,6 @@
42
41
  "react": "^18.2.0",
43
42
  "react-dom": "^18.2.0",
44
43
  "tsup": "^8.0.0",
45
- "typescript": "^5.3.0",
46
- "vitest": "^1.0.0"
44
+ "typescript": "^5.3.0"
47
45
  }
48
46
  }
package/dist/index.d.cts DELETED
@@ -1,52 +0,0 @@
1
- import React from 'react';
2
- import { CacheStrategy, RetryConfig } from '@servlyadmin/runtime-core';
3
- export { BindingContext, CacheStrategy, ComponentData, FetchOptions, LayoutElement, PropDefinition, RetryConfig, clearAllCaches, compareVersions, fetchComponent, getRegistryUrl, invalidateCache, isComponentAvailable, parseVersion, prefetchComponents, resolveVersion, satisfiesVersion, setRegistryUrl } from '@servlyadmin/runtime-core';
4
-
5
- /**
6
- * ServlyComponent
7
- * React wrapper for Servly runtime renderer with slot support
8
- */
9
-
10
- /**
11
- * Slot content type - React nodes keyed by slot name
12
- */
13
- type SlotContent = Record<string, React.ReactNode>;
14
- /**
15
- * Props for ServlyComponent
16
- */
17
- interface ServlyComponentProps<P = Record<string, any>> {
18
- /** Component ID from the registry */
19
- id: string;
20
- /** Version specifier (exact, range, or "latest") */
21
- version?: string;
22
- /** Props to pass to the component */
23
- props?: P;
24
- /** Slot content - React nodes to portal into named slots */
25
- slots?: SlotContent;
26
- /** Fallback UI while loading or on error */
27
- fallback?: React.ReactNode;
28
- /** Error callback */
29
- onError?: (error: Error) => void;
30
- /** Load complete callback */
31
- onLoad?: () => void;
32
- /** Custom className for wrapper */
33
- className?: string;
34
- /** Custom styles for wrapper */
35
- style?: React.CSSProperties;
36
- /** Show loading skeleton */
37
- showSkeleton?: boolean;
38
- /** Cache strategy */
39
- cacheStrategy?: CacheStrategy;
40
- /** Retry configuration */
41
- retryConfig?: Partial<RetryConfig>;
42
- /** Event handlers keyed by element ID then event name */
43
- eventHandlers?: Record<string, Record<string, (e: Event) => void>>;
44
- /** Children - rendered into default slot if no slots prop */
45
- children?: React.ReactNode;
46
- }
47
- /**
48
- * ServlyComponent - React wrapper for Servly runtime with slot support
49
- */
50
- declare function ServlyComponent<P = Record<string, any>>({ id, version, props, slots, fallback, onError, onLoad, className, style, showSkeleton, cacheStrategy, retryConfig, eventHandlers, children, }: ServlyComponentProps<P>): React.ReactElement | null;
51
-
52
- export { ServlyComponent, type ServlyComponentProps, ServlyComponent as default };
package/dist/index.d.ts DELETED
@@ -1,52 +0,0 @@
1
- import React from 'react';
2
- import { CacheStrategy, RetryConfig } from '@servlyadmin/runtime-core';
3
- export { BindingContext, CacheStrategy, ComponentData, FetchOptions, LayoutElement, PropDefinition, RetryConfig, clearAllCaches, compareVersions, fetchComponent, getRegistryUrl, invalidateCache, isComponentAvailable, parseVersion, prefetchComponents, resolveVersion, satisfiesVersion, setRegistryUrl } from '@servlyadmin/runtime-core';
4
-
5
- /**
6
- * ServlyComponent
7
- * React wrapper for Servly runtime renderer with slot support
8
- */
9
-
10
- /**
11
- * Slot content type - React nodes keyed by slot name
12
- */
13
- type SlotContent = Record<string, React.ReactNode>;
14
- /**
15
- * Props for ServlyComponent
16
- */
17
- interface ServlyComponentProps<P = Record<string, any>> {
18
- /** Component ID from the registry */
19
- id: string;
20
- /** Version specifier (exact, range, or "latest") */
21
- version?: string;
22
- /** Props to pass to the component */
23
- props?: P;
24
- /** Slot content - React nodes to portal into named slots */
25
- slots?: SlotContent;
26
- /** Fallback UI while loading or on error */
27
- fallback?: React.ReactNode;
28
- /** Error callback */
29
- onError?: (error: Error) => void;
30
- /** Load complete callback */
31
- onLoad?: () => void;
32
- /** Custom className for wrapper */
33
- className?: string;
34
- /** Custom styles for wrapper */
35
- style?: React.CSSProperties;
36
- /** Show loading skeleton */
37
- showSkeleton?: boolean;
38
- /** Cache strategy */
39
- cacheStrategy?: CacheStrategy;
40
- /** Retry configuration */
41
- retryConfig?: Partial<RetryConfig>;
42
- /** Event handlers keyed by element ID then event name */
43
- eventHandlers?: Record<string, Record<string, (e: Event) => void>>;
44
- /** Children - rendered into default slot if no slots prop */
45
- children?: React.ReactNode;
46
- }
47
- /**
48
- * ServlyComponent - React wrapper for Servly runtime with slot support
49
- */
50
- declare function ServlyComponent<P = Record<string, any>>({ id, version, props, slots, fallback, onError, onLoad, className, style, showSkeleton, cacheStrategy, retryConfig, eventHandlers, children, }: ServlyComponentProps<P>): React.ReactElement | null;
51
-
52
- export { ServlyComponent, type ServlyComponentProps, ServlyComponent as default };