@getrheo/flow-runtime 1.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 (126) hide show
  1. package/dist/agentPrompt/index.d.ts +72 -0
  2. package/dist/agentPrompt/index.js +739 -0
  3. package/dist/agentPrompt/index.js.map +1 -0
  4. package/dist/aiFlowGenerationMerge.d.ts +32 -0
  5. package/dist/aiFlowGenerationMerge.js +120 -0
  6. package/dist/aiFlowGenerationMerge.js.map +1 -0
  7. package/dist/animations.d.ts +110 -0
  8. package/dist/animations.js +312 -0
  9. package/dist/animations.js.map +1 -0
  10. package/dist/assignment.d.ts +7 -0
  11. package/dist/assignment.js +25 -0
  12. package/dist/assignment.js.map +1 -0
  13. package/dist/brandGradient.d.ts +57 -0
  14. package/dist/brandGradient.js +137 -0
  15. package/dist/brandGradient.js.map +1 -0
  16. package/dist/brandGradientManifestIssues.d.ts +11 -0
  17. package/dist/brandGradientManifestIssues.js +302 -0
  18. package/dist/brandGradientManifestIssues.js.map +1 -0
  19. package/dist/buildFlowPreview.d.ts +7 -0
  20. package/dist/buildFlowPreview.js +81 -0
  21. package/dist/buildFlowPreview.js.map +1 -0
  22. package/dist/buttonVariantChrome.d.ts +26 -0
  23. package/dist/buttonVariantChrome.js +59 -0
  24. package/dist/buttonVariantChrome.js.map +1 -0
  25. package/dist/checkboxGlyphStyle.d.ts +31 -0
  26. package/dist/checkboxGlyphStyle.js +241 -0
  27. package/dist/checkboxGlyphStyle.js.map +1 -0
  28. package/dist/choiceOptionSelection.d.ts +11 -0
  29. package/dist/choiceOptionSelection.js +120 -0
  30. package/dist/choiceOptionSelection.js.map +1 -0
  31. package/dist/colorAlpha.d.ts +8 -0
  32. package/dist/colorAlpha.js +48 -0
  33. package/dist/colorAlpha.js.map +1 -0
  34. package/dist/counterLayer.d.ts +42 -0
  35. package/dist/counterLayer.js +95 -0
  36. package/dist/counterLayer.js.map +1 -0
  37. package/dist/decisionEval.d.ts +27 -0
  38. package/dist/decisionEval.js +197 -0
  39. package/dist/decisionEval.js.map +1 -0
  40. package/dist/dropShadow.d.ts +26 -0
  41. package/dist/dropShadow.js +76 -0
  42. package/dist/dropShadow.js.map +1 -0
  43. package/dist/emailPasswordAuthValidation.d.ts +16 -0
  44. package/dist/emailPasswordAuthValidation.js +25 -0
  45. package/dist/emailPasswordAuthValidation.js.map +1 -0
  46. package/dist/flowBuilderRules.d.ts +15 -0
  47. package/dist/flowBuilderRules.js +368 -0
  48. package/dist/flowBuilderRules.js.map +1 -0
  49. package/dist/flowGraph.d.ts +19 -0
  50. package/dist/flowGraph.js +373 -0
  51. package/dist/flowGraph.js.map +1 -0
  52. package/dist/hyperlinkLabel.d.ts +19 -0
  53. package/dist/hyperlinkLabel.js +232 -0
  54. package/dist/hyperlinkLabel.js.map +1 -0
  55. package/dist/index.d.ts +48 -0
  56. package/dist/index.js +4200 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/interpolateTemplate.d.ts +44 -0
  59. package/dist/interpolateTemplate.js +188 -0
  60. package/dist/interpolateTemplate.js.map +1 -0
  61. package/dist/layerRotate.d.ts +10 -0
  62. package/dist/layerRotate.js +9 -0
  63. package/dist/layerRotate.js.map +1 -0
  64. package/dist/layerTypography.d.ts +36 -0
  65. package/dist/layerTypography.js +68 -0
  66. package/dist/layerTypography.js.map +1 -0
  67. package/dist/layers.d.ts +69 -0
  68. package/dist/layers.js +257 -0
  69. package/dist/layers.js.map +1 -0
  70. package/dist/layout/index.d.ts +57 -0
  71. package/dist/layout/index.js +151 -0
  72. package/dist/layout/index.js.map +1 -0
  73. package/dist/manifestBillingSlice.d.ts +17 -0
  74. package/dist/manifestBillingSlice.js +102 -0
  75. package/dist/manifestBillingSlice.js.map +1 -0
  76. package/dist/prepareAiGeneratedScreen.d.ts +17 -0
  77. package/dist/prepareAiGeneratedScreen.js +99 -0
  78. package/dist/prepareAiGeneratedScreen.js.map +1 -0
  79. package/dist/publish-exports.json +166 -0
  80. package/dist/responsive/breakpoints.d.ts +34 -0
  81. package/dist/responsive/breakpoints.js +52 -0
  82. package/dist/responsive/breakpoints.js.map +1 -0
  83. package/dist/responsive/index.d.ts +8 -0
  84. package/dist/responsive/index.js +307 -0
  85. package/dist/responsive/index.js.map +1 -0
  86. package/dist/responsive/layerResolve.d.ts +43 -0
  87. package/dist/responsive/layerResolve.js +168 -0
  88. package/dist/responsive/layerResolve.js.map +1 -0
  89. package/dist/responsive/merge.d.ts +19 -0
  90. package/dist/responsive/merge.js +74 -0
  91. package/dist/responsive/merge.js.map +1 -0
  92. package/dist/responsive/previewSafeAreaInsets.d.ts +14 -0
  93. package/dist/responsive/previewSafeAreaInsets.js +24 -0
  94. package/dist/responsive/previewSafeAreaInsets.js.map +1 -0
  95. package/dist/responsive/screenContainerResolve.d.ts +11 -0
  96. package/dist/responsive/screenContainerResolve.js +122 -0
  97. package/dist/responsive/screenContainerResolve.js.map +1 -0
  98. package/dist/responsive/screenShellInsets.d.ts +11 -0
  99. package/dist/responsive/screenShellInsets.js +26 -0
  100. package/dist/responsive/screenShellInsets.js.map +1 -0
  101. package/dist/restingMotion.d.ts +167 -0
  102. package/dist/restingMotion.js +484 -0
  103. package/dist/restingMotion.js.map +1 -0
  104. package/dist/rheoAgentManifestMerge.d.ts +33 -0
  105. package/dist/rheoAgentManifestMerge.js +55 -0
  106. package/dist/rheoAgentManifestMerge.js.map +1 -0
  107. package/dist/scaleInputStyle.d.ts +35 -0
  108. package/dist/scaleInputStyle.js +77 -0
  109. package/dist/scaleInputStyle.js.map +1 -0
  110. package/dist/scaleValidation.d.ts +9 -0
  111. package/dist/scaleValidation.js +21 -0
  112. package/dist/scaleValidation.js.map +1 -0
  113. package/dist/stateMachine.d.ts +105 -0
  114. package/dist/stateMachine.js +674 -0
  115. package/dist/stateMachine.js.map +1 -0
  116. package/dist/stepResponse-BXgoZ7o-.d.ts +112 -0
  117. package/dist/textInputValidation.d.ts +14 -0
  118. package/dist/textInputValidation.js +46 -0
  119. package/dist/textInputValidation.js.map +1 -0
  120. package/dist/translationPlaceholders.d.ts +9 -0
  121. package/dist/translationPlaceholders.js +52 -0
  122. package/dist/translationPlaceholders.js.map +1 -0
  123. package/dist/validation.d.ts +31 -0
  124. package/dist/validation.js +233 -0
  125. package/dist/validation.js.map +1 -0
  126. package/package.json +242 -0
