@weaverse/react 5.4.2 → 5.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -11,6 +11,34 @@ declare let WeaverseItemContext: react.Context<{
11
11
  parentId: string;
12
12
  }>;
13
13
 
14
+ type DataContext = Record<string, unknown>;
15
+ /**
16
+ * Replaces data connector placeholders in content with actual values from data context
17
+ * Supports {{path}} syntax with dot notation, array indexing, and route prefixes
18
+ *
19
+ * Enhanced syntax:
20
+ * - {{root.siteSettings.title}} - Access root route data
21
+ * - {{layout.navigation.items}} - Access layout route data
22
+ * - {{parent.category.name}} - Access parent route data
23
+ * - {{current.product.title}} - Access current route data
24
+ * - {{user.name}} - Auto-resolved from combined data (backward compatible)
25
+ *
26
+ * @param content - The content string containing {{}} placeholders
27
+ * @param dataContext - The enhanced WeaverseDataContext with route-keyed data
28
+ * @returns The content with placeholders replaced by actual values
29
+ */
30
+ declare function replaceContentDataConnectors(content: string, dataContext: DataContext | null | undefined): string;
31
+ /**
32
+ * Recursively replaces data connector placeholders in any data structure
33
+ * Handles strings, objects, arrays, and nested combinations
34
+ *
35
+ * @param data - The data to process (string, object, array, or primitive)
36
+ * @param dataContext - The data context for replacements
37
+ * @param visited - Set to track visited objects for circular reference protection
38
+ * @returns The data with all string placeholders replaced
39
+ */
40
+ declare function replaceContentDataConnectorsDeep<T>(data: T, dataContext: DataContext | null | undefined, visited?: WeakSet<WeakKey>): T;
41
+
14
42
  declare function useWeaverse<T = Weaverse>(): T;
15
43
  declare let useItemInstance: (id?: string) => WeaverseItemStore | null;
16
44
  declare let useParentInstance: () => WeaverseItemStore | null;
