@bravostudioai/react 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/main.js +3 -2
- package/dist/cli/commands/generate.js +161 -1438
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/codegen/generator.js +473 -0
- package/dist/codegen/generator.js.map +1 -0
- package/dist/codegen/parser.js +720 -0
- package/dist/codegen/parser.js.map +1 -0
- package/dist/components/EncoreApp.js +197 -162
- package/dist/components/EncoreApp.js.map +1 -1
- package/dist/contexts/EncoreRouterContext.js +13 -0
- package/dist/contexts/EncoreRouterContext.js.map +1 -0
- package/dist/hooks/usePusherUpdates.js +4 -2
- package/dist/hooks/usePusherUpdates.js.map +1 -1
- package/dist/lib/dynamicModules.js +75 -85
- package/dist/lib/dynamicModules.js.map +1 -1
- package/dist/lib/moduleRegistry.js +20 -0
- package/dist/lib/moduleRegistry.js.map +1 -0
- package/dist/lib/packages.js +1 -3
- package/dist/lib/packages.js.map +1 -1
- package/dist/src/cli/commands/generate.d.ts.map +1 -1
- package/dist/src/codegen/generator.d.ts +10 -0
- package/dist/src/codegen/generator.d.ts.map +1 -0
- package/dist/src/codegen/index.d.ts +4 -0
- package/dist/src/codegen/index.d.ts.map +1 -0
- package/dist/src/codegen/parser.d.ts +37 -0
- package/dist/src/codegen/parser.d.ts.map +1 -0
- package/dist/src/codegen/types.d.ts +53 -0
- package/dist/src/codegen/types.d.ts.map +1 -0
- package/dist/src/components/EncoreApp.d.ts +5 -1
- package/dist/src/components/EncoreApp.d.ts.map +1 -1
- package/dist/src/contexts/EncoreRouterContext.d.ts +10 -0
- package/dist/src/contexts/EncoreRouterContext.d.ts.map +1 -0
- package/dist/src/hooks/useAuthRedirect.d.ts.map +1 -1
- package/dist/src/lib/dynamicModules.d.ts +1 -5
- package/dist/src/lib/dynamicModules.d.ts.map +1 -1
- package/dist/src/lib/moduleRegistry.d.ts +9 -0
- package/dist/src/lib/moduleRegistry.d.ts.map +1 -0
- package/dist/src/lib/packages.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/generate.ts +88 -2723
- package/src/codegen/generator.ts +877 -0
- package/src/codegen/index.ts +3 -0
- package/src/codegen/parser.ts +1614 -0
- package/src/codegen/types.ts +58 -0
- package/src/components/EncoreApp.tsx +75 -22
- package/src/contexts/EncoreRouterContext.ts +28 -0
- package/src/hooks/useAuthRedirect.ts +56 -55
- package/src/lib/packages.ts +8 -15
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EncoreApp.js","sources":["../../src/components/EncoreApp.tsx"],"sourcesContent":["import useSWR from \"swr\";\nimport fetcher from \"../lib/fetcher\";\nimport useEncoreState from \"../stores/useEncoreState\";\nimport React, {\n Suspense,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n} from \"react\";\nimport { isLocalMode, setLocalModeOverride } from \"../lib/localMode\";\nimport EncoreBindingContext from \"../contexts/EncoreBindingContext\";\nimport EncoreComponentIdContext from \"../contexts/EncoreComponentIdContext\";\nimport EncoreActionContext, {\n type EncoreActionPayload,\n} from \"../contexts/EncoreActionContext\";\nimport EncoreRepeatingContainerContext, {\n type RepeatingContainerControl,\n} from \"../contexts/EncoreRepeatingContainerContext\";\nimport DynamicComponent from \"./DynamicComponent\";\nimport { Link } from \"react-router-dom\";\nimport { usePusherUpdates } from \"../hooks/usePusherUpdates\";\n\ntype Props = {\n appId: string;\n pageId?: string;\n componentId?: string;\n fallback?: React.ReactNode;\n onSizeChange?: (size: { width: number; height: number }) => void;\n onAction?: (payload: EncoreActionPayload) => void | Promise<void>;\n data?: Record<string, string | number | any[]>;\n // When provided, force the runtime to load from either remote or local sources\n source?: \"remote\" | \"local\";\n // Control repeating containers (sliders, lists, etc.) by container ID\n repeatingContainerControls?: Record<\n string,\n { currentIndex?: number; onIndexChange?: (index: number) => void }\n >;\n // Control input groups - maps group name to active element name\n inputGroups?: Record<string, string>;\n // Base URL for the Encore service API (e.g., \"https://api.example.com\")\n // If not provided, defaults to \"https://apps-service-dev.bravostudio.app\"\n baseURL?: string;\n appDefinition?: any;\n pageDefinition?: any;\n componentCode?: string;\n};\n\ntype EncoreAssetsById = Record<string, { url?: string }>;\ntype EncoreState = {\n setApp: (app: unknown) => void;\n setAppId: (id: string) => void;\n setPageId: (id: string) => void;\n assetsById: EncoreAssetsById;\n};\n\nconst setAppSelector = (state: EncoreState) => state.setApp;\nconst setAppIdSelector = (state: EncoreState) => state.setAppId;\nconst setPageIdSelector = (state: EncoreState) => state.setPageId;\nconst assetsByIdSelector = (state: EncoreState) => state.assetsById;\n\nconst EncoreApp = ({\n appId,\n pageId,\n componentId,\n fallback,\n onSizeChange,\n onAction,\n data,\n source,\n repeatingContainerControls,\n inputGroups,\n baseURL,\n appDefinition,\n pageDefinition,\n componentCode,\n}: Props) => {\n console.log(\"Render: EncoreApp\");\n console.log(\"🔥 ENCORE-LIB SOURCE CODE IS ACTIVE 🔥\");\n console.log(\"✨ ENCORE-LIB UPDATED - TEST MESSAGE ✨\");\n\n // CRITICAL: Set baseURL BEFORE any hooks that might trigger fetches\n // This must happen synchronously, not in useEffect, because useSWR will fetch immediately\n if (baseURL) {\n const currentBaseURL = useEncoreState.getState().baseURL;\n if (currentBaseURL !== baseURL) {\n useEncoreState.getState().setBaseURL(baseURL);\n }\n }\n\n // Apply source override immediately so hooks below observe correct mode\n if (source) {\n setLocalModeOverride(source === \"local\" ? \"local\" : \"remote\");\n }\n // const [searchParams] = useSearchParams();\n // const noRedirect = searchParams.get(\"noRedirect\");\n const noRedirect = false;\n\n const setApp = useEncoreState(setAppSelector);\n const setAppId = useEncoreState(setAppIdSelector);\n const setPageId = useEncoreState(setPageIdSelector);\n const assetsById = useEncoreState(assetsByIdSelector);\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n // State to force DynamicComponent reload when updates are received\n const [reloadKey, setReloadKey] = useState<string | number>(0);\n // Set up Pusher to listen for component updates\n const handleUpdate = useCallback(() => {\n // Increment reloadKey to force DynamicComponent to reload\n setReloadKey((prev) => (typeof prev === \"number\" ? prev + 1 : Date.now()));\n }, []);\n\n // Only enable Pusher in remote mode - it doesn't make sense in local mode\n usePusherUpdates({\n appId,\n pageId: pageId || undefined,\n enabled: !isLocalMode() && !appDefinition,\n onUpdate: handleUpdate,\n });\n\n // usePusherUpdates({\n // appId,\n // pageId: pageId || undefined,\n // enabled: false, // DISABLED FOR DEBUGGING\n // onUpdate: handleUpdate,\n // });\n\n const useLocalFlag = source === \"local\" || isLocalMode();\n // If appDefinition is provided, disable SWR fetch by setting url to null\n const appUrl = appDefinition\n ? null\n : appId && `/devices/apps/${appId}${useLocalFlag ? \"?useLocal=1\" : \"\"}`;\n\n const appSWR = useSWR(appUrl, fetcher, {\n suspense: !!appUrl, // Only use suspense if we are fetching\n });\n\n const app = appDefinition ? { data: appDefinition } : appSWR;\n\n useEffect(() => {\n setApp(app.data);\n }, [app.data, setApp]);\n\n // Load fonts declared in app.json using the FontFace API\n useEffect(() => {\n type EncoreFont = {\n id?: string;\n url?: string;\n fontName?: { family?: string; postScriptName?: string };\n };\n type AppDataWithFonts = { app?: { fonts?: EncoreFont[] } };\n const fonts: EncoreFont[] =\n (app?.data as AppDataWithFonts | undefined)?.app?.fonts ?? [];\n if (!fonts || fonts.length === 0) return;\n if (typeof window === \"undefined\" || !(\"FontFace\" in window)) return;\n fonts.forEach((f) => {\n try {\n const family = f?.fontName?.family;\n const url = f?.url;\n const postScriptName = f?.fontName?.postScriptName;\n if (!family || !url) return;\n\n // Infer font weight from postScriptName if available\n // This ensures the browser uses the correct font-face variant\n let weight: string | number | undefined = undefined;\n if (postScriptName) {\n const weightMatch = postScriptName.match(\n /(?:^|-)(Thin|ExtraLight|Light|Regular|Medium|SemiBold|Bold|ExtraBold|Black)(?:-|$)/i\n );\n if (weightMatch) {\n const weightName = weightMatch[1].toLowerCase();\n const weightMap: Record<string, number> = {\n thin: 100,\n extralight: 200,\n light: 300,\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n extrabold: 800,\n black: 900,\n };\n weight = weightMap[weightName] || 400;\n }\n }\n\n // Create FontFace with weight descriptor if we inferred it\n const fontFace =\n weight !== undefined\n ? new FontFace(family, `url(${url})`, { weight: weight.toString() })\n : new FontFace(family, `url(${url})`);\n\n fontFace\n .load()\n .then((ff) => {\n document.fonts.add(ff);\n })\n .catch(() => {\n // Ignore font load failures to avoid disrupting rendering\n });\n } catch {\n // Best-effort; ignore\n }\n });\n }, [app?.data]);\n\n useEffect(() => {\n setAppId(appId);\n }, [appId, setAppId]);\n\n useEffect(() => {\n if (!pageId) return;\n setPageId(pageId);\n }, [pageId, setPageId]);\n\n // FIXME: Asset data should be embedded into & preloaded by component, not looked up like this\n useEffect(() => {\n if (Object.keys(assetsById).length === 0) return;\n (async () => {\n // Preload images in the browser\n await Promise.allSettled(\n Object.keys(assetsById).map((id) => {\n if (assetsById[id].url) {\n return new Promise((resolve) => {\n const img = new Image();\n img.onload = resolve;\n img.onerror = resolve; // tolerate failures to avoid unhandled rejections\n img.src = assetsById[id].url!;\n });\n }\n return Promise.resolve();\n })\n );\n })();\n }, [assetsById]);\n\n const pageUrl = pageDefinition\n ? null\n : appId &&\n pageId &&\n `/devices/apps/${appId}/node/${pageId}${\n useLocalFlag ? \"?useLocal=1\" : \"\"\n }`;\n const pageSWR = useSWR(pageUrl, fetcher, { suspense: !!pageUrl });\n const pageData = pageDefinition ? { data: pageDefinition } : pageSWR;\n\n // Debug logging commented out to prevent console flooding\n /*\n useEffect(() => {\n if (pageData.data) {\n console.log(\"=== PAGE DATA STRUCTURE ===\");\n console.log(\"Full pageData.data:\", pageData.data);\n console.log(\"pageData.data keys:\", Object.keys(pageData.data));\n console.log(\"Client data:\", pageData.data.clientData);\n console.log(\"Client data type:\", typeof pageData.data.clientData);\n console.log(\n \"Client data keys:\",\n pageData.data.clientData ? Object.keys(pageData.data.clientData) : \"N/A\"\n );\n\n // Try to find the actual node data structure\n const allKeys = Object.keys(pageData.data);\n console.log(\"All top-level keys in pageData.data:\", allKeys);\n\n // Log the full structure more deeply\n console.log(\n \"Full pageData.data structure:\",\n JSON.stringify(pageData.data, null, 2)\n );\n\n const clientData = pageData.data.clientData || pageData.data;\n\n // Helper to recursively search for sliders in tree structure\n const findSlidersInTree = (nodeData: any, path = \"\"): any[] => {\n const sliders: any[] = [];\n if (!nodeData || typeof nodeData !== \"object\") return sliders;\n\n // Check if this node is a slider\n const isSlider =\n nodeData.type === \"container:slider\" ||\n nodeData.type === \"component:slider\" ||\n nodeData.name?.toLowerCase().includes(\"slider\") ||\n (Array.isArray(nodeData.tags) &&\n nodeData.tags.some((tag: string) =>\n tag.toLowerCase().includes(\"slider\")\n ));\n\n if (isSlider) {\n sliders.push({\n path,\n id: nodeData.id,\n name: nodeData.name,\n type: nodeData.type,\n tags: nodeData.tags,\n data: nodeData.data,\n style: nodeData.style,\n fullNodeData: nodeData,\n });\n }\n\n // Recursively search children\n if (nodeData.children) {\n const children = Array.isArray(nodeData.children)\n ? nodeData.children\n : [nodeData.children];\n children.forEach((child: any, index: number) => {\n if (child && typeof child === \"object\") {\n sliders.push(...findSlidersInTree(child, `${path}/${index}`));\n }\n });\n }\n\n return sliders;\n };\n\n // Check if clientData is a flat object keyed by ID (most likely)\n let sliders: any[] = [];\n if (\n clientData &&\n typeof clientData === \"object\" &&\n !Array.isArray(clientData)\n ) {\n // Check if it's a flat structure (keyed by IDs)\n const entries = Object.entries(clientData);\n console.log(`Client data has ${entries.length} entries`);\n\n // Search all entries for sliders\n entries.forEach(([key, value]: [string, any]) => {\n if (value && typeof value === \"object\") {\n // Check if this entry itself is a slider\n const isSlider =\n value.type === \"container:slider\" ||\n value.type === \"component:slider\" ||\n value.name?.toLowerCase().includes(\"slider\") ||\n (Array.isArray(value.tags) &&\n value.tags.some((tag: string) =>\n tag.toLowerCase().includes(\"slider\")\n ));\n\n if (isSlider) {\n sliders.push({\n id: key,\n name: value.name,\n type: value.type,\n tags: value.tags,\n data: value.data,\n style: value.style,\n fullNodeData: value,\n });\n }\n\n // Also search recursively in case it's nested\n sliders.push(...findSlidersInTree(value, key));\n }\n });\n\n // If no sliders found in flat structure, try treating it as a tree\n if (sliders.length === 0) {\n sliders = findSlidersInTree(clientData, \"root\");\n }\n } else {\n // Treat as tree structure\n sliders = findSlidersInTree(clientData, \"root\");\n }\n\n console.log(\"=== SLIDER COMPONENTS FOUND ===\");\n console.log(`Found ${sliders.length} slider(s):`, sliders);\n\n sliders.forEach((slider, index) => {\n console.log(`\\n--- Slider ${index + 1} ---`);\n console.log(\"ID:\", slider.id);\n console.log(\"Name:\", slider.name);\n console.log(\"Type:\", slider.type);\n console.log(\"Tags:\", slider.tags);\n console.log(\"Data:\", slider.data);\n console.log(\"Full node data:\", slider.fullNodeData);\n\n // Look for data binding tags\n if (Array.isArray(slider.tags)) {\n const bindingTags = slider.tags.filter(\n (tag: string) =>\n tag.includes(\"PROP:\") ||\n tag.includes(\"LIST:\") ||\n tag.includes(\"DATA:\")\n );\n if (bindingTags.length > 0) {\n console.log(\"🔍 Data binding tags found:\", bindingTags);\n }\n }\n });\n\n // Also log all unique tags found across all components for reference\n const allTags = new Set<string>();\n const allEntries = Object.entries(clientData);\n allEntries.forEach(([_, value]: [string, any]) => {\n if (value?.tags && Array.isArray(value.tags)) {\n value.tags.forEach((tag: string) => allTags.add(tag));\n }\n });\n console.log(\"\\n=== ALL UNIQUE TAGS IN PAGE ===\");\n console.log(Array.from(allTags).sort());\n }\n }, [pageData.data]);\n */\n\n // Memoize the context object to prevent infinite re-renders\n // Only recreate when the actual data changes, not on every render\n const context = useMemo(() => {\n let clientData = pageData.data?.clientData;\n\n // --- GENERIC DATA PATCHING START ---\n // Recursively patch the data to fix layout and slider issues based on heuristics\n const patchPageData = (node: any) => {\n if (!node || typeof node !== \"object\") return;\n\n // 1. Layout Heuristic: If children widths sum to ~100% or ~375px, force HORIZONTAL layout\n // RELAXED: No longer requires layoutSizingHorizontal: \"FIXED\" - width data alone is sufficient\n if (\n node.children &&\n Array.isArray(node.children) &&\n node.children.length > 1\n ) {\n let totalWidth = 0;\n let childrenWithWidth = 0;\n\n node.children.forEach((child: any) => {\n if (child.style?.width) {\n // Width might be a percentage or pixel value.\n // Based on logs, we saw \"width: 52\" and \"width: 48\" which sum to 100.\n // If it's percentage, we check if it sums to 100.\n // If it's pixels, we check if it sums to ~375.\n totalWidth += child.style.width;\n childrenWithWidth++;\n }\n });\n\n // Check for percentage sum ~100 or pixel sum ~375\n // Only apply if we have at least 2 children with width data\n const isFullWidthRow =\n (Math.abs(totalWidth - 100) < 1 || Math.abs(totalWidth - 375) < 5) &&\n childrenWithWidth >= 2;\n\n if (isFullWidthRow) {\n if (!node.style) node.style = {};\n if (!node.style.layout) node.style.layout = {};\n\n // Only apply if mode is missing or undefined\n if (!node.style.layout.mode) {\n console.log(\n `[PATCH] Forcing HORIZONTAL layout for node ${node.id} (${childrenWithWidth} children, widths sum: ${totalWidth})`\n );\n node.style.layout.mode = \"HORIZONTAL\";\n node.style.layout.primaryAxisAlignItems = \"flex-start\";\n node.style.layout.counterAxisAlignItems = \"flex-start\";\n }\n }\n }\n\n // 2. Slider Heuristic: If slider is taller than wide, force VERTICAL animation\n // DISABLED: This is too aggressive and breaks horizontal sliders that happen to be tall (e.g. 50% width columns)\n /*\n const isSlider =\n node.type === \"container:slider\" ||\n node.type === \"component:slider\" ||\n (node.tags &&\n Array.isArray(node.tags) &&\n node.tags.some((t: string) => t.toLowerCase().includes(\"slider\")));\n\n if (isSlider) {\n const width = node.style?.width || 0;\n const height = node.style?.height || 0;\n // Check aspect ratio. If height > width, it's likely vertical.\n // Note: width/height might be percentages or pixels.\n // If both are numbers, we can compare.\n // From logs: width: 52, height: 85.27. This is clearly vertical shape.\n if (height > width) {\n if (!node.data) node.data = {};\n if (!node.data.params) node.data.params = {};\n\n // Only apply if animation is default or missing\n if (\n !node.data.params.animation ||\n node.data.params.animation === \"default\" ||\n node.data.params.animation === \"horizontal\"\n ) {\n console.log(\n `[PATCH] Forcing VERTICAL animation for slider ${node.id} (W:${width}, H:${height})`\n );\n node.data.params.animation = \"vertical\";\n }\n }\n }\n */\n\n // Recurse\n if (node.children) {\n if (Array.isArray(node.children)) {\n node.children.forEach(patchPageData);\n } else {\n patchPageData(node.children);\n }\n }\n };\n\n if (clientData) {\n // Clone to avoid mutating SWR cache directly if possible, though deep clone might be expensive.\n // For now, patching in place as it's a fix.\n patchPageData(clientData);\n }\n // --- GENERIC DATA PATCHING END ---\n\n return {\n nodeData: undefined,\n // Allow overriding specific values by element id.\n // For now, this is used to override TextComponent content when the node has the PROP:TEXT_VAR tag.\n textOverridesById: data,\n // Support for encore:data:array tags - provide array data by component ID\n arrayDataById: data,\n // Support for standalone component data binding (encore:data tags at root level)\n rootData: data,\n };\n }, [pageData.data?.clientData, data]);\n\n // Manage repeating container controls\n const [containerControls, setContainerControls] = useState<\n Map<string, RepeatingContainerControl>\n >(new Map());\n const [controlPropsMap, setControlPropsMap] = useState<\n Map<\n string,\n { currentIndex?: number; onIndexChange?: (index: number) => void }\n >\n >(new Map());\n\n // Update control props from prop\n useEffect(() => {\n if (repeatingContainerControls) {\n setControlPropsMap((prev) => {\n // Check if content actually changed to avoid unnecessary updates\n let changed = false;\n if (prev.size !== Object.keys(repeatingContainerControls).length) {\n changed = true;\n } else {\n for (const [id, props] of Object.entries(\n repeatingContainerControls\n )) {\n const prevProps = prev.get(id);\n if (!prevProps) {\n changed = true;\n break;\n }\n if (\n prevProps.currentIndex !== props.currentIndex ||\n prevProps.onIndexChange !== props.onIndexChange\n ) {\n changed = true;\n break;\n }\n }\n }\n\n if (!changed) return prev;\n\n const newMap = new Map();\n Object.entries(repeatingContainerControls).forEach(([id, props]) => {\n newMap.set(id, props);\n });\n return newMap;\n });\n }\n }, [repeatingContainerControls]);\n\n // Sync input groups from props to store\n useEffect(() => {\n if (inputGroups) {\n const setInputGroupValue = useEncoreState.getState().setInputGroupValue;\n Object.entries(inputGroups).forEach(([groupName, elementName]) => {\n setInputGroupValue(groupName, elementName);\n });\n }\n }, [inputGroups]);\n\n const registerContainer = useCallback(\n (id: string, control: RepeatingContainerControl) => {\n setContainerControls((prev) => {\n const next = new Map(prev);\n next.set(id, control);\n return next;\n });\n },\n []\n );\n\n const unregisterContainer = useCallback((id: string) => {\n setContainerControls((prev) => {\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n // Do NOT delete from controlPropsMap here.\n // controlPropsMap contains props passed from the parent (repeatingContainerControls).\n // If we delete them, we lose the configuration passed down to us.\n // The props should persist even if the component temporarily unregisters.\n }, []);\n\n const getControl = useCallback(\n (id: string) => {\n return containerControls.get(id);\n },\n [containerControls]\n );\n\n const setControlProps = useCallback(\n (\n id: string,\n props:\n | { currentIndex?: number; onIndexChange?: (index: number) => void }\n | ((prev: {\n currentIndex?: number;\n onIndexChange?: (index: number) => void;\n }) => {\n currentIndex?: number;\n onIndexChange?: (index: number) => void;\n })\n ) => {\n setControlPropsMap((prev) => {\n const next = new Map(prev);\n const current = next.get(id) || {};\n const newProps = typeof props === \"function\" ? props(current) : props;\n next.set(id, newProps);\n return next;\n });\n },\n []\n );\n\n const getControlProps = useCallback(\n (id: string) => {\n return controlPropsMap.get(id);\n },\n [controlPropsMap]\n );\n\n // Control props are automatically passed to registered containers via context\n // Components read props via getControlProps() and update when props change\n\n // Create context value - this object changes when controlPropsMap changes,\n // causing all consumers to re-render and get updated props\n const repeatingContainerContextValue = React.useMemo(\n () => ({\n registerContainer,\n unregisterContainer,\n getControl,\n setControlProps,\n getControlProps,\n // Include controlPropsMap size in the value to trigger re-renders when it changes\n _propsVersion: controlPropsMap.size,\n }),\n [\n registerContainer,\n unregisterContainer,\n getControl,\n setControlProps,\n getControlProps,\n controlPropsMap.size,\n ]\n );\n\n // Observe size changes of the dynamic content container and notify consumer\n useEffect(() => {\n if (!onSizeChange) return;\n const element = containerRef.current;\n if (!element) return;\n const notify = (entry: ResizeObserverEntry) => {\n const cr = entry.contentRect;\n onSizeChange({ width: cr.width, height: cr.height });\n };\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n notify(entry);\n }\n });\n // Emit initial size as soon as possible\n const rect = element.getBoundingClientRect();\n onSizeChange({ width: rect.width, height: rect.height });\n observer.observe(element);\n return () => {\n observer.disconnect();\n };\n }, [onSizeChange]);\n\n // Per-instance source override\n useEffect(() => {\n if (!source) return;\n setLocalModeOverride(source === \"local\" ? \"local\" : \"remote\");\n return () => {\n // Clear override when this instance unmounts\n setLocalModeOverride(null);\n };\n }, [source]);\n\n if (!pageId) {\n return (\n <div style={{ padding: \"30px\" }}>\n <div style={{ overflowY: \"auto\" }}>\n {(isLocalMode()\n ? // Local mode: app.json provides pages under app.data.pages\n ((app?.data as any)?.app?.data?.pages || []).map(\n (pg: any) => pg?.id\n )\n : app?.data?.app.pageIds || []\n ).map((p: string) => (\n <Link\n key={p}\n to={`/apps/${appId}/pages/${p}?noRedirect=${noRedirect}`}\n style={{\n fontSize: 20,\n display: \"block\",\n marginBottom: \"10px\",\n }}\n >\n {p}\n </Link>\n ))}\n </div>\n </div>\n );\n }\n return (\n <div\n ref={containerRef}\n style={{ width: \"100%\", height: \"100%\", position: \"relative\" }}\n >\n <Suspense fallback={fallback || <div />}>\n <EncoreComponentIdContext.Provider value={{ componentId }}>\n <EncoreActionContext.Provider value={{ onAction }}>\n <EncoreRepeatingContainerContext.Provider\n value={repeatingContainerContextValue}\n >\n <EncoreBindingContext.Provider value={context}>\n <DynamicComponent\n name={`${appId}/draft/components/${pageId}`}\n fallback={fallback}\n reloadKey={reloadKey}\n componentCode={componentCode}\n >\n {\" \"}\n </DynamicComponent>\n </EncoreBindingContext.Provider>\n </EncoreRepeatingContainerContext.Provider>\n </EncoreActionContext.Provider>\n </EncoreComponentIdContext.Provider>\n </Suspense>\n </div>\n );\n};\n\nexport default EncoreApp;\n"],"names":["setAppSelector","state","setAppIdSelector","setPageIdSelector","assetsByIdSelector","EncoreApp","appId","pageId","componentId","fallback","onSizeChange","onAction","data","source","repeatingContainerControls","inputGroups","baseURL","appDefinition","pageDefinition","componentCode","useEncoreState","setLocalModeOverride","noRedirect","setApp","setAppId","setPageId","assetsById","containerRef","useRef","reloadKey","setReloadKey","useState","handleUpdate","useCallback","prev","usePusherUpdates","isLocalMode","useLocalFlag","appUrl","appSWR","useSWR","fetcher","app","useEffect","fonts","f","family","url","postScriptName","weight","weightMatch","weightName","ff","id","resolve","img","pageUrl","pageSWR","pageData","context","useMemo","clientData","patchPageData","node","totalWidth","childrenWithWidth","child","containerControls","setContainerControls","controlPropsMap","setControlPropsMap","changed","props","prevProps","newMap","setInputGroupValue","groupName","elementName","registerContainer","control","next","unregisterContainer","getControl","setControlProps","current","newProps","getControlProps","repeatingContainerContextValue","React","element","notify","entry","cr","observer","entries","rect","jsx","Suspense","EncoreComponentIdContext","EncoreActionContext","EncoreRepeatingContainerContext","EncoreBindingContext","DynamicComponent","pg","p","Link"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EncoreApp.js","sources":["../../src/components/EncoreApp.tsx"],"sourcesContent":["import useSWR from \"swr\";\nimport fetcher from \"../lib/fetcher\";\nimport useEncoreState from \"../stores/useEncoreState\";\nimport React, {\n Suspense,\n useEffect,\n useRef,\n useState,\n useCallback,\n useMemo,\n} from \"react\";\nimport { isLocalMode, setLocalModeOverride } from \"../lib/localMode\";\nimport EncoreBindingContext from \"../contexts/EncoreBindingContext\";\nimport EncoreComponentIdContext from \"../contexts/EncoreComponentIdContext\";\nimport EncoreActionContext, {\n type EncoreActionPayload,\n} from \"../contexts/EncoreActionContext\";\nimport EncoreRepeatingContainerContext, {\n type RepeatingContainerControl,\n} from \"../contexts/EncoreRepeatingContainerContext\";\nimport DynamicComponent from \"./DynamicComponent\";\n// import { Link } from \"react-router-dom\"; // Removed dependency\nimport { useEncoreRouter } from \"../contexts/EncoreRouterContext\";\nimport { usePusherUpdates } from \"../hooks/usePusherUpdates\";\n\n// Simple internal Link component that uses our router context\nconst Link = ({ to, children, style, ...props }: any) => {\n const { navigate } = useEncoreRouter();\n return (\n <a\n href={to}\n onClick={(e) => {\n e.preventDefault();\n navigate(to);\n }}\n style={{ cursor: \"pointer\", ...style }}\n {...props}\n >\n {children}\n </a>\n );\n};\n\ntype Props = {\n appId: string;\n pageId?: string;\n componentId?: string;\n fallback?: React.ReactNode;\n onSizeChange?: (size: { width: number; height: number }) => void;\n onContentSizeChange?: (size: { width: number; height: number }) => void;\n onAction?: (payload: EncoreActionPayload) => void | Promise<void>;\n data?: Record<string, string | number | any[]>;\n // When provided, force the runtime to load from either remote or local sources\n source?: \"remote\" | \"local\";\n // Control repeating containers (sliders, lists, etc.) by container ID\n repeatingContainerControls?: Record<\n string,\n { currentIndex?: number; onIndexChange?: (index: number) => void }\n >;\n // Control input groups - maps group name to active element name\n inputGroups?: Record<string, string>;\n // Base URL for the Encore service API (e.g., \"https://api.example.com\")\n // If not provided, defaults to \"https://apps-service-dev.bravostudio.app\"\n baseURL?: string;\n appDefinition?: any;\n pageDefinition?: any;\n componentCode?: string;\n};\n\ntype EncoreAssetsById = Record<string, { url?: string }>;\ntype EncoreState = {\n setApp: (app: unknown) => void;\n setAppId: (id: string) => void;\n setPageId: (id: string) => void;\n assetsById: EncoreAssetsById;\n};\n\nconst setAppSelector = (state: EncoreState) => state.setApp;\nconst setAppIdSelector = (state: EncoreState) => state.setAppId;\nconst setPageIdSelector = (state: EncoreState) => state.setPageId;\nconst assetsByIdSelector = (state: EncoreState) => state.assetsById;\n\nconst EncoreApp = ({\n appId,\n pageId,\n componentId,\n fallback,\n onSizeChange,\n onContentSizeChange,\n onAction,\n data,\n source,\n repeatingContainerControls,\n inputGroups,\n baseURL,\n appDefinition,\n pageDefinition,\n componentCode,\n}: Props) => {\n console.log(\"Render: EncoreApp\");\n console.log(\"🔥 ENCORE-LIB SOURCE CODE IS ACTIVE 🔥\");\n console.log(\"✨ ENCORE-LIB UPDATED - TEST MESSAGE ✨\");\n\n // CRITICAL: Set baseURL BEFORE any hooks that might trigger fetches\n // This must happen synchronously, not in useEffect, because useSWR will fetch immediately\n if (baseURL) {\n const currentBaseURL = useEncoreState.getState().baseURL;\n if (currentBaseURL !== baseURL) {\n useEncoreState.getState().setBaseURL(baseURL);\n }\n }\n\n // Apply source override immediately so hooks below observe correct mode\n if (source) {\n setLocalModeOverride(source === \"local\" ? \"local\" : \"remote\");\n }\n // const [searchParams] = useSearchParams();\n // const noRedirect = searchParams.get(\"noRedirect\");\n const noRedirect = false;\n\n const setApp = useEncoreState(setAppSelector);\n const setAppId = useEncoreState(setAppIdSelector);\n const setPageId = useEncoreState(setPageIdSelector);\n const assetsById = useEncoreState(assetsByIdSelector);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const contentWrapperRef = useRef<HTMLDivElement | null>(null);\n\n // Monitor content size changes\n useEffect(() => {\n if (!onContentSizeChange) return;\n const element = contentWrapperRef.current;\n if (!element) return;\n\n const notify = () => {\n // Use scroll dimensions to get full size including overflow\n onContentSizeChange({\n width: element.scrollWidth,\n height: element.scrollHeight,\n });\n };\n\n const observer = new ResizeObserver(() => {\n notify();\n });\n\n // Emit initial size\n notify();\n observer.observe(element);\n return () => observer.disconnect();\n }, [onContentSizeChange]);\n\n // State to force DynamicComponent reload when updates are received\n const [reloadKey, setReloadKey] = useState<string | number>(0);\n // Set up Pusher to listen for component updates\n const handleUpdate = useCallback(() => {\n // Increment reloadKey to force DynamicComponent to reload\n setReloadKey((prev) => (typeof prev === \"number\" ? prev + 1 : Date.now()));\n }, []);\n\n // Only enable Pusher in remote mode - it doesn't make sense in local mode\n usePusherUpdates({\n appId,\n pageId: pageId || undefined,\n enabled: !isLocalMode() && !appDefinition,\n onUpdate: handleUpdate,\n });\n\n // usePusherUpdates({\n // appId,\n // pageId: pageId || undefined,\n // enabled: false, // DISABLED FOR DEBUGGING\n // onUpdate: handleUpdate,\n // });\n\n const useLocalFlag = source === \"local\" || isLocalMode();\n // If appDefinition is provided, disable SWR fetch by setting url to null\n const appUrl = appDefinition\n ? null\n : appId && `/devices/apps/${appId}${useLocalFlag ? \"?useLocal=1\" : \"\"}`;\n\n const appSWR = useSWR(appUrl, fetcher, {\n suspense: !!appUrl, // Only use suspense if we are fetching\n });\n\n const app = appDefinition ? { data: appDefinition } : appSWR;\n\n useEffect(() => {\n setApp(app.data);\n }, [app.data, setApp]);\n\n // Load fonts declared in app.json using the FontFace API\n useEffect(() => {\n type EncoreFont = {\n id?: string;\n url?: string;\n fontName?: { family?: string; postScriptName?: string };\n };\n type AppDataWithFonts = { app?: { fonts?: EncoreFont[] } };\n const fonts: EncoreFont[] =\n (app?.data as AppDataWithFonts | undefined)?.app?.fonts ?? [];\n if (!fonts || fonts.length === 0) return;\n if (typeof window === \"undefined\" || !(\"FontFace\" in window)) return;\n fonts.forEach((f) => {\n try {\n const family = f?.fontName?.family;\n const url = f?.url;\n const postScriptName = f?.fontName?.postScriptName;\n if (!family || !url) return;\n\n // Infer font weight from postScriptName if available\n // This ensures the browser uses the correct font-face variant\n let weight: string | number | undefined = undefined;\n if (postScriptName) {\n const weightMatch = postScriptName.match(\n /(?:^|-)(Thin|ExtraLight|Light|Regular|Medium|SemiBold|Bold|ExtraBold|Black)(?:-|$)/i\n );\n if (weightMatch) {\n const weightName = weightMatch[1].toLowerCase();\n const weightMap: Record<string, number> = {\n thin: 100,\n extralight: 200,\n light: 300,\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n extrabold: 800,\n black: 900,\n };\n weight = weightMap[weightName] || 400;\n }\n }\n\n // Create FontFace with weight descriptor if we inferred it\n const fontFace =\n weight !== undefined\n ? new FontFace(family, `url(${url})`, { weight: weight.toString() })\n : new FontFace(family, `url(${url})`);\n\n fontFace\n .load()\n .then((ff) => {\n document.fonts.add(ff);\n })\n .catch(() => {\n // Ignore font load failures to avoid disrupting rendering\n });\n } catch {\n // Best-effort; ignore\n }\n });\n }, [app?.data]);\n\n useEffect(() => {\n setAppId(appId);\n }, [appId, setAppId]);\n\n useEffect(() => {\n if (!pageId) return;\n setPageId(pageId);\n }, [pageId, setPageId]);\n\n // FIXME: Asset data should be embedded into & preloaded by component, not looked up like this\n useEffect(() => {\n if (Object.keys(assetsById).length === 0) return;\n (async () => {\n // Preload images in the browser\n await Promise.allSettled(\n Object.keys(assetsById).map((id) => {\n if (assetsById[id].url) {\n return new Promise((resolve) => {\n const img = new Image();\n img.onload = resolve;\n img.onerror = resolve; // tolerate failures to avoid unhandled rejections\n img.src = assetsById[id].url!;\n });\n }\n return Promise.resolve();\n })\n );\n })();\n }, [assetsById]);\n\n const pageUrl = pageDefinition\n ? null\n : appId &&\n pageId &&\n `/devices/apps/${appId}/node/${pageId}${\n useLocalFlag ? \"?useLocal=1\" : \"\"\n }`;\n const pageSWR = useSWR(pageUrl, fetcher, { suspense: !!pageUrl });\n const pageData = pageDefinition ? { data: pageDefinition } : pageSWR;\n\n // Debug logging commented out to prevent console flooding\n /*\n useEffect(() => {\n if (pageData.data) {\n console.log(\"=== PAGE DATA STRUCTURE ===\");\n console.log(\"Full pageData.data:\", pageData.data);\n console.log(\"pageData.data keys:\", Object.keys(pageData.data));\n console.log(\"Client data:\", pageData.data.clientData);\n console.log(\"Client data type:\", typeof pageData.data.clientData);\n console.log(\n \"Client data keys:\",\n pageData.data.clientData ? Object.keys(pageData.data.clientData) : \"N/A\"\n );\n\n // Try to find the actual node data structure\n const allKeys = Object.keys(pageData.data);\n console.log(\"All top-level keys in pageData.data:\", allKeys);\n\n // Log the full structure more deeply\n console.log(\n \"Full pageData.data structure:\",\n JSON.stringify(pageData.data, null, 2)\n );\n\n const clientData = pageData.data.clientData || pageData.data;\n\n // Helper to recursively search for sliders in tree structure\n const findSlidersInTree = (nodeData: any, path = \"\"): any[] => {\n const sliders: any[] = [];\n if (!nodeData || typeof nodeData !== \"object\") return sliders;\n\n // Check if this node is a slider\n const isSlider =\n nodeData.type === \"container:slider\" ||\n nodeData.type === \"component:slider\" ||\n nodeData.name?.toLowerCase().includes(\"slider\") ||\n (Array.isArray(nodeData.tags) &&\n nodeData.tags.some((tag: string) =>\n tag.toLowerCase().includes(\"slider\")\n ));\n\n if (isSlider) {\n sliders.push({\n path,\n id: nodeData.id,\n name: nodeData.name,\n type: nodeData.type,\n tags: nodeData.tags,\n data: nodeData.data,\n style: nodeData.style,\n fullNodeData: nodeData,\n });\n }\n\n // Recursively search children\n if (nodeData.children) {\n const children = Array.isArray(nodeData.children)\n ? nodeData.children\n : [nodeData.children];\n children.forEach((child: any, index: number) => {\n if (child && typeof child === \"object\") {\n sliders.push(...findSlidersInTree(child, `${path}/${index}`));\n }\n });\n }\n\n return sliders;\n };\n\n // Check if clientData is a flat object keyed by ID (most likely)\n let sliders: any[] = [];\n if (\n clientData &&\n typeof clientData === \"object\" &&\n !Array.isArray(clientData)\n ) {\n // Check if it's a flat structure (keyed by IDs)\n const entries = Object.entries(clientData);\n console.log(`Client data has ${entries.length} entries`);\n\n // Search all entries for sliders\n entries.forEach(([key, value]: [string, any]) => {\n if (value && typeof value === \"object\") {\n // Check if this entry itself is a slider\n const isSlider =\n value.type === \"container:slider\" ||\n value.type === \"component:slider\" ||\n value.name?.toLowerCase().includes(\"slider\") ||\n (Array.isArray(value.tags) &&\n value.tags.some((tag: string) =>\n tag.toLowerCase().includes(\"slider\")\n ));\n\n if (isSlider) {\n sliders.push({\n id: key,\n name: value.name,\n type: value.type,\n tags: value.tags,\n data: value.data,\n style: value.style,\n fullNodeData: value,\n });\n }\n\n // Also search recursively in case it's nested\n sliders.push(...findSlidersInTree(value, key));\n }\n });\n\n // If no sliders found in flat structure, try treating it as a tree\n if (sliders.length === 0) {\n sliders = findSlidersInTree(clientData, \"root\");\n }\n } else {\n // Treat as tree structure\n sliders = findSlidersInTree(clientData, \"root\");\n }\n\n console.log(\"=== SLIDER COMPONENTS FOUND ===\");\n console.log(`Found ${sliders.length} slider(s):`, sliders);\n\n sliders.forEach((slider, index) => {\n console.log(`\\n--- Slider ${index + 1} ---`);\n console.log(\"ID:\", slider.id);\n console.log(\"Name:\", slider.name);\n console.log(\"Type:\", slider.type);\n console.log(\"Tags:\", slider.tags);\n console.log(\"Data:\", slider.data);\n console.log(\"Full node data:\", slider.fullNodeData);\n\n // Look for data binding tags\n if (Array.isArray(slider.tags)) {\n const bindingTags = slider.tags.filter(\n (tag: string) =>\n tag.includes(\"PROP:\") ||\n tag.includes(\"LIST:\") ||\n tag.includes(\"DATA:\")\n );\n if (bindingTags.length > 0) {\n console.log(\"🔍 Data binding tags found:\", bindingTags);\n }\n }\n });\n\n // Also log all unique tags found across all components for reference\n const allTags = new Set<string>();\n const allEntries = Object.entries(clientData);\n allEntries.forEach(([_, value]: [string, any]) => {\n if (value?.tags && Array.isArray(value.tags)) {\n value.tags.forEach((tag: string) => allTags.add(tag));\n }\n });\n console.log(\"\\n=== ALL UNIQUE TAGS IN PAGE ===\");\n console.log(Array.from(allTags).sort());\n }\n }, [pageData.data]);\n */\n\n // Memoize the context object to prevent infinite re-renders\n // Only recreate when the actual data changes, not on every render\n const context = useMemo(() => {\n let clientData = pageData.data?.clientData;\n\n // --- GENERIC DATA PATCHING START ---\n // Recursively patch the data to fix layout and slider issues based on heuristics\n const patchPageData = (node: any) => {\n if (!node || typeof node !== \"object\") return;\n\n // 1. Layout Heuristic: If children widths sum to ~100% or ~375px, force HORIZONTAL layout\n // RELAXED: No longer requires layoutSizingHorizontal: \"FIXED\" - width data alone is sufficient\n if (\n node.children &&\n Array.isArray(node.children) &&\n node.children.length > 1\n ) {\n let totalWidth = 0;\n let childrenWithWidth = 0;\n\n node.children.forEach((child: any) => {\n if (child.style?.width) {\n // Width might be a percentage or pixel value.\n // Based on logs, we saw \"width: 52\" and \"width: 48\" which sum to 100.\n // If it's percentage, we check if it sums to 100.\n // If it's pixels, we check if it sums to ~375.\n totalWidth += child.style.width;\n childrenWithWidth++;\n }\n });\n\n // Check for percentage sum ~100 or pixel sum ~375\n // Only apply if we have at least 2 children with width data\n const isFullWidthRow =\n (Math.abs(totalWidth - 100) < 1 || Math.abs(totalWidth - 375) < 5) &&\n childrenWithWidth >= 2;\n\n if (isFullWidthRow) {\n if (!node.style) node.style = {};\n if (!node.style.layout) node.style.layout = {};\n\n // Only apply if mode is missing or undefined\n if (!node.style.layout.mode) {\n console.log(\n `[PATCH] Forcing HORIZONTAL layout for node ${node.id} (${childrenWithWidth} children, widths sum: ${totalWidth})`\n );\n node.style.layout.mode = \"HORIZONTAL\";\n node.style.layout.primaryAxisAlignItems = \"flex-start\";\n node.style.layout.counterAxisAlignItems = \"flex-start\";\n }\n }\n }\n\n // 2. Slider Heuristic: If slider is taller than wide, force VERTICAL animation\n // DISABLED: This is too aggressive and breaks horizontal sliders that happen to be tall (e.g. 50% width columns)\n /*\n const isSlider =\n node.type === \"container:slider\" ||\n node.type === \"component:slider\" ||\n (node.tags &&\n Array.isArray(node.tags) &&\n node.tags.some((t: string) => t.toLowerCase().includes(\"slider\")));\n\n if (isSlider) {\n const width = node.style?.width || 0;\n const height = node.style?.height || 0;\n // Check aspect ratio. If height > width, it's likely vertical.\n // Note: width/height might be percentages or pixels.\n // If both are numbers, we can compare.\n // From logs: width: 52, height: 85.27. This is clearly vertical shape.\n if (height > width) {\n if (!node.data) node.data = {};\n if (!node.data.params) node.data.params = {};\n\n // Only apply if animation is default or missing\n if (\n !node.data.params.animation ||\n node.data.params.animation === \"default\" ||\n node.data.params.animation === \"horizontal\"\n ) {\n console.log(\n `[PATCH] Forcing VERTICAL animation for slider ${node.id} (W:${width}, H:${height})`\n );\n node.data.params.animation = \"vertical\";\n }\n }\n }\n */\n\n // Recurse\n if (node.children) {\n if (Array.isArray(node.children)) {\n node.children.forEach(patchPageData);\n } else {\n patchPageData(node.children);\n }\n }\n };\n\n if (clientData) {\n // Clone to avoid mutating SWR cache directly if possible, though deep clone might be expensive.\n // For now, patching in place as it's a fix.\n patchPageData(clientData);\n }\n // --- GENERIC DATA PATCHING END ---\n\n return {\n nodeData: undefined,\n // Allow overriding specific values by element id.\n // For now, this is used to override TextComponent content when the node has the PROP:TEXT_VAR tag.\n textOverridesById: data,\n // Support for encore:data:array tags - provide array data by component ID\n arrayDataById: data,\n // Support for standalone component data binding (encore:data tags at root level)\n rootData: data,\n };\n }, [pageData.data?.clientData, data]);\n\n // Manage repeating container controls\n const [containerControls, setContainerControls] = useState<\n Map<string, RepeatingContainerControl>\n >(new Map());\n const [controlPropsMap, setControlPropsMap] = useState<\n Map<\n string,\n { currentIndex?: number; onIndexChange?: (index: number) => void }\n >\n >(new Map());\n\n // Update control props from prop\n useEffect(() => {\n if (repeatingContainerControls) {\n setControlPropsMap((prev) => {\n // Check if content actually changed to avoid unnecessary updates\n let changed = false;\n if (prev.size !== Object.keys(repeatingContainerControls).length) {\n changed = true;\n } else {\n for (const [id, props] of Object.entries(\n repeatingContainerControls\n )) {\n const prevProps = prev.get(id);\n if (!prevProps) {\n changed = true;\n break;\n }\n if (\n prevProps.currentIndex !== props.currentIndex ||\n prevProps.onIndexChange !== props.onIndexChange\n ) {\n changed = true;\n break;\n }\n }\n }\n\n if (!changed) return prev;\n\n const newMap = new Map();\n Object.entries(repeatingContainerControls).forEach(([id, props]) => {\n newMap.set(id, props);\n });\n return newMap;\n });\n }\n }, [repeatingContainerControls]);\n\n // Sync input groups from props to store\n useEffect(() => {\n if (inputGroups) {\n const setInputGroupValue = useEncoreState.getState().setInputGroupValue;\n Object.entries(inputGroups).forEach(([groupName, elementName]) => {\n setInputGroupValue(groupName, elementName);\n });\n }\n }, [inputGroups]);\n\n const registerContainer = useCallback(\n (id: string, control: RepeatingContainerControl) => {\n setContainerControls((prev) => {\n const next = new Map(prev);\n next.set(id, control);\n return next;\n });\n },\n []\n );\n\n const unregisterContainer = useCallback((id: string) => {\n setContainerControls((prev) => {\n const next = new Map(prev);\n next.delete(id);\n return next;\n });\n // Do NOT delete from controlPropsMap here.\n // controlPropsMap contains props passed from the parent (repeatingContainerControls).\n // If we delete them, we lose the configuration passed down to us.\n // The props should persist even if the component temporarily unregisters.\n }, []);\n\n const getControl = useCallback(\n (id: string) => {\n return containerControls.get(id);\n },\n [containerControls]\n );\n\n const setControlProps = useCallback(\n (\n id: string,\n props:\n | { currentIndex?: number; onIndexChange?: (index: number) => void }\n | ((prev: {\n currentIndex?: number;\n onIndexChange?: (index: number) => void;\n }) => {\n currentIndex?: number;\n onIndexChange?: (index: number) => void;\n })\n ) => {\n setControlPropsMap((prev) => {\n const next = new Map(prev);\n const current = next.get(id) || {};\n const newProps = typeof props === \"function\" ? props(current) : props;\n next.set(id, newProps);\n return next;\n });\n },\n []\n );\n\n const getControlProps = useCallback(\n (id: string) => {\n return controlPropsMap.get(id);\n },\n [controlPropsMap]\n );\n\n // Control props are automatically passed to registered containers via context\n // Components read props via getControlProps() and update when props change\n\n // Create context value - this object changes when controlPropsMap changes,\n // causing all consumers to re-render and get updated props\n const repeatingContainerContextValue = React.useMemo(\n () => ({\n registerContainer,\n unregisterContainer,\n getControl,\n setControlProps,\n getControlProps,\n // Include controlPropsMap size in the value to trigger re-renders when it changes\n _propsVersion: controlPropsMap.size,\n }),\n [\n registerContainer,\n unregisterContainer,\n getControl,\n setControlProps,\n getControlProps,\n controlPropsMap.size,\n ]\n );\n\n // Observe size changes of the dynamic content container and notify consumer\n useEffect(() => {\n if (!onSizeChange) return;\n const element = containerRef.current;\n if (!element) return;\n const notify = (entry: ResizeObserverEntry) => {\n const cr = entry.contentRect;\n onSizeChange({ width: cr.width, height: cr.height });\n };\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n notify(entry);\n }\n });\n // Emit initial size as soon as possible\n const rect = element.getBoundingClientRect();\n onSizeChange({ width: rect.width, height: rect.height });\n observer.observe(element);\n return () => {\n observer.disconnect();\n };\n }, [onSizeChange]);\n\n // Per-instance source override\n useEffect(() => {\n if (!source) return;\n setLocalModeOverride(source === \"local\" ? \"local\" : \"remote\");\n return () => {\n // Clear override when this instance unmounts\n setLocalModeOverride(null);\n };\n }, [source]);\n\n if (!pageId) {\n return (\n <div style={{ padding: \"30px\" }}>\n <div style={{ overflowY: \"auto\" }}>\n {(isLocalMode()\n ? // Local mode: app.json provides pages under app.data.pages\n ((app?.data as any)?.app?.data?.pages || []).map(\n (pg: any) => pg?.id\n )\n : app?.data?.app.pageIds || []\n ).map((p: string) => (\n <Link\n key={p}\n to={`/apps/${appId}/pages/${p}?noRedirect=${noRedirect}`}\n style={{\n fontSize: 20,\n display: \"block\",\n marginBottom: \"10px\",\n }}\n >\n {p}\n </Link>\n ))}\n </div>\n </div>\n );\n }\n return (\n <div\n ref={containerRef}\n style={{\n width: \"100%\",\n height: \"100%\",\n position: \"relative\",\n overflow: \"hidden\",\n }}\n >\n <div ref={contentWrapperRef} style={{ width: \"100%\", minHeight: \"100%\" }}>\n <Suspense fallback={fallback || <div />}>\n <EncoreComponentIdContext.Provider value={{ componentId }}>\n <EncoreActionContext.Provider value={{ onAction }}>\n <EncoreRepeatingContainerContext.Provider\n value={repeatingContainerContextValue}\n >\n <EncoreBindingContext.Provider value={context}>\n <DynamicComponent\n name={`${appId}/draft/components/${pageId}`}\n fallback={fallback}\n reloadKey={reloadKey}\n componentCode={componentCode}\n >\n {\" \"}\n </DynamicComponent>\n </EncoreBindingContext.Provider>\n </EncoreRepeatingContainerContext.Provider>\n </EncoreActionContext.Provider>\n </EncoreComponentIdContext.Provider>\n </Suspense>\n </div>\n </div>\n );\n};\n\nexport default EncoreApp;\n"],"names":["Link","to","children","style","props","navigate","useEncoreRouter","jsx","e","setAppSelector","state","setAppIdSelector","setPageIdSelector","assetsByIdSelector","EncoreApp","appId","pageId","componentId","fallback","onSizeChange","onContentSizeChange","onAction","data","source","repeatingContainerControls","inputGroups","baseURL","appDefinition","pageDefinition","componentCode","useEncoreState","setLocalModeOverride","noRedirect","setApp","setAppId","setPageId","assetsById","containerRef","useRef","contentWrapperRef","useEffect","element","notify","observer","reloadKey","setReloadKey","useState","handleUpdate","useCallback","prev","usePusherUpdates","isLocalMode","useLocalFlag","appUrl","appSWR","useSWR","fetcher","app","fonts","f","family","url","postScriptName","weight","weightMatch","weightName","ff","id","resolve","img","pageUrl","pageSWR","pageData","context","useMemo","clientData","patchPageData","node","totalWidth","childrenWithWidth","child","containerControls","setContainerControls","controlPropsMap","setControlPropsMap","changed","prevProps","newMap","setInputGroupValue","groupName","elementName","registerContainer","control","next","unregisterContainer","getControl","setControlProps","current","newProps","getControlProps","repeatingContainerContextValue","React","entry","cr","entries","rect","Suspense","EncoreComponentIdContext","EncoreActionContext","EncoreRepeatingContainerContext","EncoreBindingContext","DynamicComponent","pg","p"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import o, { useContext as n } from "react";
|
|
2
|
+
const t = {
|
|
3
|
+
navigate: (e) => {
|
|
4
|
+
typeof window < "u" && (window.location.href = e);
|
|
5
|
+
},
|
|
6
|
+
pathname: typeof window < "u" ? window.location.pathname : "",
|
|
7
|
+
searchParams: typeof window < "u" ? new URLSearchParams(window.location.search) : new URLSearchParams()
|
|
8
|
+
}, a = o.createContext(t), i = () => n(a);
|
|
9
|
+
export {
|
|
10
|
+
a as default,
|
|
11
|
+
i as useEncoreRouter
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=EncoreRouterContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EncoreRouterContext.js","sources":["../../src/contexts/EncoreRouterContext.ts"],"sourcesContent":["import React, { useContext } from \"react\";\n\nexport type EncoreRouterContextType = {\n navigate: (path: string) => void;\n pathname: string;\n searchParams: URLSearchParams;\n};\n\n// Default implementation using window for basic fallback\nconst defaultRouter: EncoreRouterContextType = {\n navigate: (path: string) => {\n if (typeof window !== \"undefined\") {\n window.location.href = path;\n }\n },\n pathname: typeof window !== \"undefined\" ? window.location.pathname : \"\",\n searchParams:\n typeof window !== \"undefined\"\n ? new URLSearchParams(window.location.search)\n : new URLSearchParams(),\n};\n\nconst EncoreRouterContext =\n React.createContext<EncoreRouterContextType>(defaultRouter);\n\nexport const useEncoreRouter = () => useContext(EncoreRouterContext);\n\nexport default EncoreRouterContext;\n"],"names":["defaultRouter","path","EncoreRouterContext","React","useEncoreRouter","useContext"],"mappings":";AASA,MAAMA,IAAyC;AAAA,EAC7C,UAAU,CAACC,MAAiB;AAC1B,IAAI,OAAO,SAAW,QACpB,OAAO,SAAS,OAAOA;AAAA,EAE3B;AAAA,EACA,UAAU,OAAO,SAAW,MAAc,OAAO,SAAS,WAAW;AAAA,EACrE,cACE,OAAO,SAAW,MACd,IAAI,gBAAgB,OAAO,SAAS,MAAM,IAC1C,IAAI,gBAAA;AACZ,GAEMC,IACJC,EAAM,cAAuCH,CAAa,GAE/CI,IAAkB,MAAMC,EAAWH,CAAmB;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useRef as m, useEffect as g } from "react";
|
|
2
2
|
import P from "pusher-js";
|
|
3
3
|
import { mutate as t } from "swr";
|
|
4
|
-
import { clearModuleCache as v } from "../lib/
|
|
4
|
+
import { clearModuleCache as v } from "../lib/moduleRegistry.js";
|
|
5
5
|
const y = () => ({
|
|
6
6
|
key: "7b0611d0051677eed996",
|
|
7
7
|
cluster: "us2",
|
|
@@ -26,7 +26,9 @@ function R({
|
|
|
26
26
|
console.log(`[Pusher] Subscribing to channel: ${r}`);
|
|
27
27
|
const o = p.subscribe(r);
|
|
28
28
|
c.current = o, o.bind("pusher:subscription_succeeded", () => {
|
|
29
|
-
console.log(
|
|
29
|
+
console.log(
|
|
30
|
+
`[Pusher] Successfully subscribed to channel: ${r}`
|
|
31
|
+
);
|
|
30
32
|
}), o.bind("pusher:subscription_error", (i) => {
|
|
31
33
|
console.error(
|
|
32
34
|
`[Pusher] Subscription error for channel ${r}:`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePusherUpdates.js","sources":["../../src/hooks/usePusherUpdates.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport Pusher from \"pusher-js\";\nimport { mutate } from \"swr\";\nimport { clearModuleCache } from \"../lib/
|
|
1
|
+
{"version":3,"file":"usePusherUpdates.js","sources":["../../src/hooks/usePusherUpdates.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport Pusher from \"pusher-js\";\nimport { mutate } from \"swr\";\nimport { clearModuleCache } from \"../lib/moduleRegistry\";\n\ntype PusherConfig = {\n key?: string;\n cluster?: string;\n encrypted?: boolean;\n};\n\ntype UsePusherUpdatesOptions = {\n appId: string;\n pageId?: string;\n enabled?: boolean;\n onUpdate?: () => void;\n};\n\n// Get Pusher config from environment variables\nconst getPusherConfig = (): PusherConfig => {\n return {\n key: \"7b0611d0051677eed996\",\n cluster: \"us2\",\n encrypted: true,\n };\n};\n\n/**\n * Hook to listen for EncoreApp component updates via Pusher\n * Channel name format: `${appId}-${pageId}`\n * When an update event is received, it invalidates SWR cache and triggers a reload\n */\nexport function usePusherUpdates({\n appId,\n pageId,\n enabled = true,\n onUpdate,\n}: UsePusherUpdatesOptions) {\n const pusherRef = useRef<Pusher | null>(null);\n const channelRef = useRef<ReturnType<Pusher[\"subscribe\"]> | null>(null);\n\n useEffect(() => {\n // Only connect if enabled and we have both appId and pageId\n if (!enabled || !appId || !pageId) {\n return;\n }\n\n const config = getPusherConfig();\n\n // Skip if Pusher key is not configured\n if (!config.key) {\n console.warn(\"[Pusher] not configured. Pusher updates disabled.\");\n return;\n }\n\n // Initialize Pusher\n const pusher = new Pusher(config.key, {\n cluster: config.cluster || \"us2\",\n forceTLS: config.encrypted,\n });\n\n pusherRef.current = pusher;\n\n // Channel name format: appId-pageId (e.g., \"01KA23JMNBQ2V9NR7K0VXKT5TF-01KA23JMPBZSG2YRJ6M5X87SKJ\")\n const channelName = `${appId}`;\n console.log(`[Pusher] Subscribing to channel: ${channelName}`);\n\n // Subscribe to the channel\n const channel = pusher.subscribe(channelName);\n channelRef.current = channel;\n\n // Handle subscription success\n channel.bind(\"pusher:subscription_succeeded\", () => {\n console.log(\n `[Pusher] Successfully subscribed to channel: ${channelName}`\n );\n });\n\n // Handle subscription error\n channel.bind(\"pusher:subscription_error\", (status: number) => {\n console.error(\n `[Pusher] Subscription error for channel ${channelName}:`,\n status\n );\n });\n\n // Listen for update events\n // You can customize the event name based on your backend's Pusher event names\n // Common event names: 'update', 'component-updated', 'app-updated', etc.\n const handleUpdate = (data: unknown) => {\n console.log(`[Pusher] Update received for ${channelName}:`, data);\n\n // Clear the module cache for the component to force reload\n const componentName = `${appId}/draft/components/${pageId}`;\n clearModuleCache(componentName);\n\n // Invalidate SWR cache for both app and page data\n const appUrl = `/devices/apps/${appId}`;\n const pageUrl = `/devices/apps/${appId}/node/${pageId}`;\n\n // Mutate both URLs to trigger refetch\n mutate(appUrl).catch((err) => {\n console.error(\"[Pusher] Error invalidating app cache:\", err);\n });\n mutate(pageUrl).catch((err) => {\n console.error(\"[Pusher] Error invalidating page cache:\", err);\n });\n\n // Also invalidate URLs with useLocal query param if they exist\n mutate(`${appUrl}?useLocal=1`).catch(() => {\n // Ignore errors for optional URLs\n });\n mutate(`${pageUrl}?useLocal=1`).catch(() => {\n // Ignore errors for optional URLs\n });\n\n // Call the onUpdate callback if provided\n onUpdate?.();\n };\n\n // Bind to update events\n // Adjust the event name(s) based on what your backend sends\n channel.bind(\"update\", handleUpdate);\n channel.bind(\"component-updated\", handleUpdate);\n channel.bind(\"app-updated\", handleUpdate);\n\n // Cleanup function\n return () => {\n console.log(`[Pusher] Unsubscribing from channel: ${channelName}`);\n\n // Unbind all event handlers\n if (channelRef.current) {\n channelRef.current.unbind_all();\n }\n\n // Unsubscribe from channel\n if (channelRef.current && pusherRef.current) {\n pusherRef.current.unsubscribe(channelName);\n }\n\n // Disconnect Pusher if no other channels are subscribed\n if (pusherRef.current) {\n pusherRef.current.disconnect();\n pusherRef.current = null;\n }\n\n channelRef.current = null;\n };\n }, [appId, pageId, enabled, onUpdate]);\n\n // Return channel ref for advanced usage\n return {\n channel: channelRef.current,\n pusher: pusherRef.current,\n };\n}\n"],"names":["getPusherConfig","usePusherUpdates","appId","pageId","enabled","onUpdate","pusherRef","useRef","channelRef","useEffect","config","pusher","Pusher","channelName","channel","status","handleUpdate","data","componentName","clearModuleCache","appUrl","pageUrl","mutate","err"],"mappings":";;;;AAmBA,MAAMA,IAAkB,OACf;AAAA,EACL,KAAK;AAAA,EACL,SAAS;AAAA,EACT,WAAW;AAAA;AASR,SAASC,EAAiB;AAAA,EAC/B,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,UAAAC;AACF,GAA4B;AAC1B,QAAMC,IAAYC,EAAsB,IAAI,GACtCC,IAAaD,EAA+C,IAAI;AAEtE,SAAAE,EAAU,MAAM;AAEd,QAAI,CAACL,KAAW,CAACF,KAAS,CAACC;AACzB;AAGF,UAAMO,IAASV,EAAA,GASTW,IAAS,IAAIC,EAAOF,EAAO,KAAK;AAAA,MACpC,SAASA,EAAO;AAAA,MAChB,UAAUA,EAAO;AAAA,IAAA,CAClB;AAED,IAAAJ,EAAU,UAAUK;AAGpB,UAAME,IAAc,GAAGX,CAAK;AAC5B,YAAQ,IAAI,oCAAoCW,CAAW,EAAE;AAG7D,UAAMC,IAAUH,EAAO,UAAUE,CAAW;AAC5C,IAAAL,EAAW,UAAUM,GAGrBA,EAAQ,KAAK,iCAAiC,MAAM;AAClD,cAAQ;AAAA,QACN,gDAAgDD,CAAW;AAAA,MAAA;AAAA,IAE/D,CAAC,GAGDC,EAAQ,KAAK,6BAA6B,CAACC,MAAmB;AAC5D,cAAQ;AAAA,QACN,2CAA2CF,CAAW;AAAA,QACtDE;AAAA,MAAA;AAAA,IAEJ,CAAC;AAKD,UAAMC,IAAe,CAACC,MAAkB;AACtC,cAAQ,IAAI,gCAAgCJ,CAAW,KAAKI,CAAI;AAGhE,YAAMC,IAAgB,GAAGhB,CAAK,qBAAqBC,CAAM;AACzD,MAAAgB,EAAiBD,CAAa;AAG9B,YAAME,IAAS,iBAAiBlB,CAAK,IAC/BmB,IAAU,iBAAiBnB,CAAK,SAASC,CAAM;AAGrD,MAAAmB,EAAOF,CAAM,EAAE,MAAM,CAACG,MAAQ;AAC5B,gBAAQ,MAAM,0CAA0CA,CAAG;AAAA,MAC7D,CAAC,GACDD,EAAOD,CAAO,EAAE,MAAM,CAACE,MAAQ;AAC7B,gBAAQ,MAAM,2CAA2CA,CAAG;AAAA,MAC9D,CAAC,GAGDD,EAAO,GAAGF,CAAM,aAAa,EAAE,MAAM,MAAM;AAAA,MAE3C,CAAC,GACDE,EAAO,GAAGD,CAAO,aAAa,EAAE,MAAM,MAAM;AAAA,MAE5C,CAAC,GAGDhB,IAAA;AAAA,IACF;AAIA,WAAAS,EAAQ,KAAK,UAAUE,CAAY,GACnCF,EAAQ,KAAK,qBAAqBE,CAAY,GAC9CF,EAAQ,KAAK,eAAeE,CAAY,GAGjC,MAAM;AACX,cAAQ,IAAI,wCAAwCH,CAAW,EAAE,GAG7DL,EAAW,WACbA,EAAW,QAAQ,WAAA,GAIjBA,EAAW,WAAWF,EAAU,WAClCA,EAAU,QAAQ,YAAYO,CAAW,GAIvCP,EAAU,YACZA,EAAU,QAAQ,WAAA,GAClBA,EAAU,UAAU,OAGtBE,EAAW,UAAU;AAAA,IACvB;AAAA,EACF,GAAG,CAACN,GAAOC,GAAQC,GAASC,CAAQ,CAAC,GAG9B;AAAA,IACL,SAASG,EAAW;AAAA,IACpB,QAAQF,EAAU;AAAA,EAAA;AAEtB;"}
|
|
@@ -1,58 +1,51 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { isLocalMode as
|
|
1
|
+
import f from "./packages.js";
|
|
2
|
+
import { isLocalMode as p } from "./localMode.js";
|
|
3
3
|
import { CONST_COMPONENTS_CDN_URL as E } from "../packages/encore-lib/constants.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
function y(e, r) {
|
|
18
|
-
return new Promise((d, m) => {
|
|
19
|
-
const n = (t, s) => {
|
|
20
|
-
typeof t == "function" && (s = t, t = []), Promise.all(
|
|
21
|
-
t.map(async (c) => c === "require" ? ((o) => {
|
|
22
|
-
if (!g(o))
|
|
4
|
+
import { haveModule as $, getModuleExports as h, registerModule as y } from "./moduleRegistry.js";
|
|
5
|
+
import { clearModuleCache as b } from "./moduleRegistry.js";
|
|
6
|
+
const M = {};
|
|
7
|
+
Object.keys(f).forEach((t) => {
|
|
8
|
+
y(t, f[t]);
|
|
9
|
+
});
|
|
10
|
+
function g(t, s) {
|
|
11
|
+
return new Promise((i, m) => {
|
|
12
|
+
const r = (e, a) => {
|
|
13
|
+
typeof e == "function" && (a = e, e = []), Promise.all(
|
|
14
|
+
e.map(async (n) => n === "require" ? ((o) => {
|
|
15
|
+
if (!$(o))
|
|
23
16
|
throw new Error(`Module ${o} not found`);
|
|
24
17
|
return h(o);
|
|
25
|
-
}) :
|
|
26
|
-
).then((
|
|
27
|
-
const o = {},
|
|
28
|
-
|
|
18
|
+
}) : n === "exports" ? {} : ($(n) || await L(n), h(n)))
|
|
19
|
+
).then((n) => {
|
|
20
|
+
const o = {}, l = a.apply(null, n) || o;
|
|
21
|
+
i({ default: l });
|
|
29
22
|
}).catch(m);
|
|
30
23
|
};
|
|
31
|
-
|
|
24
|
+
r.amd = !0;
|
|
32
25
|
try {
|
|
33
|
-
let
|
|
34
|
-
|
|
26
|
+
let e = s;
|
|
27
|
+
e = e.replace(
|
|
35
28
|
/t\.createElement\("undefined",(\{[^}]*nodeData:\{[^}]*type:"container:slider"[^}]*\}[^}]*\})/g,
|
|
36
|
-
(
|
|
37
|
-
),
|
|
29
|
+
(n, o) => `t.createElement(e.SliderComponent,${o}`
|
|
30
|
+
), e = e.replace(
|
|
38
31
|
/t\.createElement\("undefined",(\{[^}]*nodeData:\{([^}]*type:"([^"]+)")?[^}]*\}[^}]*\})/g,
|
|
39
|
-
(
|
|
40
|
-
const
|
|
41
|
-
return `t.createElement(${
|
|
32
|
+
(n, o, u, l) => {
|
|
33
|
+
const c = o.match(/type:"([^"]+)"/), d = c ? c[1] : null;
|
|
34
|
+
return `t.createElement(${d ? `(e["${d}"] || e.DefaultLayerComponent)` : "e.DefaultLayerComponent"},${o}`;
|
|
42
35
|
}
|
|
43
|
-
),
|
|
36
|
+
), e = e.replace(
|
|
44
37
|
/t\.createElement\("undefined"/g,
|
|
45
38
|
"t.createElement(e.DefaultLayerComponent"
|
|
46
39
|
);
|
|
47
|
-
const
|
|
40
|
+
const a = Function(
|
|
48
41
|
"define",
|
|
49
42
|
`
|
|
50
43
|
try {
|
|
51
|
-
${
|
|
52
|
-
//# sourceURL=dynamic-module://${
|
|
44
|
+
${e}
|
|
45
|
+
//# sourceURL=dynamic-module://${t}.js
|
|
53
46
|
} catch (error) {
|
|
54
47
|
console.error('[Module Evaluation Error]', {
|
|
55
|
-
moduleName: '${
|
|
48
|
+
moduleName: '${t}',
|
|
56
49
|
error: error.message,
|
|
57
50
|
stack: error.stack,
|
|
58
51
|
lineNumber: error.lineNumber,
|
|
@@ -62,71 +55,68 @@ function y(e, r) {
|
|
|
62
55
|
}
|
|
63
56
|
`
|
|
64
57
|
);
|
|
65
|
-
console.debug(`[Module Loading] Attempting to load module: ${
|
|
66
|
-
} catch (
|
|
58
|
+
console.debug(`[Module Loading] Attempting to load module: ${t}`), a(r), console.debug(`[Module Loading] Successfully loaded module: ${t}`);
|
|
59
|
+
} catch (e) {
|
|
67
60
|
console.error("[Module Loading Failed]", {
|
|
68
|
-
moduleName:
|
|
69
|
-
error:
|
|
70
|
-
errorType:
|
|
71
|
-
message:
|
|
72
|
-
stack:
|
|
73
|
-
code:
|
|
61
|
+
moduleName: t,
|
|
62
|
+
error: e,
|
|
63
|
+
errorType: e.constructor.name,
|
|
64
|
+
message: e.message,
|
|
65
|
+
stack: e.stack,
|
|
66
|
+
code: s.slice(0, 500) + (s.length > 500 ? "..." : "")
|
|
74
67
|
// Show first 500 chars of code
|
|
75
|
-
}), m(
|
|
68
|
+
}), m(e);
|
|
76
69
|
}
|
|
77
70
|
});
|
|
78
71
|
}
|
|
79
|
-
async function
|
|
80
|
-
if (console.log(`🔍 fetchDep called for ${
|
|
81
|
-
const
|
|
82
|
-
if (
|
|
83
|
-
const
|
|
84
|
-
`/flex-layout/${
|
|
85
|
-
|
|
86
|
-
].filter(Boolean),
|
|
87
|
-
for (const
|
|
72
|
+
async function _(t) {
|
|
73
|
+
if (console.log(`🔍 fetchDep called for ${t}. isLocalMode: ${p()}`), p()) {
|
|
74
|
+
const r = t.match(/^([^/]+)\/draft\/components\/([^/]+)$/);
|
|
75
|
+
if (r) {
|
|
76
|
+
const e = r[1], a = r[2], n = M?.VITE_FLEX_LAYOUT_ABS || null, o = [
|
|
77
|
+
`/flex-layout/${e}/${a}.js`,
|
|
78
|
+
n ? `/@fs/${n}/${e}/${a}.js` : null
|
|
79
|
+
].filter(Boolean), u = [];
|
|
80
|
+
for (const l of o)
|
|
88
81
|
try {
|
|
89
|
-
const
|
|
90
|
-
if (!
|
|
91
|
-
|
|
82
|
+
const c = await fetch(l);
|
|
83
|
+
if (!c.ok) {
|
|
84
|
+
u.push(`${l}: ${c.status} ${c.statusText}`);
|
|
92
85
|
continue;
|
|
93
86
|
}
|
|
94
|
-
const
|
|
95
|
-
return await
|
|
96
|
-
`${
|
|
97
|
-
|
|
87
|
+
const d = await c.text();
|
|
88
|
+
return await g(
|
|
89
|
+
`${e}/draft/components/${a}`,
|
|
90
|
+
d
|
|
98
91
|
);
|
|
99
|
-
} catch (
|
|
100
|
-
|
|
92
|
+
} catch (c) {
|
|
93
|
+
u.push(`${l}: ${c.message || String(c)}`);
|
|
101
94
|
}
|
|
102
95
|
throw new Error(
|
|
103
|
-
`Local component not found for ${
|
|
96
|
+
`Local component not found for ${t}. Tried: ${o.join(
|
|
104
97
|
", "
|
|
105
|
-
)}. Errors: ${
|
|
98
|
+
)}. Errors: ${u.join("; ")}`
|
|
106
99
|
);
|
|
107
100
|
}
|
|
108
101
|
}
|
|
109
|
-
const
|
|
110
|
-
console.log(`[Module Loading] Fetching remote component from: ${
|
|
111
|
-
const m = await fetch(
|
|
112
|
-
if (!
|
|
113
|
-
throw
|
|
114
|
-
`Error: Could not fetch component '${
|
|
115
|
-
) : new Error(`Network error (${
|
|
116
|
-
return
|
|
102
|
+
const s = Math.round(Date.now() / 1e3), i = `${E}/${t}.js?cacheBuster=${s}`;
|
|
103
|
+
console.log(`[Module Loading] Fetching remote component from: ${i}`);
|
|
104
|
+
const m = await fetch(i).then(async (r) => {
|
|
105
|
+
if (!r.ok)
|
|
106
|
+
throw r.status === 403 ? new Error(
|
|
107
|
+
`Error: Could not fetch component '${t}'. Try regenerating components.`
|
|
108
|
+
) : new Error(`Network error (${r.status}): ${await r.text()}`);
|
|
109
|
+
return r.text();
|
|
117
110
|
});
|
|
118
|
-
return await
|
|
119
|
-
}
|
|
120
|
-
async function x(e) {
|
|
121
|
-
const r = await L(e);
|
|
122
|
-
_(e, () => ({ exports: r.default }));
|
|
111
|
+
return await g(t, m);
|
|
123
112
|
}
|
|
124
|
-
function
|
|
125
|
-
|
|
113
|
+
async function L(t) {
|
|
114
|
+
const s = await _(t);
|
|
115
|
+
y(t, () => ({ exports: s.default }));
|
|
126
116
|
}
|
|
127
117
|
export {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
118
|
+
b as clearModuleCache,
|
|
119
|
+
_ as fetchDep,
|
|
120
|
+
g as loadAMDModule
|
|
131
121
|
};
|
|
132
122
|
//# sourceMappingURL=dynamicModules.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamicModules.js","sources":["../../src/lib/dynamicModules.ts"],"sourcesContent":["import packages from \"./packages\";\nimport { isLocalMode } from \"./localMode\";\nimport { CONST_COMPONENTS_CDN_URL } from \"../../constants\";\n\nconst _this = Object.keys(packages).reduce(\n (acc: Record<string, any>, p: string) => {\n acc[p] = packages[p];\n return acc;\n },\n {}\n);\n\nfunction registerModule(name: string, module: any) {\n _this[name] = module;\n}\n\nfunction getModuleExports(name: string) {\n return _this[name]().exports;\n}\n\nfunction haveModule(name: string): boolean {\n return name in _this;\n}\n\nexport function loadAMDModule(name: string, code: string) {\n return new Promise<any>((resolve, reject) => {\n const define = (deps: string[], factory: (...va: unknown[]) => unknown) => {\n if (typeof deps === \"function\") {\n factory = deps;\n deps = [];\n }\n\n Promise.all(\n deps.map(async (dep) => {\n if (dep === \"require\") {\n // Return a mock require function for AMD modules\n return ((id: string) => {\n if (!haveModule(id)) {\n throw new Error(`Module ${id} not found`);\n }\n return getModuleExports(id);\n }) as typeof require;\n }\n if (dep === \"exports\") return {};\n if (!haveModule(dep)) await fetchAndRegister(dep);\n return getModuleExports(dep);\n })\n )\n .then((resolvedDeps: unknown[]) => {\n const exports = {};\n const module = factory.apply(null, resolvedDeps);\n const result = module || exports;\n resolve({ default: result });\n })\n .catch(reject);\n };\n\n define.amd = true;\n\n try {\n // Patch code to replace hardcoded \"undefined\" component references\n // This fixes remote component files that were generated before certain components existed\n let patchedCode = code;\n\n // Replace t.createElement(\"undefined\", props) for container:slider with e.SliderComponent\n // Note: Components are passed as the second parameter 'e' in AMD modules: define([\"react\",\"@/bravo/components\"],(function(t,e){...}))\n patchedCode = patchedCode.replace(\n /t\\.createElement\\(\"undefined\",(\\{[^}]*nodeData:\\{[^}]*type:\"container:slider\"[^}]*\\}[^}]*\\})/g,\n (_match, propsStr) => {\n return `t.createElement(e.SliderComponent,${propsStr}`;\n }\n );\n\n // Fallback for any other undefined components - use the type-based lookup\n patchedCode = patchedCode.replace(\n /t\\.createElement\\(\"undefined\",(\\{[^}]*nodeData:\\{([^}]*type:\"([^\"]+)\")?[^}]*\\}[^}]*\\})/g,\n (_match, propsStr, _typeStr, _type) => {\n const typeMatch = propsStr.match(/type:\"([^\"]+)\"/);\n const componentType = typeMatch ? typeMatch[1] : null;\n const componentLookup = componentType\n ? `(e[\"${componentType}\"] || e.DefaultLayerComponent)`\n : \"e.DefaultLayerComponent\";\n return `t.createElement(${componentLookup},${propsStr}`;\n }\n );\n\n // Final fallback for any remaining \"undefined\"\n patchedCode = patchedCode.replace(\n /t\\.createElement\\(\"undefined\"/g,\n \"t.createElement(e.DefaultLayerComponent\"\n );\n\n // Wrap with error boundary\n // Note: Components are already passed as the second parameter 'e' via AMD dependencies,\n // so we don't need to inject them separately\n const wrapper = Function(\n \"define\",\n `\n try {\n ${patchedCode}\\n//# sourceURL=dynamic-module://${name}.js\n } catch (error) {\n console.error('[Module Evaluation Error]', {\n moduleName: '${name}',\n error: error.message,\n stack: error.stack,\n lineNumber: error.lineNumber,\n columnNumber: error.columnNumber\n });\n throw error;\n }\n `\n );\n\n console.debug(`[Module Loading] Attempting to load module: ${name}`);\n wrapper(define);\n console.debug(`[Module Loading] Successfully loaded module: ${name}`);\n } catch (e: any) {\n // Enhanced error logging\n console.error(\"[Module Loading Failed]\", {\n moduleName: name,\n error: e,\n errorType: e.constructor.name,\n message: e.message,\n stack: e.stack,\n code: code.slice(0, 500) + (code.length > 500 ? \"...\" : \"\"), // Show first 500 chars of code\n });\n reject(e);\n }\n });\n}\n\nexport async function fetchDep(name: string) {\n // Local mode: map Encore component name to local JSX/JS under /flex-layout\n console.log(`🔍 fetchDep called for ${name}. isLocalMode: ${isLocalMode()}`);\n if (isLocalMode()) {\n // Expecting `${appId}/draft/components/${pageId}`\n const m = name.match(/^([^/]+)\\/draft\\/components\\/([^/]+)$/);\n if (m) {\n const appId = m[1];\n const pageId = m[2];\n // Load from public as AMD (do not import() public files; Vite forbids importing from /public)\n const absBase = (import.meta as any)?.env?.VITE_FLEX_LAYOUT_ABS || null;\n const candidates = [\n `/flex-layout/${appId}/${pageId}.js`,\n absBase ? `/@fs/${absBase}/${appId}/${pageId}.js` : null,\n ].filter(Boolean) as string[];\n\n // Fetch as text and evaluate via AMD define shim\n const errors: string[] = [];\n for (const url of candidates) {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n errors.push(`${url}: ${response.status} ${response.statusText}`);\n continue;\n }\n const code = await response.text();\n const amd = await loadAMDModule(\n `${appId}/draft/components/${pageId}`,\n code\n );\n return amd;\n } catch (e: any) {\n errors.push(`${url}: ${e.message || String(e)}`);\n }\n }\n throw new Error(\n `Local component not found for ${name}. Tried: ${candidates.join(\n \", \"\n )}. Errors: ${errors.join(\"; \")}`\n );\n }\n }\n // Remote mode: use AMD loader\n const cacheBuster = Math.round(Date.now() / 1000);\n const url = `${CONST_COMPONENTS_CDN_URL}/${name}.js?cacheBuster=${cacheBuster}`;\n console.log(`[Module Loading] Fetching remote component from: ${url}`);\n const text = await fetch(url).then(async (a) => {\n if (!a.ok) {\n if (a.status === 403) {\n throw new Error(\n `Error: Could not fetch component '${name}'. Try regenerating components.`\n );\n } else {\n throw new Error(`Network error (${a.status}): ${await a.text()}`);\n }\n }\n return a.text();\n });\n\n return await loadAMDModule(name, text);\n // } catch (error) {\n // return {\n // default() {\n // console.log(error);\n // throw new Error(\"Failed to render\");\n // },\n // };\n // }\n}\n\nasync function fetchAndRegister(dep: string) {\n const result = await fetchDep(dep);\n registerModule(dep, () => ({ exports: result.default }));\n}\n\n/**\n * Clear a module from the cache to force reload on next fetch\n * @param name Module name (e.g., `${appId}/draft/components/${pageId}`)\n */\nexport function clearModuleCache(name: string): void {\n if (name in _this) {\n delete _this[name];\n console.log(`[Module Cache] Cleared module: ${name}`);\n }\n}\n"],"names":["_this","packages","acc","p","registerModule","name","module","getModuleExports","haveModule","loadAMDModule","code","resolve","reject","define","deps","factory","dep","id","fetchAndRegister","resolvedDeps","exports","result","patchedCode","_match","propsStr","_typeStr","_type","typeMatch","componentType","wrapper","e","fetchDep","isLocalMode","m","appId","pageId","absBase","__vite_import_meta_env__","candidates","errors","url","response","cacheBuster","CONST_COMPONENTS_CDN_URL","text","a","clearModuleCache"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dynamicModules.js","sources":["../../src/lib/dynamicModules.ts"],"sourcesContent":["import packages from \"./packages\";\nimport { isLocalMode } from \"./localMode\";\nimport { CONST_COMPONENTS_CDN_URL } from \"../../constants\";\nimport { registerModule, getModuleExports, haveModule } from \"./moduleRegistry\";\n\n// Initialize registry with default packages\nObject.keys(packages).forEach((p) => {\n registerModule(p, packages[p]);\n});\n\nexport function loadAMDModule(name: string, code: string) {\n return new Promise<any>((resolve, reject) => {\n const define = (deps: string[], factory: (...va: unknown[]) => unknown) => {\n if (typeof deps === \"function\") {\n factory = deps;\n deps = [];\n }\n\n Promise.all(\n deps.map(async (dep) => {\n if (dep === \"require\") {\n // Return a mock require function for AMD modules\n return ((id: string) => {\n if (!haveModule(id)) {\n throw new Error(`Module ${id} not found`);\n }\n return getModuleExports(id);\n }) as typeof require;\n }\n if (dep === \"exports\") return {};\n if (!haveModule(dep)) await fetchAndRegister(dep);\n return getModuleExports(dep);\n })\n )\n .then((resolvedDeps: unknown[]) => {\n const exports = {};\n const module = factory.apply(null, resolvedDeps);\n const result = module || exports;\n resolve({ default: result });\n })\n .catch(reject);\n };\n\n define.amd = true;\n\n try {\n // Patch code to replace hardcoded \"undefined\" component references\n // This fixes remote component files that were generated before certain components existed\n let patchedCode = code;\n\n // Replace t.createElement(\"undefined\", props) for container:slider with e.SliderComponent\n // Note: Components are passed as the second parameter 'e' in AMD modules: define([\"react\",\"@/bravo/components\"],(function(t,e){...}))\n patchedCode = patchedCode.replace(\n /t\\.createElement\\(\"undefined\",(\\{[^}]*nodeData:\\{[^}]*type:\"container:slider\"[^}]*\\}[^}]*\\})/g,\n (_match, propsStr) => {\n return `t.createElement(e.SliderComponent,${propsStr}`;\n }\n );\n\n // Fallback for any other undefined components - use the type-based lookup\n patchedCode = patchedCode.replace(\n /t\\.createElement\\(\"undefined\",(\\{[^}]*nodeData:\\{([^}]*type:\"([^\"]+)\")?[^}]*\\}[^}]*\\})/g,\n (_match, propsStr, _typeStr, _type) => {\n const typeMatch = propsStr.match(/type:\"([^\"]+)\"/);\n const componentType = typeMatch ? typeMatch[1] : null;\n const componentLookup = componentType\n ? `(e[\"${componentType}\"] || e.DefaultLayerComponent)`\n : \"e.DefaultLayerComponent\";\n return `t.createElement(${componentLookup},${propsStr}`;\n }\n );\n\n // Final fallback for any remaining \"undefined\"\n patchedCode = patchedCode.replace(\n /t\\.createElement\\(\"undefined\"/g,\n \"t.createElement(e.DefaultLayerComponent\"\n );\n\n // Wrap with error boundary\n // Note: Components are already passed as the second parameter 'e' via AMD dependencies,\n // so we don't need to inject them separately\n const wrapper = Function(\n \"define\",\n `\n try {\n ${patchedCode}\\n//# sourceURL=dynamic-module://${name}.js\n } catch (error) {\n console.error('[Module Evaluation Error]', {\n moduleName: '${name}',\n error: error.message,\n stack: error.stack,\n lineNumber: error.lineNumber,\n columnNumber: error.columnNumber\n });\n throw error;\n }\n `\n );\n\n console.debug(`[Module Loading] Attempting to load module: ${name}`);\n wrapper(define);\n console.debug(`[Module Loading] Successfully loaded module: ${name}`);\n } catch (e: any) {\n // Enhanced error logging\n console.error(\"[Module Loading Failed]\", {\n moduleName: name,\n error: e,\n errorType: e.constructor.name,\n message: e.message,\n stack: e.stack,\n code: code.slice(0, 500) + (code.length > 500 ? \"...\" : \"\"), // Show first 500 chars of code\n });\n reject(e);\n }\n });\n}\n\nexport async function fetchDep(name: string) {\n // Local mode: map Encore component name to local JSX/JS under /flex-layout\n console.log(`🔍 fetchDep called for ${name}. isLocalMode: ${isLocalMode()}`);\n if (isLocalMode()) {\n // Expecting `${appId}/draft/components/${pageId}`\n const m = name.match(/^([^/]+)\\/draft\\/components\\/([^/]+)$/);\n if (m) {\n const appId = m[1];\n const pageId = m[2];\n // Load from public as AMD (do not import() public files; Vite forbids importing from /public)\n const absBase = (import.meta as any)?.env?.VITE_FLEX_LAYOUT_ABS || null;\n const candidates = [\n `/flex-layout/${appId}/${pageId}.js`,\n absBase ? `/@fs/${absBase}/${appId}/${pageId}.js` : null,\n ].filter(Boolean) as string[];\n\n // Fetch as text and evaluate via AMD define shim\n const errors: string[] = [];\n for (const url of candidates) {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n errors.push(`${url}: ${response.status} ${response.statusText}`);\n continue;\n }\n const code = await response.text();\n const amd = await loadAMDModule(\n `${appId}/draft/components/${pageId}`,\n code\n );\n return amd;\n } catch (e: any) {\n errors.push(`${url}: ${e.message || String(e)}`);\n }\n }\n throw new Error(\n `Local component not found for ${name}. Tried: ${candidates.join(\n \", \"\n )}. Errors: ${errors.join(\"; \")}`\n );\n }\n }\n // Remote mode: use AMD loader\n const cacheBuster = Math.round(Date.now() / 1000);\n const url = `${CONST_COMPONENTS_CDN_URL}/${name}.js?cacheBuster=${cacheBuster}`;\n console.log(`[Module Loading] Fetching remote component from: ${url}`);\n const text = await fetch(url).then(async (a) => {\n if (!a.ok) {\n if (a.status === 403) {\n throw new Error(\n `Error: Could not fetch component '${name}'. Try regenerating components.`\n );\n } else {\n throw new Error(`Network error (${a.status}): ${await a.text()}`);\n }\n }\n return a.text();\n });\n\n return await loadAMDModule(name, text);\n // } catch (error) {\n // return {\n // default() {\n // console.log(error);\n // throw new Error(\"Failed to render\");\n // },\n // };\n // }\n}\n\nasync function fetchAndRegister(dep: string) {\n const result = await fetchDep(dep);\n registerModule(dep, () => ({ exports: result.default }));\n}\n\nexport { clearModuleCache } from \"./moduleRegistry\";\n"],"names":["packages","p","registerModule","loadAMDModule","name","code","resolve","reject","define","deps","factory","dep","id","haveModule","getModuleExports","fetchAndRegister","resolvedDeps","exports","result","patchedCode","_match","propsStr","_typeStr","_type","typeMatch","componentType","wrapper","fetchDep","isLocalMode","m","appId","pageId","absBase","__vite_import_meta_env__","candidates","errors","url","response","e","cacheBuster","CONST_COMPONENTS_CDN_URL","text","a"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const o = {};
|
|
2
|
+
function r(e, t) {
|
|
3
|
+
o[e] = t;
|
|
4
|
+
}
|
|
5
|
+
function n(e) {
|
|
6
|
+
return o[e]().exports;
|
|
7
|
+
}
|
|
8
|
+
function u(e) {
|
|
9
|
+
return e in o;
|
|
10
|
+
}
|
|
11
|
+
function l(e) {
|
|
12
|
+
e in o && (delete o[e], console.log(`[Module Cache] Cleared module: ${e}`));
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
l as clearModuleCache,
|
|
16
|
+
n as getModuleExports,
|
|
17
|
+
u as haveModule,
|
|
18
|
+
r as registerModule
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=moduleRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moduleRegistry.js","sources":["../../src/lib/moduleRegistry.ts"],"sourcesContent":["const registry: Record<string, any> = {};\n\nexport function registerModule(name: string, module: any) {\n registry[name] = module;\n}\n\nexport function getModuleExports(name: string) {\n return registry[name]().exports;\n}\n\nexport function haveModule(name: string): boolean {\n return name in registry;\n}\n\n/**\n * Clear a module from the cache to force reload on next fetch\n * @param name Module name (e.g., `${appId}/draft/components/${pageId}`)\n */\nexport function clearModuleCache(name: string): void {\n if (name in registry) {\n delete registry[name];\n console.log(`[Module Cache] Cleared module: ${name}`);\n }\n}\n"],"names":["registry","registerModule","name","module","getModuleExports","haveModule","clearModuleCache"],"mappings":"AAAA,MAAMA,IAAgC,CAAA;AAE/B,SAASC,EAAeC,GAAcC,GAAa;AACxD,EAAAH,EAASE,CAAI,IAAIC;AACnB;AAEO,SAASC,EAAiBF,GAAc;AAC7C,SAAOF,EAASE,CAAI,EAAA,EAAI;AAC1B;AAEO,SAASG,EAAWH,GAAuB;AAChD,SAAOA,KAAQF;AACjB;AAMO,SAASM,EAAiBJ,GAAoB;AACnD,EAAIA,KAAQF,MACV,OAAOA,EAASE,CAAI,GACpB,QAAQ,IAAI,kCAAkCA,CAAI,EAAE;AAExD;"}
|
package/dist/lib/packages.js
CHANGED
|
@@ -5,9 +5,7 @@ import * as t from "../app.js";
|
|
|
5
5
|
const a = {
|
|
6
6
|
"@/bravo/app": () => ({ exports: t }),
|
|
7
7
|
// Disabled: app module doesn't exist
|
|
8
|
-
//
|
|
9
|
-
// exports: { Link, useSearchParams, useNavigate, useLocation },
|
|
10
|
-
// }),
|
|
8
|
+
// React router dom removed
|
|
11
9
|
axios: () => ({ exports: r }),
|
|
12
10
|
react: () => ({ exports: o })
|
|
13
11
|
};
|
package/dist/lib/packages.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packages.js","sources":["../../src/lib/packages.ts"],"sourcesContent":["import React from \"react\";\n//
|
|
1
|
+
{"version":3,"file":"packages.js","sources":["../../src/lib/packages.ts"],"sourcesContent":["import React from \"react\";\n// React router dom dependency removed\nimport axios from \"axios\";\nimport EncoreComponents from \"../components\";\nimport * as EncoreApp from \"../app\";\n// Note: ../app module doesn't exist in encore-lib, commenting out for now\n\nexport type Package = {\n exports: unknown;\n};\n\n// These are the packages that will be available to remotely loaded code\nconst Packages: Record<string, () => Package> = {\n \"@/bravo/app\": () => ({ exports: EncoreApp }), // Disabled: app module doesn't exist\n // React router dom removed\n axios: () => ({ exports: axios }),\n react: () => ({ exports: React }),\n};\n\n// Enable this if you want to use components from local project\nconst USE_LOCAL_BRAVO_RN = true;\nif (USE_LOCAL_BRAVO_RN) {\n Packages[\"@/bravo/components\"] = () => ({ exports: EncoreComponents });\n}\n\nexport default Packages;\n"],"names":["Packages","EncoreApp","axios","React","EncoreComponents"],"mappings":";;;;AAYA,MAAMA,IAA0C;AAAA,EAC9C,eAAe,OAAO,EAAE,SAASC;;;EAEjC,OAAO,OAAO,EAAE,SAASC;EACzB,OAAO,OAAO,EAAE,SAASC,EAAA;AAC3B;AAKEH,EAAS,oBAAoB,IAAI,OAAO,EAAE,SAASI,EAAA;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAgWA,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,iBAyD/C"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ComponentInfo, SliderInfo, InputGroupInfo, FormInfo, SelectInputInfo, ActionButtonInfo } from "./types";
|
|
2
|
+
export interface ComponentMetadata {
|
|
3
|
+
props: string[];
|
|
4
|
+
events: string[];
|
|
5
|
+
jsx: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function generateComponentCode(appId: string, pageId: string, componentName: string, sliders: SliderInfo[], standaloneComponents: ComponentInfo[], inputGroups: InputGroupInfo[], forms: FormInfo[], selectInputs: SelectInputInfo[], actionButtons: ActionButtonInfo[], isProduction?: boolean): string;
|
|
8
|
+
export declare function generateReadme(appId: string, pageId: string, appName: string, pageName: string, componentName: string, sliders: SliderInfo[], standaloneComponents: ComponentInfo[], inputGroups: InputGroupInfo[], forms: FormInfo[], selectInputs: SelectInputInfo[], actionButtons: ActionButtonInfo[]): string;
|
|
9
|
+
export declare function generateComponentMetadata(_appName: string, pageName: string, sliders: SliderInfo[], standaloneComponents: ComponentInfo[], inputGroups: InputGroupInfo[], forms: FormInfo[], selectInputs: SelectInputInfo[], actionButtons: ActionButtonInfo[]): ComponentMetadata;
|
|
10
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/codegen/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,QAAQ,EACR,eAAe,EACf,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAOjB,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,UAAU,EAAE,EACrB,oBAAoB,EAAE,aAAa,EAAE,EACrC,WAAW,EAAE,cAAc,EAAE,EAC7B,KAAK,EAAE,QAAQ,EAAE,EACjB,YAAY,EAAE,eAAe,EAAE,EAC/B,aAAa,EAAE,gBAAgB,EAAE,EACjC,YAAY,GAAE,OAAe,GAC5B,MAAM,CA2ZR;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,UAAU,EAAE,EACrB,oBAAoB,EAAE,aAAa,EAAE,EACrC,WAAW,EAAE,cAAc,EAAE,EAC7B,KAAK,EAAE,QAAQ,EAAE,EACjB,YAAY,EAAE,eAAe,EAAE,EAC/B,aAAa,EAAE,gBAAgB,EAAE,GAChC,MAAM,CAwVR;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,UAAU,EAAE,EACrB,oBAAoB,EAAE,aAAa,EAAE,EACrC,WAAW,EAAE,cAAc,EAAE,EAC7B,KAAK,EAAE,QAAQ,EAAE,EACjB,YAAY,EAAE,eAAe,EAAE,EAC/B,aAAa,EAAE,gBAAgB,EAAE,GAChC,iBAAiB,CAiEnB"}
|