@usefragments/core 1.9.1 → 1.10.1

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.
@@ -0,0 +1,48 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { V as VariantRenderOptions, a as VariantLoader } from './governance-CLk_wkP9.js';
4
+ import 'zod';
5
+ import './topology/index.js';
6
+ import './types-xJ2xyp_G.js';
7
+
8
+ /**
9
+ * Minimal contract for rendering a preview variant.
10
+ * Compatible with fragment variants and Storybook-adapted variants.
11
+ */
12
+ interface PreviewVariantLike {
13
+ render: (options?: VariantRenderOptions) => ReactNode;
14
+ loaders?: VariantLoader[];
15
+ }
16
+ interface PreviewRuntimeState {
17
+ content: ReactNode | null;
18
+ isLoading: boolean;
19
+ error: Error | null;
20
+ loadedData?: Record<string, unknown>;
21
+ }
22
+ interface PreviewRuntimeOptions {
23
+ variant?: PreviewVariantLike | null;
24
+ loadedData?: Record<string, unknown>;
25
+ }
26
+ /**
27
+ * Execute all variant loaders and merge their payloads.
28
+ * `loadedData` is applied last so host-level overrides win.
29
+ */
30
+ declare function executeVariantLoaders(loaders: VariantLoader[] | undefined, loadedData?: Record<string, unknown>): Promise<Record<string, unknown> | undefined>;
31
+ /**
32
+ * Resolve a full runtime state (loader execution + render) in one async call.
33
+ * This is useful for testing and for hook/component orchestration.
34
+ */
35
+ declare function resolvePreviewRuntimeState(options: PreviewRuntimeOptions): Promise<PreviewRuntimeState>;
36
+ /**
37
+ * Hook for rendering a preview variant with loader support.
38
+ */
39
+ declare function usePreviewVariantRuntime(options: PreviewRuntimeOptions): PreviewRuntimeState;
40
+ interface PreviewVariantRuntimeProps extends PreviewRuntimeOptions {
41
+ children: (state: PreviewRuntimeState) => ReactNode;
42
+ }
43
+ /**
44
+ * Render-prop component wrapper around `usePreviewVariantRuntime`.
45
+ */
46
+ declare function PreviewVariantRuntime({ variant, loadedData, children, }: PreviewVariantRuntimeProps): react_jsx_runtime.JSX.Element;
47
+
48
+ export { type PreviewRuntimeOptions, type PreviewRuntimeState, type PreviewVariantLike, PreviewVariantRuntime, executeVariantLoaders, resolvePreviewRuntimeState, usePreviewVariantRuntime };
@@ -0,0 +1,91 @@
1
+ // src/preview-runtime.tsx
2
+ import { useEffect, useState } from "react";
3
+ import { Fragment, jsx } from "react/jsx-runtime";
4
+ var EMPTY_STATE = {
5
+ content: null,
6
+ isLoading: false,
7
+ error: null,
8
+ loadedData: void 0
9
+ };
10
+ function toError(error) {
11
+ return error instanceof Error ? error : new Error(String(error));
12
+ }
13
+ async function executeVariantLoaders(loaders, loadedData) {
14
+ const hasLoaders = !!loaders && loaders.length > 0;
15
+ if (!hasLoaders) {
16
+ return loadedData;
17
+ }
18
+ const results = await Promise.all(loaders.map((loader) => loader()));
19
+ const mergedFromLoaders = results.reduce(
20
+ (acc, result) => ({ ...acc, ...result }),
21
+ {}
22
+ );
23
+ return loadedData ? { ...mergedFromLoaders, ...loadedData } : mergedFromLoaders;
24
+ }
25
+ async function resolvePreviewRuntimeState(options) {
26
+ const { variant, loadedData } = options;
27
+ if (!variant) {
28
+ return EMPTY_STATE;
29
+ }
30
+ try {
31
+ const mergedLoadedData = await executeVariantLoaders(variant.loaders, loadedData);
32
+ const content = variant.render({ loadedData: mergedLoadedData });
33
+ return {
34
+ content,
35
+ isLoading: false,
36
+ error: null,
37
+ loadedData: mergedLoadedData
38
+ };
39
+ } catch (error) {
40
+ return {
41
+ content: null,
42
+ isLoading: false,
43
+ error: toError(error),
44
+ loadedData: void 0
45
+ };
46
+ }
47
+ }
48
+ function usePreviewVariantRuntime(options) {
49
+ const { variant, loadedData } = options;
50
+ const [state, setState] = useState(EMPTY_STATE);
51
+ useEffect(() => {
52
+ let cancelled = false;
53
+ if (!variant) {
54
+ setState(EMPTY_STATE);
55
+ return () => {
56
+ cancelled = true;
57
+ };
58
+ }
59
+ const hasLoaders = !!variant.loaders && variant.loaders.length > 0;
60
+ setState({
61
+ content: null,
62
+ isLoading: hasLoaders,
63
+ error: null,
64
+ loadedData: void 0
65
+ });
66
+ resolvePreviewRuntimeState({ variant, loadedData }).then((nextState) => {
67
+ if (!cancelled) {
68
+ setState(nextState);
69
+ }
70
+ });
71
+ return () => {
72
+ cancelled = true;
73
+ };
74
+ }, [variant, loadedData]);
75
+ return state;
76
+ }
77
+ function PreviewVariantRuntime({
78
+ variant,
79
+ loadedData,
80
+ children
81
+ }) {
82
+ const state = usePreviewVariantRuntime({ variant, loadedData });
83
+ return /* @__PURE__ */ jsx(Fragment, { children: children(state) });
84
+ }
85
+ export {
86
+ PreviewVariantRuntime,
87
+ executeVariantLoaders,
88
+ resolvePreviewRuntimeState,
89
+ usePreviewVariantRuntime
90
+ };
91
+ //# sourceMappingURL=preview-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/preview-runtime.tsx"],"sourcesContent":["import { useEffect, useState, type ReactNode } from \"react\";\nimport type { VariantLoader, VariantRenderOptions } from \"./types.js\";\n\n/**\n * Minimal contract for rendering a preview variant.\n * Compatible with fragment variants and Storybook-adapted variants.\n */\nexport interface PreviewVariantLike {\n render: (options?: VariantRenderOptions) => ReactNode;\n loaders?: VariantLoader[];\n}\n\nexport interface PreviewRuntimeState {\n content: ReactNode | null;\n isLoading: boolean;\n error: Error | null;\n loadedData?: Record<string, unknown>;\n}\n\nexport interface PreviewRuntimeOptions {\n variant?: PreviewVariantLike | null;\n loadedData?: Record<string, unknown>;\n}\n\nconst EMPTY_STATE: PreviewRuntimeState = {\n content: null,\n isLoading: false,\n error: null,\n loadedData: undefined,\n};\n\nfunction toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\n/**\n * Execute all variant loaders and merge their payloads.\n * `loadedData` is applied last so host-level overrides win.\n */\nexport async function executeVariantLoaders(\n loaders: VariantLoader[] | undefined,\n loadedData?: Record<string, unknown>,\n): Promise<Record<string, unknown> | undefined> {\n const hasLoaders = !!loaders && loaders.length > 0;\n if (!hasLoaders) {\n return loadedData;\n }\n\n const results = await Promise.all(loaders.map((loader) => loader()));\n const mergedFromLoaders = results.reduce<Record<string, unknown>>(\n (acc, result) => ({ ...acc, ...result }),\n {},\n );\n\n return loadedData ? { ...mergedFromLoaders, ...loadedData } : mergedFromLoaders;\n}\n\n/**\n * Resolve a full runtime state (loader execution + render) in one async call.\n * This is useful for testing and for hook/component orchestration.\n */\nexport async function resolvePreviewRuntimeState(\n options: PreviewRuntimeOptions,\n): Promise<PreviewRuntimeState> {\n const { variant, loadedData } = options;\n if (!variant) {\n return EMPTY_STATE;\n }\n\n try {\n const mergedLoadedData = await executeVariantLoaders(variant.loaders, loadedData);\n const content = variant.render({ loadedData: mergedLoadedData });\n return {\n content,\n isLoading: false,\n error: null,\n loadedData: mergedLoadedData,\n };\n } catch (error) {\n return {\n content: null,\n isLoading: false,\n error: toError(error),\n loadedData: undefined,\n };\n }\n}\n\n/**\n * Hook for rendering a preview variant with loader support.\n */\nexport function usePreviewVariantRuntime(\n options: PreviewRuntimeOptions,\n): PreviewRuntimeState {\n const { variant, loadedData } = options;\n const [state, setState] = useState<PreviewRuntimeState>(EMPTY_STATE);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!variant) {\n setState(EMPTY_STATE);\n return () => {\n cancelled = true;\n };\n }\n\n const hasLoaders = !!variant.loaders && variant.loaders.length > 0;\n setState({\n content: null,\n isLoading: hasLoaders,\n error: null,\n loadedData: undefined,\n });\n\n resolvePreviewRuntimeState({ variant, loadedData }).then((nextState) => {\n if (!cancelled) {\n setState(nextState);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [variant, loadedData]);\n\n return state;\n}\n\ninterface PreviewVariantRuntimeProps extends PreviewRuntimeOptions {\n children: (state: PreviewRuntimeState) => ReactNode;\n}\n\n/**\n * Render-prop component wrapper around `usePreviewVariantRuntime`.\n */\nexport function PreviewVariantRuntime({\n variant,\n loadedData,\n children,\n}: PreviewVariantRuntimeProps) {\n const state = usePreviewVariantRuntime({ variant, loadedData });\n return <>{children(state)}</>;\n}\n"],"mappings":";AAAA,SAAS,WAAW,gBAAgC;AA8I3C;AAtHT,IAAM,cAAmC;AAAA,EACvC,SAAS;AAAA,EACT,WAAW;AAAA,EACX,OAAO;AAAA,EACP,YAAY;AACd;AAEA,SAAS,QAAQ,OAAuB;AACtC,SAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACjE;AAMA,eAAsB,sBACpB,SACA,YAC8C;AAC9C,QAAM,aAAa,CAAC,CAAC,WAAW,QAAQ,SAAS;AACjD,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ,IAAI,CAAC,WAAW,OAAO,CAAC,CAAC;AACnE,QAAM,oBAAoB,QAAQ;AAAA,IAChC,CAAC,KAAK,YAAY,EAAE,GAAG,KAAK,GAAG,OAAO;AAAA,IACtC,CAAC;AAAA,EACH;AAEA,SAAO,aAAa,EAAE,GAAG,mBAAmB,GAAG,WAAW,IAAI;AAChE;AAMA,eAAsB,2BACpB,SAC8B;AAC9B,QAAM,EAAE,SAAS,WAAW,IAAI;AAChC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,mBAAmB,MAAM,sBAAsB,QAAQ,SAAS,UAAU;AAChF,UAAM,UAAU,QAAQ,OAAO,EAAE,YAAY,iBAAiB,CAAC;AAC/D,WAAO;AAAA,MACL;AAAA,MACA,WAAW;AAAA,MACX,OAAO;AAAA,MACP,YAAY;AAAA,IACd;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO,QAAQ,KAAK;AAAA,MACpB,YAAY;AAAA,IACd;AAAA,EACF;AACF;AAKO,SAAS,yBACd,SACqB;AACrB,QAAM,EAAE,SAAS,WAAW,IAAI;AAChC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA8B,WAAW;AAEnE,YAAU,MAAM;AACd,QAAI,YAAY;AAEhB,QAAI,CAAC,SAAS;AACZ,eAAS,WAAW;AACpB,aAAO,MAAM;AACX,oBAAY;AAAA,MACd;AAAA,IACF;AAEA,UAAM,aAAa,CAAC,CAAC,QAAQ,WAAW,QAAQ,QAAQ,SAAS;AACjE,aAAS;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO;AAAA,MACP,YAAY;AAAA,IACd,CAAC;AAED,+BAA2B,EAAE,SAAS,WAAW,CAAC,EAAE,KAAK,CAAC,cAAc;AACtE,UAAI,CAAC,WAAW;AACd,iBAAS,SAAS;AAAA,MACpB;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,SAAS,UAAU,CAAC;AAExB,SAAO;AACT;AASO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AACF,GAA+B;AAC7B,QAAM,QAAQ,yBAAyB,EAAE,SAAS,WAAW,CAAC;AAC9D,SAAO,gCAAG,mBAAS,KAAK,GAAE;AAC5B;","names":[]}
@@ -1,5 +1,5 @@
1
1
  import { ComponentType, ReactNode, JSX } from 'react';
