@weaverse/react 5.5.0-beta.4 → 5.5.0-beta.5

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/index.d.mts CHANGED
@@ -30,12 +30,13 @@ type DataContext = Record<string, unknown>;
30
30
  declare function replaceContentDataConnectors(content: string, dataContext: DataContext | null | undefined): string;
31
31
  /**
32
32
  * Recursively replaces data connector placeholders in any data structure
33
+ * IMMUTABLE: Creates deep copies during processing to avoid mutating original data
33
34
  * Handles strings, objects, arrays, and nested combinations
34
35
  *
35
36
  * @param data - The data to process (string, object, array, or primitive)
36
37
  * @param dataContext - The data context for replacements
37
38
  * @param visited - Set to track visited objects for circular reference protection
38
- * @returns The data with all string placeholders replaced
39
+ * @returns IMMUTABLE copy of the data with all string placeholders replaced
39
40
  */
40
41
  declare function replaceContentDataConnectorsDeep<T>(data: T, dataContext: DataContext | null | undefined, visited?: WeakSet<WeakKey>): T;
41
42
 
@@ -58,6 +59,6 @@ type ItemComponentProps = {
58
59
  };
59
60
 
60
61
  declare const useSafeExternalStore: (subscribe: any, getSnapshot: any, getServerSnapshot?: any) => any;
61
- declare let WeaverseRoot: react.MemoExoticComponent<({ context }: WeaverseRootPropsType) => react_jsx_runtime.JSX.Element | null>;
62
+ declare const WeaverseRoot: react.MemoExoticComponent<({ context }: WeaverseRootPropsType) => react_jsx_runtime.JSX.Element | null>;
62
63
 
63
64
  export { type ItemComponentProps, WeaverseContext, WeaverseContextProvider, type WeaverseElementProps, WeaverseItemContext, WeaverseRoot, type WeaverseRootPropsType, replaceContentDataConnectors, replaceContentDataConnectorsDeep, useChildInstances, useItemInstance, useParentInstance, useSafeExternalStore, useWeaverse };
package/dist/index.d.ts CHANGED
@@ -30,12 +30,13 @@ type DataContext = Record<string, unknown>;
30
30
  declare function replaceContentDataConnectors(content: string, dataContext: DataContext | null | undefined): string;
31
31
  /**
32
32
  * Recursively replaces data connector placeholders in any data structure
33
+ * IMMUTABLE: Creates deep copies during processing to avoid mutating original data
33
34
  * Handles strings, objects, arrays, and nested combinations
34
35
  *
35
36
  * @param data - The data to process (string, object, array, or primitive)
36
37
  * @param dataContext - The data context for replacements
37
38
  * @param visited - Set to track visited objects for circular reference protection
38
- * @returns The data with all string placeholders replaced
39
+ * @returns IMMUTABLE copy of the data with all string placeholders replaced
39
40
  */
40
41
  declare function replaceContentDataConnectorsDeep<T>(data: T, dataContext: DataContext | null | undefined, visited?: WeakSet<WeakKey>): T;
41
42
 
@@ -58,6 +59,6 @@ type ItemComponentProps = {
58
59
  };
59
60
 
60
61
  declare const useSafeExternalStore: (subscribe: any, getSnapshot: any, getServerSnapshot?: any) => any;
61
- declare let WeaverseRoot: react.MemoExoticComponent<({ context }: WeaverseRootPropsType) => react_jsx_runtime.JSX.Element | null>;
62
+ declare const WeaverseRoot: react.MemoExoticComponent<({ context }: WeaverseRootPropsType) => react_jsx_runtime.JSX.Element | null>;
62
63
 
63
64
  export { type ItemComponentProps, WeaverseContext, WeaverseContextProvider, type WeaverseElementProps, WeaverseItemContext, WeaverseRoot, type WeaverseRootPropsType, replaceContentDataConnectors, replaceContentDataConnectorsDeep, useChildInstances, useItemInstance, useParentInstance, useSafeExternalStore, useWeaverse };
