@usefragments/core 1.10.2 → 2.0.0

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.
Files changed (130) hide show
  1. package/dist/{chunk-MZ4SW3TP.js → chunk-3IOWHECM.js} +8 -1
  2. package/dist/{chunk-MZ4SW3TP.js.map → chunk-3IOWHECM.js.map} +1 -1
  3. package/dist/chunk-7ULGH74M.js +66 -0
  4. package/dist/chunk-7ULGH74M.js.map +1 -0
  5. package/dist/{chunk-XN3LSDPY.js → chunk-BMPYIUZE.js} +612 -344
  6. package/dist/chunk-BMPYIUZE.js.map +1 -0
  7. package/dist/{chunk-YF65VYRY.js → chunk-ML5S6QNU.js} +191 -169
  8. package/dist/chunk-ML5S6QNU.js.map +1 -0
  9. package/dist/{chunk-3LLRNCPX.js → chunk-MZ2FS7U4.js} +1 -1
  10. package/dist/chunk-MZ2FS7U4.js.map +1 -0
  11. package/dist/chunk-PWIJMOI4.js +202 -0
  12. package/dist/chunk-PWIJMOI4.js.map +1 -0
  13. package/dist/chunk-RYFULE43.js +578 -0
  14. package/dist/chunk-RYFULE43.js.map +1 -0
  15. package/dist/codes/index.d.ts +2 -2
  16. package/dist/codes/index.js +3 -2
  17. package/dist/compiled-types/index.d.ts +327 -2
  18. package/dist/compiled-types/index.js +1 -1
  19. package/dist/generate/index.d.ts +3 -2
  20. package/dist/{governance-CLk_wkP9.d.ts → governance-hOPXGbbs.d.ts} +474 -515
  21. package/dist/governance-telemetry.d.ts +6 -0
  22. package/dist/governance-telemetry.js +1 -1
  23. package/dist/{index-_sxhUNqx.d.ts → index-C8bcXVav.d.ts} +448 -448
  24. package/dist/index.d.ts +3280 -1305
  25. package/dist/index.js +2414 -350
  26. package/dist/index.js.map +1 -1
  27. package/dist/manifest.d.ts +228 -0
  28. package/dist/manifest.js +24 -0
  29. package/dist/manifest.js.map +1 -0
  30. package/dist/preview/index.js +45 -1
  31. package/dist/preview/index.js.map +1 -1
  32. package/dist/preview-runtime.d.ts +1 -2
  33. package/dist/preview-runtime.js +150 -14
  34. package/dist/preview-runtime.js.map +1 -1
  35. package/dist/react-types.d.ts +1 -2
  36. package/dist/registry.d.ts +1412 -203
  37. package/dist/registry.js +30 -3
  38. package/dist/schemas/index.d.ts +1 -1
  39. package/dist/schemas/index.js +3 -2
  40. package/dist/storyAdapter.d.ts +1 -2
  41. package/dist/storyAdapter.js +11 -49
  42. package/dist/storyAdapter.js.map +1 -1
  43. package/dist/test-utils.d.ts +3 -2
  44. package/dist/topology/index.d.ts +1 -1
  45. package/dist/topology/index.js +1 -1
  46. package/package.json +8 -2
  47. package/src/__tests__/contract-parser.test.ts +318 -277
  48. package/src/__tests__/preview-runtime-hook.test.tsx +315 -0
  49. package/src/__tests__/preview-runtime.test.tsx +30 -8
  50. package/src/__tests__/schema.test.ts +191 -14
  51. package/src/analysis-plan/analysis-plan-v1.test.ts +320 -0
  52. package/src/analysis-plan/coverage.ts +181 -0
  53. package/src/analysis-plan/digest.ts +141 -0
  54. package/src/analysis-plan/index.ts +34 -0
  55. package/src/analysis-plan/types.ts +207 -0
  56. package/src/approved-contract-tokens.test.ts +39 -0
  57. package/src/approved-contract-tokens.ts +18 -0
  58. package/src/codes/__tests__/codes.test.ts +13 -0
  59. package/src/codes/codes.ts +40 -0
  60. package/src/compiled-types/index.ts +640 -39
  61. package/src/compiled-types/parse.test.ts +145 -4
  62. package/src/component-contract.ts +95 -53
  63. package/src/composition.ts +7 -13
  64. package/src/constants.ts +3 -6
  65. package/src/contract/hash.test.ts +20 -0
  66. package/src/contract/hash.ts +66 -9
  67. package/src/contract/index.ts +24 -1
  68. package/src/contract/manifest.test.ts +94 -0
  69. package/src/contract/manifest.ts +68 -0
  70. package/src/contract/preimage.test.ts +219 -1
  71. package/src/contract/preimage.ts +326 -6
  72. package/src/contract/stamp.test.ts +3 -0
  73. package/src/contract/stamp.ts +1 -1
  74. package/src/contract-parser.ts +54 -30
  75. package/src/defineFragment.test.ts +476 -91
  76. package/src/defineFragment.ts +204 -114
  77. package/src/domain-ids.test.ts +35 -0
  78. package/src/domain-ids.ts +61 -0
  79. package/src/evaluation/evaluate.test.ts +522 -0
  80. package/src/evaluation/evaluate.ts +690 -0
  81. package/src/evaluation/evaluation-v2-receipt-v1.test.ts +772 -0
  82. package/src/evaluation/index.ts +58 -0
  83. package/src/evaluation/receipt.ts +753 -0
  84. package/src/evaluation/types.ts +406 -0
  85. package/src/facts/builders.ts +2 -0
  86. package/src/facts/compile.ts +29 -6
  87. package/src/facts/fact-index.ts +13 -3
  88. package/src/facts/fact-integrity-v1.test.ts +172 -0
  89. package/src/facts/facts.test.ts +15 -0
  90. package/src/facts/ids.ts +46 -3
  91. package/src/facts/index.ts +14 -1
  92. package/src/facts/integrity.ts +134 -0
  93. package/src/facts/types.ts +36 -0
  94. package/src/governance-integrity.test.ts +1 -0
  95. package/src/governance-integrity.ts +5 -3
  96. package/src/governance-telemetry.ts +8 -0
  97. package/src/governance.ts +70 -8
  98. package/src/index.ts +230 -37
  99. package/src/preview/validation.test.ts +62 -0
  100. package/src/preview/validation.ts +48 -2
  101. package/src/preview-runtime.tsx +227 -20
  102. package/src/registry-install-plan.ts +200 -109
  103. package/src/registry-shards.test.ts +263 -0
  104. package/src/registry.ts +237 -0
  105. package/src/repository-binding.test.ts +50 -0
  106. package/src/repository-binding.ts +96 -0
  107. package/src/rules/families.test.ts +36 -0
  108. package/src/rules/finding.ts +7 -2
  109. package/src/rules/index.ts +17 -1
  110. package/src/rules/rule-config.test.ts +66 -0
  111. package/src/rules/rule-config.ts +73 -0
  112. package/src/rules/rules.test.ts +26 -0
  113. package/src/rules/tokens-css-vars-must-be-defined.test.ts +51 -2
  114. package/src/rules/tokens-css-vars-must-be-defined.ts +34 -1
  115. package/src/schema.ts +293 -113
  116. package/src/schemas/index.ts +1 -1
  117. package/src/storyAdapter.test.ts +68 -12
  118. package/src/storyAdapter.ts +44 -75
  119. package/src/topology/resolve-area.ts +1 -1
  120. package/src/types.ts +258 -40
  121. package/dist/chunk-3LLRNCPX.js.map +0 -1
  122. package/dist/chunk-RANPUC6C.js +0 -72
  123. package/dist/chunk-RANPUC6C.js.map +0 -1
  124. package/dist/chunk-XN3LSDPY.js.map +0 -1
  125. package/dist/chunk-YF65VYRY.js.map +0 -1
  126. package/src/fragment-types.ts +0 -214
  127. package/src/react-create-element.test.ts +0 -22
  128. package/src/react-create-element.ts +0 -12
  129. package/src/storyFilters.test.ts +0 -350
  130. package/src/storyFilters.ts +0 -253
