@xmachines/docs 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +15 -0
- package/api/@xmachines/play/README.md +130 -0
- package/api/@xmachines/play/type-aliases/PlayEvent.md +81 -0
- package/api/@xmachines/play-actor/README.md +247 -0
- package/api/@xmachines/play-actor/classes/AbstractActor.md +520 -0
- package/api/@xmachines/play-actor/interfaces/Routable.md +29 -0
- package/api/@xmachines/play-actor/interfaces/ViewMetadata.md +17 -0
- package/api/@xmachines/play-actor/interfaces/Viewable.md +12 -0
- package/api/@xmachines/play-catalog/README.md +331 -0
- package/api/@xmachines/play-catalog/functions/defineCatalog.md +98 -0
- package/api/@xmachines/play-catalog/functions/defineComponents.md +134 -0
- package/api/@xmachines/play-catalog/type-aliases/Catalog.md +48 -0
- package/api/@xmachines/play-catalog/type-aliases/ComponentsFor.md +20 -0
- package/api/@xmachines/play-catalog/type-aliases/InferComponentProps.md +65 -0
- package/api/@xmachines/play-catalog/type-aliases/NoExtraKeys.md +17 -0
- package/api/@xmachines/play-react/README.md +423 -0
- package/api/@xmachines/play-react/classes/PlayErrorBoundary.md +613 -0
- package/api/@xmachines/play-react/functions/useSignalEffect.md +68 -0
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryProps.md +15 -0
- package/api/@xmachines/play-react/interfaces/PlayErrorBoundaryState.md +14 -0
- package/api/@xmachines/play-react/interfaces/PlayRendererProps.md +15 -0
- package/api/@xmachines/play-react/variables/PlayRenderer.md +64 -0
- package/api/@xmachines/play-react-router/README.md +198 -0
- package/api/@xmachines/play-react-router/classes/ReactRouterBridge.md +321 -0
- package/api/@xmachines/play-react-router/classes/RouteMap.md +137 -0
- package/api/@xmachines/play-react-router/functions/PlayRouterProvider.md +19 -0
- package/api/@xmachines/play-react-router/functions/createRouteMapFromTree.md +35 -0
- package/api/@xmachines/play-react-router/interfaces/PlayRouteEvent.md +119 -0
- package/api/@xmachines/play-react-router/interfaces/PlayRouterProviderProps.md +14 -0
- package/api/@xmachines/play-react-router/interfaces/RouteMapping.md +17 -0
- package/api/@xmachines/play-react-router/interfaces/RouterBridge.md +104 -0
- package/api/@xmachines/play-react-router-demo/README.md +137 -0
- package/api/@xmachines/play-router/README.md +502 -0
- package/api/@xmachines/play-router/classes/BaseRouteMap.md +142 -0
- package/api/@xmachines/play-router/classes/RouterBridgeBase.md +300 -0
- package/api/@xmachines/play-router/functions/buildRouteTree.md +27 -0
- package/api/@xmachines/play-router/functions/connectRouter.md +67 -0
- package/api/@xmachines/play-router/functions/crawlMachine.md +92 -0
- package/api/@xmachines/play-router/functions/createBrowserHistory.md +47 -0
- package/api/@xmachines/play-router/functions/createRouteMap.md +53 -0
- package/api/@xmachines/play-router/functions/createRouter.md +76 -0
- package/api/@xmachines/play-router/functions/detectDuplicateRoutes.md +32 -0
- package/api/@xmachines/play-router/functions/extractMachineRoutes.md +64 -0
- package/api/@xmachines/play-router/functions/extractRoute.md +45 -0
- package/api/@xmachines/play-router/functions/findRouteById.md +37 -0
- package/api/@xmachines/play-router/functions/findRouteByPath.md +39 -0
- package/api/@xmachines/play-router/functions/getNavigableRoutes.md +35 -0
- package/api/@xmachines/play-router/functions/getRoutableRoutes.md +39 -0
- package/api/@xmachines/play-router/functions/routeExists.md +26 -0
- package/api/@xmachines/play-router/functions/validateRouteFormat.md +29 -0
- package/api/@xmachines/play-router/functions/validateStateExists.md +29 -0
- package/api/@xmachines/play-router/interfaces/BaseRouteMapping.md +27 -0
- package/api/@xmachines/play-router/interfaces/BrowserHistory.md +172 -0
- package/api/@xmachines/play-router/interfaces/BrowserWindow.md +69 -0
- package/api/@xmachines/play-router/interfaces/ConnectRouterOptions.md +13 -0
- package/api/@xmachines/play-router/interfaces/PlayRouteEvent.md +119 -0
- package/api/@xmachines/play-router/interfaces/RouteInfo.md +19 -0
- package/api/@xmachines/play-router/interfaces/RouteMap.md +56 -0
- package/api/@xmachines/play-router/interfaces/RouteNode.md +21 -0
- package/api/@xmachines/play-router/interfaces/RouteObject.md +21 -0
- package/api/@xmachines/play-router/interfaces/RouteTree.md +20 -0
- package/api/@xmachines/play-router/interfaces/RouterBridge.md +104 -0
- package/api/@xmachines/play-router/interfaces/StateVisit.md +15 -0
- package/api/@xmachines/play-router/interfaces/VanillaRouter.md +28 -0
- package/api/@xmachines/play-router/type-aliases/RouteMetadata.md +11 -0
- package/api/@xmachines/play-router-demo/README.md +137 -0
- package/api/@xmachines/play-signals/README.md +176 -0
- package/api/@xmachines/play-signals/interfaces/ComputedOptions.md +34 -0
- package/api/@xmachines/play-signals/interfaces/SignalComputed.md +49 -0
- package/api/@xmachines/play-signals/interfaces/SignalOptions.md +35 -0
- package/api/@xmachines/play-signals/interfaces/SignalState.md +68 -0
- package/api/@xmachines/play-signals/interfaces/SignalWatcher.md +97 -0
- package/api/@xmachines/play-signals/namespaces/Signal/README.md +22 -0
- package/api/@xmachines/play-signals/namespaces/Signal/classes/Computed.md +52 -0
- package/api/@xmachines/play-signals/namespaces/Signal/classes/State.md +72 -0
- package/api/@xmachines/play-signals/namespaces/Signal/interfaces/Options.md +19 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/README.md +21 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/classes/Watcher.md +85 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/currentComputed.md +13 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/hasSinks.md +19 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/hasSources.md +19 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/introspectSinks.md +19 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/introspectSources.md +19 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/functions/untrack.md +25 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/variables/unwatched.md +9 -0
- package/api/@xmachines/play-signals/namespaces/Signal/namespaces/subtle/variables/watched.md +9 -0
- package/api/@xmachines/play-signals/namespaces/Signal/variables/isComputed.md +19 -0
- package/api/@xmachines/play-signals/namespaces/Signal/variables/isState.md +19 -0
- package/api/@xmachines/play-signals/namespaces/Signal/variables/isWatcher.md +19 -0
- package/api/@xmachines/play-signals/type-aliases/WatcherNotify.md +32 -0
- package/api/@xmachines/play-solid/README.md +311 -0
- package/api/@xmachines/play-solid/interfaces/PlayRendererProps.md +15 -0
- package/api/@xmachines/play-solid/variables/PlayRenderer.md +70 -0
- package/api/@xmachines/play-solid-router/README.md +666 -0
- package/api/@xmachines/play-solid-router/classes/RouteMap.md +150 -0
- package/api/@xmachines/play-solid-router/classes/SolidRouterBridge.md +347 -0
- package/api/@xmachines/play-solid-router/functions/PlayRouterProvider.md +19 -0
- package/api/@xmachines/play-solid-router/functions/createRouteMap.md +32 -0
- package/api/@xmachines/play-solid-router/interfaces/AbstractActor.md +486 -0
- package/api/@xmachines/play-solid-router/interfaces/PlayRouteEvent.md +119 -0
- package/api/@xmachines/play-solid-router/interfaces/PlayRouterProviderProps.md +14 -0
- package/api/@xmachines/play-solid-router/interfaces/RouteMapping.md +14 -0
- package/api/@xmachines/play-solid-router/interfaces/RouterBridge.md +104 -0
- package/api/@xmachines/play-solid-router/type-aliases/RoutableActor.md +9 -0
- package/api/@xmachines/play-solid-router/type-aliases/SolidRouterHooks.md +51 -0
- package/api/@xmachines/play-solid-router-demo/README.md +127 -0
- package/api/@xmachines/play-tanstack-react-router/README.md +226 -0
- package/api/@xmachines/play-tanstack-react-router/classes/RouteMap.md +137 -0
- package/api/@xmachines/play-tanstack-react-router/classes/TanStackReactRouterBridge.md +348 -0
- package/api/@xmachines/play-tanstack-react-router/functions/PlayRouterProvider.md +19 -0
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMap.md +53 -0
- package/api/@xmachines/play-tanstack-react-router/functions/createRouteMapFromTree.md +35 -0
- package/api/@xmachines/play-tanstack-react-router/functions/extractParams.md +38 -0
- package/api/@xmachines/play-tanstack-react-router/functions/extractQueryParams.md +33 -0
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouteEvent.md +119 -0
- package/api/@xmachines/play-tanstack-react-router/interfaces/PlayRouterProviderProps.md +14 -0
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteMapping.md +17 -0
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouteNavigateEvent.md +26 -0
- package/api/@xmachines/play-tanstack-react-router/interfaces/RouterBridge.md +104 -0
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterInstance.md +9 -0
- package/api/@xmachines/play-tanstack-react-router/type-aliases/TanStackRouterLike.md +78 -0
- package/api/@xmachines/play-tanstack-react-router/variables/extractMachineRoutes.md +64 -0
- package/api/@xmachines/play-tanstack-react-router-demo/README.md +126 -0
- package/api/@xmachines/play-tanstack-solid-router/README.md +285 -0
- package/api/@xmachines/play-tanstack-solid-router/classes/RouteMap.md +150 -0
- package/api/@xmachines/play-tanstack-solid-router/classes/SolidRouterBridge.md +343 -0
- package/api/@xmachines/play-tanstack-solid-router/functions/PlayRouterProvider.md +19 -0
- package/api/@xmachines/play-tanstack-solid-router/functions/createRouteMap.md +32 -0
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouteEvent.md +119 -0
- package/api/@xmachines/play-tanstack-solid-router/interfaces/PlayRouterProviderProps.md +14 -0
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouteMapping.md +23 -0
- package/api/@xmachines/play-tanstack-solid-router/interfaces/RouterBridge.md +104 -0
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/RoutableActor.md +9 -0
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterInstance.md +9 -0
- package/api/@xmachines/play-tanstack-solid-router/type-aliases/TanStackRouterLike.md +78 -0
- package/api/@xmachines/play-tanstack-solid-router-demo/README.md +126 -0
- package/api/@xmachines/play-vue/README.md +292 -0
- package/api/@xmachines/play-vue/interfaces/PlayRendererProps.md +14 -0
- package/api/@xmachines/play-vue/variables/PlayRenderer.md +9 -0
- package/api/@xmachines/play-vue-router/README.md +604 -0
- package/api/@xmachines/play-vue-router/classes/RouteMap.md +209 -0
- package/api/@xmachines/play-vue-router/classes/VueBaseRouteMap.md +201 -0
- package/api/@xmachines/play-vue-router/classes/VueRouterBridge.md +360 -0
- package/api/@xmachines/play-vue-router/functions/createRouteMap.md +19 -0
- package/api/@xmachines/play-vue-router/interfaces/PlayRouteEvent.md +119 -0
- package/api/@xmachines/play-vue-router/interfaces/RouteMapping.md +15 -0
- package/api/@xmachines/play-vue-router/interfaces/RouterBridge.md +104 -0
- package/api/@xmachines/play-vue-router/type-aliases/RoutableActor.md +9 -0
- package/api/@xmachines/play-vue-router/variables/PlayRouterProvider.md +67 -0
- package/api/@xmachines/play-vue-router-demo/README.md +133 -0
- package/api/@xmachines/play-xstate/README.md +512 -0
- package/api/@xmachines/play-xstate/classes/PlayerActor.md +527 -0
- package/api/@xmachines/play-xstate/functions/buildRouteUrl.md +43 -0
- package/api/@xmachines/play-xstate/functions/composeGuards.md +79 -0
- package/api/@xmachines/play-xstate/functions/composeGuardsOr.md +67 -0
- package/api/@xmachines/play-xstate/functions/definePlayer.md +127 -0
- package/api/@xmachines/play-xstate/functions/deriveRoute.md +109 -0
- package/api/@xmachines/play-xstate/functions/eventMatches.md +40 -0
- package/api/@xmachines/play-xstate/functions/formatPlayRouteTransitions.md +54 -0
- package/api/@xmachines/play-xstate/functions/hasContext.md +42 -0
- package/api/@xmachines/play-xstate/functions/isAbsoluteRoute.md +41 -0
- package/api/@xmachines/play-xstate/functions/mergeViewProps.md +26 -0
- package/api/@xmachines/play-xstate/functions/negateGuard.md +61 -0
- package/api/@xmachines/play-xstate/functions/stateMatches.md +25 -0
- package/api/@xmachines/play-xstate/functions/validateComponentBinding.md +39 -0
- package/api/@xmachines/play-xstate/functions/validateViewProps.md +80 -0
- package/api/@xmachines/play-xstate/interfaces/CatalogEntry.md +16 -0
- package/api/@xmachines/play-xstate/interfaces/PlayerConfig.md +24 -0
- package/api/@xmachines/play-xstate/interfaces/PlayerOptions.md +26 -0
- package/api/@xmachines/play-xstate/interfaces/RouteContext.md +22 -0
- package/api/@xmachines/play-xstate/type-aliases/Catalog.md +21 -0
- package/api/@xmachines/play-xstate/type-aliases/ComposedGuard.md +14 -0
- package/api/@xmachines/play-xstate/type-aliases/Guard.md +34 -0
- package/api/@xmachines/play-xstate/type-aliases/GuardArray.md +20 -0
- package/api/@xmachines/play-xstate/type-aliases/PlayerFactory.md +29 -0
- package/api/@xmachines/play-xstate/type-aliases/RouteMachineConfig.md +45 -0
- package/api/@xmachines/play-xstate/type-aliases/RouteStateNode.md +51 -0
- package/api/@xmachines/play-xstate/type-aliases/ValidationResult.md +17 -0
- package/api/@xmachines/play-xstate/type-aliases/ViewMergeContext.md +35 -0
- package/api/@xmachines/shared/README.md +379 -0
- package/api/@xmachines/shared/functions/defineXmVitestConfig.md +29 -0
- package/api/@xmachines/shared/functions/xmAliases.md +24 -0
- package/api/README.md +25 -0
- package/api/llms.txt +26 -0
- package/examples/README.md +63 -0
- package/examples/basic-state-machine.md +70 -0
- package/examples/form-validation.md +167 -0
- package/examples/multi-router-integration.md +277 -0
- package/examples/routing-patterns.md +260 -0
- package/examples/traffic-light.md +99 -0
- package/guides/README.md +29 -0
- package/guides/getting-started.md +223 -0
- package/guides/installation.md +323 -0
- package/index.d.ts +3 -0
- package/index.js +4 -0
- package/package.json +54 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
[Documentation](../../README.md) / @xmachines/play-catalog
|
|
2
|
+
|
|
3
|
+
# @xmachines/play-catalog
|
|
4
|
+
|
|
5
|
+
**Framework-agnostic UI schema with Zod validation for XMachines Play Architecture**
|
|
6
|
+
|
|
7
|
+
Type-safe catalog defining component contracts without framework dependencies.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
`@xmachines/play-catalog` provides `defineCatalog()` and `defineComponents()` for creating type-safe component catalogs with Zod schema validation. It enables business logic to define component props declaratively while maintaining zero framework dependencies — components can be React, Vue, Svelte, or any other framework.
|
|
12
|
+
|
|
13
|
+
Per [RFC Play v1](https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md), this package implements:
|
|
14
|
+
|
|
15
|
+
- **Strict Separation (INV-02):** Business logic has zero framework imports
|
|
16
|
+
- Catalog validates prop types at state entry (build-time + runtime)
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install zod@^4.3.6
|
|
22
|
+
npm install @xmachines/play-catalog
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Current Exports
|
|
26
|
+
|
|
27
|
+
- `defineCatalog`
|
|
28
|
+
- `defineComponents`
|
|
29
|
+
- types: `Catalog`, `InferComponentProps`
|
|
30
|
+
|
|
31
|
+
**Peer dependencies:**
|
|
32
|
+
|
|
33
|
+
- `zod` ^4.3.6 — Schema validation (you control the version)
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { z } from "zod";
|
|
39
|
+
import { defineCatalog } from "@xmachines/play-catalog";
|
|
40
|
+
import type { InferComponentProps } from "@xmachines/play-catalog";
|
|
41
|
+
|
|
42
|
+
// 1. Define catalog with Zod schemas (business logic layer)
|
|
43
|
+
const catalog = defineCatalog({
|
|
44
|
+
LoginForm: z.object({
|
|
45
|
+
error: z.string().optional(),
|
|
46
|
+
}),
|
|
47
|
+
Dashboard: z.object({
|
|
48
|
+
userId: z.string(),
|
|
49
|
+
username: z.string(),
|
|
50
|
+
stats: z.object({
|
|
51
|
+
logins: z.number(),
|
|
52
|
+
lastLogin: z.date(),
|
|
53
|
+
}),
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// 2. TypeScript infers prop types from schemas
|
|
58
|
+
type DashboardProps = InferComponentProps<typeof catalog, "Dashboard">;
|
|
59
|
+
// => { userId: string; username: string; stats: { logins: number; lastLogin: Date } }
|
|
60
|
+
|
|
61
|
+
// 3. Use in state machine meta.view
|
|
62
|
+
const machine = setup({...}).createMachine({
|
|
63
|
+
states: {
|
|
64
|
+
dashboard: {
|
|
65
|
+
meta: {
|
|
66
|
+
route: "/dashboard",
|
|
67
|
+
view: {
|
|
68
|
+
component: "Dashboard", // Type-checked against catalog
|
|
69
|
+
props: {
|
|
70
|
+
userId: "user123",
|
|
71
|
+
username: "Alice",
|
|
72
|
+
stats: {
|
|
73
|
+
logins: 42,
|
|
74
|
+
lastLogin: new Date(),
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## API Reference
|
|
85
|
+
|
|
86
|
+
### defineCatalog()
|
|
87
|
+
|
|
88
|
+
Create type-safe component catalog from Zod schemas:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const catalog = defineCatalog({
|
|
92
|
+
ComponentName: z.object({
|
|
93
|
+
/* props schema */
|
|
94
|
+
}),
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Parameters:**
|
|
99
|
+
|
|
100
|
+
- `schemas: Record<string, ZodObject>` - Map of component names to Zod schemas
|
|
101
|
+
|
|
102
|
+
**Returns:** Frozen catalog object (immutable in development)
|
|
103
|
+
|
|
104
|
+
**Example:**
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
const catalog = defineCatalog({
|
|
108
|
+
UserProfile: z.object({
|
|
109
|
+
userId: z.string(),
|
|
110
|
+
avatar: z.string().url().optional(),
|
|
111
|
+
bio: z.string().max(500).optional(),
|
|
112
|
+
}),
|
|
113
|
+
SettingsForm: z.object({
|
|
114
|
+
theme: z.enum(["light", "dark"]),
|
|
115
|
+
notifications: z.boolean(),
|
|
116
|
+
}),
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### InferComponentProps<Catalog, Component>
|
|
121
|
+
|
|
122
|
+
Utility type extracting prop types from catalog:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
type Props = InferComponentProps<typeof catalog, "ComponentName">;
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Example:**
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const catalog = defineCatalog({
|
|
132
|
+
Dashboard: z.object({
|
|
133
|
+
userId: z.string(),
|
|
134
|
+
data: z.array(z.number()),
|
|
135
|
+
}),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
type DashboardProps = InferComponentProps<typeof catalog, "Dashboard">;
|
|
139
|
+
// => { userId: string; data: number[] }
|
|
140
|
+
|
|
141
|
+
// Use in component definition
|
|
142
|
+
function Dashboard(props: DashboardProps) {
|
|
143
|
+
// props.userId is string
|
|
144
|
+
// props.data is number[]
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### defineComponents()
|
|
149
|
+
|
|
150
|
+
Validate React component implementations match catalog (compile-time):
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const components = defineComponents(catalog, {
|
|
154
|
+
ComponentName: ComponentImplementation,
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Compile-time validation:**
|
|
159
|
+
|
|
160
|
+
- Component names must exist in catalog
|
|
161
|
+
- Component prop types must match schema-inferred types
|
|
162
|
+
|
|
163
|
+
**Example:**
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { defineComponents } from "@xmachines/play-catalog";
|
|
167
|
+
|
|
168
|
+
const catalog = defineCatalog({
|
|
169
|
+
LoginForm: z.object({ error: z.string().optional() }),
|
|
170
|
+
Dashboard: z.object({ userId: z.string() }),
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const components = defineComponents(catalog, {
|
|
174
|
+
LoginForm: ({ error }) => {
|
|
175
|
+
// error is string | undefined (inferred from schema)
|
|
176
|
+
return <form>{error && <p>{error}</p>}</form>;
|
|
177
|
+
},
|
|
178
|
+
Dashboard: ({ userId }) => {
|
|
179
|
+
// userId is string (inferred from schema)
|
|
180
|
+
return <div>User: {userId}</div>;
|
|
181
|
+
},
|
|
182
|
+
// @ts-expect-error - "InvalidComponent" not in catalog
|
|
183
|
+
InvalidComponent: () => <div />,
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Examples
|
|
188
|
+
|
|
189
|
+
### Progressive Validation
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { z } from "zod";
|
|
193
|
+
import { defineCatalog } from "@xmachines/play-catalog";
|
|
194
|
+
|
|
195
|
+
// Start simple
|
|
196
|
+
const catalog = defineCatalog({
|
|
197
|
+
UserCard: z.object({
|
|
198
|
+
name: z.string(),
|
|
199
|
+
}),
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Add validation rules
|
|
203
|
+
const enhancedCatalog = defineCatalog({
|
|
204
|
+
UserCard: z.object({
|
|
205
|
+
name: z.string().min(1).max(100),
|
|
206
|
+
email: z.string().email(),
|
|
207
|
+
age: z.number().int().positive().max(150),
|
|
208
|
+
}),
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Complex nested schemas
|
|
212
|
+
const advancedCatalog = defineCatalog({
|
|
213
|
+
UserCard: z.object({
|
|
214
|
+
name: z.string().min(1),
|
|
215
|
+
email: z.string().email(),
|
|
216
|
+
profile: z.object({
|
|
217
|
+
avatar: z.string().url().optional(),
|
|
218
|
+
bio: z.string().max(500).optional(),
|
|
219
|
+
links: z.array(z.string().url()).max(5).optional(),
|
|
220
|
+
}),
|
|
221
|
+
preferences: z.object({
|
|
222
|
+
theme: z.enum(["light", "dark", "auto"]),
|
|
223
|
+
language: z.string().length(2), // ISO 639-1
|
|
224
|
+
}),
|
|
225
|
+
}),
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Machine Integration
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { setup } from "xstate";
|
|
233
|
+
import { defineCatalog } from "@xmachines/play-catalog";
|
|
234
|
+
import { z } from "zod";
|
|
235
|
+
|
|
236
|
+
const catalog = defineCatalog({
|
|
237
|
+
LoginForm: z.object({ error: z.string().optional() }),
|
|
238
|
+
Dashboard: z.object({
|
|
239
|
+
userId: z.string(),
|
|
240
|
+
notifications: z.number(),
|
|
241
|
+
}),
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const machine = setup({
|
|
245
|
+
types: {
|
|
246
|
+
context: {} as { userId: string; errorMsg: string | null },
|
|
247
|
+
},
|
|
248
|
+
}).createMachine({
|
|
249
|
+
initial: "login",
|
|
250
|
+
context: { userId: "", errorMsg: null },
|
|
251
|
+
states: {
|
|
252
|
+
login: {
|
|
253
|
+
meta: {
|
|
254
|
+
view: {
|
|
255
|
+
component: "LoginForm", // Type-checked against catalog
|
|
256
|
+
props: (context) => ({
|
|
257
|
+
error: context.errorMsg ?? undefined,
|
|
258
|
+
}),
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
on: {
|
|
262
|
+
"auth.login": {
|
|
263
|
+
target: "dashboard",
|
|
264
|
+
actions: assign({ userId: ({ event }) => event.userId }),
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
dashboard: {
|
|
269
|
+
meta: {
|
|
270
|
+
view: {
|
|
271
|
+
component: "Dashboard",
|
|
272
|
+
props: (context) => ({
|
|
273
|
+
userId: context.userId,
|
|
274
|
+
notifications: 5, // Hardcoded for example
|
|
275
|
+
}),
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Architecture
|
|
284
|
+
|
|
285
|
+
This package enforces **Strict Separation (INV-02)**:
|
|
286
|
+
|
|
287
|
+
1. **Zero Framework Dependencies:**
|
|
288
|
+
- Catalog definition has no React/Vue/Svelte imports
|
|
289
|
+
- Business logic stays framework-agnostic
|
|
290
|
+
- Same catalog works with any renderer
|
|
291
|
+
|
|
292
|
+
2. **Validation at State Entry:**
|
|
293
|
+
- Zod validates props when actor enters state
|
|
294
|
+
- Invalid props trigger validation error (catchable)
|
|
295
|
+
- Build-time + runtime safety
|
|
296
|
+
|
|
297
|
+
3. **Compile-Time Type Safety:**
|
|
298
|
+
- TypeScript infers prop types from Zod schemas
|
|
299
|
+
- Component implementations type-checked at compile time
|
|
300
|
+
- Refactoring propagates through catalog and components
|
|
301
|
+
|
|
302
|
+
**Benefits:**
|
|
303
|
+
|
|
304
|
+
- Swap React for Vue without changing business logic
|
|
305
|
+
- Test catalog validation without framework overhead
|
|
306
|
+
- Framework updates don't affect business logic
|
|
307
|
+
|
|
308
|
+
## Related Packages
|
|
309
|
+
|
|
310
|
+
- **[@xmachines/play-xstate](../play-xstate/README.md)** - XState adapter using catalogs
|
|
311
|
+
- **[@xmachines/play-react](../play-react/README.md)** - React renderer consuming catalogs
|
|
312
|
+
- **[@xmachines/play](../play/README.md)** - Protocol types
|
|
313
|
+
|
|
314
|
+
## License
|
|
315
|
+
|
|
316
|
+
Copyright (c) 2016 [Mikael Karon](mailto:mikael@karon.se). All rights reserved.
|
|
317
|
+
|
|
318
|
+
This work is licensed under the terms of the MIT license.
|
|
319
|
+
For a copy, see <https://opensource.org/licenses/MIT>.
|
|
320
|
+
|
|
321
|
+
## Type Aliases
|
|
322
|
+
|
|
323
|
+
- [Catalog](type-aliases/Catalog.md)
|
|
324
|
+
- [ComponentsFor](type-aliases/ComponentsFor.md)
|
|
325
|
+
- [InferComponentProps](type-aliases/InferComponentProps.md)
|
|
326
|
+
- [NoExtraKeys](type-aliases/NoExtraKeys.md)
|
|
327
|
+
|
|
328
|
+
## Functions
|
|
329
|
+
|
|
330
|
+
- [defineCatalog](functions/defineCatalog.md)
|
|
331
|
+
- [defineComponents](functions/defineComponents.md)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
[Documentation](../../../README.md) / [@xmachines/play-catalog](../README.md) / defineCatalog
|
|
2
|
+
|
|
3
|
+
# Function: defineCatalog()
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
function defineCatalog<TCatalog>(schemas): TCatalog;
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Defined in: [define-catalog.ts:74](https://gitlab.com/xmachin-es/xmachines-js/-/blob/00a28432ed57807112288436d1ae4387d9f06919/packages/play-catalog/src/define-catalog.ts#L74)
|
|
10
|
+
|
|
11
|
+
Define component catalog with Zod schemas for type-safe UI projection
|
|
12
|
+
|
|
13
|
+
Creates a catalog mapping component names to their prop schemas using Zod validators.
|
|
14
|
+
The catalog enables **Strict Separation (INV-02)** by defining UI vocabulary in
|
|
15
|
+
framework-agnostic terms that the Actor can reference without coupling to React/Vue/etc.
|
|
16
|
+
|
|
17
|
+
**Architectural Context:** Implements **Strict Separation (INV-02)** where business
|
|
18
|
+
logic (state machine) has zero framework imports. The catalog serves as the contract
|
|
19
|
+
between Actor (which references component names in `meta.view`) and Infrastructure
|
|
20
|
+
(which renders actual framework components).
|
|
21
|
+
|
|
22
|
+
## Type Parameters
|
|
23
|
+
|
|
24
|
+
| Type Parameter |
|
|
25
|
+
| ------------------------------------------------------------------------------------------------------------------------- |
|
|
26
|
+
| `TCatalog` _extends_ `Record`\<`string`, `ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\>\> |
|
|
27
|
+
|
|
28
|
+
## Parameters
|
|
29
|
+
|
|
30
|
+
| Parameter | Type | Description |
|
|
31
|
+
| --------- | ---------- | --------------------------------------------- |
|
|
32
|
+
| `schemas` | `TCatalog` | Record mapping component names to Zod schemas |
|
|
33
|
+
|
|
34
|
+
## Returns
|
|
35
|
+
|
|
36
|
+
`TCatalog`
|
|
37
|
+
|
|
38
|
+
Typed catalog object with schema entries (frozen in development for immutability)
|
|
39
|
+
|
|
40
|
+
## Examples
|
|
41
|
+
|
|
42
|
+
Basic catalog definition
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { z } from "zod";
|
|
46
|
+
import { defineCatalog } from "@xmachines/play-catalog";
|
|
47
|
+
|
|
48
|
+
const catalog = defineCatalog({
|
|
49
|
+
Dashboard: z.object({ userId: z.string() }),
|
|
50
|
+
LoginForm: z.object({ error: z.string().optional() }),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// TypeScript infers catalog type automatically
|
|
54
|
+
type CatalogType = typeof catalog;
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Progressive catalog with multiple components
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { z } from "zod";
|
|
61
|
+
import { defineCatalog } from "@xmachines/play-catalog";
|
|
62
|
+
|
|
63
|
+
const catalog = defineCatalog({
|
|
64
|
+
// Public pages
|
|
65
|
+
HomePage: z.object({}),
|
|
66
|
+
AboutPage: z.object({}),
|
|
67
|
+
|
|
68
|
+
// Auth components
|
|
69
|
+
LoginForm: z.object({
|
|
70
|
+
error: z.string().optional(),
|
|
71
|
+
returnUrl: z.string().optional(),
|
|
72
|
+
}),
|
|
73
|
+
|
|
74
|
+
// Protected pages
|
|
75
|
+
Dashboard: z.object({
|
|
76
|
+
userId: z.string(),
|
|
77
|
+
stats: z.object({
|
|
78
|
+
views: z.number(),
|
|
79
|
+
clicks: z.number(),
|
|
80
|
+
}),
|
|
81
|
+
}),
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## See
|
|
86
|
+
|
|
87
|
+
- [RFC Play v1 - Invariant INV-02](https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md)
|
|
88
|
+
- [defineComponents](defineComponents.md) for binding components to catalog
|
|
89
|
+
- [Catalog](../type-aliases/Catalog.md) for the catalog type definition
|
|
90
|
+
|
|
91
|
+
## Remarks
|
|
92
|
+
|
|
93
|
+
**Primary Purpose:** Type inference. The returned catalog object is primarily used
|
|
94
|
+
for TypeScript type inference. Runtime validation happens at state entry when the
|
|
95
|
+
Actor attempts to project a view through the renderer.
|
|
96
|
+
|
|
97
|
+
**Immutability:** In development mode, the catalog is frozen via `Object.freeze()`
|
|
98
|
+
to prevent accidental mutation. In production, freezing is skipped for performance.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
[Documentation](../../../README.md) / [@xmachines/play-catalog](../README.md) / defineComponents
|
|
2
|
+
|
|
3
|
+
# Function: defineComponents()
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
function defineComponents<TCatalog, TComponents>(
|
|
7
|
+
catalog,
|
|
8
|
+
components,
|
|
9
|
+
): NoExtraKeys<TComponents, TCatalog>;
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Defined in: [define-components.ts:116](https://gitlab.com/xmachin-es/xmachines-js/-/blob/00a28432ed57807112288436d1ae4387d9f06919/packages/play-catalog/src/define-components.ts#L116)
|
|
13
|
+
|
|
14
|
+
Define components matching catalog schema with compile-time validation
|
|
15
|
+
|
|
16
|
+
Enforces bidirectional validation between catalog and component implementations:
|
|
17
|
+
|
|
18
|
+
- All catalog keys must have corresponding components (no missing components)
|
|
19
|
+
- No extra components outside catalog (no undefined keys)
|
|
20
|
+
- TypeScript compilation fails for mismatches (build-time safety)
|
|
21
|
+
|
|
22
|
+
**Architectural Context:** Implements **Strict Separation (INV-02)** by validating
|
|
23
|
+
that framework components (React/Vue/etc.) exactly match the framework-agnostic
|
|
24
|
+
catalog that the Actor references. This ensures the Actor can reference component
|
|
25
|
+
names in `meta.view` without importing framework code.
|
|
26
|
+
|
|
27
|
+
## Type Parameters
|
|
28
|
+
|
|
29
|
+
| Type Parameter |
|
|
30
|
+
| ------------------------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| `TCatalog` _extends_ `Record`\<`string`, `ZodType`\<`unknown`, `unknown`, `$ZodTypeInternals`\<`unknown`, `unknown`\>\>\> |
|
|
32
|
+
| `TComponents` _extends_ [`ComponentsFor`](../type-aliases/ComponentsFor.md)\<`TCatalog`\> |
|
|
33
|
+
|
|
34
|
+
## Parameters
|
|
35
|
+
|
|
36
|
+
| Parameter | Type | Description |
|
|
37
|
+
| ------------ | ---------------------------------------------------------------------------- | ------------------------------------------------------- |
|
|
38
|
+
| `catalog` | `TCatalog` | Component catalog with Zod schemas |
|
|
39
|
+
| `components` | [`NoExtraKeys`](../type-aliases/NoExtraKeys.md)\<`TComponents`, `TCatalog`\> | Component implementations matching catalog keys exactly |
|
|
40
|
+
|
|
41
|
+
## Returns
|
|
42
|
+
|
|
43
|
+
[`NoExtraKeys`](../type-aliases/NoExtraKeys.md)\<`TComponents`, `TCatalog`\>
|
|
44
|
+
|
|
45
|
+
Component map validated at compile time (frozen in development)
|
|
46
|
+
|
|
47
|
+
## Throws
|
|
48
|
+
|
|
49
|
+
Error if runtime validation detects missing or extra keys
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
|
|
53
|
+
Valid component definition
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { defineComponents } from "@xmachines/play-catalog";
|
|
57
|
+
import { catalog } from "./catalog.js";
|
|
58
|
+
import { DashboardComponent, LoginFormComponent } from "./components.js";
|
|
59
|
+
|
|
60
|
+
// ✅ Valid - all keys match catalog
|
|
61
|
+
const components = defineComponents(catalog, {
|
|
62
|
+
Dashboard: DashboardComponent,
|
|
63
|
+
LoginForm: LoginFormComponent,
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
TypeScript compile errors
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { defineComponents } from "@xmachines/play-catalog";
|
|
71
|
+
import { catalog } from "./catalog.js";
|
|
72
|
+
|
|
73
|
+
// ❌ TypeScript error - missing 'LoginForm'
|
|
74
|
+
const components = defineComponents(catalog, {
|
|
75
|
+
Dashboard: DashboardComponent,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// ❌ TypeScript error - extra 'UnknownComponent' not in catalog
|
|
79
|
+
const components = defineComponents(catalog, {
|
|
80
|
+
Dashboard: DashboardComponent,
|
|
81
|
+
LoginForm: LoginFormComponent,
|
|
82
|
+
UnknownComponent: SomeComponent,
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Progressive example with Actor integration
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { z } from "zod";
|
|
90
|
+
import { defineCatalog, defineComponents } from "@xmachines/play-catalog";
|
|
91
|
+
import { definePlayer } from "@xmachines/play-xstate";
|
|
92
|
+
import { setup } from "xstate";
|
|
93
|
+
|
|
94
|
+
// 1. Define catalog
|
|
95
|
+
const catalog = defineCatalog({
|
|
96
|
+
HomePage: z.object({}),
|
|
97
|
+
Dashboard: z.object({ userId: z.string() })
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// 2. Define components
|
|
101
|
+
const components = defineComponents(catalog, {
|
|
102
|
+
HomePage: () => <div>Home</div>,
|
|
103
|
+
Dashboard: ({ userId }) => <div>Dashboard for {userId}</div>
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// 3. Create machine referencing catalog components
|
|
107
|
+
const machine = setup({}).createMachine({
|
|
108
|
+
initial: 'home',
|
|
109
|
+
states: {
|
|
110
|
+
home: {
|
|
111
|
+
meta: {
|
|
112
|
+
route: '/',
|
|
113
|
+
view: { component: 'HomePage' } // References catalog key
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
dashboard: {
|
|
117
|
+
meta: {
|
|
118
|
+
route: '/dashboard',
|
|
119
|
+
view: { component: 'Dashboard', userId: '123' }
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// 4. Create actor with catalog
|
|
126
|
+
const createPlayer = definePlayer({ machine, catalog });
|
|
127
|
+
const actor = createPlayer();
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## See
|
|
131
|
+
|
|
132
|
+
- [RFC Play v1 - Invariant INV-02](https://gitlab.com/xmachin-es/rfc/-/blob/main/src/play-v1.md)
|
|
133
|
+
- [defineCatalog](defineCatalog.md) for creating the catalog schema
|
|
134
|
+
- [Catalog](../type-aliases/Catalog.md) for the catalog type definition
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[Documentation](../../../README.md) / [@xmachines/play-catalog](../README.md) / Catalog
|
|
2
|
+
|
|
3
|
+
# Type Alias: Catalog\<TCatalog\>
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
type Catalog<TCatalog> = TCatalog;
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Defined in: [types.ts:35](https://gitlab.com/xmachin-es/xmachines-js/-/blob/00a28432ed57807112288436d1ae4387d9f06919/packages/play-catalog/src/types.ts#L35)
|
|
10
|
+
|
|
11
|
+
Component catalog mapping component names to Zod prop schemas
|
|
12
|
+
|
|
13
|
+
Generic type that maps component name strings to their Zod schema validators.
|
|
14
|
+
The catalog enables type-safe UI projection by defining the vocabulary of
|
|
15
|
+
components that the Actor can reference in `meta.view` without coupling to
|
|
16
|
+
framework implementations.
|
|
17
|
+
|
|
18
|
+
## Type Parameters
|
|
19
|
+
|
|
20
|
+
| Type Parameter | Default type | Description |
|
|
21
|
+
| ------------------------------------------------------ | --------------------------------- | -------------------------------------------------- |
|
|
22
|
+
| `TCatalog` _extends_ `Record`\<`string`, `z.ZodType`\> | `Record`\<`string`, `z.ZodType`\> | Record mapping component names to Zod schema types |
|
|
23
|
+
|
|
24
|
+
## Example
|
|
25
|
+
|
|
26
|
+
Basic catalog type
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { z } from "zod";
|
|
30
|
+
import { defineCatalog } from "@xmachines/play-catalog";
|
|
31
|
+
import type { Catalog } from "@xmachines/play-catalog";
|
|
32
|
+
|
|
33
|
+
const catalog = defineCatalog({
|
|
34
|
+
Dashboard: z.object({ userId: z.string() }),
|
|
35
|
+
LoginForm: z.object({ error: z.string().optional() }),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
type MyCatalog = typeof catalog;
|
|
39
|
+
// Inferred as: Catalog<{
|
|
40
|
+
// Dashboard: z.ZodObject<...>,
|
|
41
|
+
// LoginForm: z.ZodObject<...>
|
|
42
|
+
// }>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## See
|
|
46
|
+
|
|
47
|
+
- [defineCatalog](../functions/defineCatalog.md) for creating catalog instances
|
|
48
|
+
- [InferComponentProps](InferComponentProps.md) for extracting prop types
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[Documentation](../../../README.md) / [@xmachines/play-catalog](../README.md) / ComponentsFor
|
|
2
|
+
|
|
3
|
+
# Type Alias: ComponentsFor\<TCatalog\>
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
type ComponentsFor<TCatalog> = { [K in keyof TCatalog]: unknown };
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Defined in: [define-components.ts:10](https://gitlab.com/xmachin-es/xmachines-js/-/blob/00a28432ed57807112288436d1ae4387d9f06919/packages/play-catalog/src/define-components.ts#L10)
|
|
10
|
+
|
|
11
|
+
Component map type enforcing catalog keys
|
|
12
|
+
|
|
13
|
+
Mapped type ensures components object has exactly catalog keys - no missing, no extra.
|
|
14
|
+
This provides compile-time validation that framework components match the catalog schema.
|
|
15
|
+
|
|
16
|
+
## Type Parameters
|
|
17
|
+
|
|
18
|
+
| Type Parameter |
|
|
19
|
+
| ------------------------------------------------------ |
|
|
20
|
+
| `TCatalog` _extends_ `Record`\<`string`, `z.ZodType`\> |
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[Documentation](../../../README.md) / [@xmachines/play-catalog](../README.md) / InferComponentProps
|
|
2
|
+
|
|
3
|
+
# Type Alias: InferComponentProps\<TCatalog, TKey\>
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
type InferComponentProps<TCatalog, TKey> = z.infer<TCatalog[TKey]>;
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Defined in: [types.ts:84](https://gitlab.com/xmachin-es/xmachines-js/-/blob/00a28432ed57807112288436d1ae4387d9f06919/packages/play-catalog/src/types.ts#L84)
|
|
10
|
+
|
|
11
|
+
Infer component prop types from catalog entry
|
|
12
|
+
|
|
13
|
+
Utility type that extracts the TypeScript type of a component's props from its
|
|
14
|
+
Zod schema definition in the catalog. Enables type-safe component implementations
|
|
15
|
+
that match the catalog schema.
|
|
16
|
+
|
|
17
|
+
## Type Parameters
|
|
18
|
+
|
|
19
|
+
| Type Parameter | Description |
|
|
20
|
+
| ------------------------------------------------------ | ----------------------------------------------------- |
|
|
21
|
+
| `TCatalog` _extends_ `Record`\<`string`, `z.ZodType`\> | Catalog record mapping component names to Zod schemas |
|
|
22
|
+
| `TKey` _extends_ keyof `TCatalog` | Specific component key to extract props for |
|
|
23
|
+
|
|
24
|
+
## Returns
|
|
25
|
+
|
|
26
|
+
TypeScript type inferred from the Zod schema
|
|
27
|
+
|
|
28
|
+
## Example
|
|
29
|
+
|
|
30
|
+
Extracting prop types for components
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { z } from "zod";
|
|
34
|
+
import { defineCatalog } from "@xmachines/play-catalog";
|
|
35
|
+
import type { InferComponentProps } from "@xmachines/play-catalog";
|
|
36
|
+
|
|
37
|
+
const catalog = defineCatalog({
|
|
38
|
+
Dashboard: z.object({
|
|
39
|
+
userId: z.string(),
|
|
40
|
+
stats: z.object({
|
|
41
|
+
views: z.number(),
|
|
42
|
+
clicks: z.number()
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
type DashboardProps = InferComponentProps<typeof catalog, 'Dashboard'>;
|
|
48
|
+
// Inferred as: {
|
|
49
|
+
// userId: string;
|
|
50
|
+
// stats: {
|
|
51
|
+
// views: number;
|
|
52
|
+
// clicks: number;
|
|
53
|
+
// };
|
|
54
|
+
// }
|
|
55
|
+
|
|
56
|
+
// Use in React component
|
|
57
|
+
function Dashboard({ userId, stats }: DashboardProps) {
|
|
58
|
+
return <div>{userId}: {stats.views} views</div>;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## See
|
|
63
|
+
|
|
64
|
+
- [Catalog](Catalog.md) for the catalog type definition
|
|
65
|
+
- [defineCatalog](../functions/defineCatalog.md) for creating catalog instances
|