@@ -32,4 +60,4 @@ type ItemComponentProps = {
32
60
  declare const useSafeExternalStore: (subscribe: any, getSnapshot: any, getServerSnapshot?: any) => any;
33
61
  declare let WeaverseRoot: react.MemoExoticComponent<({ context }: WeaverseRootPropsType) => react_jsx_runtime.JSX.Element | null>;
34
62
 
35
- export { type ItemComponentProps, WeaverseContext, WeaverseContextProvider, type WeaverseElementProps, WeaverseItemContext, WeaverseRoot, type WeaverseRootPropsType, useChildInstances, useItemInstance, useParentInstance, useSafeExternalStore, useWeaverse };
63
+ export { type ItemComponentProps, WeaverseContext, WeaverseContextProvider, type WeaverseElementProps, WeaverseItemContext, WeaverseRoot, type WeaverseRootPropsType, replaceContentDataConnectors, replaceContentDataConnectorsDeep, useChildInstances, useItemInstance, useParentInstance, useSafeExternalStore, useWeaverse };
package/dist/index.d.ts CHANGED
@@ -11,6 +11,34 @@ declare let WeaverseItemContext: react.Context<{
11
11
  parentId: string;
12
12
  }>;
13
13
 
14
+ type DataContext = Record<string, unknown>;
15
+ /**
16
+ * Replaces data connector placeholders in content with actual values from data context
17
+ * Supports {{path}} syntax with dot notation, array indexing, and route prefixes
18
+ *
19
+ * Enhanced syntax:
20
+ * - {{root.siteSettings.title}} - Access root route data
21
+ * - {{layout.navigation.items}} - Access layout route data
22
+ * - {{parent.category.name}} - Access parent route data
23
+ * - {{current.product.title}} - Access current route data
24
+ * - {{user.name}} - Auto-resolved from combined data (backward compatible)
25
+ *
26
+ * @param content - The content string containing {{}} placeholders
27
+ * @param dataContext - The enhanced WeaverseDataContext with route-keyed data
28
+ * @returns The content with placeholders replaced by actual values
29
+ */
30
+ declare function replaceContentDataConnectors(content: string, dataContext: DataContext | null | undefined): string;
31
+ /**
32
+ * Recursively replaces data connector placeholders in any data structure
33
+ * Handles strings, objects, arrays, and nested combinations
34
+ *
35
+ * @param data - The data to process (string, object, array, or primitive)
36
+ * @param dataContext - The data context for replacements
37
+ * @param visited - Set to track visited objects for circular reference protection
38
+ * @returns The data with all string placeholders replaced
39
+ */
40
+ declare function replaceContentDataConnectorsDeep<T>(data: T, dataContext: DataContext | null | undefined, visited?: WeakSet<WeakKey>): T;
41
+
14
42
  declare function useWeaverse<T = Weaverse>(): T;
15
43
  declare let useItemInstance: (id?: string) => WeaverseItemStore | null;
16
44
  declare let useParentInstance: () => WeaverseItemStore | null;
@@ -32,4 +60,4 @@ type ItemComponentProps = {
32
60
  declare const useSafeExternalStore: (subscribe: any, getSnapshot: any, getServerSnapshot?: any) => any;
33
61
  declare let WeaverseRoot: react.MemoExoticComponent<({ context }: WeaverseRootPropsType) => react_jsx_runtime.JSX.Element | null>;
34
62
 
35
- export { type ItemComponentProps, WeaverseContext, WeaverseContextProvider, type WeaverseElementProps, WeaverseItemContext, WeaverseRoot, type WeaverseRootPropsType, useChildInstances, useItemInstance, useParentInstance, useSafeExternalStore, useWeaverse };
63
+ export { type ItemComponentProps, WeaverseContext, WeaverseContextProvider, type WeaverseElementProps, WeaverseItemContext, WeaverseRoot, type WeaverseRootPropsType, replaceContentDataConnectors, replaceContentDataConnectorsDeep, useChildInstances, useItemInstance, useParentInstance, useSafeExternalStore, useWeaverse };
package/dist/index.js CHANGED
@@ -34,6 +34,8 @@ __export(index_exports, {
34
34
  WeaverseContextProvider: () => WeaverseContextProvider,
35
35
  WeaverseItemContext: () => WeaverseItemContext,
36
36
  WeaverseRoot: () => WeaverseRoot,
37
+ replaceContentDataConnectors: () => replaceContentDataConnectors,
38
+ replaceContentDataConnectorsDeep: () => replaceContentDataConnectorsDeep,
37
39
  useChildInstances: () => useChildInstances,
38
40
  useItemInstance: () => useItemInstance,
39
41
  useParentInstance: () => useParentInstance,
@@ -52,6 +54,189 @@ var WeaverseItemContext = (0, import_react.createContext)({ id: "", parentId: ""
52
54
  // src/hooks.ts
53
55
  var import_core = require("@weaverse/core");
54
56
  var import_react2 = require("react");
57
+
58
+ // src/utils/data-connector.ts
59
+ var TEMPLATE_REGEX = /\{\{([^}]+)\}\}/g;
60
+ var ARRAY_INDEX_REGEX = /^(\w+)\[(\d+)\]$/;
61
+ function isSafePropertyName(key) {
62
+ return key !== "__proto__" && key !== "constructor" && key !== "prototype";
63
+ }
64
+ var templateCache = /* @__PURE__ */ new Map();
65
+ var MAX_CACHE_SIZE = 100;
66
+ var fallbackCache = /* @__PURE__ */ new Map();
67
+ var FALLBACK_CACHE_MAX_SIZE = 50;
68
+ function getNestedValue(obj, path, visited = /* @__PURE__ */ new WeakSet()) {
69
+ return path.split(".").reduce((current, key) => {
70
+ if (!current || typeof current !== "object") {
71
+ return;
72
+ }
73
+ if (visited.has(current)) {
74
+ console.warn("Circular reference detected in data connector path:", path);
75
+ return;
76
+ }
77
+ visited.add(current);
78
+ const arrayMatch = key.match(ARRAY_INDEX_REGEX);
79
+ if (arrayMatch) {
80
+ const [, arrayKey, index] = arrayMatch;
81
+ const arrayObj = current[arrayKey];
82
+ if (Array.isArray(arrayObj)) {
83
+ const indexNum = Number.parseInt(index, 10);
84
+ if (indexNum >= 0 && indexNum < arrayObj.length) {
85
+ return arrayObj[indexNum];
86
+ }
87
+ }
88
+ return;
89
+ }
90
+ if (!isSafePropertyName(key)) {
91
+ console.warn(`Unsafe property access attempted: ${key}`);
92
+ return;
93
+ }
94
+ return current !== null && key in current ? current[key] : void 0;
95
+ }, obj);
96
+ }
97
+ function sanitizeValue(value) {
98
+ if (value === null || value === void 0) {
99
+ return "";
100
+ }
101
+ const stringValue = String(value);
102
+ return stringValue.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;").replace(/\//g, "&#x2F;");
103
+ }
104
+ function createCacheKey(content, data) {
105
+ try {
106
+ const dataStr = JSON.stringify(data);
107
+ return `${content}:${dataStr.slice(0, 100)}`;
108
+ } catch {
109
+ const keys = Object.keys(data).sort().join(",");
110
+ return `${content}:keys:${keys}`;
111
+ }
112
+ }
113
+ function resolveDataFromContext(path, dataContext) {
114
+ if (!dataContext) {
115
+ return void 0;
116
+ }
117
+ const trimmedPath = path.trim();
118
+ const pathParts = trimmedPath.split(".");
119
+ const potentialRouteKey = pathParts[0];
120
+ if (dataContext[potentialRouteKey] && typeof dataContext[potentialRouteKey] === "object" && dataContext[potentialRouteKey] !== null) {
121
+ const remainingPath = pathParts.slice(1).join(".");
122
+ if (remainingPath) {
123
+ return getNestedValue(dataContext[potentialRouteKey], remainingPath);
124
+ }
125
+ return dataContext[potentialRouteKey];
126
+ }
127
+ const cachedResult = fallbackCache.get(trimmedPath);
128
+ if (cachedResult && dataContext[cachedResult.routeKey]) {
129
+ const value = getNestedValue(
130
+ dataContext[cachedResult.routeKey],
131
+ trimmedPath
132
+ );
133
+ if (value !== void 0) {
134
+ cachedResult.timestamp = Date.now();
135
+ return value;
136
+ }
137
+ }
138
+ const priorityRoutes = ["root", "routes/product", "routes/collection"];
139
+ const allRoutes = [
140
+ ...priorityRoutes,
141
+ ...Object.keys(dataContext).filter((k) => !priorityRoutes.includes(k))
142
+ ];
143
+ for (const routeKey of allRoutes) {
144
+ const routeData = dataContext[routeKey];
145
+ if (routeData && typeof routeData === "object" && routeData !== null) {
146
+ const value = getNestedValue(routeData, trimmedPath);
147
+ if (value !== void 0) {
148
+ if (fallbackCache.size >= FALLBACK_CACHE_MAX_SIZE) {
149
+ const entries = Array.from(fallbackCache.entries());
150
+ entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
151
+ const toRemove = Math.floor(entries.length * 0.25);
152
+ for (let i = 0; i < toRemove; i++) {
153
+ fallbackCache.delete(entries[i][0]);
154
+ }
155
+ }
156
+ fallbackCache.set(trimmedPath, {
157
+ routeKey,
158
+ value,
159
+ timestamp: Date.now()
160
+ });
161
+ return value;
162
+ }
163
+ }
164
+ }
165
+ return getNestedValue(dataContext, trimmedPath);
166
+ }
167
+ function replaceContentDataConnectors(content, dataContext) {
168
+ if (!dataContext || typeof content !== "string") {
169
+ return content;
170
+ }
171
+ try {
172
+ const cacheKey = createCacheKey(content, dataContext);
173
+ if (templateCache.has(cacheKey)) {
174
+ return templateCache.get(cacheKey);
175
+ }
176
+ const newContent = content.replace(TEMPLATE_REGEX, (match, path) => {
177
+ try {
178
+ const value = resolveDataFromContext(path, dataContext);
179
+ if (value === void 0 || value === null) {
180
+ return match;
181
+ }
182
+ return sanitizeValue(value);
183
+ } catch (pathError) {
184
+ console.warn(
185
+ `Error resolving data connector path "${path}":`,
186
+ pathError
187
+ );
188
+ return match;
189
+ }
190
+ });
191
+ if (templateCache.size >= MAX_CACHE_SIZE) {
192
+ const firstKey = templateCache.keys().next().value;
193
+ templateCache.delete(firstKey);
194
+ }
195
+ templateCache.set(cacheKey, newContent);
196
+ return newContent;
197
+ } catch (error) {
198
+ console.warn("Error processing data connectors:", error, { content });
199
+ return content;
200
+ }
201
+ }
202
+ function replaceContentDataConnectorsDeep(data, dataContext, visited = /* @__PURE__ */ new WeakSet()) {
203
+ if (!dataContext) {
204
+ return data;
205
+ }
206
+ if (typeof data === "string") {
207
+ return replaceContentDataConnectors(data, dataContext);
208
+ }
209
+ if (typeof data !== "object" || data === null) {
210
+ return data;
211
+ }
212
+ if (visited.has(data)) {
213
+ console.warn(
214
+ "Circular reference detected in deep data connector replacement"
215
+ );
216
+ return data;
217
+ }
218
+ visited.add(data);
219
+ try {
220
+ if (Array.isArray(data)) {
221
+ return data.map(
222
+ (item) => replaceContentDataConnectorsDeep(item, dataContext, visited)
223
+ );
224
+ }
225
+ const result = {};
226
+ for (const [key, value] of Object.entries(data)) {
227
+ ;
228
+ result[key] = replaceContentDataConnectorsDeep(value, dataContext, visited);
229
+ }
230
+ return result;
231
+ } catch (error) {
232
+ console.warn("Error in deep data connector replacement:", error);
233
+ return data;
234
+ } finally {
235
+ visited.delete(data);
236
+ }
237
+ }
238
+
239
+ // src/hooks.ts
55
240
  function useWeaverse() {
56
241
  let weaverse = (0, import_react2.useContext)(WeaverseContext);
57
242
  return weaverse;
@@ -189,8 +374,13 @@ var ItemComponent = (0, import_react3.memo)(({ instance }) => {
189
374
  __hidden,
190
375
  // Need to get rid of this `data` property
191
376
  data: _,
377
+ content,
192
378
  ...rest
193
379
  } = data;
380
+ if (content !== void 0 && content !== null) {
381
+ content = replaceContentDataConnectorsDeep(content, context.dataContext);
382
+ rest.content = content;
383
+ }
194
384
  (0, import_react3.useEffect)(() => {
195
385
  if (!instance.ref.current) {
196
386
  Object.assign(instance.ref, {
@@ -249,6 +439,8 @@ ItemInstance.displayName = "WeaverseInstanceProvider";
249
439
  WeaverseContextProvider,
250
440
  WeaverseItemContext,
251
441
  WeaverseRoot,
442
+ replaceContentDataConnectors,
443
+ replaceContentDataConnectorsDeep,
252
444
  useChildInstances,
253
445
  useItemInstance,
254
446
  useParentInstance,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/hooks.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\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","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'\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 ...rest\n } = data\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 undefined\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"]}
package/dist/index.mjs CHANGED
@@ -10,6 +10,189 @@ var WeaverseItemContext = createContext({ id: "", parentId: "" });
10
10
  // src/hooks.ts
11
11
  import { Weaverse } from "@weaverse/core";
12
12
  import { useContext } from "react";
13
+
14
+ // src/utils/data-connector.ts
15
+ var TEMPLATE_REGEX = /\{\{([^}]+)\}\}/g;
16
+ var ARRAY_INDEX_REGEX = /^(\w+)\[(\d+)\]$/;
17
+ function isSafePropertyName(key) {
18
+ return key !== "__proto__" && key !== "constructor" && key !== "prototype";
19
+ }
20
+ var templateCache = /* @__PURE__ */ new Map();
21
+ var MAX_CACHE_SIZE = 100;
22
+ var fallbackCache = /* @__PURE__ */ new Map();
23
+ var FALLBACK_CACHE_MAX_SIZE = 50;
24
+ function getNestedValue(obj, path, visited = /* @__PURE__ */ new WeakSet()) {
25
+ return path.split(".").reduce((current, key) => {
26
+ if (!current || typeof current !== "object") {
27
+ return;
28
+ }
29
+ if (visited.has(current)) {
30
+ console.warn("Circular reference detected in data connector path:", path);
31
+ return;
32
+ }
33
+ visited.add(current);
34
+ const arrayMatch = key.match(ARRAY_INDEX_REGEX);
35
+ if (arrayMatch) {
36
+ const [, arrayKey, index] = arrayMatch;
37
+ const arrayObj = current[arrayKey];
38
+ if (Array.isArray(arrayObj)) {
39
+ const indexNum = Number.parseInt(index, 10);
40
+ if (indexNum >= 0 && indexNum < arrayObj.length) {
41
+ return arrayObj[indexNum];
42
+ }
43
+ }
44
+ return;
45
+ }
46
+ if (!isSafePropertyName(key)) {
47
+ console.warn(`Unsafe property access attempted: ${key}`);
48
+ return;
49
+ }
50
+ return current !== null && key in current ? current[key] : void 0;
51
+ }, obj);
52
+ }
53
+ function sanitizeValue(value) {
54
+ if (value === null || value === void 0) {
55
+ return "";
56
+ }
57
+ const stringValue = String(value);
58
+ return stringValue.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;").replace(/\//g, "&#x2F;");
59
+ }
60
+ function createCacheKey(content, data) {
61
+ try {
62
+ const dataStr = JSON.stringify(data);
63
+ return `${content}:${dataStr.slice(0, 100)}`;
64
+ } catch {
65
+ const keys = Object.keys(data).sort().join(",");
66
+ return `${content}:keys:${keys}`;
67
+ }
68
+ }
69
+ function resolveDataFromContext(path, dataContext) {
70
+ if (!dataContext) {
71
+ return void 0;
72
+ }
73
+ const trimmedPath = path.trim();
74
+ const pathParts = trimmedPath.split(".");
75
+ const potentialRouteKey = pathParts[0];
76
+ if (dataContext[potentialRouteKey] && typeof dataContext[potentialRouteKey] === "object" && dataContext[potentialRouteKey] !== null) {
77
+ const remainingPath = pathParts.slice(1).join(".");
78
+ if (remainingPath) {
79
+ return getNestedValue(dataContext[potentialRouteKey], remainingPath);
80
+ }
81
+ return dataContext[potentialRouteKey];
82
+ }
83
+ const cachedResult = fallbackCache.get(trimmedPath);
84
+ if (cachedResult && dataContext[cachedResult.routeKey]) {
85
+ const value = getNestedValue(
86
+ dataContext[cachedResult.routeKey],
87
+ trimmedPath
88
+ );
89
+ if (value !== void 0) {
90
+ cachedResult.timestamp = Date.now();
91
+ return value;
92
+ }
93
+ }
94
+ const priorityRoutes = ["root", "routes/product", "routes/collection"];
95
+ const allRoutes = [
96
+ ...priorityRoutes,
97
+ ...Object.keys(dataContext).filter((k) => !priorityRoutes.includes(k))
98
+ ];
99
+ for (const routeKey of allRoutes) {
100
+ const routeData = dataContext[routeKey];
101
+ if (routeData && typeof routeData === "object" && routeData !== null) {
102
+ const value = getNestedValue(routeData, trimmedPath);
103
+ if (value !== void 0) {
104
+ if (fallbackCache.size >= FALLBACK_CACHE_MAX_SIZE) {
105
+ const entries = Array.from(fallbackCache.entries());
106
+ entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
107
+ const toRemove = Math.floor(entries.length * 0.25);
108
+ for (let i = 0; i < toRemove; i++) {
109
+ fallbackCache.delete(entries[i][0]);
110
+ }
111
+ }
112
+ fallbackCache.set(trimmedPath, {
113
+ routeKey,
114
+ value,
115
+ timestamp: Date.now()
116
+ });
117
+ return value;
118
+ }
119
+ }
120
+ }
121
+ return getNestedValue(dataContext, trimmedPath);
122
+ }
123
+ function replaceContentDataConnectors(content, dataContext) {
124
+ if (!dataContext || typeof content !== "string") {
125
+ return content;
126
+ }
127
+ try {
128
+ const cacheKey = createCacheKey(content, dataContext);
129
+ if (templateCache.has(cacheKey)) {
130
+ return templateCache.get(cacheKey);
131
+ }
132
+ const newContent = content.replace(TEMPLATE_REGEX, (match, path) => {
133
+ try {
134
+ const value = resolveDataFromContext(path, dataContext);
135
+ if (value === void 0 || value === null) {
136
+ return match;
137
+ }
138
+ return sanitizeValue(value);
139
+ } catch (pathError) {
140
+ console.warn(
141
+ `Error resolving data connector path "${path}":`,
142
+ pathError
143
+ );
144
+ return match;
145
+ }
146
+ });
147
+ if (templateCache.size >= MAX_CACHE_SIZE) {
148
+ const firstKey = templateCache.keys().next().value;
149
+ templateCache.delete(firstKey);
150
+ }
151
+ templateCache.set(cacheKey, newContent);
152
+ return newContent;
153
+ } catch (error) {
154
+ console.warn("Error processing data connectors:", error, { content });
155
+ return content;
156
+ }
157
+ }
158
+ function replaceContentDataConnectorsDeep(data, dataContext, visited = /* @__PURE__ */ new WeakSet()) {
159
+ if (!dataContext) {
160
+ return data;
161
+ }
162
+ if (typeof data === "string") {
163
+ return replaceContentDataConnectors(data, dataContext);
164
+ }
165
+ if (typeof data !== "object" || data === null) {
166
+ return data;
167
+ }
168
+ if (visited.has(data)) {
169
+ console.warn(
170
+ "Circular reference detected in deep data connector replacement"
171
+ );
172
+ return data;
173
+ }
174
+ visited.add(data);
175
+ try {
176
+ if (Array.isArray(data)) {
177
+ return data.map(
178
+ (item) => replaceContentDataConnectorsDeep(item, dataContext, visited)
179
+ );
180
+ }
181
+ const result = {};
182
+ for (const [key, value] of Object.entries(data)) {
183
+ ;
184
+ result[key] = replaceContentDataConnectorsDeep(value, dataContext, visited);
185
+ }
186
+ return result;
187
+ } catch (error) {
188
+ console.warn("Error in deep data connector replacement:", error);
189
+ return data;
190
+ } finally {
191
+ visited.delete(data);
192
+ }
193
+ }
194
+
195
+ // src/hooks.ts
13
196
  function useWeaverse() {
14
197
  let weaverse = useContext(WeaverseContext);
15
198
  return weaverse;
@@ -147,8 +330,13 @@ var ItemComponent = memo(({ instance }) => {
147
330
  __hidden,
148
331
  // Need to get rid of this `data` property
149
332
  data: _,
333
+ content,
150
334
  ...rest
151
335
  } = data;
336
+ if (content !== void 0 && content !== null) {
337
+ content = replaceContentDataConnectorsDeep(content, context.dataContext);
338
+ rest.content = content;
339
+ }
152
340
  useEffect(() => {
153
341
  if (!instance.ref.current) {
154
342
  Object.assign(instance.ref, {
@@ -206,6 +394,8 @@ export {
206
394
  WeaverseContextProvider,
207
395
  WeaverseItemContext,
208
396
  WeaverseRoot,
397
+ replaceContentDataConnectors,
398
+ replaceContentDataConnectorsDeep,
209
399
  useChildInstances,
210
400
  useItemInstance,
211
401
  useParentInstance,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/hooks.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\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","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'\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 ...rest\n } = data\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":";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;AAGpB,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,IAAAA,IAAG,MAAsB,cAAc,IAAIA,GAAE,CAAC,EACrD,OAAO,OAAO;AACnB;;;ACrCA,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;;;ADSU,cA8FG,YA9FH;AAsEJ;AAtHN,IAAI,eAAe,OAAa,eAAS,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;AAGpD,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,IAAI,eAAe,KAAK,CAAC,EAAE,QAAQ,MAA6B;AACrE,MAAI,OAAO;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,MAAI,UAAU,OAAoB,IAAI;AAEtC,YAAU,MAAM;AACd,YAAQ,qBAAqB,QAAQ;AAAA,EACvC,GAAG,CAAC,OAAO,CAAC;AAEZ,MAAI,gBAAgB,SAAS,cAAc,iBAAiB,CAAC;AAC7D,MAAI,aAAa,QAAQ,iBAAiB,MAAM;AAEhD,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,MAAI,UAAU,YAAY;AAC1B,MAAI,EAAE,kBAAkB,iBAAiB,aAAa,IAAI;AAC1D,MAAI,OAAO;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AACA,MAAI;AAAA,IACF;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,GAAG;AAAA,EACL,IAAI;AAEJ,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,MAAI,UAAU,gBAAgB,IAAI,IAAI;AAEtC,MAAI,SAAS,WAAW;AACtB,QAAI,YAAY,QAAQ;AACxB,cAAU,cAAc;AACxB,QACE,UAAU,aAAa,OAAO,IAAI,mBAAmB,KACrD,eAAe,IACf;AACA,WAAK,MAAM,SAAS;AAAA,IACtB;AACA,QAAI,kBACF,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,KAAK,MAAM;AAAA,QACb;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,IAAI,eAAe;AAAA,EACjB,CAAC,EAAE,IAAI,SAAS,MAAwC;AACtD,QAAI,WAAW,gBAAgB,EAAE;AACjC,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":["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 undefined\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"]}
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.4.2",
5
+ "version": "5.5.0-beta.1",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
8
8
  "typings": "dist/index.d.ts",
@@ -21,6 +21,13 @@
21
21
  "engines": {
22
22
  "node": ">=18"
23
23
  },
24
+ "scripts": {
25
+ "dev": "tsup --watch",
26
+ "build": "tsup",
27
+ "clean": "rimraf dist",
28
+ "test": "vitest --run",
29
+ "test:watch": "vitest --watch"
30
+ },
24
31
  "tsup": {
25
32
  "entry": [
26
33
  "src/index.ts"
@@ -35,14 +42,15 @@
35
42
  "outDir": "dist"
36
43
  },
37
44
  "dependencies": {
38
- "@weaverse/core": "5.4.2",
45
+ "@weaverse/core": "5.5.0-beta.1",
39
46
  "clsx": "^2.1.1",
40
47
  "react": ">=18",
41
48
  "react-dom": ">=18"
42
49
  },
43
- "scripts": {
44
- "dev": "tsup --watch",
45
- "build": "tsup",
46
- "clean": "rimraf dist"
50
+ "peerDependencies": {
51
+ "react-router": ">=6"
52
+ },
53
+ "devDependencies": {
54
+ "vitest": "^2.0.0"
47
55
  }
48
- }
56
+ }