@@ -1,5 +1,5 @@
1
1
  // src/preview-runtime.tsx
2
- import { useEffect, useState } from "react";
2
+ import { useEffect, useRef, useState } from "react";
3
3
  import { Fragment, jsx } from "react/jsx-runtime";
4
4
  var EMPTY_STATE = {
5
5
  content: null,
@@ -7,9 +7,131 @@ var EMPTY_STATE = {
7
7
  error: null,
8
8
  loadedData: void 0
9
9
  };
10
+ var LOADING_STATE = {
11
+ content: null,
12
+ isLoading: true,
13
+ error: null,
14
+ loadedData: void 0
15
+ };
16
+ var LOADED_DATA_COMPARISON_MAX_DEPTH = 32;
17
+ var LOADED_DATA_COMPARISON_MAX_OBJECTS = 1e3;
18
+ var LOADED_DATA_COMPARISON_MAX_PROPERTIES = 4e3;
19
+ var LOADED_DATA_COMPARISON_ERROR = new Error(
20
+ `Preview loadedData could not be compared safely. Pass a stable object reference, or use JSON-like data within ${LOADED_DATA_COMPARISON_MAX_DEPTH} levels, ${LOADED_DATA_COMPARISON_MAX_OBJECTS} objects, and ${LOADED_DATA_COMPARISON_MAX_PROPERTIES} property inspections.`
21
+ );
22
+ var LOADED_DATA_COMPARISON_ERROR_STATE = {
23
+ content: null,
24
+ isLoading: false,
25
+ error: LOADED_DATA_COMPARISON_ERROR,
26
+ loadedData: void 0
27
+ };
10
28
  function toError(error) {
11
29
  return error instanceof Error ? error : new Error(String(error));
12
30
  }
31
+ var NO_PENDING_LOADED_DATA = /* @__PURE__ */ Symbol("no-pending-loaded-data");
32
+ function isPlainRecord(value) {
33
+ const prototype = Object.getPrototypeOf(value);
34
+ return prototype === Object.prototype || prototype === null;
35
+ }
36
+ function compareLoadedDataProperties(left, right, depth, context) {
37
+ let leftPropertyCount = 0;
38
+ for (const key in left) {
39
+ if (context.inspectedProperties >= LOADED_DATA_COMPARISON_MAX_PROPERTIES) {
40
+ return "indeterminate";
41
+ }
42
+ context.inspectedProperties += 1;
43
+ if (!Object.prototype.hasOwnProperty.call(left, key)) continue;
44
+ leftPropertyCount += 1;
45
+ if (!Object.prototype.hasOwnProperty.call(right, key)) return "different";
46
+ const leftDescriptor = Object.getOwnPropertyDescriptor(left, key);
47
+ const rightDescriptor = Object.getOwnPropertyDescriptor(right, key);
48
+ if (!leftDescriptor || !rightDescriptor || !("value" in leftDescriptor) || !("value" in rightDescriptor)) {
49
+ return "indeterminate";
50
+ }
51
+ const comparison = compareLoadedDataValue(
52
+ leftDescriptor.value,
53
+ rightDescriptor.value,
54
+ depth + 1,
55
+ context
56
+ );
57
+ if (comparison !== "equal") return comparison;
58
+ }
59
+ let rightPropertyCount = 0;
60
+ for (const key in right) {
61
+ if (context.inspectedProperties >= LOADED_DATA_COMPARISON_MAX_PROPERTIES) {
62
+ return "indeterminate";
63
+ }
64
+ context.inspectedProperties += 1;
65
+ if (Object.prototype.hasOwnProperty.call(right, key)) rightPropertyCount += 1;
66
+ }
67
+ return leftPropertyCount === rightPropertyCount ? "equal" : "different";
68
+ }
69
+ function compareLoadedDataValue(left, right, depth, context) {
70
+ if (Object.is(left, right)) return "equal";
71
+ const leftType = typeof left;
72
+ const rightType = typeof right;
73
+ if (leftType !== rightType || left === null || right === null) return "different";
74
+ if (leftType === "function" || leftType === "symbol") return "indeterminate";
75
+ if (leftType !== "object") return "different";
76
+ const leftObject = left;
77
+ const rightObject = right;
78
+ const pairedRight = context.leftToRight.get(leftObject);
79
+ const pairedLeft = context.rightToLeft.get(rightObject);
80
+ if (pairedRight || pairedLeft) {
81
+ return pairedRight === rightObject && pairedLeft === leftObject ? "equal" : "different";
82
+ }
83
+ if (depth >= LOADED_DATA_COMPARISON_MAX_DEPTH) return "indeterminate";
84
+ if (context.comparedObjects >= LOADED_DATA_COMPARISON_MAX_OBJECTS) {
85
+ return "indeterminate";
86
+ }
87
+ const leftIsArray = Array.isArray(leftObject);
88
+ const rightIsArray = Array.isArray(rightObject);
89
+ if (leftIsArray !== rightIsArray) return "different";
90
+ if (leftIsArray && leftObject.length !== rightObject.length) {
91
+ return "different";
92
+ }
93
+ if (!leftIsArray) {
94
+ const leftIsPlainRecord = isPlainRecord(leftObject);
95
+ const rightIsPlainRecord = isPlainRecord(rightObject);
96
+ if (leftIsPlainRecord !== rightIsPlainRecord) return "different";
97
+ if (!leftIsPlainRecord) return "indeterminate";
98
+ }
99
+ context.comparedObjects += 1;
100
+ context.leftToRight.set(leftObject, rightObject);
101
+ context.rightToLeft.set(rightObject, leftObject);
102
+ return compareLoadedDataProperties(leftObject, rightObject, depth, context);
103
+ }
104
+ function compareLoadedData(left, right) {
105
+ try {
106
+ return compareLoadedDataValue(left, right, 0, {
107
+ comparedObjects: 0,
108
+ inspectedProperties: 0,
109
+ leftToRight: /* @__PURE__ */ new WeakMap(),
110
+ rightToLeft: /* @__PURE__ */ new WeakMap()
111
+ });
112
+ } catch {
113
+ return "indeterminate";
114
+ }
115
+ }
116
+ function useStableLoadedData(loadedData) {
117
+ const stableLoadedData = useRef(loadedData);
118
+ const pendingLoadedData = useRef(NO_PENDING_LOADED_DATA);
119
+ const comparison = compareLoadedData(stableLoadedData.current, loadedData);
120
+ if (comparison === "equal") {
121
+ pendingLoadedData.current = NO_PENDING_LOADED_DATA;
122
+ return { loadedData: stableLoadedData.current, comparisonError: null };
123
+ }
124
+ if (comparison === "different" || pendingLoadedData.current === loadedData) {
125
+ stableLoadedData.current = loadedData;
126
+ pendingLoadedData.current = NO_PENDING_LOADED_DATA;
127
+ return { loadedData, comparisonError: null };
128
+ }
129
+ pendingLoadedData.current = loadedData;
130
+ return {
131
+ loadedData: stableLoadedData.current,
132
+ comparisonError: LOADED_DATA_COMPARISON_ERROR
133
+ };
134
+ }
13
135
  async function executeVariantLoaders(loaders, loadedData) {
14
136
  const hasLoaders = !!loaders && loaders.length > 0;
15
137
  if (!hasLoaders) {
@@ -46,33 +168,47 @@ async function resolvePreviewRuntimeState(options) {
46
168
  }
47
169
  }
48
170
  function usePreviewVariantRuntime(options) {
49
- const { variant, loadedData } = options;
50
- const [state, setState] = useState(EMPTY_STATE);
171
+ const { variant } = options;
172
+ const { loadedData, comparisonError } = useStableLoadedData(options.loadedData);
173
+ const [resolution, setResolution] = useState({
174
+ variant: null,
175
+ loadedData: void 0,
176
+ state: EMPTY_STATE
177
+ });
51
178
  useEffect(() => {
52
179
  let cancelled = false;
53
180
  if (!variant) {
54
- setState(EMPTY_STATE);
181
+ setResolution({ variant: null, loadedData, state: EMPTY_STATE });
55
182
  return () => {
56
183
  cancelled = true;
57
184
  };
58
185
  }
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
- });
186
+ if (comparisonError) {
187
+ setResolution({ variant, loadedData, state: LOADED_DATA_COMPARISON_ERROR_STATE });
188
+ return () => {
189
+ cancelled = true;
190
+ };
191
+ }
192
+ setResolution({ variant, loadedData, state: LOADING_STATE });
66
193
  resolvePreviewRuntimeState({ variant, loadedData }).then((nextState) => {
67
194
  if (!cancelled) {
68
- setState(nextState);
195
+ setResolution({ variant, loadedData, state: nextState });
69
196
  }
70
197
  });
71
198
  return () => {
72
199
  cancelled = true;
73
200
  };
74
- }, [variant, loadedData]);
75
- return state;
201
+ }, [variant, loadedData, comparisonError]);
202
+ if (!variant) {
203
+ return EMPTY_STATE;
204
+ }
205
+ if (comparisonError) {
206
+ return LOADED_DATA_COMPARISON_ERROR_STATE;
207
+ }
208
+ if (resolution.variant !== variant || resolution.loadedData !== loadedData) {
209
+ return LOADING_STATE;
210
+ }
211
+ return resolution.state;
76
212
  }