2
- export { F as FragmentDefinition, a as FragmentDefinitionV2 } from './governance-eEzCyfes.js';
2
+ export { F as FragmentDefinition, b as FragmentDefinitionV2 } from './governance-CLk_wkP9.js';
3
3
  import 'zod';
4
4
  import './topology/index.js';
5
5
  import './types-xJ2xyp_G.js';
@@ -9,7 +9,8 @@ import './types-xJ2xyp_G.js';
9
9
  *
10
10
  * Import from '@usefragments/core/react' when you need React-typed
11
11
  * component definitions. The main '@usefragments/core' entrypoint
12
- * works without React installed.
12
+ * works without React installed — story and preview-runtime APIs live on
13
+ * `@usefragments/core/story` and `@usefragments/core/preview-runtime`.
13
14
  */
14
15
 
15
16
  /**
@@ -24,7 +24,7 @@ import {
24
24
  suppressionDirectiveSchema,
25
25
  validatorResultSchema,
26
26
  violationSchema
27
- } from "../chunk-DGHZQTLH.js";
27
+ } from "../chunk-XN3LSDPY.js";
28
28
  import "../chunk-JNBFJ34I.js";
29
29
  import "../chunk-EIYNNS77.js";
30
30
  import {
@@ -0,0 +1,187 @@
1
+ import { ReactNode, ComponentType } from 'react';
2
+ import { isExportStory as isExportStory$1, storyNameFromExport as storyNameFromExport$1, toId as toId$1 } from '@storybook/csf';
3
+ import { F as FragmentDefinition } from './governance-CLk_wkP9.js';
4
+ import 'zod';
5
+ import './topology/index.js';
6
+ import './types-xJ2xyp_G.js';
7
+
8
+ declare const toId: typeof toId$1;
9
+ declare const storyNameFromExport: typeof storyNameFromExport$1;
10
+ declare const isExportStory: typeof isExportStory$1;
11
+
12
+ /**
13
+ * Runtime adapter for converting Storybook CSF modules to Fragment definitions.
14
+ *
15
+ * This operates on IMPORTED modules at runtime, not source code parsing.
16
+ * By leveraging Vite's module system, we get 100% accurate render functions
17
+ * without any regex or AST parsing complexity.
18
+ *
19
+ * Supports Storybook 8.x with both CSF2 (Template.bind) and CSF3 (object stories).
20
+ */
21
+
22
+ /**
23
+ * Storybook decorator function signature
24
+ */
25
+ type Decorator = (Story: () => ReactNode, context: StoryContext) => ReactNode;
26
+ /**
27
+ * Storybook loader function signature
28
+ */
29
+ type Loader = (context: StoryContext) => Promise<Record<string, unknown>>;
30
+ /**
31
+ * Storybook play function signature (internal, extends StoryContext)
32
+ */
33
+ type StorybookPlayFunction = (context: StorybookPlayFunctionContext) => Promise<void>;
34
+ /**
35
+ * Context passed to Storybook play functions (extends StoryContext for compatibility)
36
+ */
37
+ interface StorybookPlayFunctionContext extends StoryContext {
38
+ canvasElement: HTMLElement;
39
+ step: (name: string, fn: () => Promise<void>) => Promise<void>;
40
+ }
41
+ /**
42
+ * Context passed to decorators and render functions
43
+ */
44
+ interface StoryContext {
45
+ args: Record<string, unknown>;
46
+ argTypes: Record<string, StoryArgType>;
47
+ globals: Record<string, unknown>;
48
+ parameters: Record<string, unknown>;
49
+ id: string;
50
+ kind: string;
51
+ name: string;
52
+ story: string;
53
+ viewMode: "story" | "docs";
54
+ loaded: Record<string, unknown>;
55
+ abortSignal: AbortSignal;
56
+ componentId: string;
57
+ title: string;
58
+ }
59
+ /**
60
+ * Storybook Meta (default export)
61
+ */
62
+ interface StoryMeta {
63
+ title?: string;
64
+ component?: ComponentType<unknown>;
65
+ subcomponents?: Record<string, ComponentType<unknown>>;
66
+ tags?: string[];
67
+ parameters?: Record<string, unknown> & {
68
+ docs?: {
69
+ description?: {
70
+ component?: string;
71
+ };
72
+ };
73
+ };
74
+ argTypes?: Record<string, StoryArgType>;
75
+ args?: Record<string, unknown>;
76
+ decorators?: Decorator[];
77
+ loaders?: Loader[];
78
+ render?: (args: Record<string, unknown>, context?: StoryContext) => ReactNode;
79
+ includeStories?: string[] | RegExp;
80
+ excludeStories?: string[] | RegExp;
81
+ }
82
+ /**
83
+ * Storybook argType definition
84
+ */
85
+ interface StoryArgType {
86
+ control?: string | false | {
87
+ type: string;
88
+ min?: number;
89
+ max?: number;
90
+ step?: number;
91
+ presetColors?: string[];
92
+ };
93
+ options?: string[];
94
+ description?: string;
95
+ table?: {
96
+ defaultValue?: {
97
+ summary: string;
98
+ };
99
+ type?: {
100
+ summary: string;
101
+ };
102
+ category?: string;
103
+ subcategory?: string;
104
+ disable?: boolean;
105
+ };
106
+ type?: {
107
+ name: string;
108
+ required?: boolean;
109
+ };
110
+ name?: string;
111
+ defaultValue?: unknown;
112
+ if?: {
113
+ arg?: string;
114
+ exists?: boolean;
115
+ };
116
+ mapping?: Record<string, unknown>;
117
+ action?: string;
118
+ }
119
+ /**
120
+ * Storybook Story export (CSF3)
121
+ */
122
+ interface Story {
123
+ args?: Record<string, unknown>;
124
+ argTypes?: Record<string, StoryArgType>;
125
+ render?: (args: Record<string, unknown>, context?: StoryContext) => ReactNode;
126
+ decorators?: Decorator[];
127
+ loaders?: Loader[];
128
+ play?: StorybookPlayFunction;
129
+ parameters?: Record<string, unknown> & {
130
+ docs?: {
131
+ description?: {
132
+ story?: string;
133
+ };
134
+ };
135
+ };
136
+ name?: string;
137
+ storyName?: string;
138
+ tags?: string[];
139
+ }
140
+ /**
141
+ * CSF2 story function (from Template.bind({})) with args attached
142
+ */
143
+ type CSF2Story = ((args: Record<string, unknown>) => ReactNode) & {
144
+ args?: Record<string, unknown>;
145
+ argTypes?: Record<string, StoryArgType>;
146
+ decorators?: Decorator[];
147
+ loaders?: Loader[];
148
+ play?: StorybookPlayFunction;
149
+ parameters?: Record<string, unknown>;
150
+ storyName?: string;
151
+ };
152
+ /**
153
+ * A complete Storybook module with default meta and named story exports
154
+ */
155
+ interface StoryModule {
156
+ default: StoryMeta;
157
+ [exportName: string]: Story | CSF2Story | StoryMeta | unknown;
158
+ }
159
+ /**
160
+ * Global configuration from preview.tsx
161
+ */
162
+ interface PreviewConfig {
163
+ decorators?: Decorator[];
164
+ parameters?: Record<string, unknown>;
165
+ globalTypes?: Record<string, unknown>;
166
+ args?: Record<string, unknown>;
167
+ argTypes?: Record<string, StoryArgType>;
168
+ loaders?: Loader[];
169
+ }
170
+ /**
171
+ * Set the global preview configuration loaded from .storybook/preview.tsx
172
+ */
173
+ declare function setPreviewConfig(config: PreviewConfig): void;
174
+ /**
175
+ * Get the current global preview configuration
176
+ */
177
+ declare function getPreviewConfig(): PreviewConfig;
178
+ /**
179
+ * Convert a Storybook module to a Fragment definition at runtime.
180
+ *
181
+ * @param storyModule - The imported Storybook module
182
+ * @param filePath - File path for metadata extraction
183
+ * @returns A complete FragmentDefinition ready for the viewer
184
+ */
185
+ declare function storyModuleToFragment(storyModule: StoryModule, filePath: string): FragmentDefinition | null;
186
+
187
+ export { type CSF2Story, type Decorator, type Loader, type PreviewConfig, type Story, type StoryArgType, type StoryContext, type StoryMeta, type StoryModule, getPreviewConfig, isExportStory, setPreviewConfig, storyModuleToFragment, storyNameFromExport, toId };