@@ -0,0 +1,102 @@
1
+ import '@getrheo/contracts/localized';
2
+ import '@getrheo/contracts/layers';
3
+
4
+ // src/layers.ts
5
+ var walkLayers = (root, fn) => {
6
+ const visit = (l, depth) => {
7
+ fn(l, depth);
8
+ if (l.kind === "stack") l.children.forEach((c) => visit(c, depth + 1));
9
+ else if (l.kind === "carousel") l.slides.forEach((c) => visit(c, depth + 1));
10
+ else if (l.kind === "button") l.children.forEach((c) => visit(c, depth + 1));
11
+ else if (l.kind === "back_button") l.children.forEach((c) => visit(c, depth + 1));
12
+ else if (l.kind === "hyperlink") l.children.forEach((c) => visit(c, depth + 1));
13
+ else if (l.kind === "single_choice" || l.kind === "multiple_choice") {
14
+ l.children.forEach((c) => visit(c, depth + 1));
15
+ } else if (l.kind === "text_input" || l.kind === "scale_input") {
16
+ l.children?.forEach((c) => visit(c, depth + 1));
17
+ } else if (l.kind === "oauth_login") {
18
+ l.children.forEach((c) => visit(c, depth + 1));
19
+ } else if (l.kind === "oauth_provider" && l.variant === "custom") {
20
+ l.children.forEach((c) => visit(c, depth + 1));
21
+ } else if (l.kind === "email_password_auth") {
22
+ l.children.forEach((c) => visit(c, depth + 1));
23
+ } else if (l.kind === "email_password_field") {
24
+ l.children?.forEach((c) => visit(c, depth + 1));
25
+ } else if (l.kind === "email_password_submit") {
26
+ l.children.forEach((c) => visit(c, depth + 1));
27
+ }
28
+ };
29
+ visit(root, 0);
30
+ };
31
+ var walkScreen = (screen, fn) => {
32
+ if (screen.regions.header) walkLayers(screen.regions.header, fn);
33
+ walkLayers(screen.regions.body, fn);
34
+ if (screen.regions.footer) walkLayers(screen.regions.footer, fn);
35
+ };
36
+
37
+ // src/manifestBillingSlice.ts
38
+ var cloneManifestForBillingSlice = (m) => structuredClone(m);
39
+ var stripRestingMotionFromLayer = (layer) => {
40
+ const l = layer;
41
+ delete l.restingMotion;
42
+ delete l.restingMotions;
43
+ };
44
+ var stripManifestAnimations = (manifest) => {
45
+ const next = cloneManifestForBillingSlice(manifest);
46
+ for (const screen of next.screens) {
47
+ const s = screen;
48
+ delete s.animations;
49
+ delete s.stagger;
50
+ }
51
+ return next;
52
+ };
53
+ var stripManifestMotion = (manifest) => {
54
+ const next = stripManifestAnimations(manifest);
55
+ for (const screen of next.screens) {
56
+ walkScreen(screen, stripRestingMotionFromLayer);
57
+ }
58
+ return next;
59
+ };
60
+ var collapseLocalizedObjects = (node) => {
61
+ if (node === null || node === void 0) return;
62
+ if (Array.isArray(node)) {
63
+ for (const x of node) collapseLocalizedObjects(x);
64
+ return;
65
+ }
66
+ if (typeof node !== "object") return;
67
+ const o = node;
68
+ if (typeof o.default === "string" && Object.prototype.hasOwnProperty.call(o, "translations")) {
69
+ delete o.translations;
70
+ }
71
+ for (const v of Object.values(o)) collapseLocalizedObjects(v);
72
+ };
73
+ var collapseManifestToDefaultLocaleOnly = (manifest) => {
74
+ const next = cloneManifestForBillingSlice(manifest);
75
+ collapseLocalizedObjects(next);
76
+ next.locales = [next.defaultLocale];
77
+ return next;
78
+ };
79
+ var manifestHasScreenAnimations = (manifest) => manifest.screens.some((s) => {
80
+ const anim = s.animations;
81
+ return Array.isArray(anim) && anim.length > 0;
82
+ });
83
+ var recordHasNonEmptyTranslations = (node) => {
84
+ if (node === null || node === void 0) return false;
85
+ if (Array.isArray(node)) return node.some(recordHasNonEmptyTranslations);
86
+ if (typeof node !== "object") return false;
87
+ const o = node;
88
+ const tr = o.translations;
89
+ if (tr && typeof tr === "object" && Object.keys(tr).length > 0) return true;
90
+ return Object.values(o).some(recordHasNonEmptyTranslations);
91
+ };
92
+ var manifestUsesTranslationsBeyondDefault = (manifest) => {
93
+ if (manifest.locales.length > 1) return true;
94
+ return recordHasNonEmptyTranslations(manifest);
95
+ };
96
+ var manifestUsesExternalIntegrations = (manifest) => (manifest.externalSurfaceNodes ?? []).some(
97
+ (n) => n.config?.provider != null && n.config.provider !== "unspecified"
98
+ );
99
+
100
+ export { cloneManifestForBillingSlice, collapseManifestToDefaultLocaleOnly, manifestHasScreenAnimations, manifestUsesExternalIntegrations, manifestUsesTranslationsBeyondDefault, stripManifestAnimations, stripManifestMotion };
101
+ //# sourceMappingURL=manifestBillingSlice.js.map
102
+ //# sourceMappingURL=manifestBillingSlice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/layers.ts","../src/manifestBillingSlice.ts"],"names":[],"mappings":"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","file":"manifestBillingSlice.js","sourcesContent":["import type { Branding } from '@getrheo/contracts/dashboard';\nimport type { FlowManifest, Theme } from '@getrheo/contracts/manifest';\nimport type { Screen } from '@getrheo/contracts/screens';\nimport {\n brandGradientFromThemedColor,\n brandGradientNativeLinear,\n brandGradientSolidFallback,\n isStoredLinearGradientCss,\n nativeLinearFromAngleAndStops,\n parseLinearGradientCss,\n resolveBrandGradientToken,\n type BrandGradientNativeLinear,\n} from './brandGradient';\nimport type {\n InputLayer,\n Layer,\n MultipleChoiceLayer,\n ScaleInputLayer,\n SingleChoiceLayer,\n StackLayer,\n TextInputLayer,\n ThemedColor,\n} from '@getrheo/contracts/layers';\nimport type { LocalizedText } from '@getrheo/contracts/localized';\nimport { resolveLocalizedText } from '@getrheo/contracts/localized';\nimport { isInputLayer } from '@getrheo/contracts/layers';\n\n/** Walk a layer tree depth-first. */\nexport const walkLayers = (root: Layer, fn: (l: Layer, depth: number) => void): void => {\n const visit = (l: Layer, depth: number): void => {\n fn(l, depth);\n if (l.kind === 'stack') l.children.forEach((c) => visit(c, depth + 1));\n else if (l.kind === 'carousel') l.slides.forEach((c) => visit(c, depth + 1));\n else if (l.kind === 'button') l.children.forEach((c) => visit(c, depth + 1));\n else if (l.kind === 'back_button') l.children.forEach((c) => visit(c, depth + 1));\n else if (l.kind === 'hyperlink') l.children.forEach((c) => visit(c, depth + 1));\n else if (l.kind === 'single_choice' || l.kind === 'multiple_choice') {\n l.children.forEach((c) => visit(c, depth + 1));\n } else if (l.kind === 'text_input' || l.kind === 'scale_input') {\n l.children?.forEach((c) => visit(c, depth + 1));\n } else if (l.kind === 'oauth_login') {\n l.children.forEach((c) => visit(c, depth + 1));\n } else if (l.kind === 'oauth_provider' && l.variant === 'custom') {\n l.children.forEach((c) => visit(c, depth + 1));\n } else if (l.kind === 'email_password_auth') {\n l.children.forEach((c) => visit(c, depth + 1));\n } else if (l.kind === 'email_password_field') {\n l.children?.forEach((c) => visit(c, depth + 1));\n } else if (l.kind === 'email_password_submit') {\n l.children.forEach((c) => visit(c, depth + 1));\n }\n };\n visit(root, 0);\n};\n\n/** Walk every layer in a screen's regions (header → body → footer). */\nexport const walkScreen = (screen: Screen, fn: (l: Layer) => void): void => {\n if (screen.regions.header) walkLayers(screen.regions.header, fn);\n walkLayers(screen.regions.body, fn);\n if (screen.regions.footer) walkLayers(screen.regions.footer, fn);\n};\n\n/** Find the screen's lone input layer (if any). Schema enforces ≤1. */\nexport const findInputLayer = (screen: Screen): InputLayer | null => {\n let found: InputLayer | null = null;\n walkScreen(screen, (l) => {\n if (!found && isInputLayer(l)) found = l;\n });\n return found;\n};\n\n/** Input kinds that use a screen draft and require an explicit Continue to submit. */\nexport const findManualSubmitInputLayer = (\n screen: Screen,\n): MultipleChoiceLayer | TextInputLayer | ScaleInputLayer | null => {\n const input = findInputLayer(screen);\n if (!input) return null;\n if (input.kind === 'multiple_choice' || input.kind === 'text_input' || input.kind === 'scale_input') {\n return input;\n }\n return null;\n};\n\n/**\n * Whether the screen contains any Button layer that submits the screen\n * (i.e. `action.kind === 'continue'`). Used by input layers to decide\n * between auto-submit-on-tap (legacy behaviour for choice-only screens)\n * and writing into the screen-level draft for a Button to submit.\n */\nexport const screenHasContinueButton = (screen: Screen): boolean => {\n let found = false;\n walkScreen(screen, (l) => {\n if (l.kind === 'button' && l.action.kind === 'continue') found = true;\n });\n return found;\n};\n\n/**\n * Resolve a choice layer's option stack by stable optionId via its\n * binding. Returns null when the binding is missing or the bound child\n * was removed (manifest validation rejects that, but runtime stays safe).\n */\nexport const findOptionStackForChoice = (\n layer: SingleChoiceLayer | MultipleChoiceLayer,\n optionId: string,\n): StackLayer | null => {\n const binding = layer.optionBindings.find((b) => b.optionId === optionId);\n if (!binding) return null;\n const stack = layer.children.find((c) => c.id === binding.rootLayerId);\n return stack ?? null;\n};\n\n/**\n * Best-effort textual label for a choice option, used by interpolation\n * (e.g. `{{ goal }}` rendering the chosen option's label) and by editor\n * surfaces that show option rows. Walks the option's child subtree\n * depth-first and returns the first `text` layer's content; falls back\n * to the option's stable id when no text is present.\n */\nexport const choiceOptionLabel = (\n layer: SingleChoiceLayer | MultipleChoiceLayer,\n optionId: string,\n locale: string,\n): string => {\n const stack = findOptionStackForChoice(layer, optionId);\n if (!stack) return '';\n let foundText: LocalizedText | null = null;\n walkLayers(stack, (l) => {\n if (foundText) return;\n if (l.kind === 'text') foundText = l.text;\n });\n if (foundText) return resolveLocalizedText(foundText, locale);\n return optionId;\n};\n\n/** Find a layer in a screen by id, including nested children/slides. */\nexport const findLayerById = (screen: Screen, id: string): Layer | null => {\n let found: Layer | null = null;\n walkScreen(screen, (l) => {\n if (!found && l.id === id) found = l;\n });\n return found;\n};\n\n/** Collect all input fieldKeys across a manifest. */\nexport const collectFieldKeys = (manifest: FlowManifest): { fieldKey: string; screenId: string }[] => {\n const out: { fieldKey: string; screenId: string }[] = [];\n for (const screen of manifest.screens) {\n walkScreen(screen as unknown as Screen, (l) => {\n if (isInputLayer(l)) out.push({ fieldKey: l.fieldKey, screenId: screen.id });\n if (l.kind === 'checkbox') out.push({ fieldKey: l.fieldKey, screenId: screen.id });\n if (l.kind === 'email_password_auth') {\n out.push({ fieldKey: l.fieldKey, screenId: screen.id });\n }\n });\n }\n return out;\n};\n\n/**\n * Pick a snake_case field key starting from `base` that is not in `used`\n * (e.g. `text` → `text_2` → `text_3` when `text` is taken).\n */\nexport const nextUniqueFieldKey = (base: string, used: Iterable<string>): string => {\n const set = used instanceof Set ? used : new Set(used);\n if (!set.has(base)) return base;\n let n = 2;\n while (set.has(`${base}_${n}`)) n += 1;\n return `${base}_${n}`;\n};\n\n/**\n * Resolve a token reference like `$primary` to a literal value from `theme`.\n * Pass-through for non-token strings; returns undefined for `undefined`.\n */\nexport const resolveTokens = <T extends string | undefined>(\n theme: Theme | undefined,\n value: T,\n): T | string => {\n if (value === undefined) return value;\n if (typeof value !== 'string' || !value.startsWith('$')) return value;\n const key = value.slice(1) as keyof Theme;\n const literal = theme?.[key];\n if (typeof literal === 'string') return literal;\n return value;\n};\n\n/**\n * Resolve a layer color for the current appearance (`light` | `dark`).\n * Plain string uses `resolveTokens` for both modes (legacy). Object form\n * picks `light` / `dark` with fallback to the other key when one is omitted.\n */\nexport const resolveThemedColor = (\n theme: Theme | undefined,\n palette: 'light' | 'dark',\n value: ThemedColor | undefined,\n): string | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === 'string') return resolveTokens(theme, value) as string;\n const raw = palette === 'dark' ? (value.dark ?? value.light) : (value.light ?? value.dark);\n if (raw === undefined) return undefined;\n return resolveTokens(theme, raw) as string;\n};\n\n/**\n * Resolve a themed value used for CSS `background` (or RN background fill).\n * Supports `$brandGradient:<uuid>` when branding presets are provided; other values match {@link resolveThemedColor}.\n */\nexport const resolveThemedBackground = (\n theme: Theme | undefined,\n branding: Branding | undefined,\n palette: 'light' | 'dark',\n value: ThemedColor | undefined,\n): string | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === 'string') {\n if (value.startsWith('$brandGradient:')) {\n return resolveBrandGradientToken(branding, value);\n }\n return resolveTokens(theme, value) as string;\n }\n const raw = palette === 'dark' ? (value.dark ?? value.light) : (value.light ?? value.dark);\n if (raw === undefined) return undefined;\n if (raw.startsWith('$brandGradient:')) {\n return resolveBrandGradientToken(branding, raw);\n }\n return resolveTokens(theme, raw) as string;\n};\n\nexport const nativeBrandBackgroundFromThemedColor = (\n theme: Theme | undefined,\n branding: Branding | undefined,\n palette: 'light' | 'dark',\n value: ThemedColor | undefined,\n): { solid?: string; linear?: BrandGradientNativeLinear } => {\n const preset = brandGradientFromThemedColor(branding, palette, value);\n if (preset) {\n const lin = brandGradientNativeLinear(preset);\n if (lin) return { linear: lin };\n return { solid: brandGradientSolidFallback(preset) };\n }\n const bg = resolveThemedBackground(theme, branding, palette, value) as string | undefined;\n if (!bg) return {};\n const parsed = parseLinearGradientCss(bg);\n if (parsed) {\n return {\n linear: nativeLinearFromAngleAndStops(\n parsed.angleDeg,\n parsed.stops.map((s) => ({ color: s.color, offsetPct: s.offsetPct })),\n ),\n };\n }\n if (isStoredLinearGradientCss(bg)) {\n const first = bg.match(/#[0-9a-fA-F]{3,8}/);\n return { solid: first ? first[0] : '#808080' };\n }\n return { solid: bg };\n};\n","import type { Layer } from '@getrheo/contracts/layers';\nimport type { FlowManifest } from '@getrheo/contracts/manifest';\nimport { walkScreen } from './layers.js';\n\n/** Deep clone manifest JSON shape for SDK responses. */\nexport const cloneManifestForBillingSlice = (m: FlowManifest): FlowManifest =>\n structuredClone(m) as FlowManifest;\n\nconst stripRestingMotionFromLayer = (layer: Layer): void => {\n const l = layer as { restingMotion?: unknown; restingMotions?: unknown };\n delete l.restingMotion;\n delete l.restingMotions;\n};\n\n/** Removes per-screen animation clips (timeline / transitions). */\nexport const stripManifestAnimations = (manifest: FlowManifest): FlowManifest => {\n const next = cloneManifestForBillingSlice(manifest);\n for (const screen of next.screens) {\n const s = screen as { animations?: unknown; stagger?: unknown };\n delete s.animations;\n delete s.stagger;\n }\n return next;\n};\n\n/** Removes screen clips, stagger defaults, and per-layer resting motion. */\nexport const stripManifestMotion = (manifest: FlowManifest): FlowManifest => {\n const next = stripManifestAnimations(manifest);\n for (const screen of next.screens) {\n walkScreen(screen, stripRestingMotionFromLayer);\n }\n return next;\n};\n\nconst collapseLocalizedObjects = (node: unknown): void => {\n if (node === null || node === undefined) return;\n if (Array.isArray(node)) {\n for (const x of node) collapseLocalizedObjects(x);\n return;\n }\n if (typeof node !== 'object') return;\n const o = node as Record<string, unknown>;\n if (\n typeof o.default === 'string' &&\n Object.prototype.hasOwnProperty.call(o, 'translations')\n ) {\n delete o.translations;\n }\n for (const v of Object.values(o)) collapseLocalizedObjects(v);\n};\n\n/** Drops `translations` on every LocalizedText-shaped object; trims locales list to default only. */\nexport const collapseManifestToDefaultLocaleOnly = (manifest: FlowManifest): FlowManifest => {\n const next = cloneManifestForBillingSlice(manifest);\n collapseLocalizedObjects(next);\n next.locales = [next.defaultLocale];\n return next;\n};\n\nexport const manifestHasScreenAnimations = (manifest: FlowManifest): boolean =>\n manifest.screens.some((s) => {\n const anim = (s as { animations?: unknown }).animations;\n return Array.isArray(anim) && anim.length > 0;\n });\n\nconst recordHasNonEmptyTranslations = (node: unknown): boolean => {\n if (node === null || node === undefined) return false;\n if (Array.isArray(node)) return node.some(recordHasNonEmptyTranslations);\n if (typeof node !== 'object') return false;\n const o = node as Record<string, unknown>;\n const tr = o.translations;\n if (tr && typeof tr === 'object' && Object.keys(tr as object).length > 0) return true;\n return Object.values(o).some(recordHasNonEmptyTranslations);\n};\n\n/** True when manifest carries locale variants editors expect Grow+ for. */\nexport const manifestUsesTranslationsBeyondDefault = (manifest: FlowManifest): boolean => {\n if (manifest.locales.length > 1) return true;\n return recordHasNonEmptyTranslations(manifest);\n};\n\n/** True when manifest includes an external integration step with a concrete provider (Grow+). */\nexport const manifestUsesExternalIntegrations = (manifest: FlowManifest): boolean =>\n (manifest.externalSurfaceNodes ?? []).some(\n (n) => n.config?.provider != null && n.config.provider !== 'unspecified',\n );\n"]}
@@ -0,0 +1,17 @@
1
+ import { FlowManifest } from '@getrheo/contracts/manifest';
2
+ import { Screen } from '@getrheo/contracts/screens';
3
+
4
+ /** All layer ids across every screen (manifest-level uniqueness). */
5
+ declare const collectManifestLayerIds: (manifest: FlowManifest) => Set<string>;
6
+ /**
7
+ * Rewrites the screen's id and every layer id so they cannot collide with an existing manifest.
8
+ * Uses JSON substitution with longest-id-first ordering to avoid partial replacements.
9
+ */
10
+ declare const remapScreenIdsForManifestIngest: (manifest: FlowManifest, screen: Screen) => Screen;
11
+ /**
12
+ * After in-place AI screen replace, ensure layer ids are unique across the manifest:
13
+ * forbidden = ids used on other screens; duplicate ids within the replacement tree are remapped.
14
+ */
15
+ declare const remapReplacedScreenLayerCollisionsInManifest: (manifest: FlowManifest, targetScreenId: string, screen: Screen) => Screen;
16
+
17
+ export { collectManifestLayerIds, remapReplacedScreenLayerCollisionsInManifest, remapScreenIdsForManifestIngest };
@@ -0,0 +1,99 @@
1
+ import { walkScreenLayers } from '@getrheo/contracts/screens';
2
+
3
+ // src/prepareAiGeneratedScreen.ts
4
+ var randomHex = (byteLength) => {
5
+ const bytes = new Uint8Array(byteLength);
6
+ if (typeof globalThis.crypto?.getRandomValues === "function") {
7
+ globalThis.crypto.getRandomValues(bytes);
8
+ } else {
9
+ for (let i = 0; i < byteLength; i++) bytes[i] = Math.floor(Math.random() * 256);
10
+ }
11
+ return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
12
+ };
13
+ var collectManifestLayerIds = (manifest) => {
14
+ const ids = /* @__PURE__ */ new Set();
15
+ for (const s of manifest.screens) {
16
+ walkScreenLayers(s, (l) => {
17
+ ids.add(l.id);
18
+ });
19
+ }
20
+ return ids;
21
+ };
22
+ var remapScreenIdsForManifestIngest = (manifest, screen) => {
23
+ const screenIds = new Set(manifest.screens.map((s) => s.id));
24
+ let newScreenId = `scr_ai_${randomHex(4)}`;
25
+ let sn = 0;
26
+ while (screenIds.has(newScreenId)) {
27
+ newScreenId = `scr_ai_${randomHex(4)}_${sn++}`.slice(0, 64);
28
+ }
29
+ const usedLayers = collectManifestLayerIds(manifest);
30
+ const token = randomHex(3);
31
+ const map = /* @__PURE__ */ new Map();
32
+ walkScreenLayers(screen, (l) => {
33
+ if (map.has(l.id)) return;
34
+ const tail = l.id.replace(/^lyr_/i, "").replace(/[^a-z0-9_]/gi, "_") || "layer";
35
+ let nid = `lyr_ai_${token}_${tail}`;
36
+ let i = 0;
37
+ for (; ; ) {
38
+ const taken = usedLayers.has(nid) || [...map.values()].some((v) => v === nid);
39
+ if (!taken) break;
40
+ i += 1;
41
+ nid = `lyr_ai_${token}_${tail}_${i}`.slice(0, 64);
42
+ }
43
+ map.set(l.id, nid);
44
+ usedLayers.add(nid);
45
+ });
46
+ let json = JSON.stringify({ ...screen, id: newScreenId });
47
+ const pairs = [...map.entries()].sort((a, b) => b[0].length - a[0].length);
48
+ for (const [oldId, newId] of pairs) {
49
+ json = json.split(oldId).join(newId);
50
+ }
51
+ return JSON.parse(json);
52
+ };
53
+ var remapReplacedScreenLayerCollisionsInManifest = (manifest, targetScreenId, screen) => {
54
+ const forbidden = /* @__PURE__ */ new Set();
55
+ for (const s of manifest.screens) {
56
+ if (s.id === targetScreenId) continue;
57
+ walkScreenLayers(s, (l) => forbidden.add(l.id));
58
+ }
59
+ const next = JSON.parse(JSON.stringify(screen));
60
+ const seen = /* @__PURE__ */ new Set();
61
+ const used = new Set(forbidden);
62
+ const alloc = () => {
63
+ let i = 0;
64
+ for (; ; ) {
65
+ const nid = `lyr_ai_${randomHex(4)}_${i++}`.slice(0, 64);
66
+ if (!used.has(nid)) {
67
+ used.add(nid);
68
+ return nid;
69
+ }
70
+ }
71
+ };
72
+ const fix = (layer) => {
73
+ if (forbidden.has(layer.id) || seen.has(layer.id)) {
74
+ layer.id = alloc();
75
+ }
76
+ seen.add(layer.id);
77
+ if (layer.kind === "stack") layer.children.forEach(fix);
78
+ else if (layer.kind === "carousel") layer.slides.forEach(fix);
79
+ else if (layer.kind === "button" || layer.kind === "back_button") layer.children.forEach(fix);
80
+ else if (layer.kind === "hyperlink") layer.children.forEach(fix);
81
+ else if (layer.kind === "single_choice" || layer.kind === "multiple_choice") {
82
+ layer.children.forEach(fix);
83
+ } else if (layer.kind === "text_input" || layer.kind === "scale_input") {
84
+ layer.children?.forEach(fix);
85
+ } else if (layer.kind === "oauth_login") layer.children.forEach(fix);
86
+ else if (layer.kind === "oauth_provider" && layer.variant === "custom") layer.children.forEach(fix);
87
+ else if (layer.kind === "email_password_auth") layer.children.forEach(fix);
88
+ else if (layer.kind === "email_password_field") layer.children?.forEach(fix);
89
+ else if (layer.kind === "email_password_submit") layer.children.forEach(fix);
90
+ };
91
+ if (next.regions.header) fix(next.regions.header);
92
+ fix(next.regions.body);
93
+ if (next.regions.footer) fix(next.regions.footer);
94
+ return next;
95
+ };
96
+
97
+ export { collectManifestLayerIds, remapReplacedScreenLayerCollisionsInManifest, remapScreenIdsForManifestIngest };
98
+ //# sourceMappingURL=prepareAiGeneratedScreen.js.map
99
+ //# sourceMappingURL=prepareAiGeneratedScreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/prepareAiGeneratedScreen.ts"],"names":[],"mappings":"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","file":"prepareAiGeneratedScreen.js","sourcesContent":["import type { Layer } from '@getrheo/contracts/layers';\nimport type { FlowManifest } from '@getrheo/contracts/manifest';\nimport type { Screen } from '@getrheo/contracts/screens';\nimport { walkScreenLayers } from '@getrheo/contracts/screens';\n\nconst randomHex = (byteLength: number): string => {\n const bytes = new Uint8Array(byteLength);\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes);\n } else {\n for (let i = 0; i < byteLength; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n return [...bytes].map((b) => b.toString(16).padStart(2, '0')).join('');\n};\n\n/** All layer ids across every screen (manifest-level uniqueness). */\nexport const collectManifestLayerIds = (manifest: FlowManifest): Set<string> => {\n const ids = new Set<string>();\n for (const s of manifest.screens) {\n walkScreenLayers(s, (l) => {\n ids.add(l.id);\n });\n }\n return ids;\n};\n\n/**\n * Rewrites the screen's id and every layer id so they cannot collide with an existing manifest.\n * Uses JSON substitution with longest-id-first ordering to avoid partial replacements.\n */\nexport const remapScreenIdsForManifestIngest = (\n manifest: FlowManifest,\n screen: Screen,\n): Screen => {\n const screenIds = new Set(manifest.screens.map((s) => s.id));\n let newScreenId = `scr_ai_${randomHex(4)}`;\n let sn = 0;\n while (screenIds.has(newScreenId)) {\n newScreenId = `scr_ai_${randomHex(4)}_${sn++}`.slice(0, 64);\n }\n\n const usedLayers = collectManifestLayerIds(manifest);\n const token = randomHex(3);\n const map = new Map<string, string>();\n\n walkScreenLayers(screen, (l) => {\n if (map.has(l.id)) return;\n const tail = l.id.replace(/^lyr_/i, '').replace(/[^a-z0-9_]/gi, '_') || 'layer';\n let nid = `lyr_ai_${token}_${tail}`;\n let i = 0;\n for (;;) {\n const taken =\n usedLayers.has(nid) || [...map.values()].some((v) => v === nid);\n if (!taken) break;\n i += 1;\n nid = `lyr_ai_${token}_${tail}_${i}`.slice(0, 64);\n }\n map.set(l.id, nid);\n usedLayers.add(nid);\n });\n\n let json = JSON.stringify({ ...screen, id: newScreenId });\n const pairs = [...map.entries()].sort((a, b) => b[0].length - a[0].length);\n for (const [oldId, newId] of pairs) {\n json = json.split(oldId).join(newId);\n }\n return JSON.parse(json) as Screen;\n};\n\n/**\n * After in-place AI screen replace, ensure layer ids are unique across the manifest:\n * forbidden = ids used on other screens; duplicate ids within the replacement tree are remapped.\n */\nexport const remapReplacedScreenLayerCollisionsInManifest = (\n manifest: FlowManifest,\n targetScreenId: string,\n screen: Screen,\n): Screen => {\n const forbidden = new Set<string>();\n for (const s of manifest.screens) {\n if (s.id === targetScreenId) continue;\n walkScreenLayers(s, (l) => forbidden.add(l.id));\n }\n\n const next = JSON.parse(JSON.stringify(screen)) as Screen;\n const seen = new Set<string>();\n const used = new Set(forbidden);\n\n const alloc = (): string => {\n let i = 0;\n for (;;) {\n const nid = `lyr_ai_${randomHex(4)}_${i++}`.slice(0, 64);\n if (!used.has(nid)) {\n used.add(nid);\n return nid;\n }\n }\n };\n\n const fix = (layer: Layer): void => {\n if (forbidden.has(layer.id) || seen.has(layer.id)) {\n layer.id = alloc();\n }\n seen.add(layer.id);\n\n if (layer.kind === 'stack') layer.children.forEach(fix);\n else if (layer.kind === 'carousel') layer.slides.forEach(fix);\n else if (layer.kind === 'button' || layer.kind === 'back_button') layer.children.forEach(fix);\n else if (layer.kind === 'hyperlink') layer.children.forEach(fix);\n else if (layer.kind === 'single_choice' || layer.kind === 'multiple_choice') {\n layer.children.forEach(fix);\n } else if (layer.kind === 'text_input' || layer.kind === 'scale_input') {\n layer.children?.forEach(fix);\n } else if (layer.kind === 'oauth_login') layer.children.forEach(fix);\n else if (layer.kind === 'oauth_provider' && layer.variant === 'custom') layer.children.forEach(fix);\n else if (layer.kind === 'email_password_auth') layer.children.forEach(fix);\n else if (layer.kind === 'email_password_field') layer.children?.forEach(fix);\n else if (layer.kind === 'email_password_submit') layer.children.forEach(fix);\n };\n\n if (next.regions.header) fix(next.regions.header);\n fix(next.regions.body);\n if (next.regions.footer) fix(next.regions.footer);\n return next;\n};\n"]}
@@ -0,0 +1,166 @@
1
+ [
2
+ {
3
+ "exportKey": ".",
4
+ "distFile": "./dist/index.js"
5
+ },
6
+ {
7
+ "exportKey": "./agentPrompt",
8
+ "distFile": "./dist/agentPrompt/index.js"
9
+ },
10
+ {
11
+ "exportKey": "./animations",
12
+ "distFile": "./dist/animations.js"
13
+ },
14
+ {
15
+ "exportKey": "./buttonVariantChrome",
16
+ "distFile": "./dist/buttonVariantChrome.js"
17
+ },
18
+ {
19
+ "exportKey": "./counterLayer",
20
+ "distFile": "./dist/counterLayer.js"
21
+ },
22
+ {
23
+ "exportKey": "./emailPasswordAuthValidation",
24
+ "distFile": "./dist/emailPasswordAuthValidation.js"
25
+ },
26
+ {
27
+ "exportKey": "./hyperlinkLabel",
28
+ "distFile": "./dist/hyperlinkLabel.js"
29
+ },
30
+ {
31
+ "exportKey": "./interpolateTemplate",
32
+ "distFile": "./dist/interpolateTemplate.js"
33
+ },
34
+ {
35
+ "exportKey": "./layerTypography",
36
+ "distFile": "./dist/layerTypography.js"
37
+ },
38
+ {
39
+ "exportKey": "./layers",
40
+ "distFile": "./dist/layers.js"
41
+ },
42
+ {
43
+ "exportKey": "./layout",
44
+ "distFile": "./dist/layout/index.js"
45
+ },
46
+ {
47
+ "exportKey": "./responsive",
48
+ "distFile": "./dist/responsive/index.js"
49
+ },
50
+ {
51
+ "exportKey": "./responsive/breakpoints",
52
+ "distFile": "./dist/responsive/breakpoints.js"
53
+ },
54
+ {
55
+ "exportKey": "./responsive/layerResolve",
56
+ "distFile": "./dist/responsive/layerResolve.js"
57
+ },
58
+ {
59
+ "exportKey": "./responsive/merge",
60
+ "distFile": "./dist/responsive/merge.js"
61
+ },
62
+ {
63
+ "exportKey": "./responsive/previewSafeAreaInsets",
64
+ "distFile": "./dist/responsive/previewSafeAreaInsets.js"
65
+ },
66
+ {
67
+ "exportKey": "./responsive/screenContainerResolve",
68
+ "distFile": "./dist/responsive/screenContainerResolve.js"
69
+ },
70
+ {
71
+ "exportKey": "./responsive/screenShellInsets",
72
+ "distFile": "./dist/responsive/screenShellInsets.js"
73
+ },
74
+ {
75
+ "exportKey": "./restingMotion",
76
+ "distFile": "./dist/restingMotion.js"
77
+ },
78
+ {
79
+ "exportKey": "./scaleValidation",
80
+ "distFile": "./dist/scaleValidation.js"
81
+ },
82
+ {
83
+ "exportKey": "./stateMachine",
84
+ "distFile": "./dist/stateMachine.js"
85
+ },
86
+ {
87
+ "exportKey": "./textInputValidation",
88
+ "distFile": "./dist/textInputValidation.js"
89
+ },
90
+ {
91
+ "exportKey": "./aiFlowGenerationMerge",
92
+ "distFile": "./dist/aiFlowGenerationMerge.js"
93
+ },
94
+ {
95
+ "exportKey": "./assignment",
96
+ "distFile": "./dist/assignment.js"
97
+ },
98
+ {
99
+ "exportKey": "./brandGradient",
100
+ "distFile": "./dist/brandGradient.js"
101
+ },
102
+ {
103
+ "exportKey": "./brandGradientManifestIssues",
104
+ "distFile": "./dist/brandGradientManifestIssues.js"
105
+ },
106
+ {
107
+ "exportKey": "./buildFlowPreview",
108
+ "distFile": "./dist/buildFlowPreview.js"
109
+ },
110
+ {
111
+ "exportKey": "./checkboxGlyphStyle",
112
+ "distFile": "./dist/checkboxGlyphStyle.js"
113
+ },
114
+ {
115
+ "exportKey": "./choiceOptionSelection",
116
+ "distFile": "./dist/choiceOptionSelection.js"
117
+ },
118
+ {
119
+ "exportKey": "./colorAlpha",
120
+ "distFile": "./dist/colorAlpha.js"
121
+ },
122
+ {
123
+ "exportKey": "./decisionEval",
124
+ "distFile": "./dist/decisionEval.js"
125
+ },
126
+ {
127
+ "exportKey": "./dropShadow",
128
+ "distFile": "./dist/dropShadow.js"
129
+ },
130
+ {
131
+ "exportKey": "./flowBuilderRules",
132
+ "distFile": "./dist/flowBuilderRules.js"
133
+ },
134
+ {
135
+ "exportKey": "./flowGraph",
136
+ "distFile": "./dist/flowGraph.js"
137
+ },
138
+ {
139
+ "exportKey": "./layerRotate",
140
+ "distFile": "./dist/layerRotate.js"
141
+ },
142
+ {
143
+ "exportKey": "./manifestBillingSlice",
144
+ "distFile": "./dist/manifestBillingSlice.js"
145
+ },
146
+ {
147
+ "exportKey": "./prepareAiGeneratedScreen",
148
+ "distFile": "./dist/prepareAiGeneratedScreen.js"
149
+ },
150
+ {
151
+ "exportKey": "./rheoAgentManifestMerge",
152
+ "distFile": "./dist/rheoAgentManifestMerge.js"
153
+ },
154
+ {
155
+ "exportKey": "./scaleInputStyle",
156
+ "distFile": "./dist/scaleInputStyle.js"
157
+ },
158
+ {
159
+ "exportKey": "./translationPlaceholders",
160
+ "distFile": "./dist/translationPlaceholders.js"
161
+ },
162
+ {
163
+ "exportKey": "./validation",
164
+ "distFile": "./dist/validation.js"
165
+ }
166
+ ]
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Tailwind CSS default `screens` min-width values (px). Single source of truth
3
+ * for preview buckets, manifest breakpoints, and runtime style resolution.
4
+ *
5
+ * @see https://tailwindcss.com/docs/screens
6
+ */
7
+ declare const TAILWIND_DEFAULT_BREAKPOINTS: {
8
+ readonly sm: 640;
9
+ readonly md: 768;
10
+ readonly lg: 1024;
11
+ readonly xl: 1280;
12
+ readonly '2xl': 1536;
13
+ };
14
+ /** Viewport classification used by preview UI and editing scope. */
15
+ type ScreenSizeBucket = 'default' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
16
+ /** Ordered keys stored on layers (`styleBreakpoints`) and merged mobile-first. */
17
+ declare const STYLE_BREAKPOINT_MERGE_ORDER: readonly ["sm", "md", "lg", "xl", "2xl"];
18
+ type StyleBreakpointKey = (typeof STYLE_BREAKPOINT_MERGE_ORDER)[number];
19
+ declare const SCREEN_SIZE_BUCKET_ORDER: readonly ScreenSizeBucket[];
20
+ /** Buckets shown in the flow builder inspector (xl / 2xl omitted from authoring UI). */
21
+ declare const BUILDER_INSPECTOR_BUCKET_ORDER: readonly ScreenSizeBucket[];
22
+ /** Human-readable bucket titles; ranges lie between consecutive breakpoints. */
23
+ declare const SCREEN_SIZE_BUCKET_LABEL: Record<ScreenSizeBucket, string>;
24
+ /** Fallback viewport width when no `previewWidthPx` is passed (simulator / static previews). */
25
+ declare const DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX = 390;
26
+ /** Maps viewport width (CSS px) to the Tailwind viewport bucket. */
27
+ declare const getScreenSizeBucketForWidth: (width: number) => ScreenSizeBucket;
28
+ /**
29
+ * Breakpoint keys whose partials apply at this width (mobile-first), e.g.
30
+ * width 800 → `['sm','md']`.
31
+ */
32
+ declare const getActiveStyleBreakpointChain: (widthPx: number) => StyleBreakpointKey[];
33
+
34
+ export { BUILDER_INSPECTOR_BUCKET_ORDER, DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX, SCREEN_SIZE_BUCKET_LABEL, SCREEN_SIZE_BUCKET_ORDER, STYLE_BREAKPOINT_MERGE_ORDER, type ScreenSizeBucket, type StyleBreakpointKey, TAILWIND_DEFAULT_BREAKPOINTS, getActiveStyleBreakpointChain, getScreenSizeBucketForWidth };
@@ -0,0 +1,52 @@
1
+ // src/responsive/breakpoints.ts
2
+ var TAILWIND_DEFAULT_BREAKPOINTS = {
3
+ sm: 640,
4
+ md: 768,
5
+ lg: 1024,
6
+ xl: 1280,
7
+ "2xl": 1536
8
+ };
9
+ var STYLE_BREAKPOINT_MERGE_ORDER = ["sm", "md", "lg", "xl", "2xl"];
10
+ var SCREEN_SIZE_BUCKET_ORDER = [
11
+ "default",
12
+ "sm",
13
+ "md",
14
+ "lg",
15
+ "xl",
16
+ "2xl"
17
+ ];
18
+ var BUILDER_INSPECTOR_BUCKET_ORDER = [
19
+ "default",
20
+ "sm",
21
+ "md",
22
+ "lg"
23
+ ];
24
+ var SCREEN_SIZE_BUCKET_LABEL = {
25
+ default: "Default (< 640px)",
26
+ sm: "sm (640\u2013767px)",
27
+ md: "md (768\u20131023px)",
28
+ lg: "lg (1024\u20131279px)",
29
+ xl: "xl (1280\u20131535px)",
30
+ "2xl": "2xl (1536px+)"
31
+ };
32
+ var DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX = 390;
33
+ var getScreenSizeBucketForWidth = (width) => {
34
+ const { sm, md, lg, xl, "2xl": xxl } = TAILWIND_DEFAULT_BREAKPOINTS;
35
+ if (width < sm) return "default";
36
+ if (width < md) return "sm";
37
+ if (width < lg) return "md";
38
+ if (width < xl) return "lg";
39
+ if (width < xxl) return "xl";
40
+ return "2xl";
41
+ };
42
+ var getActiveStyleBreakpointChain = (widthPx) => {
43
+ const bucket = getScreenSizeBucketForWidth(widthPx);
44
+ if (bucket === "default") return [];
45
+ const idx = STYLE_BREAKPOINT_MERGE_ORDER.indexOf(bucket);
46
+ if (idx < 0) return [];
47
+ return STYLE_BREAKPOINT_MERGE_ORDER.slice(0, idx + 1);
48
+ };
49
+
50
+ export { BUILDER_INSPECTOR_BUCKET_ORDER, DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX, SCREEN_SIZE_BUCKET_LABEL, SCREEN_SIZE_BUCKET_ORDER, STYLE_BREAKPOINT_MERGE_ORDER, TAILWIND_DEFAULT_BREAKPOINTS, getActiveStyleBreakpointChain, getScreenSizeBucketForWidth };
51
+ //# sourceMappingURL=breakpoints.js.map
52
+ //# sourceMappingURL=breakpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/responsive/breakpoints.ts"],"names":[],"mappings":";AAMO,IAAM,4BAAA,GAA+B;AAAA,EAC1C,EAAA,EAAI,GAAA;AAAA,EACJ,EAAA,EAAI,GAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,EAAA,EAAI,IAAA;AAAA,EACJ,KAAA,EAAO;AACT;AAMO,IAAM,+BAA+B,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,MAAM,KAAK;AAGnE,IAAM,wBAAA,GAAwD;AAAA,EACnE,SAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF;AAGO,IAAM,8BAAA,GAA8D;AAAA,EACzE,SAAA;AAAA,EACA,IAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF;AAGO,IAAM,wBAAA,GAA6D;AAAA,EACxE,OAAA,EAAS,mBAAA;AAAA,EACT,EAAA,EAAI,qBAAA;AAAA,EACJ,EAAA,EAAI,sBAAA;AAAA,EACJ,EAAA,EAAI,uBAAA;AAAA,EACJ,EAAA,EAAI,uBAAA;AAAA,EACJ,KAAA,EAAO;AACT;AAGO,IAAM,iCAAA,GAAoC;AAG1C,IAAM,2BAAA,GAA8B,CAAC,KAAA,KAAoC;AAC9E,EAAA,MAAM,EAAE,EAAA,EAAI,EAAA,EAAI,IAAI,EAAA,EAAI,KAAA,EAAO,KAAI,GAAI,4BAAA;AACvC,EAAA,IAAI,KAAA,GAAQ,IAAI,OAAO,SAAA;AACvB,EAAA,IAAI,KAAA,GAAQ,IAAI,OAAO,IAAA;AACvB,EAAA,IAAI,KAAA,GAAQ,IAAI,OAAO,IAAA;AACvB,EAAA,IAAI,KAAA,GAAQ,IAAI,OAAO,IAAA;AACvB,EAAA,IAAI,KAAA,GAAQ,KAAK,OAAO,IAAA;AACxB,EAAA,OAAO,KAAA;AACT;AAMO,IAAM,6BAAA,GAAgC,CAAC,OAAA,KAA0C;AACtF,EAAA,MAAM,MAAA,GAAS,4BAA4B,OAAO,CAAA;AAClD,EAAA,IAAI,MAAA,KAAW,SAAA,EAAW,OAAO,EAAC;AAClC,EAAA,MAAM,GAAA,GAAM,4BAAA,CAA6B,OAAA,CAAQ,MAA4B,CAAA;AAC7E,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,OAAO,EAAC;AACrB,EAAA,OAAO,4BAAA,CAA6B,KAAA,CAAM,CAAA,EAAG,GAAA,GAAM,CAAC,CAAA;AACtD","file":"breakpoints.js","sourcesContent":["/**\n * Tailwind CSS default `screens` min-width values (px). Single source of truth\n * for preview buckets, manifest breakpoints, and runtime style resolution.\n *\n * @see https://tailwindcss.com/docs/screens\n */\nexport const TAILWIND_DEFAULT_BREAKPOINTS = {\n sm: 640,\n md: 768,\n lg: 1024,\n xl: 1280,\n '2xl': 1536,\n} as const;\n\n/** Viewport classification used by preview UI and editing scope. */\nexport type ScreenSizeBucket = 'default' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\n/** Ordered keys stored on layers (`styleBreakpoints`) and merged mobile-first. */\nexport const STYLE_BREAKPOINT_MERGE_ORDER = ['sm', 'md', 'lg', 'xl', '2xl'] as const;\nexport type StyleBreakpointKey = (typeof STYLE_BREAKPOINT_MERGE_ORDER)[number];\n\nexport const SCREEN_SIZE_BUCKET_ORDER: readonly ScreenSizeBucket[] = [\n 'default',\n 'sm',\n 'md',\n 'lg',\n 'xl',\n '2xl',\n] as const;\n\n/** Buckets shown in the flow builder inspector (xl / 2xl omitted from authoring UI). */\nexport const BUILDER_INSPECTOR_BUCKET_ORDER: readonly ScreenSizeBucket[] = [\n 'default',\n 'sm',\n 'md',\n 'lg',\n] as const;\n\n/** Human-readable bucket titles; ranges lie between consecutive breakpoints. */\nexport const SCREEN_SIZE_BUCKET_LABEL: Record<ScreenSizeBucket, string> = {\n default: 'Default (< 640px)',\n sm: 'sm (640–767px)',\n md: 'md (768–1023px)',\n lg: 'lg (1024–1279px)',\n xl: 'xl (1280–1535px)',\n '2xl': '2xl (1536px+)',\n};\n\n/** Fallback viewport width when no `previewWidthPx` is passed (simulator / static previews). */\nexport const DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX = 390;\n\n/** Maps viewport width (CSS px) to the Tailwind viewport bucket. */\nexport const getScreenSizeBucketForWidth = (width: number): ScreenSizeBucket => {\n const { sm, md, lg, xl, '2xl': xxl } = TAILWIND_DEFAULT_BREAKPOINTS;\n if (width < sm) return 'default';\n if (width < md) return 'sm';\n if (width < lg) return 'md';\n if (width < xl) return 'lg';\n if (width < xxl) return 'xl';\n return '2xl';\n};\n\n/**\n * Breakpoint keys whose partials apply at this width (mobile-first), e.g.\n * width 800 → `['sm','md']`.\n */\nexport const getActiveStyleBreakpointChain = (widthPx: number): StyleBreakpointKey[] => {\n const bucket = getScreenSizeBucketForWidth(widthPx);\n if (bucket === 'default') return [];\n const idx = STYLE_BREAKPOINT_MERGE_ORDER.indexOf(bucket as StyleBreakpointKey);\n if (idx < 0) return [];\n return STYLE_BREAKPOINT_MERGE_ORDER.slice(0, idx + 1) as StyleBreakpointKey[];\n};\n"]}
@@ -0,0 +1,8 @@
1
+ export { BUILDER_INSPECTOR_BUCKET_ORDER, DEFAULT_PREVIEW_VIEWPORT_WIDTH_PX, SCREEN_SIZE_BUCKET_LABEL, SCREEN_SIZE_BUCKET_ORDER, STYLE_BREAKPOINT_MERGE_ORDER, ScreenSizeBucket, StyleBreakpointKey, TAILWIND_DEFAULT_BREAKPOINTS, getActiveStyleBreakpointChain, getScreenSizeBucketForWidth } from './breakpoints.js';
2
+ export { deepMergeStyle, mergeResponsivePartial, mergeResponsivePartialUpToBucket } from './merge.js';
3
+ export { ButtonLayoutBreakpointPatch, StackLayoutBreakpointPatch, resolveButtonLayoutAtWidth, resolveButtonStyleAtWidth, resolveCommonStyleAtWidth, resolveCommonStyleForEditBucket, resolveIconStyleAtWidth, resolveImageStyleAtWidth, resolveLayerGap, resolveLoaderCircularSizePx, resolveLoaderLinearHeightPx, resolveLoaderStrokeWidthPx, resolveProgressLinearHeightPx, resolveStackLayoutAtWidth, resolveTextStyleAtWidth, resolveTextStyleForEditBucket } from './layerResolve.js';
4
+ export { resolveScreenContainerForEditBucket, resolveScreenContainerStyleAtWidth, screenBackgroundFillUsesMedia } from './screenContainerResolve.js';
5
+ export { PreviewPhoneSystemUi, previewPhoneSafeAreaInsetBottomPx, previewPhoneSafeAreaInsetHorizontalPx, previewPhoneSafeAreaInsetTopPx, previewPhoneSafeAreaPadding } from './previewSafeAreaInsets.js';
6
+ export { addPadding, resolveEffectiveScreenShellPadding } from './screenShellInsets.js';
7
+ import '@getrheo/contracts/layers';
8
+ import '@getrheo/contracts';