77
213
  function PreviewVariantRuntime({
78
214
  variant,
@@ -1 +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
+ {"version":3,"sources":["../src/preview-runtime.tsx"],"sourcesContent":["import { useEffect, useRef, 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\nconst LOADING_STATE: PreviewRuntimeState = {\n content: null,\n isLoading: true,\n error: null,\n loadedData: undefined,\n};\n\nconst LOADED_DATA_COMPARISON_MAX_DEPTH = 32;\nconst LOADED_DATA_COMPARISON_MAX_OBJECTS = 1_000;\nconst LOADED_DATA_COMPARISON_MAX_PROPERTIES = 4_000;\n\nconst LOADED_DATA_COMPARISON_ERROR = new Error(\n \"Preview loadedData could not be compared safely. Pass a stable object reference, or use \" +\n `JSON-like data within ${LOADED_DATA_COMPARISON_MAX_DEPTH} levels, ` +\n `${LOADED_DATA_COMPARISON_MAX_OBJECTS} objects, and ` +\n `${LOADED_DATA_COMPARISON_MAX_PROPERTIES} property inspections.`\n);\n\nconst LOADED_DATA_COMPARISON_ERROR_STATE: PreviewRuntimeState = {\n content: null,\n isLoading: false,\n error: LOADED_DATA_COMPARISON_ERROR,\n loadedData: undefined,\n};\n\ninterface PreviewRuntimeResolution {\n variant: PreviewVariantLike | null;\n loadedData?: Record<string, unknown>;\n state: PreviewRuntimeState;\n}\n\nfunction toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\ntype LoadedDataComparison = \"equal\" | \"different\" | \"indeterminate\";\nconst NO_PENDING_LOADED_DATA = Symbol(\"no-pending-loaded-data\");\n\ninterface LoadedDataComparisonContext {\n comparedObjects: number;\n inspectedProperties: number;\n leftToRight: WeakMap<object, object>;\n rightToLeft: WeakMap<object, object>;\n}\n\nfunction isPlainRecord(value: object): value is Record<string, unknown> {\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction compareLoadedDataProperties(\n left: object,\n right: object,\n depth: number,\n context: LoadedDataComparisonContext\n): LoadedDataComparison {\n let leftPropertyCount = 0;\n for (const key in left) {\n if (context.inspectedProperties >= LOADED_DATA_COMPARISON_MAX_PROPERTIES) {\n return \"indeterminate\";\n }\n context.inspectedProperties += 1;\n\n if (!Object.prototype.hasOwnProperty.call(left, key)) continue;\n leftPropertyCount += 1;\n if (!Object.prototype.hasOwnProperty.call(right, key)) return \"different\";\n\n const leftDescriptor = Object.getOwnPropertyDescriptor(left, key);\n const rightDescriptor = Object.getOwnPropertyDescriptor(right, key);\n if (\n !leftDescriptor ||\n !rightDescriptor ||\n !(\"value\" in leftDescriptor) ||\n !(\"value\" in rightDescriptor)\n ) {\n return \"indeterminate\";\n }\n\n const comparison = compareLoadedDataValue(\n leftDescriptor.value,\n rightDescriptor.value,\n depth + 1,\n context\n );\n if (comparison !== \"equal\") return comparison;\n }\n\n let rightPropertyCount = 0;\n for (const key in right) {\n if (context.inspectedProperties >= LOADED_DATA_COMPARISON_MAX_PROPERTIES) {\n return \"indeterminate\";\n }\n context.inspectedProperties += 1;\n if (Object.prototype.hasOwnProperty.call(right, key)) rightPropertyCount += 1;\n }\n\n return leftPropertyCount === rightPropertyCount ? \"equal\" : \"different\";\n}\n\nfunction compareLoadedDataValue(\n left: unknown,\n right: unknown,\n depth: number,\n context: LoadedDataComparisonContext\n): LoadedDataComparison {\n if (Object.is(left, right)) return \"equal\";\n\n const leftType = typeof left;\n const rightType = typeof right;\n if (leftType !== rightType || left === null || right === null) return \"different\";\n if (leftType === \"function\" || leftType === \"symbol\") return \"indeterminate\";\n if (leftType !== \"object\") return \"different\";\n\n const leftObject = left as object;\n const rightObject = right as object;\n const pairedRight = context.leftToRight.get(leftObject);\n const pairedLeft = context.rightToLeft.get(rightObject);\n if (pairedRight || pairedLeft) {\n return pairedRight === rightObject && pairedLeft === leftObject ? \"equal\" : \"different\";\n }\n\n if (depth >= LOADED_DATA_COMPARISON_MAX_DEPTH) return \"indeterminate\";\n if (context.comparedObjects >= LOADED_DATA_COMPARISON_MAX_OBJECTS) {\n return \"indeterminate\";\n }\n\n const leftIsArray = Array.isArray(leftObject);\n const rightIsArray = Array.isArray(rightObject);\n if (leftIsArray !== rightIsArray) return \"different\";\n if (leftIsArray && (leftObject as unknown[]).length !== (rightObject as unknown[]).length) {\n return \"different\";\n }\n if (!leftIsArray) {\n const leftIsPlainRecord = isPlainRecord(leftObject);\n const rightIsPlainRecord = isPlainRecord(rightObject);\n if (leftIsPlainRecord !== rightIsPlainRecord) return \"different\";\n if (!leftIsPlainRecord) return \"indeterminate\";\n }\n\n context.comparedObjects += 1;\n context.leftToRight.set(leftObject, rightObject);\n context.rightToLeft.set(rightObject, leftObject);\n\n return compareLoadedDataProperties(leftObject, rightObject, depth, context);\n}\n\nfunction compareLoadedData(\n left: Record<string, unknown> | undefined,\n right: Record<string, unknown> | undefined\n): LoadedDataComparison {\n try {\n return compareLoadedDataValue(left, right, 0, {\n comparedObjects: 0,\n inspectedProperties: 0,\n leftToRight: new WeakMap(),\n rightToLeft: new WeakMap(),\n });\n } catch {\n // Host data must not make render fail when an accessor or proxy cannot be inspected safely.\n return \"indeterminate\";\n }\n}\n\ninterface StableLoadedDataResult {\n loadedData: Record<string, unknown> | undefined;\n comparisonError: Error | null;\n}\n\nfunction useStableLoadedData(\n loadedData: Record<string, unknown> | undefined\n): StableLoadedDataResult {\n const stableLoadedData = useRef(loadedData);\n const pendingLoadedData = useRef<\n Record<string, unknown> | undefined | typeof NO_PENDING_LOADED_DATA\n >(NO_PENDING_LOADED_DATA);\n const comparison = compareLoadedData(stableLoadedData.current, loadedData);\n\n if (comparison === \"equal\") {\n pendingLoadedData.current = NO_PENDING_LOADED_DATA;\n return { loadedData: stableLoadedData.current, comparisonError: null };\n }\n\n if (comparison === \"different\" || pendingLoadedData.current === loadedData) {\n stableLoadedData.current = loadedData;\n pendingLoadedData.current = NO_PENDING_LOADED_DATA;\n return { loadedData, comparisonError: null };\n }\n\n pendingLoadedData.current = loadedData;\n return {\n loadedData: stableLoadedData.current,\n comparisonError: LOADED_DATA_COMPARISON_ERROR,\n };\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(options: PreviewRuntimeOptions): PreviewRuntimeState {\n const { variant } = options;\n const { loadedData, comparisonError } = useStableLoadedData(options.loadedData);\n const [resolution, setResolution] = useState<PreviewRuntimeResolution>({\n variant: null,\n loadedData: undefined,\n state: EMPTY_STATE,\n });\n\n useEffect(() => {\n let cancelled = false;\n\n if (!variant) {\n setResolution({ variant: null, loadedData, state: EMPTY_STATE });\n return () => {\n cancelled = true;\n };\n }\n\n if (comparisonError) {\n setResolution({ variant, loadedData, state: LOADED_DATA_COMPARISON_ERROR_STATE });\n return () => {\n cancelled = true;\n };\n }\n\n setResolution({ variant, loadedData, state: LOADING_STATE });\n\n resolvePreviewRuntimeState({ variant, loadedData }).then((nextState) => {\n if (!cancelled) {\n setResolution({ variant, loadedData, state: nextState });\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [variant, loadedData, comparisonError]);\n\n if (!variant) {\n return EMPTY_STATE;\n }\n\n if (comparisonError) {\n return LOADED_DATA_COMPARISON_ERROR_STATE;\n }\n\n if (resolution.variant !== variant || resolution.loadedData !== loadedData) {\n return LOADING_STATE;\n }\n\n return resolution.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":"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","names":[]}
@@ -1,8 +1,7 @@
1
1
  import { ComponentType, ReactNode, JSX } from 'react';
2
- export { F as FragmentDefinition, b as FragmentDefinitionV2 } from './governance-CLk_wkP9.js';
2
+ export { F as FragmentDefinition, a as FragmentDefinitionV2 } from './governance-hOPXGbbs.js';
3
3
  import 'zod';
4
4
  import './topology/index.js';
5
- import './types-xJ2xyp_G.js';
6
5
 
7
6
  /**
8
7
  * React-specific types for Fragments.