package/dist/index.js CHANGED
@@ -217,10 +217,14 @@ function replaceContentDataConnectorsDeep(data, dataContext, visited = /* @__PUR
217
217
  }
218
218
  visited.add(data);
219
219
  try {
220
+ if (data instanceof Date) {
221
+ return new Date(data.getTime());
222
+ }
220
223
  if (Array.isArray(data)) {
221
- return data.map(
224
+ const result2 = data.map(
222
225
  (item) => replaceContentDataConnectorsDeep(item, dataContext, visited)
223
226
  );
227
+ return result2;
224
228
  }
225
229
  const result = {};
226
230
  for (const [key, value] of Object.entries(data)) {
@@ -320,17 +324,17 @@ var useSafeExternalStore = (subscribe, getSnapshot, getServerSnapshot = getSnaps
320
324
  return getSnapshot();
321
325
  };
322
326
  var WeaverseRoot = (0, import_react3.memo)(({ context }) => {
323
- let data = useSafeExternalStore(
327
+ const data = useSafeExternalStore(
324
328
  context.subscribe,
325
329
  context.getSnapShot,
326
330
  context.getSnapShot
327
331
  );
328
- let rootRef = (0, import_react3.useRef)(null);
332
+ const rootRef = (0, import_react3.useRef)(null);
329
333
  (0, import_react3.useEffect)(() => {
330
334
  context.contentRootElement = rootRef.current;
331
335
  }, [context]);
332
- let eventHandlers = context?.studioBridge?.eventHandlers || {};
333
- let themeClass = context.stitchesInstance.theme.className;
336
+ const eventHandlers = context?.studioBridge?.eventHandlers || {};
337
+ const themeClass = context.stitchesInstance.theme.className;
334
338
  if (context.projectId) {
335
339
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
336
340
  "div",
@@ -354,14 +358,14 @@ var WeaverseRoot = (0, import_react3.memo)(({ context }) => {
354
358
  });
355
359
  WeaverseRoot.displayName = "WeaverseRoot";
356
360
  var ItemComponent = (0, import_react3.memo)(({ instance }) => {
357
- let context = useWeaverse();
358
- let { stitchesInstance, elementRegistry, platformType } = context;
359
- let data = useSafeExternalStore(
361
+ const context = useWeaverse();
362
+ const { stitchesInstance, elementRegistry, platformType } = context;
363
+ const data = useSafeExternalStore(
360
364
  instance.subscribe,
361
365
  instance.getSnapShot,
362
366
  instance.getSnapShot
363
367
  );
364
- let {
368
+ const {
365
369
  id,
366
370
  type,
367
371
  childIds = [],
@@ -377,9 +381,13 @@ var ItemComponent = (0, import_react3.memo)(({ instance }) => {
377
381
  content,
378
382
  ...rest
379
383
  } = data;
384
+ let processedRest = rest;
380
385
  if (content !== void 0 && content !== null) {
381
- content = replaceContentDataConnectorsDeep(content, context.dataContext);
382
- rest.content = content;
386
+ const processedContent = replaceContentDataConnectorsDeep(
387
+ content,
388
+ context.dataContext
389
+ );
390
+ processedRest = { ...rest, content: processedContent };
383
391
  }
384
392
  (0, import_react3.useEffect)(() => {
385
393
  if (!instance.ref.current) {
@@ -391,22 +399,22 @@ var ItemComponent = (0, import_react3.memo)(({ instance }) => {
391
399
  if (__hidden) {
392
400
  return null;
393
401
  }
394
- let Element = elementRegistry.get(type);
402
+ const Element = elementRegistry.get(type);
395
403
  if (Element?.Component) {
396
- let Component = Element.Component;
404
+ const Component = Element.Component;
397
405
  Component.displayName = type;
398
406
  if (Component.$$typeof === Symbol.for("react.forward_ref") || reactVersion > 18) {
399
- rest.ref = instance.ref;
407
+ processedRest.ref = instance.ref;
400
408
  }
401
- let renderChildren = (children?.length ? children : childIds?.length ? childIds.map((cid) => ({ id: cid })) : []).map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ItemInstance, { id: item.id, parentId: id }, `${item.id}-${index}`));
409
+ const renderChildren = (children?.length ? children : childIds?.length ? childIds.map((cid) => ({ id: cid })) : []).map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ItemInstance, { id: item.id, parentId: id }, `${item.id}-${index}`));
402
410
  return /* @__PURE__ */ (0, import_react4.createElement)(
403
411
  Component,
404
412
  {
405
- ...rest,
413
+ ...processedRest,
406
414
  children: renderChildren.length ? renderChildren : void 0,
407
415
  className: (0, import_clsx2.default)(
408
416
  platformType !== "shopify-hydrogen" && generateItemClassName(instance, stitchesInstance),
409
- rest.data?.className
417
+ processedRest.data?.className
410
418
  ),
411
419
  "data-wv-id": id,
412
420
  "data-wv-type": type,
@@ -421,7 +429,7 @@ var ItemComponent = (0, import_react3.memo)(({ instance }) => {
421
429
  ItemComponent.displayName = "WeaverseComponent";
422
430
  var ItemInstance = (0, import_react3.memo)(
423
431
  ({ id, parentId }) => {
424
- let instance = useItemInstance(id);
432
+ const instance = useItemInstance(id);
425
433
  if (!instance) {
426
434
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "none" }, children: [
427
435
  "Item instance ",
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/hooks.ts","../src/utils/data-connector.ts","../src/renderer.tsx","../src/utils/css.ts"],"sourcesContent":["export * from '@weaverse/core'\nexport * from './context'\nexport * from './hooks'\nexport * from './renderer'\nexport * from './types'\n","import type { Weaverse } from '@weaverse/core'\nimport { createContext } from 'react'\n\nexport let WeaverseContext = createContext<Weaverse>({} as Weaverse)\nexport let WeaverseContextProvider = WeaverseContext.Provider\nexport let WeaverseItemContext = createContext<{\n id: string\n parentId: string\n}>({ id: '', parentId: '' })\n","import { Weaverse, type WeaverseItemStore } from '@weaverse/core'\nimport { useContext } from 'react'\nimport { WeaverseContext, WeaverseItemContext } from '~/context'\n\n// Re-export the data connector utilities\nexport {\n replaceContentDataConnectors,\n replaceContentDataConnectorsDeep,\n} from './utils/data-connector'\n\nexport function useWeaverse<T = Weaverse>() {\n let weaverse = useContext(WeaverseContext)\n return weaverse as T\n}\n\nexport let useItemInstance = (id?: string) => {\n let { id: currentId } = useContext(WeaverseItemContext)\n let instance = Weaverse.itemInstances.get(id || currentId)\n if (!instance) {\n console.log(`Item instance ${id} not found`)\n return null\n }\n return instance as WeaverseItemStore\n}\n\nexport let useParentInstance = () => {\n let { parentId } = useContext(WeaverseItemContext)\n return useItemInstance(parentId || '')\n}\n\nexport let useChildInstances = (id?: string) => {\n let currentInstance = useItemInstance(id)\n if (!currentInstance) {\n return []\n }\n let { itemInstances } = Weaverse\n\n let {\n data: { children },\n } = currentInstance\n return children\n .map(({ id }: { id: string }) => itemInstances.get(id))\n .filter(Boolean) as WeaverseItemStore[]\n}\n","// Data connector utilities for replacing placeholders with real data\n// Generic data context type for flexible usage\nexport type DataContext = Record<string, unknown>\n\n// Cached regex pattern for better performance\nconst TEMPLATE_REGEX = /\\{\\{([^}]+)\\}\\}/g\nconst ARRAY_INDEX_REGEX = /^(\\w+)\\[(\\d+)\\]$/\n\n/**\n * Validates that a property name is safe to access (prevents prototype pollution)\n */\nfunction isSafePropertyName(key: string): boolean {\n return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'\n}\n\n// Simple cache for parsed templates (max 100 entries)\nconst templateCache = new Map<string, string>()\nconst MAX_CACHE_SIZE = 100\n\n// Cache for fallback lookups to improve performance (moved to module level to prevent memory leaks)\nconst fallbackCache = new Map<\n string,\n { routeKey: string; value: unknown; timestamp: number }\n>()\nconst FALLBACK_CACHE_MAX_SIZE = 50\n\n/**\n * Safely gets a nested value from an object using dot notation path\n * Supports array indexing with [index] syntax\n * @param obj - The object to traverse\n * @param path - Dot notation path (e.g., \"user.name\" or \"items[0].title\")\n * @param visited - Set to track visited objects for circular reference protection\n * @returns The resolved value or undefined if not found\n */\nfunction getNestedValue(\n obj: unknown,\n path: string,\n visited = new WeakSet()\n): unknown {\n return path.split('.').reduce((current, key) => {\n if (!current || typeof current !== 'object') {\n return\n }\n\n // Protect against circular references\n if (visited.has(current as WeakKey)) {\n console.warn('Circular reference detected in data connector path:', path)\n return\n }\n\n // Add to circular reference tracking\n visited.add(current as WeakKey)\n\n // Handle array indexing like items[0] or items[1]\n const arrayMatch = key.match(ARRAY_INDEX_REGEX)\n if (arrayMatch) {\n const [, arrayKey, index] = arrayMatch\n const arrayObj = (current as Record<string, unknown>)[arrayKey]\n if (Array.isArray(arrayObj)) {\n const indexNum = Number.parseInt(index, 10)\n if (indexNum >= 0 && indexNum < arrayObj.length) {\n return arrayObj[indexNum]\n }\n }\n return\n }\n\n // Handle regular object property access with security validation\n if (!isSafePropertyName(key)) {\n console.warn(`Unsafe property access attempted: ${key}`)\n return\n }\n\n return current !== null && key in current\n ? (current as Record<string, unknown>)[key]\n : undefined\n }, obj)\n}\n\n/**\n * Sanitizes a string value to prevent XSS attacks\n * @param value - The value to sanitize\n * @returns Sanitized string safe for HTML rendering\n */\nfunction sanitizeValue(value: unknown): string {\n if (value === null || value === undefined) {\n return ''\n }\n\n const stringValue = String(value)\n\n // Basic HTML entity encoding to prevent XSS\n return stringValue\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;')\n .replace(/\\//g, '&#x2F;')\n}\n\n/**\n * Creates a safe cache key from content and data\n * Handles circular references by using a simplified approach\n */\nfunction createCacheKey(\n content: string,\n data: Record<string, unknown>\n): string {\n try {\n // Try a simple JSON stringification with a limit\n const dataStr = JSON.stringify(data)\n return `${content}:${dataStr.slice(0, 100)}`\n } catch {\n // If JSON.stringify fails (circular references), use a simpler approach\n const keys = Object.keys(data).sort().join(',')\n return `${content}:keys:${keys}`\n }\n}\n\n/**\n * Resolves data from the flat route-keyed data context\n * Supports both route-specific ({{root.layout.shop.name}}) and fallback ({{shop.name}}) access\n */\nfunction resolveDataFromContext(\n path: string,\n dataContext: DataContext | null | undefined\n): unknown {\n if (!dataContext) {\n return\n }\n\n const trimmedPath = path.trim()\n\n // Check if path starts with a route key (e.g., \"root.layout.shop.name\")\n const pathParts = trimmedPath.split('.')\n const potentialRouteKey = pathParts[0]\n\n // If we have route-keyed data and the first part matches a route\n if (\n dataContext[potentialRouteKey] &&\n typeof dataContext[potentialRouteKey] === 'object' &&\n dataContext[potentialRouteKey] !== null\n ) {\n // Remove route key and resolve rest of path from that route's data\n const remainingPath = pathParts.slice(1).join('.')\n if (remainingPath) {\n return getNestedValue(dataContext[potentialRouteKey], remainingPath)\n }\n return dataContext[potentialRouteKey]\n }\n\n // Fallback: search across all route data for backward compatibility\n // This handles cases like {{shop.name}} without route prefix\n\n // Check cache first\n const cachedResult = fallbackCache.get(trimmedPath)\n if (cachedResult && dataContext[cachedResult.routeKey]) {\n const value = getNestedValue(\n dataContext[cachedResult.routeKey],\n trimmedPath\n )\n if (value !== undefined) {\n // Update timestamp on cache hit\n cachedResult.timestamp = Date.now()\n return value\n }\n }\n\n // Search with priority order (most common routes first)\n const priorityRoutes = ['root', 'routes/product', 'routes/collection']\n const allRoutes = [\n ...priorityRoutes,\n ...Object.keys(dataContext).filter((k) => !priorityRoutes.includes(k)),\n ]\n\n for (const routeKey of allRoutes) {\n const routeData = dataContext[routeKey]\n if (routeData && typeof routeData === 'object' && routeData !== null) {\n const value = getNestedValue(routeData, trimmedPath)\n if (value !== undefined) {\n // Clean cache if it's getting too large\n if (fallbackCache.size >= FALLBACK_CACHE_MAX_SIZE) {\n const entries = Array.from(fallbackCache.entries())\n entries.sort((a, b) => a[1].timestamp - b[1].timestamp)\n // Remove oldest 25% of entries\n const toRemove = Math.floor(entries.length * 0.25)\n for (let i = 0; i < toRemove; i++) {\n fallbackCache.delete(entries[i][0])\n }\n }\n fallbackCache.set(trimmedPath, {\n routeKey,\n value,\n timestamp: Date.now(),\n })\n return value\n }\n }\n }\n\n // Final fallback: try direct access (for non-route-keyed legacy data)\n return getNestedValue(dataContext, trimmedPath)\n}\n\n/**\n * Replaces data connector placeholders in content with actual values from data context\n * Supports {{path}} syntax with dot notation, array indexing, and route prefixes\n *\n * Enhanced syntax:\n * - {{root.siteSettings.title}} - Access root route data\n * - {{layout.navigation.items}} - Access layout route data\n * - {{parent.category.name}} - Access parent route data\n * - {{current.product.title}} - Access current route data\n * - {{user.name}} - Auto-resolved from combined data (backward compatible)\n *\n * @param content - The content string containing {{}} placeholders\n * @param dataContext - The enhanced WeaverseDataContext with route-keyed data\n * @returns The content with placeholders replaced by actual values\n */\nexport function replaceContentDataConnectors(\n content: string,\n dataContext: DataContext | null | undefined\n): string {\n if (!dataContext || typeof content !== 'string') {\n return content\n }\n\n try {\n // Simplified caching - dataContext is already the combined data\n const cacheKey = createCacheKey(content, dataContext)\n\n if (templateCache.has(cacheKey)) {\n return templateCache.get(cacheKey)!\n }\n\n const newContent = content.replace(TEMPLATE_REGEX, (match, path) => {\n try {\n const value = resolveDataFromContext(path, dataContext)\n\n if (value === undefined || value === null) {\n return match // Return original placeholder if value not found\n }\n\n return sanitizeValue(value)\n } catch (pathError) {\n console.warn(\n `Error resolving data connector path \"${path}\":`,\n pathError\n )\n return match\n }\n })\n\n // Cache the result (with size limit)\n if (templateCache.size >= MAX_CACHE_SIZE) {\n const firstKey = templateCache.keys().next().value\n templateCache.delete(firstKey)\n }\n templateCache.set(cacheKey, newContent)\n\n return newContent\n } catch (error) {\n console.warn('Error processing data connectors:', error, { content })\n return content\n }\n}\n\n/**\n * Recursively replaces data connector placeholders in any data structure\n * Handles strings, objects, arrays, and nested combinations\n *\n * @param data - The data to process (string, object, array, or primitive)\n * @param dataContext - The data context for replacements\n * @param visited - Set to track visited objects for circular reference protection\n * @returns The data with all string placeholders replaced\n */\nexport function replaceContentDataConnectorsDeep<T>(\n data: T,\n dataContext: DataContext | null | undefined,\n visited = new WeakSet()\n): T {\n if (!dataContext) {\n return data\n }\n\n // Handle primitive types\n if (typeof data === 'string') {\n return replaceContentDataConnectors(data, dataContext) as T\n }\n\n if (typeof data !== 'object' || data === null) {\n return data\n }\n\n // Protect against circular references\n if (visited.has(data as WeakKey)) {\n console.warn(\n 'Circular reference detected in deep data connector replacement'\n )\n return data\n }\n\n // Add to circular reference tracking\n visited.add(data as WeakKey)\n\n try {\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map((item) =>\n replaceContentDataConnectorsDeep(item, dataContext, visited)\n ) as T\n }\n\n // Handle objects\n const result = {} as T\n for (const [key, value] of Object.entries(data)) {\n ;(result as Record<string, unknown>)[key] =\n replaceContentDataConnectorsDeep(value, dataContext, visited)\n }\n\n return result\n } catch (error) {\n console.warn('Error in deep data connector replacement:', error)\n return data\n } finally {\n // Remove from tracking when done processing this object\n visited.delete(data as WeakKey)\n }\n}\n","import clsx from 'clsx'\nimport * as React from 'react'\nimport { memo, useEffect, useRef } from 'react'\nimport { useItemInstance, useWeaverse } from '~/hooks'\nimport { WeaverseContextProvider, WeaverseItemContext } from './context'\nimport type { ItemComponentProps, WeaverseRootPropsType } from './types'\nimport { generateItemClassName } from './utils/css'\nimport { replaceContentDataConnectorsDeep } from './utils/data-connector'\n\nlet reactVersion = Number(React.version?.split('.')[0]) || 0\n\n// Create a safe version of useSyncExternalStore that works in both client and server environments\nexport const useSafeExternalStore = (\n subscribe: any,\n getSnapshot: any,\n getServerSnapshot: any = getSnapshot\n) => {\n // In server environment or during SSR, just return the snapshot directly\n if (typeof window === 'undefined') {\n return getServerSnapshot()\n }\n\n // In client environment, use React.useSyncExternalStore if available (React 18+)\n if (React.useSyncExternalStore) {\n // biome-ignore lint/correctness/useHookAtTopLevel: <$>\n return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n }\n\n // Fallback for older React versions - just return the current snapshot\n return getSnapshot()\n}\n\nexport let WeaverseRoot = memo(({ context }: WeaverseRootPropsType) => {\n let data = useSafeExternalStore(\n context.subscribe,\n context.getSnapShot,\n context.getSnapShot\n )\n let rootRef = useRef<HTMLElement>(null)\n\n useEffect(() => {\n context.contentRootElement = rootRef.current\n }, [context])\n\n let eventHandlers = context?.studioBridge?.eventHandlers || {}\n let themeClass = context.stitchesInstance.theme.className\n\n if (context.projectId) {\n return (\n <div\n className={`weaverse-content-root ${themeClass}`}\n {...eventHandlers}\n data-weaverse-project-id={context.projectId}\n data-weaverse-template-id={data.id}\n ref={rootRef}\n >\n <WeaverseContextProvider value={context}>\n <ItemInstance\n id={context.data.rootId || context.projectId}\n parentId={''}\n />\n </WeaverseContextProvider>\n </div>\n )\n }\n return null\n})\nWeaverseRoot.displayName = 'WeaverseRoot'\nconst ItemComponent = memo(({ instance }: ItemComponentProps) => {\n let context = useWeaverse()\n let { stitchesInstance, elementRegistry, platformType } = context\n let data = useSafeExternalStore(\n instance.subscribe,\n instance.getSnapShot,\n instance.getSnapShot\n )\n let {\n id,\n type,\n childIds = [],\n children = [],\n parentId,\n createdAt,\n updatedAt,\n deletedAt,\n css,\n __hidden,\n // Need to get rid of this `data` property\n data: _,\n content,\n ...rest\n } = data\n // Replace data connectors in content (handles strings, objects, and arrays recursively)\n if (content !== undefined && content !== null) {\n content = replaceContentDataConnectorsDeep(content, context.dataContext)\n rest.content = content\n }\n\n useEffect(() => {\n if (!instance.ref.current) {\n // Fallback `ref` if the element isn't created by `React.forwardRef`\n Object.assign(instance.ref, {\n current: document.querySelector(`[data-wv-id=\"${id}\"]`),\n })\n }\n }, [instance, id])\n\n if (__hidden) {\n return null\n }\n\n let Element = elementRegistry.get(type)\n\n if (Element?.Component) {\n let Component = Element.Component\n Component.displayName = type\n if (\n Component.$$typeof === Symbol.for('react.forward_ref') ||\n reactVersion > 18\n ) {\n rest.ref = instance.ref\n }\n let renderChildren = (\n children?.length\n ? children\n : childIds?.length\n ? childIds.map((cid: string) => ({ id: cid }))\n : []\n ).map((item: { id: string }, index: number) => (\n <ItemInstance id={item.id} key={`${item.id}-${index}`} parentId={id} />\n ))\n\n return (\n <Component\n {...rest}\n children={renderChildren.length ? renderChildren : undefined}\n className={clsx(\n platformType !== 'shopify-hydrogen' &&\n generateItemClassName(instance, stitchesInstance),\n rest.data?.className\n )}\n data-wv-id={id}\n data-wv-type={type}\n key={id}\n />\n )\n }\n instance._store.deleted = true\n console.log(`❌ Unknown element: ${type}`)\n return null\n})\nItemComponent.displayName = 'WeaverseComponent'\n\nlet ItemInstance = memo(\n ({ id, parentId }: { id: string; parentId: string }) => {\n let instance = useItemInstance(id)\n if (!instance) {\n return <div style={{ display: 'none' }}>Item instance {id} not found</div>\n }\n return (\n <WeaverseItemContext.Provider value={{ parentId, id }}>\n <ItemComponent instance={instance} key={id} />\n </WeaverseItemContext.Provider>\n )\n }\n)\nItemInstance.displayName = 'WeaverseInstanceProvider'\n","import type Stitches from '@stitches/react/types/stitches'\nimport type { ElementCSS, WeaverseItemStore } from '@weaverse/core'\nimport clsx from 'clsx'\n\n// Make the css data formatted to correct order (desktop, tablet, mobile)\nfunction formatCSS(css: ElementCSS) {\n return {\n '@desktop': css['@desktop'],\n '@mobile': css['@mobile'],\n }\n}\n\nlet permanentClasses: Record<string, string> = {}\nexport function generateItemClassName(\n instance: WeaverseItemStore,\n stitchesInstance: Stitches\n) {\n let { css, type, className: cls = '' } = instance.data\n let className = ''\n let permanentClass = ''\n let perCss = instance.Element?.permanentCss\n if (perCss) {\n if (type in permanentClasses) {\n permanentClass = permanentClasses[type]\n } else {\n // @ts-expect-error\n let { className: perCls } = stitchesInstance.css(perCss)()\n Object.assign(permanentClasses, { [type]: perCls })\n permanentClass = perCls\n }\n }\n className = permanentClass\n if (css) {\n // let stitches create the style from css object and\n // then return the classname, so we can use it in the render\n let formattedCss = formatCSS(css)\n let newStitchesClass = stitchesInstance.css(formattedCss)().className || ''\n let { stitchesClass = '' } = instance\n let otherClass = (instance.ref.current?.className || '')\n .replace(stitchesClass, '')\n .replace(cls, '')\n .replace(permanentClass, '')\n .trim()\n className = clsx(permanentClass, cls, newStitchesClass, otherClass)\n instance.stitchesClass = newStitchesClass\n }\n return className\n}\n"],"mappings":"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","names":["import_react","id","import_clsx","import_react","clsx","import_react","clsx"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/hooks.ts","../src/utils/data-connector.ts","../src/renderer.tsx","../src/utils/css.ts"],"sourcesContent":["export * from '@weaverse/core'\nexport * from './context'\nexport * from './hooks'\nexport * from './renderer'\nexport * from './types'\n","import type { Weaverse } from '@weaverse/core'\nimport { createContext } from 'react'\n\nexport let WeaverseContext = createContext<Weaverse>({} as Weaverse)\nexport let WeaverseContextProvider = WeaverseContext.Provider\nexport let WeaverseItemContext = createContext<{\n id: string\n parentId: string\n}>({ id: '', parentId: '' })\n","import { Weaverse, type WeaverseItemStore } from '@weaverse/core'\nimport { useContext } from 'react'\nimport { WeaverseContext, WeaverseItemContext } from '~/context'\n\n// Re-export the data connector utilities\nexport {\n replaceContentDataConnectors,\n replaceContentDataConnectorsDeep,\n} from './utils/data-connector'\n\nexport function useWeaverse<T = Weaverse>() {\n let weaverse = useContext(WeaverseContext)\n return weaverse as T\n}\n\nexport let useItemInstance = (id?: string) => {\n let { id: currentId } = useContext(WeaverseItemContext)\n let instance = Weaverse.itemInstances.get(id || currentId)\n if (!instance) {\n console.log(`Item instance ${id} not found`)\n return null\n }\n return instance as WeaverseItemStore\n}\n\nexport let useParentInstance = () => {\n let { parentId } = useContext(WeaverseItemContext)\n return useItemInstance(parentId || '')\n}\n\nexport let useChildInstances = (id?: string) => {\n let currentInstance = useItemInstance(id)\n if (!currentInstance) {\n return []\n }\n let { itemInstances } = Weaverse\n\n let {\n data: { children },\n } = currentInstance\n return children\n .map(({ id }: { id: string }) => itemInstances.get(id))\n .filter(Boolean) as WeaverseItemStore[]\n}\n","// Data connector utilities for replacing placeholders with real data\n// Generic data context type for flexible usage\nexport type DataContext = Record<string, unknown>\n\n// Cached regex pattern for better performance\nconst TEMPLATE_REGEX = /\\{\\{([^}]+)\\}\\}/g\nconst ARRAY_INDEX_REGEX = /^(\\w+)\\[(\\d+)\\]$/\n\n/**\n * Validates that a property name is safe to access (prevents prototype pollution)\n */\nfunction isSafePropertyName(key: string): boolean {\n return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'\n}\n\n// Simple cache for parsed templates (max 100 entries)\nconst templateCache = new Map<string, string>()\nconst MAX_CACHE_SIZE = 100\n\n// Cache for fallback lookups to improve performance (moved to module level to prevent memory leaks)\nconst fallbackCache = new Map<\n string,\n { routeKey: string; value: unknown; timestamp: number }\n>()\nconst FALLBACK_CACHE_MAX_SIZE = 50\n\n/**\n * Safely gets a nested value from an object using dot notation path\n * Supports array indexing with [index] syntax\n * @param obj - The object to traverse\n * @param path - Dot notation path (e.g., \"user.name\" or \"items[0].title\")\n * @param visited - Set to track visited objects for circular reference protection\n * @returns The resolved value or undefined if not found\n */\nfunction getNestedValue(\n obj: unknown,\n path: string,\n visited = new WeakSet()\n): unknown {\n return path.split('.').reduce((current, key) => {\n if (!current || typeof current !== 'object') {\n return\n }\n\n // Protect against circular references\n if (visited.has(current as WeakKey)) {\n console.warn('Circular reference detected in data connector path:', path)\n return\n }\n\n // Add to circular reference tracking\n visited.add(current as WeakKey)\n\n // Handle array indexing like items[0] or items[1]\n const arrayMatch = key.match(ARRAY_INDEX_REGEX)\n if (arrayMatch) {\n const [, arrayKey, index] = arrayMatch\n const arrayObj = (current as Record<string, unknown>)[arrayKey]\n if (Array.isArray(arrayObj)) {\n const indexNum = Number.parseInt(index, 10)\n if (indexNum >= 0 && indexNum < arrayObj.length) {\n return arrayObj[indexNum]\n }\n }\n return\n }\n\n // Handle regular object property access with security validation\n if (!isSafePropertyName(key)) {\n console.warn(`Unsafe property access attempted: ${key}`)\n return\n }\n\n return current !== null && key in current\n ? (current as Record<string, unknown>)[key]\n : undefined\n }, obj)\n}\n\n/**\n * Sanitizes a string value to prevent XSS attacks\n * @param value - The value to sanitize\n * @returns Sanitized string safe for HTML rendering\n */\nfunction sanitizeValue(value: unknown): string {\n if (value === null || value === undefined) {\n return ''\n }\n\n const stringValue = String(value)\n\n // Basic HTML entity encoding to prevent XSS\n return stringValue\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;')\n .replace(/\\//g, '&#x2F;')\n}\n\n/**\n * Creates a safe cache key from content and data\n * Handles circular references by using a simplified approach\n */\nfunction createCacheKey(\n content: string,\n data: Record<string, unknown>\n): string {\n try {\n // Try a simple JSON stringification with a limit\n const dataStr = JSON.stringify(data)\n return `${content}:${dataStr.slice(0, 100)}`\n } catch {\n // If JSON.stringify fails (circular references), use a simpler approach\n const keys = Object.keys(data).sort().join(',')\n return `${content}:keys:${keys}`\n }\n}\n\n/**\n * Resolves data from the flat route-keyed data context\n * Supports both route-specific ({{root.layout.shop.name}}) and fallback ({{shop.name}}) access\n */\nfunction resolveDataFromContext(\n path: string,\n dataContext: DataContext | null | undefined\n): unknown {\n if (!dataContext) {\n return\n }\n\n const trimmedPath = path.trim()\n\n // Check if path starts with a route key (e.g., \"root.layout.shop.name\")\n const pathParts = trimmedPath.split('.')\n const potentialRouteKey = pathParts[0]\n\n // If we have route-keyed data and the first part matches a route\n if (\n dataContext[potentialRouteKey] &&\n typeof dataContext[potentialRouteKey] === 'object' &&\n dataContext[potentialRouteKey] !== null\n ) {\n // Remove route key and resolve rest of path from that route's data\n const remainingPath = pathParts.slice(1).join('.')\n if (remainingPath) {\n return getNestedValue(dataContext[potentialRouteKey], remainingPath)\n }\n return dataContext[potentialRouteKey]\n }\n\n // Fallback: search across all route data for backward compatibility\n // This handles cases like {{shop.name}} without route prefix\n\n // Check cache first\n const cachedResult = fallbackCache.get(trimmedPath)\n if (cachedResult && dataContext[cachedResult.routeKey]) {\n const value = getNestedValue(\n dataContext[cachedResult.routeKey],\n trimmedPath\n )\n if (value !== undefined) {\n // Update timestamp on cache hit\n cachedResult.timestamp = Date.now()\n return value\n }\n }\n\n // Search with priority order (most common routes first)\n const priorityRoutes = ['root', 'routes/product', 'routes/collection']\n const allRoutes = [\n ...priorityRoutes,\n ...Object.keys(dataContext).filter((k) => !priorityRoutes.includes(k)),\n ]\n\n for (const routeKey of allRoutes) {\n const routeData = dataContext[routeKey]\n if (routeData && typeof routeData === 'object' && routeData !== null) {\n const value = getNestedValue(routeData, trimmedPath)\n if (value !== undefined) {\n // Clean cache if it's getting too large\n if (fallbackCache.size >= FALLBACK_CACHE_MAX_SIZE) {\n const entries = Array.from(fallbackCache.entries())\n entries.sort((a, b) => a[1].timestamp - b[1].timestamp)\n // Remove oldest 25% of entries\n const toRemove = Math.floor(entries.length * 0.25)\n for (let i = 0; i < toRemove; i++) {\n fallbackCache.delete(entries[i][0])\n }\n }\n fallbackCache.set(trimmedPath, {\n routeKey,\n value,\n timestamp: Date.now(),\n })\n return value\n }\n }\n }\n\n // Final fallback: try direct access (for non-route-keyed legacy data)\n return getNestedValue(dataContext, trimmedPath)\n}\n\n/**\n * Replaces data connector placeholders in content with actual values from data context\n * Supports {{path}} syntax with dot notation, array indexing, and route prefixes\n *\n * Enhanced syntax:\n * - {{root.siteSettings.title}} - Access root route data\n * - {{layout.navigation.items}} - Access layout route data\n * - {{parent.category.name}} - Access parent route data\n * - {{current.product.title}} - Access current route data\n * - {{user.name}} - Auto-resolved from combined data (backward compatible)\n *\n * @param content - The content string containing {{}} placeholders\n * @param dataContext - The enhanced WeaverseDataContext with route-keyed data\n * @returns The content with placeholders replaced by actual values\n */\nexport function replaceContentDataConnectors(\n content: string,\n dataContext: DataContext | null | undefined\n): string {\n if (!dataContext || typeof content !== 'string') {\n return content\n }\n\n try {\n // Simplified caching - dataContext is already the combined data\n const cacheKey = createCacheKey(content, dataContext)\n\n if (templateCache.has(cacheKey)) {\n return templateCache.get(cacheKey)!\n }\n\n const newContent = content.replace(TEMPLATE_REGEX, (match, path) => {\n try {\n const value = resolveDataFromContext(path, dataContext)\n\n if (value === undefined || value === null) {\n return match // Return original placeholder if value not found\n }\n\n return sanitizeValue(value)\n } catch (pathError) {\n console.warn(\n `Error resolving data connector path \"${path}\":`,\n pathError\n )\n return match\n }\n })\n\n // Cache the result (with size limit)\n if (templateCache.size >= MAX_CACHE_SIZE) {\n const firstKey = templateCache.keys().next().value\n templateCache.delete(firstKey)\n }\n templateCache.set(cacheKey, newContent)\n\n return newContent\n } catch (error) {\n console.warn('Error processing data connectors:', error, { content })\n return content\n }\n}\n\n/**\n * Recursively replaces data connector placeholders in any data structure\n * IMMUTABLE: Creates deep copies during processing to avoid mutating original data\n * Handles strings, objects, arrays, and nested combinations\n *\n * @param data - The data to process (string, object, array, or primitive)\n * @param dataContext - The data context for replacements\n * @param visited - Set to track visited objects for circular reference protection\n * @returns IMMUTABLE copy of the data with all string placeholders replaced\n */\nexport function replaceContentDataConnectorsDeep<T>(\n data: T,\n dataContext: DataContext | null | undefined,\n visited = new WeakSet()\n): T {\n if (!dataContext) {\n return data\n }\n\n // Handle primitive types - no cloning needed for primitives\n if (typeof data === 'string') {\n return replaceContentDataConnectors(data, dataContext) as T\n }\n\n if (typeof data !== 'object' || data === null) {\n return data\n }\n\n // Protect against circular references\n if (visited.has(data as WeakKey)) {\n console.warn(\n 'Circular reference detected in deep data connector replacement'\n )\n return data\n }\n\n // Add to circular reference tracking\n visited.add(data as WeakKey)\n\n try {\n // Handle special objects that should be cloned as-is\n if (data instanceof Date) {\n return new Date(data.getTime()) as T\n }\n\n // Handle arrays - create new array with processed items\n if (Array.isArray(data)) {\n const result = data.map((item) =>\n replaceContentDataConnectorsDeep(item, dataContext, visited)\n ) as T\n return result\n }\n\n // Handle plain objects - create new object with processed values\n const result = {} as T\n for (const [key, value] of Object.entries(data)) {\n ;(result as Record<string, unknown>)[key] =\n replaceContentDataConnectorsDeep(value, dataContext, visited)\n }\n\n return result\n } catch (error) {\n console.warn('Error in deep data connector replacement:', error)\n return data\n } finally {\n // Remove from tracking when done processing this object\n visited.delete(data as WeakKey)\n }\n}\n","import clsx from 'clsx'\nimport * as React from 'react'\nimport { memo, useEffect, useRef } from 'react'\nimport { useItemInstance, useWeaverse } from '~/hooks'\nimport { WeaverseContextProvider, WeaverseItemContext } from './context'\nimport type { ItemComponentProps, WeaverseRootPropsType } from './types'\nimport { generateItemClassName } from './utils/css'\nimport { replaceContentDataConnectorsDeep } from './utils/data-connector'\n\nconst reactVersion = Number(React.version?.split('.')[0]) || 0\n\n// Create a safe version of useSyncExternalStore that works in both client and server environments\nexport const useSafeExternalStore = (\n subscribe: any,\n getSnapshot: any,\n getServerSnapshot: any = getSnapshot\n) => {\n // In server environment or during SSR, just return the snapshot directly\n if (typeof window === 'undefined') {\n return getServerSnapshot()\n }\n\n // In client environment, use React.useSyncExternalStore if available (React 18+)\n if (React.useSyncExternalStore) {\n // biome-ignore lint/correctness/useHookAtTopLevel: <$>\n return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n }\n\n // Fallback for older React versions - just return the current snapshot\n return getSnapshot()\n}\n\nexport const WeaverseRoot = memo(({ context }: WeaverseRootPropsType) => {\n const data = useSafeExternalStore(\n context.subscribe,\n context.getSnapShot,\n context.getSnapShot\n )\n const rootRef = useRef<HTMLElement>(null)\n\n useEffect(() => {\n context.contentRootElement = rootRef.current\n }, [context])\n\n const eventHandlers = context?.studioBridge?.eventHandlers || {}\n const themeClass = context.stitchesInstance.theme.className\n\n if (context.projectId) {\n return (\n <div\n className={`weaverse-content-root ${themeClass}`}\n {...eventHandlers}\n data-weaverse-project-id={context.projectId}\n data-weaverse-template-id={data.id}\n ref={rootRef}\n >\n <WeaverseContextProvider value={context}>\n <ItemInstance\n id={context.data.rootId || context.projectId}\n parentId={''}\n />\n </WeaverseContextProvider>\n </div>\n )\n }\n return null\n})\nWeaverseRoot.displayName = 'WeaverseRoot'\nconst ItemComponent = memo(({ instance }: ItemComponentProps) => {\n const context = useWeaverse()\n const { stitchesInstance, elementRegistry, platformType } = context\n const data = useSafeExternalStore(\n instance.subscribe,\n instance.getSnapShot,\n instance.getSnapShot\n )\n const {\n id,\n type,\n childIds = [],\n children = [],\n parentId,\n createdAt,\n updatedAt,\n deletedAt,\n css,\n __hidden,\n // Need to get rid of this `data` property\n data: _,\n content,\n ...rest\n } = data\n\n // Replace data connectors in content (handles strings, objects, and arrays recursively)\n // IMMUTABLE: Process the entire data object to avoid mutating original content\n let processedRest = rest\n if (content !== undefined && content !== null) {\n const processedContent = replaceContentDataConnectorsDeep(\n content,\n context.dataContext\n )\n // Create new rest object instead of mutating original\n processedRest = { ...rest, content: processedContent }\n }\n\n useEffect(() => {\n if (!instance.ref.current) {\n // Fallback `ref` if the element isn't created by `React.forwardRef`\n Object.assign(instance.ref, {\n current: document.querySelector(`[data-wv-id=\"${id}\"]`),\n })\n }\n }, [instance, id])\n\n if (__hidden) {\n return null\n }\n\n const Element = elementRegistry.get(type)\n\n if (Element?.Component) {\n const Component = Element.Component\n Component.displayName = type\n if (\n Component.$$typeof === Symbol.for('react.forward_ref') ||\n reactVersion > 18\n ) {\n processedRest.ref = instance.ref\n }\n const renderChildren = (\n children?.length\n ? children\n : childIds?.length\n ? childIds.map((cid: string) => ({ id: cid }))\n : []\n ).map((item: { id: string }, index: number) => (\n <ItemInstance id={item.id} key={`${item.id}-${index}`} parentId={id} />\n ))\n\n return (\n <Component\n {...processedRest}\n children={renderChildren.length ? renderChildren : undefined}\n className={clsx(\n platformType !== 'shopify-hydrogen' &&\n generateItemClassName(instance, stitchesInstance),\n processedRest.data?.className\n )}\n data-wv-id={id}\n data-wv-type={type}\n key={id}\n />\n )\n }\n instance._store.deleted = true\n console.log(`❌ Unknown element: ${type}`)\n return null\n})\nItemComponent.displayName = 'WeaverseComponent'\n\nconst ItemInstance = memo(\n ({ id, parentId }: { id: string; parentId: string }) => {\n const instance = useItemInstance(id)\n if (!instance) {\n return <div style={{ display: 'none' }}>Item instance {id} not found</div>\n }\n return (\n <WeaverseItemContext.Provider value={{ parentId, id }}>\n <ItemComponent instance={instance} key={id} />\n </WeaverseItemContext.Provider>\n )\n }\n)\nItemInstance.displayName = 'WeaverseInstanceProvider'\n","import type Stitches from '@stitches/react/types/stitches'\nimport type { ElementCSS, WeaverseItemStore } from '@weaverse/core'\nimport clsx from 'clsx'\n\n// Make the css data formatted to correct order (desktop, tablet, mobile)\nfunction formatCSS(css: ElementCSS) {\n return {\n '@desktop': css['@desktop'],\n '@mobile': css['@mobile'],\n }\n}\n\nlet permanentClasses: Record<string, string> = {}\nexport function generateItemClassName(\n instance: WeaverseItemStore,\n stitchesInstance: Stitches\n) {\n let { css, type, className: cls = '' } = instance.data\n let className = ''\n let permanentClass = ''\n let perCss = instance.Element?.permanentCss\n if (perCss) {\n if (type in permanentClasses) {\n permanentClass = permanentClasses[type]\n } else {\n // @ts-expect-error\n let { className: perCls } = stitchesInstance.css(perCss)()\n Object.assign(permanentClasses, { [type]: perCls })\n permanentClass = perCls\n }\n }\n className = permanentClass\n if (css) {\n // let stitches create the style from css object and\n // then return the classname, so we can use it in the render\n let formattedCss = formatCSS(css)\n let newStitchesClass = stitchesInstance.css(formattedCss)().className || ''\n let { stitchesClass = '' } = instance\n let otherClass = (instance.ref.current?.className || '')\n .replace(stitchesClass, '')\n .replace(cls, '')\n .replace(permanentClass, '')\n .trim()\n className = clsx(permanentClass, cls, newStitchesClass, otherClass)\n instance.stitchesClass = newStitchesClass\n }\n return className\n}\n"],"mappings":"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","names":["import_react","result","id","import_clsx","import_react","clsx","import_react","clsx"]}
package/dist/index.mjs CHANGED
@@ -173,10 +173,14 @@ function replaceContentDataConnectorsDeep(data, dataContext, visited = /* @__PUR
173
173
  }
174
174
  visited.add(data);
175
175
  try {
176
+ if (data instanceof Date) {
177
+ return new Date(data.getTime());
178
+ }
176
179
  if (Array.isArray(data)) {
177
- return data.map(
180
+ const result2 = data.map(
178
181
  (item) => replaceContentDataConnectorsDeep(item, dataContext, visited)
179
182
  );
183
+ return result2;
180
184
  }
181
185
  const result = {};
182
186
  for (const [key, value] of Object.entries(data)) {
@@ -276,17 +280,17 @@ var useSafeExternalStore = (subscribe, getSnapshot, getServerSnapshot = getSnaps
276
280
  return getSnapshot();
277
281
  };
278
282
  var WeaverseRoot = memo(({ context }) => {
279
- let data = useSafeExternalStore(
283
+ const data = useSafeExternalStore(
280
284
  context.subscribe,
281
285
  context.getSnapShot,
282
286
  context.getSnapShot
283
287
  );
284
- let rootRef = useRef(null);
288
+ const rootRef = useRef(null);
285
289
  useEffect(() => {
286
290
  context.contentRootElement = rootRef.current;
287
291
  }, [context]);
288
- let eventHandlers = context?.studioBridge?.eventHandlers || {};
289
- let themeClass = context.stitchesInstance.theme.className;
292
+ const eventHandlers = context?.studioBridge?.eventHandlers || {};
293
+ const themeClass = context.stitchesInstance.theme.className;
290
294
  if (context.projectId) {
291
295
  return /* @__PURE__ */ jsx(
292
296
  "div",
@@ -310,14 +314,14 @@ var WeaverseRoot = memo(({ context }) => {
310
314
  });
311
315
  WeaverseRoot.displayName = "WeaverseRoot";
312
316
  var ItemComponent = memo(({ instance }) => {
313
- let context = useWeaverse();
314
- let { stitchesInstance, elementRegistry, platformType } = context;
315
- let data = useSafeExternalStore(
317
+ const context = useWeaverse();
318
+ const { stitchesInstance, elementRegistry, platformType } = context;
319
+ const data = useSafeExternalStore(
316
320
  instance.subscribe,
317
321
  instance.getSnapShot,
318
322
  instance.getSnapShot
319
323
  );
320
- let {
324
+ const {
321
325
  id,
322
326
  type,
323
327
  childIds = [],
@@ -333,9 +337,13 @@ var ItemComponent = memo(({ instance }) => {
333
337
  content,
334
338
  ...rest
335
339
  } = data;
340
+ let processedRest = rest;
336
341
  if (content !== void 0 && content !== null) {
337
- content = replaceContentDataConnectorsDeep(content, context.dataContext);
338
- rest.content = content;
342
+ const processedContent = replaceContentDataConnectorsDeep(
343
+ content,
344
+ context.dataContext
345
+ );
346
+ processedRest = { ...rest, content: processedContent };
339
347
  }
340
348
  useEffect(() => {
341
349
  if (!instance.ref.current) {
@@ -347,22 +355,22 @@ var ItemComponent = memo(({ instance }) => {
347
355
  if (__hidden) {
348
356
  return null;
349
357
  }
350
- let Element = elementRegistry.get(type);
358
+ const Element = elementRegistry.get(type);
351
359
  if (Element?.Component) {
352
- let Component = Element.Component;
360
+ const Component = Element.Component;
353
361
  Component.displayName = type;
354
362
  if (Component.$$typeof === Symbol.for("react.forward_ref") || reactVersion > 18) {
355
- rest.ref = instance.ref;
363
+ processedRest.ref = instance.ref;
356
364
  }
357
- let renderChildren = (children?.length ? children : childIds?.length ? childIds.map((cid) => ({ id: cid })) : []).map((item, index) => /* @__PURE__ */ jsx(ItemInstance, { id: item.id, parentId: id }, `${item.id}-${index}`));
365
+ const renderChildren = (children?.length ? children : childIds?.length ? childIds.map((cid) => ({ id: cid })) : []).map((item, index) => /* @__PURE__ */ jsx(ItemInstance, { id: item.id, parentId: id }, `${item.id}-${index}`));
358
366
  return /* @__PURE__ */ createElement(
359
367
  Component,
360
368
  {
361
- ...rest,
369
+ ...processedRest,
362
370
  children: renderChildren.length ? renderChildren : void 0,
363
371
  className: clsx2(
364
372
  platformType !== "shopify-hydrogen" && generateItemClassName(instance, stitchesInstance),
365
- rest.data?.className
373
+ processedRest.data?.className
366
374
  ),
367
375
  "data-wv-id": id,
368
376
  "data-wv-type": type,
@@ -377,7 +385,7 @@ var ItemComponent = memo(({ instance }) => {
377
385
  ItemComponent.displayName = "WeaverseComponent";
378
386
  var ItemInstance = memo(
379
387
  ({ id, parentId }) => {
380
- let instance = useItemInstance(id);
388
+ const instance = useItemInstance(id);
381
389
  if (!instance) {
382
390
  return /* @__PURE__ */ jsxs("div", { style: { display: "none" }, children: [
383
391
  "Item instance ",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/hooks.ts","../src/utils/data-connector.ts","../src/renderer.tsx","../src/utils/css.ts"],"sourcesContent":["export * from '@weaverse/core'\nexport * from './context'\nexport * from './hooks'\nexport * from './renderer'\nexport * from './types'\n","import type { Weaverse } from '@weaverse/core'\nimport { createContext } from 'react'\n\nexport let WeaverseContext = createContext<Weaverse>({} as Weaverse)\nexport let WeaverseContextProvider = WeaverseContext.Provider\nexport let WeaverseItemContext = createContext<{\n id: string\n parentId: string\n}>({ id: '', parentId: '' })\n","import { Weaverse, type WeaverseItemStore } from '@weaverse/core'\nimport { useContext } from 'react'\nimport { WeaverseContext, WeaverseItemContext } from '~/context'\n\n// Re-export the data connector utilities\nexport {\n replaceContentDataConnectors,\n replaceContentDataConnectorsDeep,\n} from './utils/data-connector'\n\nexport function useWeaverse<T = Weaverse>() {\n let weaverse = useContext(WeaverseContext)\n return weaverse as T\n}\n\nexport let useItemInstance = (id?: string) => {\n let { id: currentId } = useContext(WeaverseItemContext)\n let instance = Weaverse.itemInstances.get(id || currentId)\n if (!instance) {\n console.log(`Item instance ${id} not found`)\n return null\n }\n return instance as WeaverseItemStore\n}\n\nexport let useParentInstance = () => {\n let { parentId } = useContext(WeaverseItemContext)\n return useItemInstance(parentId || '')\n}\n\nexport let useChildInstances = (id?: string) => {\n let currentInstance = useItemInstance(id)\n if (!currentInstance) {\n return []\n }\n let { itemInstances } = Weaverse\n\n let {\n data: { children },\n } = currentInstance\n return children\n .map(({ id }: { id: string }) => itemInstances.get(id))\n .filter(Boolean) as WeaverseItemStore[]\n}\n","// Data connector utilities for replacing placeholders with real data\n// Generic data context type for flexible usage\nexport type DataContext = Record<string, unknown>\n\n// Cached regex pattern for better performance\nconst TEMPLATE_REGEX = /\\{\\{([^}]+)\\}\\}/g\nconst ARRAY_INDEX_REGEX = /^(\\w+)\\[(\\d+)\\]$/\n\n/**\n * Validates that a property name is safe to access (prevents prototype pollution)\n */\nfunction isSafePropertyName(key: string): boolean {\n return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'\n}\n\n// Simple cache for parsed templates (max 100 entries)\nconst templateCache = new Map<string, string>()\nconst MAX_CACHE_SIZE = 100\n\n// Cache for fallback lookups to improve performance (moved to module level to prevent memory leaks)\nconst fallbackCache = new Map<\n string,\n { routeKey: string; value: unknown; timestamp: number }\n>()\nconst FALLBACK_CACHE_MAX_SIZE = 50\n\n/**\n * Safely gets a nested value from an object using dot notation path\n * Supports array indexing with [index] syntax\n * @param obj - The object to traverse\n * @param path - Dot notation path (e.g., \"user.name\" or \"items[0].title\")\n * @param visited - Set to track visited objects for circular reference protection\n * @returns The resolved value or undefined if not found\n */\nfunction getNestedValue(\n obj: unknown,\n path: string,\n visited = new WeakSet()\n): unknown {\n return path.split('.').reduce((current, key) => {\n if (!current || typeof current !== 'object') {\n return\n }\n\n // Protect against circular references\n if (visited.has(current as WeakKey)) {\n console.warn('Circular reference detected in data connector path:', path)\n return\n }\n\n // Add to circular reference tracking\n visited.add(current as WeakKey)\n\n // Handle array indexing like items[0] or items[1]\n const arrayMatch = key.match(ARRAY_INDEX_REGEX)\n if (arrayMatch) {\n const [, arrayKey, index] = arrayMatch\n const arrayObj = (current as Record<string, unknown>)[arrayKey]\n if (Array.isArray(arrayObj)) {\n const indexNum = Number.parseInt(index, 10)\n if (indexNum >= 0 && indexNum < arrayObj.length) {\n return arrayObj[indexNum]\n }\n }\n return\n }\n\n // Handle regular object property access with security validation\n if (!isSafePropertyName(key)) {\n console.warn(`Unsafe property access attempted: ${key}`)\n return\n }\n\n return current !== null && key in current\n ? (current as Record<string, unknown>)[key]\n : undefined\n }, obj)\n}\n\n/**\n * Sanitizes a string value to prevent XSS attacks\n * @param value - The value to sanitize\n * @returns Sanitized string safe for HTML rendering\n */\nfunction sanitizeValue(value: unknown): string {\n if (value === null || value === undefined) {\n return ''\n }\n\n const stringValue = String(value)\n\n // Basic HTML entity encoding to prevent XSS\n return stringValue\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;')\n .replace(/\\//g, '&#x2F;')\n}\n\n/**\n * Creates a safe cache key from content and data\n * Handles circular references by using a simplified approach\n */\nfunction createCacheKey(\n content: string,\n data: Record<string, unknown>\n): string {\n try {\n // Try a simple JSON stringification with a limit\n const dataStr = JSON.stringify(data)\n return `${content}:${dataStr.slice(0, 100)}`\n } catch {\n // If JSON.stringify fails (circular references), use a simpler approach\n const keys = Object.keys(data).sort().join(',')\n return `${content}:keys:${keys}`\n }\n}\n\n/**\n * Resolves data from the flat route-keyed data context\n * Supports both route-specific ({{root.layout.shop.name}}) and fallback ({{shop.name}}) access\n */\nfunction resolveDataFromContext(\n path: string,\n dataContext: DataContext | null | undefined\n): unknown {\n if (!dataContext) {\n return\n }\n\n const trimmedPath = path.trim()\n\n // Check if path starts with a route key (e.g., \"root.layout.shop.name\")\n const pathParts = trimmedPath.split('.')\n const potentialRouteKey = pathParts[0]\n\n // If we have route-keyed data and the first part matches a route\n if (\n dataContext[potentialRouteKey] &&\n typeof dataContext[potentialRouteKey] === 'object' &&\n dataContext[potentialRouteKey] !== null\n ) {\n // Remove route key and resolve rest of path from that route's data\n const remainingPath = pathParts.slice(1).join('.')\n if (remainingPath) {\n return getNestedValue(dataContext[potentialRouteKey], remainingPath)\n }\n return dataContext[potentialRouteKey]\n }\n\n // Fallback: search across all route data for backward compatibility\n // This handles cases like {{shop.name}} without route prefix\n\n // Check cache first\n const cachedResult = fallbackCache.get(trimmedPath)\n if (cachedResult && dataContext[cachedResult.routeKey]) {\n const value = getNestedValue(\n dataContext[cachedResult.routeKey],\n trimmedPath\n )\n if (value !== undefined) {\n // Update timestamp on cache hit\n cachedResult.timestamp = Date.now()\n return value\n }\n }\n\n // Search with priority order (most common routes first)\n const priorityRoutes = ['root', 'routes/product', 'routes/collection']\n const allRoutes = [\n ...priorityRoutes,\n ...Object.keys(dataContext).filter((k) => !priorityRoutes.includes(k)),\n ]\n\n for (const routeKey of allRoutes) {\n const routeData = dataContext[routeKey]\n if (routeData && typeof routeData === 'object' && routeData !== null) {\n const value = getNestedValue(routeData, trimmedPath)\n if (value !== undefined) {\n // Clean cache if it's getting too large\n if (fallbackCache.size >= FALLBACK_CACHE_MAX_SIZE) {\n const entries = Array.from(fallbackCache.entries())\n entries.sort((a, b) => a[1].timestamp - b[1].timestamp)\n // Remove oldest 25% of entries\n const toRemove = Math.floor(entries.length * 0.25)\n for (let i = 0; i < toRemove; i++) {\n fallbackCache.delete(entries[i][0])\n }\n }\n fallbackCache.set(trimmedPath, {\n routeKey,\n value,\n timestamp: Date.now(),\n })\n return value\n }\n }\n }\n\n // Final fallback: try direct access (for non-route-keyed legacy data)\n return getNestedValue(dataContext, trimmedPath)\n}\n\n/**\n * Replaces data connector placeholders in content with actual values from data context\n * Supports {{path}} syntax with dot notation, array indexing, and route prefixes\n *\n * Enhanced syntax:\n * - {{root.siteSettings.title}} - Access root route data\n * - {{layout.navigation.items}} - Access layout route data\n * - {{parent.category.name}} - Access parent route data\n * - {{current.product.title}} - Access current route data\n * - {{user.name}} - Auto-resolved from combined data (backward compatible)\n *\n * @param content - The content string containing {{}} placeholders\n * @param dataContext - The enhanced WeaverseDataContext with route-keyed data\n * @returns The content with placeholders replaced by actual values\n */\nexport function replaceContentDataConnectors(\n content: string,\n dataContext: DataContext | null | undefined\n): string {\n if (!dataContext || typeof content !== 'string') {\n return content\n }\n\n try {\n // Simplified caching - dataContext is already the combined data\n const cacheKey = createCacheKey(content, dataContext)\n\n if (templateCache.has(cacheKey)) {\n return templateCache.get(cacheKey)!\n }\n\n const newContent = content.replace(TEMPLATE_REGEX, (match, path) => {\n try {\n const value = resolveDataFromContext(path, dataContext)\n\n if (value === undefined || value === null) {\n return match // Return original placeholder if value not found\n }\n\n return sanitizeValue(value)\n } catch (pathError) {\n console.warn(\n `Error resolving data connector path \"${path}\":`,\n pathError\n )\n return match\n }\n })\n\n // Cache the result (with size limit)\n if (templateCache.size >= MAX_CACHE_SIZE) {\n const firstKey = templateCache.keys().next().value\n templateCache.delete(firstKey)\n }\n templateCache.set(cacheKey, newContent)\n\n return newContent\n } catch (error) {\n console.warn('Error processing data connectors:', error, { content })\n return content\n }\n}\n\n/**\n * Recursively replaces data connector placeholders in any data structure\n * Handles strings, objects, arrays, and nested combinations\n *\n * @param data - The data to process (string, object, array, or primitive)\n * @param dataContext - The data context for replacements\n * @param visited - Set to track visited objects for circular reference protection\n * @returns The data with all string placeholders replaced\n */\nexport function replaceContentDataConnectorsDeep<T>(\n data: T,\n dataContext: DataContext | null | undefined,\n visited = new WeakSet()\n): T {\n if (!dataContext) {\n return data\n }\n\n // Handle primitive types\n if (typeof data === 'string') {\n return replaceContentDataConnectors(data, dataContext) as T\n }\n\n if (typeof data !== 'object' || data === null) {\n return data\n }\n\n // Protect against circular references\n if (visited.has(data as WeakKey)) {\n console.warn(\n 'Circular reference detected in deep data connector replacement'\n )\n return data\n }\n\n // Add to circular reference tracking\n visited.add(data as WeakKey)\n\n try {\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map((item) =>\n replaceContentDataConnectorsDeep(item, dataContext, visited)\n ) as T\n }\n\n // Handle objects\n const result = {} as T\n for (const [key, value] of Object.entries(data)) {\n ;(result as Record<string, unknown>)[key] =\n replaceContentDataConnectorsDeep(value, dataContext, visited)\n }\n\n return result\n } catch (error) {\n console.warn('Error in deep data connector replacement:', error)\n return data\n } finally {\n // Remove from tracking when done processing this object\n visited.delete(data as WeakKey)\n }\n}\n","import clsx from 'clsx'\nimport * as React from 'react'\nimport { memo, useEffect, useRef } from 'react'\nimport { useItemInstance, useWeaverse } from '~/hooks'\nimport { WeaverseContextProvider, WeaverseItemContext } from './context'\nimport type { ItemComponentProps, WeaverseRootPropsType } from './types'\nimport { generateItemClassName } from './utils/css'\nimport { replaceContentDataConnectorsDeep } from './utils/data-connector'\n\nlet reactVersion = Number(React.version?.split('.')[0]) || 0\n\n// Create a safe version of useSyncExternalStore that works in both client and server environments\nexport const useSafeExternalStore = (\n subscribe: any,\n getSnapshot: any,\n getServerSnapshot: any = getSnapshot\n) => {\n // In server environment or during SSR, just return the snapshot directly\n if (typeof window === 'undefined') {\n return getServerSnapshot()\n }\n\n // In client environment, use React.useSyncExternalStore if available (React 18+)\n if (React.useSyncExternalStore) {\n // biome-ignore lint/correctness/useHookAtTopLevel: <$>\n return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n }\n\n // Fallback for older React versions - just return the current snapshot\n return getSnapshot()\n}\n\nexport let WeaverseRoot = memo(({ context }: WeaverseRootPropsType) => {\n let data = useSafeExternalStore(\n context.subscribe,\n context.getSnapShot,\n context.getSnapShot\n )\n let rootRef = useRef<HTMLElement>(null)\n\n useEffect(() => {\n context.contentRootElement = rootRef.current\n }, [context])\n\n let eventHandlers = context?.studioBridge?.eventHandlers || {}\n let themeClass = context.stitchesInstance.theme.className\n\n if (context.projectId) {\n return (\n <div\n className={`weaverse-content-root ${themeClass}`}\n {...eventHandlers}\n data-weaverse-project-id={context.projectId}\n data-weaverse-template-id={data.id}\n ref={rootRef}\n >\n <WeaverseContextProvider value={context}>\n <ItemInstance\n id={context.data.rootId || context.projectId}\n parentId={''}\n />\n </WeaverseContextProvider>\n </div>\n )\n }\n return null\n})\nWeaverseRoot.displayName = 'WeaverseRoot'\nconst ItemComponent = memo(({ instance }: ItemComponentProps) => {\n let context = useWeaverse()\n let { stitchesInstance, elementRegistry, platformType } = context\n let data = useSafeExternalStore(\n instance.subscribe,\n instance.getSnapShot,\n instance.getSnapShot\n )\n let {\n id,\n type,\n childIds = [],\n children = [],\n parentId,\n createdAt,\n updatedAt,\n deletedAt,\n css,\n __hidden,\n // Need to get rid of this `data` property\n data: _,\n content,\n ...rest\n } = data\n // Replace data connectors in content (handles strings, objects, and arrays recursively)\n if (content !== undefined && content !== null) {\n content = replaceContentDataConnectorsDeep(content, context.dataContext)\n rest.content = content\n }\n\n useEffect(() => {\n if (!instance.ref.current) {\n // Fallback `ref` if the element isn't created by `React.forwardRef`\n Object.assign(instance.ref, {\n current: document.querySelector(`[data-wv-id=\"${id}\"]`),\n })\n }\n }, [instance, id])\n\n if (__hidden) {\n return null\n }\n\n let Element = elementRegistry.get(type)\n\n if (Element?.Component) {\n let Component = Element.Component\n Component.displayName = type\n if (\n Component.$$typeof === Symbol.for('react.forward_ref') ||\n reactVersion > 18\n ) {\n rest.ref = instance.ref\n }\n let renderChildren = (\n children?.length\n ? children\n : childIds?.length\n ? childIds.map((cid: string) => ({ id: cid }))\n : []\n ).map((item: { id: string }, index: number) => (\n <ItemInstance id={item.id} key={`${item.id}-${index}`} parentId={id} />\n ))\n\n return (\n <Component\n {...rest}\n children={renderChildren.length ? renderChildren : undefined}\n className={clsx(\n platformType !== 'shopify-hydrogen' &&\n generateItemClassName(instance, stitchesInstance),\n rest.data?.className\n )}\n data-wv-id={id}\n data-wv-type={type}\n key={id}\n />\n )\n }\n instance._store.deleted = true\n console.log(`❌ Unknown element: ${type}`)\n return null\n})\nItemComponent.displayName = 'WeaverseComponent'\n\nlet ItemInstance = memo(\n ({ id, parentId }: { id: string; parentId: string }) => {\n let instance = useItemInstance(id)\n if (!instance) {\n return <div style={{ display: 'none' }}>Item instance {id} not found</div>\n }\n return (\n <WeaverseItemContext.Provider value={{ parentId, id }}>\n <ItemComponent instance={instance} key={id} />\n </WeaverseItemContext.Provider>\n )\n }\n)\nItemInstance.displayName = 'WeaverseInstanceProvider'\n","import type Stitches from '@stitches/react/types/stitches'\nimport type { ElementCSS, WeaverseItemStore } from '@weaverse/core'\nimport clsx from 'clsx'\n\n// Make the css data formatted to correct order (desktop, tablet, mobile)\nfunction formatCSS(css: ElementCSS) {\n return {\n '@desktop': css['@desktop'],\n '@mobile': css['@mobile'],\n }\n}\n\nlet permanentClasses: Record<string, string> = {}\nexport function generateItemClassName(\n instance: WeaverseItemStore,\n stitchesInstance: Stitches\n) {\n let { css, type, className: cls = '' } = instance.data\n let className = ''\n let permanentClass = ''\n let perCss = instance.Element?.permanentCss\n if (perCss) {\n if (type in permanentClasses) {\n permanentClass = permanentClasses[type]\n } else {\n // @ts-expect-error\n let { className: perCls } = stitchesInstance.css(perCss)()\n Object.assign(permanentClasses, { [type]: perCls })\n permanentClass = perCls\n }\n }\n className = permanentClass\n if (css) {\n // let stitches create the style from css object and\n // then return the classname, so we can use it in the render\n let formattedCss = formatCSS(css)\n let newStitchesClass = stitchesInstance.css(formattedCss)().className || ''\n let { stitchesClass = '' } = instance\n let otherClass = (instance.ref.current?.className || '')\n .replace(stitchesClass, '')\n .replace(cls, '')\n .replace(permanentClass, '')\n .trim()\n className = clsx(permanentClass, cls, newStitchesClass, otherClass)\n instance.stitchesClass = newStitchesClass\n }\n return className\n}\n"],"mappings":"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","names":["id","clsx","clsx"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/hooks.ts","../src/utils/data-connector.ts","../src/renderer.tsx","../src/utils/css.ts"],"sourcesContent":["export * from '@weaverse/core'\nexport * from './context'\nexport * from './hooks'\nexport * from './renderer'\nexport * from './types'\n","import type { Weaverse } from '@weaverse/core'\nimport { createContext } from 'react'\n\nexport let WeaverseContext = createContext<Weaverse>({} as Weaverse)\nexport let WeaverseContextProvider = WeaverseContext.Provider\nexport let WeaverseItemContext = createContext<{\n id: string\n parentId: string\n}>({ id: '', parentId: '' })\n","import { Weaverse, type WeaverseItemStore } from '@weaverse/core'\nimport { useContext } from 'react'\nimport { WeaverseContext, WeaverseItemContext } from '~/context'\n\n// Re-export the data connector utilities\nexport {\n replaceContentDataConnectors,\n replaceContentDataConnectorsDeep,\n} from './utils/data-connector'\n\nexport function useWeaverse<T = Weaverse>() {\n let weaverse = useContext(WeaverseContext)\n return weaverse as T\n}\n\nexport let useItemInstance = (id?: string) => {\n let { id: currentId } = useContext(WeaverseItemContext)\n let instance = Weaverse.itemInstances.get(id || currentId)\n if (!instance) {\n console.log(`Item instance ${id} not found`)\n return null\n }\n return instance as WeaverseItemStore\n}\n\nexport let useParentInstance = () => {\n let { parentId } = useContext(WeaverseItemContext)\n return useItemInstance(parentId || '')\n}\n\nexport let useChildInstances = (id?: string) => {\n let currentInstance = useItemInstance(id)\n if (!currentInstance) {\n return []\n }\n let { itemInstances } = Weaverse\n\n let {\n data: { children },\n } = currentInstance\n return children\n .map(({ id }: { id: string }) => itemInstances.get(id))\n .filter(Boolean) as WeaverseItemStore[]\n}\n","// Data connector utilities for replacing placeholders with real data\n// Generic data context type for flexible usage\nexport type DataContext = Record<string, unknown>\n\n// Cached regex pattern for better performance\nconst TEMPLATE_REGEX = /\\{\\{([^}]+)\\}\\}/g\nconst ARRAY_INDEX_REGEX = /^(\\w+)\\[(\\d+)\\]$/\n\n/**\n * Validates that a property name is safe to access (prevents prototype pollution)\n */\nfunction isSafePropertyName(key: string): boolean {\n return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'\n}\n\n// Simple cache for parsed templates (max 100 entries)\nconst templateCache = new Map<string, string>()\nconst MAX_CACHE_SIZE = 100\n\n// Cache for fallback lookups to improve performance (moved to module level to prevent memory leaks)\nconst fallbackCache = new Map<\n string,\n { routeKey: string; value: unknown; timestamp: number }\n>()\nconst FALLBACK_CACHE_MAX_SIZE = 50\n\n/**\n * Safely gets a nested value from an object using dot notation path\n * Supports array indexing with [index] syntax\n * @param obj - The object to traverse\n * @param path - Dot notation path (e.g., \"user.name\" or \"items[0].title\")\n * @param visited - Set to track visited objects for circular reference protection\n * @returns The resolved value or undefined if not found\n */\nfunction getNestedValue(\n obj: unknown,\n path: string,\n visited = new WeakSet()\n): unknown {\n return path.split('.').reduce((current, key) => {\n if (!current || typeof current !== 'object') {\n return\n }\n\n // Protect against circular references\n if (visited.has(current as WeakKey)) {\n console.warn('Circular reference detected in data connector path:', path)\n return\n }\n\n // Add to circular reference tracking\n visited.add(current as WeakKey)\n\n // Handle array indexing like items[0] or items[1]\n const arrayMatch = key.match(ARRAY_INDEX_REGEX)\n if (arrayMatch) {\n const [, arrayKey, index] = arrayMatch\n const arrayObj = (current as Record<string, unknown>)[arrayKey]\n if (Array.isArray(arrayObj)) {\n const indexNum = Number.parseInt(index, 10)\n if (indexNum >= 0 && indexNum < arrayObj.length) {\n return arrayObj[indexNum]\n }\n }\n return\n }\n\n // Handle regular object property access with security validation\n if (!isSafePropertyName(key)) {\n console.warn(`Unsafe property access attempted: ${key}`)\n return\n }\n\n return current !== null && key in current\n ? (current as Record<string, unknown>)[key]\n : undefined\n }, obj)\n}\n\n/**\n * Sanitizes a string value to prevent XSS attacks\n * @param value - The value to sanitize\n * @returns Sanitized string safe for HTML rendering\n */\nfunction sanitizeValue(value: unknown): string {\n if (value === null || value === undefined) {\n return ''\n }\n\n const stringValue = String(value)\n\n // Basic HTML entity encoding to prevent XSS\n return stringValue\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;')\n .replace(/\\//g, '&#x2F;')\n}\n\n/**\n * Creates a safe cache key from content and data\n * Handles circular references by using a simplified approach\n */\nfunction createCacheKey(\n content: string,\n data: Record<string, unknown>\n): string {\n try {\n // Try a simple JSON stringification with a limit\n const dataStr = JSON.stringify(data)\n return `${content}:${dataStr.slice(0, 100)}`\n } catch {\n // If JSON.stringify fails (circular references), use a simpler approach\n const keys = Object.keys(data).sort().join(',')\n return `${content}:keys:${keys}`\n }\n}\n\n/**\n * Resolves data from the flat route-keyed data context\n * Supports both route-specific ({{root.layout.shop.name}}) and fallback ({{shop.name}}) access\n */\nfunction resolveDataFromContext(\n path: string,\n dataContext: DataContext | null | undefined\n): unknown {\n if (!dataContext) {\n return\n }\n\n const trimmedPath = path.trim()\n\n // Check if path starts with a route key (e.g., \"root.layout.shop.name\")\n const pathParts = trimmedPath.split('.')\n const potentialRouteKey = pathParts[0]\n\n // If we have route-keyed data and the first part matches a route\n if (\n dataContext[potentialRouteKey] &&\n typeof dataContext[potentialRouteKey] === 'object' &&\n dataContext[potentialRouteKey] !== null\n ) {\n // Remove route key and resolve rest of path from that route's data\n const remainingPath = pathParts.slice(1).join('.')\n if (remainingPath) {\n return getNestedValue(dataContext[potentialRouteKey], remainingPath)\n }\n return dataContext[potentialRouteKey]\n }\n\n // Fallback: search across all route data for backward compatibility\n // This handles cases like {{shop.name}} without route prefix\n\n // Check cache first\n const cachedResult = fallbackCache.get(trimmedPath)\n if (cachedResult && dataContext[cachedResult.routeKey]) {\n const value = getNestedValue(\n dataContext[cachedResult.routeKey],\n trimmedPath\n )\n if (value !== undefined) {\n // Update timestamp on cache hit\n cachedResult.timestamp = Date.now()\n return value\n }\n }\n\n // Search with priority order (most common routes first)\n const priorityRoutes = ['root', 'routes/product', 'routes/collection']\n const allRoutes = [\n ...priorityRoutes,\n ...Object.keys(dataContext).filter((k) => !priorityRoutes.includes(k)),\n ]\n\n for (const routeKey of allRoutes) {\n const routeData = dataContext[routeKey]\n if (routeData && typeof routeData === 'object' && routeData !== null) {\n const value = getNestedValue(routeData, trimmedPath)\n if (value !== undefined) {\n // Clean cache if it's getting too large\n if (fallbackCache.size >= FALLBACK_CACHE_MAX_SIZE) {\n const entries = Array.from(fallbackCache.entries())\n entries.sort((a, b) => a[1].timestamp - b[1].timestamp)\n // Remove oldest 25% of entries\n const toRemove = Math.floor(entries.length * 0.25)\n for (let i = 0; i < toRemove; i++) {\n fallbackCache.delete(entries[i][0])\n }\n }\n fallbackCache.set(trimmedPath, {\n routeKey,\n value,\n timestamp: Date.now(),\n })\n return value\n }\n }\n }\n\n // Final fallback: try direct access (for non-route-keyed legacy data)\n return getNestedValue(dataContext, trimmedPath)\n}\n\n/**\n * Replaces data connector placeholders in content with actual values from data context\n * Supports {{path}} syntax with dot notation, array indexing, and route prefixes\n *\n * Enhanced syntax:\n * - {{root.siteSettings.title}} - Access root route data\n * - {{layout.navigation.items}} - Access layout route data\n * - {{parent.category.name}} - Access parent route data\n * - {{current.product.title}} - Access current route data\n * - {{user.name}} - Auto-resolved from combined data (backward compatible)\n *\n * @param content - The content string containing {{}} placeholders\n * @param dataContext - The enhanced WeaverseDataContext with route-keyed data\n * @returns The content with placeholders replaced by actual values\n */\nexport function replaceContentDataConnectors(\n content: string,\n dataContext: DataContext | null | undefined\n): string {\n if (!dataContext || typeof content !== 'string') {\n return content\n }\n\n try {\n // Simplified caching - dataContext is already the combined data\n const cacheKey = createCacheKey(content, dataContext)\n\n if (templateCache.has(cacheKey)) {\n return templateCache.get(cacheKey)!\n }\n\n const newContent = content.replace(TEMPLATE_REGEX, (match, path) => {\n try {\n const value = resolveDataFromContext(path, dataContext)\n\n if (value === undefined || value === null) {\n return match // Return original placeholder if value not found\n }\n\n return sanitizeValue(value)\n } catch (pathError) {\n console.warn(\n `Error resolving data connector path \"${path}\":`,\n pathError\n )\n return match\n }\n })\n\n // Cache the result (with size limit)\n if (templateCache.size >= MAX_CACHE_SIZE) {\n const firstKey = templateCache.keys().next().value\n templateCache.delete(firstKey)\n }\n templateCache.set(cacheKey, newContent)\n\n return newContent\n } catch (error) {\n console.warn('Error processing data connectors:', error, { content })\n return content\n }\n}\n\n/**\n * Recursively replaces data connector placeholders in any data structure\n * IMMUTABLE: Creates deep copies during processing to avoid mutating original data\n * Handles strings, objects, arrays, and nested combinations\n *\n * @param data - The data to process (string, object, array, or primitive)\n * @param dataContext - The data context for replacements\n * @param visited - Set to track visited objects for circular reference protection\n * @returns IMMUTABLE copy of the data with all string placeholders replaced\n */\nexport function replaceContentDataConnectorsDeep<T>(\n data: T,\n dataContext: DataContext | null | undefined,\n visited = new WeakSet()\n): T {\n if (!dataContext) {\n return data\n }\n\n // Handle primitive types - no cloning needed for primitives\n if (typeof data === 'string') {\n return replaceContentDataConnectors(data, dataContext) as T\n }\n\n if (typeof data !== 'object' || data === null) {\n return data\n }\n\n // Protect against circular references\n if (visited.has(data as WeakKey)) {\n console.warn(\n 'Circular reference detected in deep data connector replacement'\n )\n return data\n }\n\n // Add to circular reference tracking\n visited.add(data as WeakKey)\n\n try {\n // Handle special objects that should be cloned as-is\n if (data instanceof Date) {\n return new Date(data.getTime()) as T\n }\n\n // Handle arrays - create new array with processed items\n if (Array.isArray(data)) {\n const result = data.map((item) =>\n replaceContentDataConnectorsDeep(item, dataContext, visited)\n ) as T\n return result\n }\n\n // Handle plain objects - create new object with processed values\n const result = {} as T\n for (const [key, value] of Object.entries(data)) {\n ;(result as Record<string, unknown>)[key] =\n replaceContentDataConnectorsDeep(value, dataContext, visited)\n }\n\n return result\n } catch (error) {\n console.warn('Error in deep data connector replacement:', error)\n return data\n } finally {\n // Remove from tracking when done processing this object\n visited.delete(data as WeakKey)\n }\n}\n","import clsx from 'clsx'\nimport * as React from 'react'\nimport { memo, useEffect, useRef } from 'react'\nimport { useItemInstance, useWeaverse } from '~/hooks'\nimport { WeaverseContextProvider, WeaverseItemContext } from './context'\nimport type { ItemComponentProps, WeaverseRootPropsType } from './types'\nimport { generateItemClassName } from './utils/css'\nimport { replaceContentDataConnectorsDeep } from './utils/data-connector'\n\nconst reactVersion = Number(React.version?.split('.')[0]) || 0\n\n// Create a safe version of useSyncExternalStore that works in both client and server environments\nexport const useSafeExternalStore = (\n subscribe: any,\n getSnapshot: any,\n getServerSnapshot: any = getSnapshot\n) => {\n // In server environment or during SSR, just return the snapshot directly\n if (typeof window === 'undefined') {\n return getServerSnapshot()\n }\n\n // In client environment, use React.useSyncExternalStore if available (React 18+)\n if (React.useSyncExternalStore) {\n // biome-ignore lint/correctness/useHookAtTopLevel: <$>\n return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n }\n\n // Fallback for older React versions - just return the current snapshot\n return getSnapshot()\n}\n\nexport const WeaverseRoot = memo(({ context }: WeaverseRootPropsType) => {\n const data = useSafeExternalStore(\n context.subscribe,\n context.getSnapShot,\n context.getSnapShot\n )\n const rootRef = useRef<HTMLElement>(null)\n\n useEffect(() => {\n context.contentRootElement = rootRef.current\n }, [context])\n\n const eventHandlers = context?.studioBridge?.eventHandlers || {}\n const themeClass = context.stitchesInstance.theme.className\n\n if (context.projectId) {\n return (\n <div\n className={`weaverse-content-root ${themeClass}`}\n {...eventHandlers}\n data-weaverse-project-id={context.projectId}\n data-weaverse-template-id={data.id}\n ref={rootRef}\n >\n <WeaverseContextProvider value={context}>\n <ItemInstance\n id={context.data.rootId || context.projectId}\n parentId={''}\n />\n </WeaverseContextProvider>\n </div>\n )\n }\n return null\n})\nWeaverseRoot.displayName = 'WeaverseRoot'\nconst ItemComponent = memo(({ instance }: ItemComponentProps) => {\n const context = useWeaverse()\n const { stitchesInstance, elementRegistry, platformType } = context\n const data = useSafeExternalStore(\n instance.subscribe,\n instance.getSnapShot,\n instance.getSnapShot\n )\n const {\n id,\n type,\n childIds = [],\n children = [],\n parentId,\n createdAt,\n updatedAt,\n deletedAt,\n css,\n __hidden,\n // Need to get rid of this `data` property\n data: _,\n content,\n ...rest\n } = data\n\n // Replace data connectors in content (handles strings, objects, and arrays recursively)\n // IMMUTABLE: Process the entire data object to avoid mutating original content\n let processedRest = rest\n if (content !== undefined && content !== null) {\n const processedContent = replaceContentDataConnectorsDeep(\n content,\n context.dataContext\n )\n // Create new rest object instead of mutating original\n processedRest = { ...rest, content: processedContent }\n }\n\n useEffect(() => {\n if (!instance.ref.current) {\n // Fallback `ref` if the element isn't created by `React.forwardRef`\n Object.assign(instance.ref, {\n current: document.querySelector(`[data-wv-id=\"${id}\"]`),\n })\n }\n }, [instance, id])\n\n if (__hidden) {\n return null\n }\n\n const Element = elementRegistry.get(type)\n\n if (Element?.Component) {\n const Component = Element.Component\n Component.displayName = type\n if (\n Component.$$typeof === Symbol.for('react.forward_ref') ||\n reactVersion > 18\n ) {\n processedRest.ref = instance.ref\n }\n const renderChildren = (\n children?.length\n ? children\n : childIds?.length\n ? childIds.map((cid: string) => ({ id: cid }))\n : []\n ).map((item: { id: string }, index: number) => (\n <ItemInstance id={item.id} key={`${item.id}-${index}`} parentId={id} />\n ))\n\n return (\n <Component\n {...processedRest}\n children={renderChildren.length ? renderChildren : undefined}\n className={clsx(\n platformType !== 'shopify-hydrogen' &&\n generateItemClassName(instance, stitchesInstance),\n processedRest.data?.className\n )}\n data-wv-id={id}\n data-wv-type={type}\n key={id}\n />\n )\n }\n instance._store.deleted = true\n console.log(`❌ Unknown element: ${type}`)\n return null\n})\nItemComponent.displayName = 'WeaverseComponent'\n\nconst ItemInstance = memo(\n ({ id, parentId }: { id: string; parentId: string }) => {\n const instance = useItemInstance(id)\n if (!instance) {\n return <div style={{ display: 'none' }}>Item instance {id} not found</div>\n }\n return (\n <WeaverseItemContext.Provider value={{ parentId, id }}>\n <ItemComponent instance={instance} key={id} />\n </WeaverseItemContext.Provider>\n )\n }\n)\nItemInstance.displayName = 'WeaverseInstanceProvider'\n","import type Stitches from '@stitches/react/types/stitches'\nimport type { ElementCSS, WeaverseItemStore } from '@weaverse/core'\nimport clsx from 'clsx'\n\n// Make the css data formatted to correct order (desktop, tablet, mobile)\nfunction formatCSS(css: ElementCSS) {\n return {\n '@desktop': css['@desktop'],\n '@mobile': css['@mobile'],\n }\n}\n\nlet permanentClasses: Record<string, string> = {}\nexport function generateItemClassName(\n instance: WeaverseItemStore,\n stitchesInstance: Stitches\n) {\n let { css, type, className: cls = '' } = instance.data\n let className = ''\n let permanentClass = ''\n let perCss = instance.Element?.permanentCss\n if (perCss) {\n if (type in permanentClasses) {\n permanentClass = permanentClasses[type]\n } else {\n // @ts-expect-error\n let { className: perCls } = stitchesInstance.css(perCss)()\n Object.assign(permanentClasses, { [type]: perCls })\n permanentClass = perCls\n }\n }\n className = permanentClass\n if (css) {\n // let stitches create the style from css object and\n // then return the classname, so we can use it in the render\n let formattedCss = formatCSS(css)\n let newStitchesClass = stitchesInstance.css(formattedCss)().className || ''\n let { stitchesClass = '' } = instance\n let otherClass = (instance.ref.current?.className || '')\n .replace(stitchesClass, '')\n .replace(cls, '')\n .replace(permanentClass, '')\n .trim()\n className = clsx(permanentClass, cls, newStitchesClass, otherClass)\n instance.stitchesClass = newStitchesClass\n }\n return className\n}\n"],"mappings":";AAAA,cAAc;;;ACCd,SAAS,qBAAqB;AAEvB,IAAI,kBAAkB,cAAwB,CAAC,CAAa;AAC5D,IAAI,0BAA0B,gBAAgB;AAC9C,IAAI,sBAAsB,cAG9B,EAAE,IAAI,IAAI,UAAU,GAAG,CAAC;;;ACR3B,SAAS,gBAAwC;AACjD,SAAS,kBAAkB;;;ACI3B,IAAM,iBAAiB;AACvB,IAAM,oBAAoB;AAK1B,SAAS,mBAAmB,KAAsB;AAChD,SAAO,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ;AACjE;AAGA,IAAM,gBAAgB,oBAAI,IAAoB;AAC9C,IAAM,iBAAiB;AAGvB,IAAM,gBAAgB,oBAAI,IAGxB;AACF,IAAM,0BAA0B;AAUhC,SAAS,eACP,KACA,MACA,UAAU,oBAAI,QAAQ,GACb;AACT,SAAO,KAAK,MAAM,GAAG,EAAE,OAAO,CAAC,SAAS,QAAQ;AAC9C,QAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C;AAAA,IACF;AAGA,QAAI,QAAQ,IAAI,OAAkB,GAAG;AACnC,cAAQ,KAAK,uDAAuD,IAAI;AACxE;AAAA,IACF;AAGA,YAAQ,IAAI,OAAkB;AAG9B,UAAM,aAAa,IAAI,MAAM,iBAAiB;AAC9C,QAAI,YAAY;AACd,YAAM,CAAC,EAAE,UAAU,KAAK,IAAI;AAC5B,YAAM,WAAY,QAAoC,QAAQ;AAC9D,UAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,cAAM,WAAW,OAAO,SAAS,OAAO,EAAE;AAC1C,YAAI,YAAY,KAAK,WAAW,SAAS,QAAQ;AAC/C,iBAAO,SAAS,QAAQ;AAAA,QAC1B;AAAA,MACF;AACA;AAAA,IACF;AAGA,QAAI,CAAC,mBAAmB,GAAG,GAAG;AAC5B,cAAQ,KAAK,qCAAqC,GAAG,EAAE;AACvD;AAAA,IACF;AAEA,WAAO,YAAY,QAAQ,OAAO,UAC7B,QAAoC,GAAG,IACxC;AAAA,EACN,GAAG,GAAG;AACR;AAOA,SAAS,cAAc,OAAwB;AAC7C,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,OAAO,KAAK;AAGhC,SAAO,YACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,OAAO,QAAQ;AAC5B;AAMA,SAAS,eACP,SACA,MACQ;AACR,MAAI;AAEF,UAAM,UAAU,KAAK,UAAU,IAAI;AACnC,WAAO,GAAG,OAAO,IAAI,QAAQ,MAAM,GAAG,GAAG,CAAC;AAAA,EAC5C,QAAQ;AAEN,UAAM,OAAO,OAAO,KAAK,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG;AAC9C,WAAO,GAAG,OAAO,SAAS,IAAI;AAAA,EAChC;AACF;AAMA,SAAS,uBACP,MACA,aACS;AACT,MAAI,CAAC,aAAa;AAChB;AAAA,EACF;AAEA,QAAM,cAAc,KAAK,KAAK;AAG9B,QAAM,YAAY,YAAY,MAAM,GAAG;AACvC,QAAM,oBAAoB,UAAU,CAAC;AAGrC,MACE,YAAY,iBAAiB,KAC7B,OAAO,YAAY,iBAAiB,MAAM,YAC1C,YAAY,iBAAiB,MAAM,MACnC;AAEA,UAAM,gBAAgB,UAAU,MAAM,CAAC,EAAE,KAAK,GAAG;AACjD,QAAI,eAAe;AACjB,aAAO,eAAe,YAAY,iBAAiB,GAAG,aAAa;AAAA,IACrE;AACA,WAAO,YAAY,iBAAiB;AAAA,EACtC;AAMA,QAAM,eAAe,cAAc,IAAI,WAAW;AAClD,MAAI,gBAAgB,YAAY,aAAa,QAAQ,GAAG;AACtD,UAAM,QAAQ;AAAA,MACZ,YAAY,aAAa,QAAQ;AAAA,MACjC;AAAA,IACF;AACA,QAAI,UAAU,QAAW;AAEvB,mBAAa,YAAY,KAAK,IAAI;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,iBAAiB,CAAC,QAAQ,kBAAkB,mBAAmB;AACrE,QAAM,YAAY;AAAA,IAChB,GAAG;AAAA,IACH,GAAG,OAAO,KAAK,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,eAAe,SAAS,CAAC,CAAC;AAAA,EACvE;AAEA,aAAW,YAAY,WAAW;AAChC,UAAM,YAAY,YAAY,QAAQ;AACtC,QAAI,aAAa,OAAO,cAAc,YAAY,cAAc,MAAM;AACpE,YAAM,QAAQ,eAAe,WAAW,WAAW;AACnD,UAAI,UAAU,QAAW;AAEvB,YAAI,cAAc,QAAQ,yBAAyB;AACjD,gBAAM,UAAU,MAAM,KAAK,cAAc,QAAQ,CAAC;AAClD,kBAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS;AAEtD,gBAAM,WAAW,KAAK,MAAM,QAAQ,SAAS,IAAI;AACjD,mBAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,0BAAc,OAAO,QAAQ,CAAC,EAAE,CAAC,CAAC;AAAA,UACpC;AAAA,QACF;AACA,sBAAc,IAAI,aAAa;AAAA,UAC7B;AAAA,UACA;AAAA,UACA,WAAW,KAAK,IAAI;AAAA,QACtB,CAAC;AACD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGA,SAAO,eAAe,aAAa,WAAW;AAChD;AAiBO,SAAS,6BACd,SACA,aACQ;AACR,MAAI,CAAC,eAAe,OAAO,YAAY,UAAU;AAC/C,WAAO;AAAA,EACT;AAEA,MAAI;AAEF,UAAM,WAAW,eAAe,SAAS,WAAW;AAEpD,QAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B,aAAO,cAAc,IAAI,QAAQ;AAAA,IACnC;AAEA,UAAM,aAAa,QAAQ,QAAQ,gBAAgB,CAAC,OAAO,SAAS;AAClE,UAAI;AACF,cAAM,QAAQ,uBAAuB,MAAM,WAAW;AAEtD,YAAI,UAAU,UAAa,UAAU,MAAM;AACzC,iBAAO;AAAA,QACT;AAEA,eAAO,cAAc,KAAK;AAAA,MAC5B,SAAS,WAAW;AAClB,gBAAQ;AAAA,UACN,wCAAwC,IAAI;AAAA,UAC5C;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAGD,QAAI,cAAc,QAAQ,gBAAgB;AACxC,YAAM,WAAW,cAAc,KAAK,EAAE,KAAK,EAAE;AAC7C,oBAAc,OAAO,QAAQ;AAAA,IAC/B;AACA,kBAAc,IAAI,UAAU,UAAU;AAEtC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,KAAK,qCAAqC,OAAO,EAAE,QAAQ,CAAC;AACpE,WAAO;AAAA,EACT;AACF;AAYO,SAAS,iCACd,MACA,aACA,UAAU,oBAAI,QAAQ,GACnB;AACH,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,6BAA6B,MAAM,WAAW;AAAA,EACvD;AAEA,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,IAAI,IAAe,GAAG;AAChC,YAAQ;AAAA,MACN;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAGA,UAAQ,IAAI,IAAe;AAE3B,MAAI;AAEF,QAAI,gBAAgB,MAAM;AACxB,aAAO,IAAI,KAAK,KAAK,QAAQ,CAAC;AAAA,IAChC;AAGA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,YAAMA,UAAS,KAAK;AAAA,QAAI,CAAC,SACvB,iCAAiC,MAAM,aAAa,OAAO;AAAA,MAC7D;AACA,aAAOA;AAAA,IACT;AAGA,UAAM,SAAS,CAAC;AAChB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C;AAAC,MAAC,OAAmC,GAAG,IACtC,iCAAiC,OAAO,aAAa,OAAO;AAAA,IAChE;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,KAAK,6CAA6C,KAAK;AAC/D,WAAO;AAAA,EACT,UAAE;AAEA,YAAQ,OAAO,IAAe;AAAA,EAChC;AACF;;;ADtUO,SAAS,cAA4B;AAC1C,MAAI,WAAW,WAAW,eAAe;AACzC,SAAO;AACT;AAEO,IAAI,kBAAkB,CAAC,OAAgB;AAC5C,MAAI,EAAE,IAAI,UAAU,IAAI,WAAW,mBAAmB;AACtD,MAAI,WAAW,SAAS,cAAc,IAAI,MAAM,SAAS;AACzD,MAAI,CAAC,UAAU;AACb,YAAQ,IAAI,iBAAiB,EAAE,YAAY;AAC3C,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,IAAI,oBAAoB,MAAM;AACnC,MAAI,EAAE,SAAS,IAAI,WAAW,mBAAmB;AACjD,SAAO,gBAAgB,YAAY,EAAE;AACvC;AAEO,IAAI,oBAAoB,CAAC,OAAgB;AAC9C,MAAI,kBAAkB,gBAAgB,EAAE;AACxC,MAAI,CAAC,iBAAiB;AACpB,WAAO,CAAC;AAAA,EACV;AACA,MAAI,EAAE,cAAc,IAAI;AAExB,MAAI;AAAA,IACF,MAAM,EAAE,SAAS;AAAA,EACnB,IAAI;AACJ,SAAO,SACJ,IAAI,CAAC,EAAE,IAAAC,IAAG,MAAsB,cAAc,IAAIA,GAAE,CAAC,EACrD,OAAO,OAAO;AACnB;;;AE3CA,OAAOC,WAAU;AACjB,YAAY,WAAW;AACvB,SAAS,MAAM,WAAW,cAAc;;;ACAxC,OAAO,UAAU;AAGjB,SAAS,UAAU,KAAiB;AAClC,SAAO;AAAA,IACL,YAAY,IAAI,UAAU;AAAA,IAC1B,WAAW,IAAI,SAAS;AAAA,EAC1B;AACF;AAEA,IAAI,mBAA2C,CAAC;AACzC,SAAS,sBACd,UACA,kBACA;AACA,MAAI,EAAE,KAAK,MAAM,WAAW,MAAM,GAAG,IAAI,SAAS;AAClD,MAAI,YAAY;AAChB,MAAI,iBAAiB;AACrB,MAAI,SAAS,SAAS,SAAS;AAC/B,MAAI,QAAQ;AACV,QAAI,QAAQ,kBAAkB;AAC5B,uBAAiB,iBAAiB,IAAI;AAAA,IACxC,OAAO;AAEL,UAAI,EAAE,WAAW,OAAO,IAAI,iBAAiB,IAAI,MAAM,EAAE;AACzD,aAAO,OAAO,kBAAkB,EAAE,CAAC,IAAI,GAAG,OAAO,CAAC;AAClD,uBAAiB;AAAA,IACnB;AAAA,EACF;AACA,cAAY;AACZ,MAAI,KAAK;AAGP,QAAI,eAAe,UAAU,GAAG;AAChC,QAAI,mBAAmB,iBAAiB,IAAI,YAAY,EAAE,EAAE,aAAa;AACzE,QAAI,EAAE,gBAAgB,GAAG,IAAI;AAC7B,QAAI,cAAc,SAAS,IAAI,SAAS,aAAa,IAClD,QAAQ,eAAe,EAAE,EACzB,QAAQ,KAAK,EAAE,EACf,QAAQ,gBAAgB,EAAE,EAC1B,KAAK;AACR,gBAAY,KAAK,gBAAgB,KAAK,kBAAkB,UAAU;AAClE,aAAS,gBAAgB;AAAA,EAC3B;AACA,SAAO;AACT;;;ADUU,cA2GG,YA3GH;AAmFJ;AAnIN,IAAM,eAAe,OAAa,eAAS,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;AAGtD,IAAM,uBAAuB,CAClC,WACA,aACA,oBAAyB,gBACtB;AAEH,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,kBAAkB;AAAA,EAC3B;AAGA,MAAU,4BAAsB;AAE9B,WAAa,2BAAqB,WAAW,aAAa,iBAAiB;AAAA,EAC7E;AAGA,SAAO,YAAY;AACrB;AAEO,IAAM,eAAe,KAAK,CAAC,EAAE,QAAQ,MAA6B;AACvE,QAAM,OAAO;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,QAAM,UAAU,OAAoB,IAAI;AAExC,YAAU,MAAM;AACd,YAAQ,qBAAqB,QAAQ;AAAA,EACvC,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,gBAAgB,SAAS,cAAc,iBAAiB,CAAC;AAC/D,QAAM,aAAa,QAAQ,iBAAiB,MAAM;AAElD,MAAI,QAAQ,WAAW;AACrB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,yBAAyB,UAAU;AAAA,QAC7C,GAAG;AAAA,QACJ,4BAA0B,QAAQ;AAAA,QAClC,6BAA2B,KAAK;AAAA,QAChC,KAAK;AAAA,QAEL,8BAAC,2BAAwB,OAAO,SAC9B;AAAA,UAAC;AAAA;AAAA,YACC,IAAI,QAAQ,KAAK,UAAU,QAAQ;AAAA,YACnC,UAAU;AAAA;AAAA,QACZ,GACF;AAAA;AAAA,IACF;AAAA,EAEJ;AACA,SAAO;AACT,CAAC;AACD,aAAa,cAAc;AAC3B,IAAM,gBAAgB,KAAK,CAAC,EAAE,SAAS,MAA0B;AAC/D,QAAM,UAAU,YAAY;AAC5B,QAAM,EAAE,kBAAkB,iBAAiB,aAAa,IAAI;AAC5D,QAAM,OAAO;AAAA,IACX,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AACA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,WAAW,CAAC;AAAA,IACZ,WAAW,CAAC;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,MAAM;AAAA,IACN;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AAIJ,MAAI,gBAAgB;AACpB,MAAI,YAAY,UAAa,YAAY,MAAM;AAC7C,UAAM,mBAAmB;AAAA,MACvB;AAAA,MACA,QAAQ;AAAA,IACV;AAEA,oBAAgB,EAAE,GAAG,MAAM,SAAS,iBAAiB;AAAA,EACvD;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,SAAS,IAAI,SAAS;AAEzB,aAAO,OAAO,SAAS,KAAK;AAAA,QAC1B,SAAS,SAAS,cAAc,gBAAgB,EAAE,IAAI;AAAA,MACxD,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,UAAU,EAAE,CAAC;AAEjB,MAAI,UAAU;AACZ,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,gBAAgB,IAAI,IAAI;AAExC,MAAI,SAAS,WAAW;AACtB,UAAM,YAAY,QAAQ;AAC1B,cAAU,cAAc;AACxB,QACE,UAAU,aAAa,OAAO,IAAI,mBAAmB,KACrD,eAAe,IACf;AACA,oBAAc,MAAM,SAAS;AAAA,IAC/B;AACA,UAAM,kBACJ,UAAU,SACN,WACA,UAAU,SACR,SAAS,IAAI,CAAC,SAAiB,EAAE,IAAI,IAAI,EAAE,IAC3C,CAAC,GACP,IAAI,CAAC,MAAsB,UAC3B,oBAAC,gBAAa,IAAI,KAAK,IAAgC,UAAU,MAAjC,GAAG,KAAK,EAAE,IAAI,KAAK,EAAkB,CACtE;AAED,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,UAAU,eAAe,SAAS,iBAAiB;AAAA,QACnD,WAAWC;AAAA,UACT,iBAAiB,sBACf,sBAAsB,UAAU,gBAAgB;AAAA,UAClD,cAAc,MAAM;AAAA,QACtB;AAAA,QACA,cAAY;AAAA,QACZ,gBAAc;AAAA,QACd,KAAK;AAAA;AAAA,IACP;AAAA,EAEJ;AACA,WAAS,OAAO,UAAU;AAC1B,UAAQ,IAAI,2BAAsB,IAAI,EAAE;AACxC,SAAO;AACT,CAAC;AACD,cAAc,cAAc;AAE5B,IAAM,eAAe;AAAA,EACnB,CAAC,EAAE,IAAI,SAAS,MAAwC;AACtD,UAAM,WAAW,gBAAgB,EAAE;AACnC,QAAI,CAAC,UAAU;AACb,aAAO,qBAAC,SAAI,OAAO,EAAE,SAAS,OAAO,GAAG;AAAA;AAAA,QAAe;AAAA,QAAG;AAAA,SAAU;AAAA,IACtE;AACA,WACE,oBAAC,oBAAoB,UAApB,EAA6B,OAAO,EAAE,UAAU,GAAG,GAClD,8BAAC,iBAAc,YAAyB,EAAI,GAC9C;AAAA,EAEJ;AACF;AACA,aAAa,cAAc;","names":["result","id","clsx","clsx"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@weaverse/react",
3
3
  "author": "Weaverse Team",
4
4
  "description": "React bindings for Weaverse",
5
- "version": "5.5.0-beta.4",
5
+ "version": "5.5.0-beta.5",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
8
8
  "typings": "dist/index.d.ts",
@@ -42,7 +42,7 @@
42
42
  "outDir": "dist"
43
43
  },
44
44
  "dependencies": {
45
- "@weaverse/core": "5.5.0-beta.4",
45
+ "@weaverse/core": "5.5.0-beta.5",
46
46
  "clsx": "^2.1.1",
47
47
  "react": ">=18",
48
48
  "react-dom": ">=18"