@weaverse/next 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,265 @@
1
+ import { WeaverseElement, WeaverseResourcePickerData } from '@weaverse/react';
2
+ export { isBrowser, isIframe, useChildInstances, useItemInstance, useParentInstance, useWeaverse } from '@weaverse/react';
3
+ import { PageType, SchemaType } from '@weaverse/schema';
4
+ export { InspectorGroup, PageType, SchemaType, createSchema } from '@weaverse/schema';
5
+ import * as react from 'react';
6
+ import { ReactNode, ComponentType, ForwardRefExoticComponent } from 'react';
7
+ import * as react_jsx_runtime from 'react/jsx-runtime';
8
+
9
+ /**
10
+ * Locale/market info passed through to component loaders and the Storefront
11
+ * client. Kept structurally close to Hydrogen's `WeaverseI18n` but without the
12
+ * `@shopify/hydrogen` `I18nBase` dependency so the adapter stays framework
13
+ * neutral.
14
+ */
15
+ interface WeaverseNextI18n {
16
+ country?: string;
17
+ label?: string;
18
+ language?: string;
19
+ locale?: string;
20
+ pathPrefix?: string;
21
+ [key: string]: unknown;
22
+ }
23
+ /**
24
+ * Minimal Storefront client shape required by component loaders. The host app
25
+ * provides this (public or private token mode); Weaverse never owns it.
26
+ */
27
+ interface WeaverseNextStorefront {
28
+ i18n?: WeaverseNextI18n;
29
+ query: (query: string, options?: unknown) => Promise<unknown>;
30
+ [key: string]: unknown;
31
+ }
32
+ /**
33
+ * App-provided commerce context. `storefront` is the only v0 must-have; cart
34
+ * and customer-account stay app-owned and are passed through untouched.
35
+ */
36
+ interface WeaverseNextCommerceContext {
37
+ cart?: unknown;
38
+ customerAccount?: unknown;
39
+ storefront?: WeaverseNextStorefront;
40
+ [key: string]: unknown;
41
+ }
42
+ /**
43
+ * Explicit, framework-neutral replacement for React Router's
44
+ * `LoaderFunctionArgs`. Built by the Next route/page from params + headers +
45
+ * searchParams instead of an implicit loader context.
46
+ */
47
+ interface WeaverseNextRequestContext {
48
+ handle?: string;
49
+ headers?: Headers;
50
+ i18n?: WeaverseNextI18n;
51
+ isDesignMode?: boolean;
52
+ isPreviewMode?: boolean;
53
+ isRevisionPreview?: boolean;
54
+ pageType?: PageType;
55
+ pathname?: string;
56
+ searchParams?: URLSearchParams;
57
+ sectionType?: string;
58
+ url?: URL | string;
59
+ [key: string]: unknown;
60
+ }
61
+ /** A single serialized item in a Weaverse page tree. */
62
+ interface WeaverseNextComponentData {
63
+ children?: WeaverseNextComponentData[] | {
64
+ id: string;
65
+ }[];
66
+ data?: Record<string, unknown>;
67
+ id: string;
68
+ /** Attached by {@link runWeaverseComponentLoaders} after a loader runs. */
69
+ loaderData?: unknown;
70
+ type: string;
71
+ [key: string]: unknown;
72
+ }
73
+ /** Serialized page tree fetched from Weaverse. */
74
+ interface WeaverseNextPageData {
75
+ id: string;
76
+ items: WeaverseNextComponentData[];
77
+ name?: string;
78
+ rootId?: string;
79
+ [key: string]: unknown;
80
+ }
81
+ /**
82
+ * Top-level payload returned by `client.loadPage`. Kept close to Hydrogen's
83
+ * `WeaverseLoaderData` so registered components stay portable.
84
+ */
85
+ interface WeaverseNextLoaderData {
86
+ configs?: Record<string, unknown>;
87
+ page: WeaverseNextPageData;
88
+ pageAssignment?: Record<string, unknown>;
89
+ project?: Record<string, unknown>;
90
+ [key: string]: unknown;
91
+ }
92
+ /** Props injected into every registered Weaverse component. */
93
+ interface WeaverseNextComponentProps<L = unknown> extends Partial<WeaverseElement> {
94
+ children?: ReactNode;
95
+ className?: string;
96
+ loaderData?: L;
97
+ [key: string]: unknown;
98
+ }
99
+ /**
100
+ * Arguments passed to a component `loader`. `commerce.storefront` is the
101
+ * explicit contract; `weaverse.storefront` exists as a compatibility alias for
102
+ * Pilot-style loaders that call `weaverse.storefront.query(...)`.
103
+ */
104
+ interface WeaverseNextComponentLoaderArgs<TData = unknown> {
105
+ commerce?: WeaverseNextCommerceContext;
106
+ context?: WeaverseNextRequestContext;
107
+ data: TData;
108
+ weaverse: WeaverseNextClient;
109
+ }
110
+ /** Registered component module shape: `default` + `schema` + optional `loader`. */
111
+ interface WeaverseNextComponent<TProps extends WeaverseNextComponentProps = WeaverseNextComponentProps> {
112
+ default: ComponentType<TProps> | ForwardRefExoticComponent<TProps>;
113
+ loader?: (args: WeaverseNextComponentLoaderArgs) => Promise<unknown>;
114
+ schema: SchemaType;
115
+ }
116
+ /** Input for `client.loadPage`. The Next route maps `params` → `type/handle`. */
117
+ interface WeaverseNextLoadPageInput {
118
+ handle?: string;
119
+ locale?: string;
120
+ type?: PageType;
121
+ [key: string]: unknown;
122
+ }
123
+ interface WeaverseNextClientConfig {
124
+ commerce?: WeaverseNextCommerceContext;
125
+ components: WeaverseNextComponent[];
126
+ /**
127
+ * Injected page fetcher. v0 delegates network I/O to the host app so the
128
+ * adapter can be tested without real Weaverse API calls.
129
+ */
130
+ fetchPage?: (input: WeaverseNextLoadPageInput) => Promise<WeaverseNextLoaderData | null>;
131
+ /** Injected theme-settings fetcher. */
132
+ fetchThemeSettings?: (context?: WeaverseNextRequestContext) => Promise<unknown>;
133
+ projectId: string;
134
+ requestContext?: WeaverseNextRequestContext;
135
+ themeSchema?: unknown;
136
+ themeSettings?: Record<string, unknown>;
137
+ }
138
+ /**
139
+ * Request-safe client returned by {@link createWeaverseNextClient}. Holds the
140
+ * registry/config plus the currently loaded page data, and is the object passed
141
+ * to component loaders as `weaverse`.
142
+ */
143
+ interface WeaverseNextClient {
144
+ commerce?: WeaverseNextCommerceContext;
145
+ components: WeaverseNextComponent[];
146
+ /** Currently loaded page payload (set by `loadPage`). */
147
+ data: WeaverseNextLoaderData | null;
148
+ /** Data-connector context handed to the React renderer. */
149
+ dataContext: Record<string, unknown>;
150
+ loadPage: (input?: WeaverseNextLoadPageInput) => Promise<WeaverseNextLoaderData | null>;
151
+ loadThemeSettings: (context?: WeaverseNextRequestContext) => Promise<unknown>;
152
+ projectId: string;
153
+ requestContext?: WeaverseNextRequestContext;
154
+ /** Compatibility alias for `commerce.storefront`. */
155
+ storefront?: WeaverseNextStorefront;
156
+ themeSchema?: unknown;
157
+ themeSettings: Record<string, unknown>;
158
+ }
159
+ type WeaverseProduct = WeaverseResourcePickerData;
160
+ type WeaverseCollection = WeaverseResourcePickerData;
161
+
162
+ /**
163
+ * Create a {@link WeaverseNextClient} from explicit config.
164
+ *
165
+ * @example
166
+ * ```ts
167
+ * let client = createWeaverseNextClient({
168
+ * projectId: process.env.WEAVERSE_PROJECT_ID!,
169
+ * components,
170
+ * commerce: { storefront },
171
+ * fetchPage: async ({ type, handle }) => fetchWeaversePage({ type, handle }),
172
+ * })
173
+ * ```
174
+ */
175
+ declare function createWeaverseNextClient(config: WeaverseNextClientConfig): WeaverseNextClient;
176
+
177
+ /**
178
+ * Read explicit root/global data passed to the provider. Next-native
179
+ * replacement for `useRouteLoaderData('root')`.
180
+ */
181
+ declare function useWeaverseRootData<T = unknown>(): T;
182
+ /**
183
+ * Read explicit page/route commerce data passed to the provider. Next-native
184
+ * replacement for section-level `useLoaderData()`.
185
+ */
186
+ declare function useWeaversePageData<T = unknown>(): T;
187
+ /** Read the app-provided commerce context (storefront/cart/customer). */
188
+ declare function useWeaverseCommerce<T = WeaverseNextCommerceContext>(): T;
189
+ /**
190
+ * Read Weaverse theme settings. Next version backed by provider root/theme
191
+ * data (`client.themeSettings`), not the Hydrogen theme-settings store.
192
+ */
193
+ declare function useThemeSettings<T = Record<string, unknown>>(): T;
194
+
195
+ interface RunComponentLoadersArgs {
196
+ client: WeaverseNextClient;
197
+ commerce?: WeaverseNextCommerceContext;
198
+ context?: WeaverseNextRequestContext;
199
+ /** Page payload to walk; defaults to `client.data`. */
200
+ data?: WeaverseNextLoaderData | null;
201
+ }
202
+ /**
203
+ * Walk a serialized page tree and run each registered component's `loader`,
204
+ * attaching the result to the item as `loaderData`.
205
+ *
206
+ * Loaders receive explicit `commerce.storefront` (and `weaverse.storefront` as
207
+ * a compatibility alias via the client). Children are walked recursively when
208
+ * they are inline item objects; flat `items` arrays are covered by the
209
+ * top-level walk.
210
+ *
211
+ * @returns a cloned `data` object with `loaderData` attached to cloned items.
212
+ */
213
+ declare function runWeaverseComponentLoaders(args: RunComponentLoadersArgs): Promise<WeaverseNextLoaderData | null>;
214
+
215
+ interface WeaverseNextProviderProps {
216
+ children: ReactNode;
217
+ client?: WeaverseNextClient;
218
+ /** App-provided commerce context (storefront/cart/customer). */
219
+ commerce?: WeaverseNextCommerceContext;
220
+ /** Explicit page/route commerce data (replaces section-level `useLoaderData`). */
221
+ pageData?: unknown;
222
+ /** Explicit root/global data (replaces `useRouteLoaderData('root')`). */
223
+ rootData?: unknown;
224
+ /** Theme settings override; falls back to `client.themeSettings`. */
225
+ themeSettings?: Record<string, unknown>;
226
+ }
227
+ /**
228
+ * Client boundary that supplies explicit root/page/commerce data to Weaverse
229
+ * sections. Next-native replacement for `withWeaverse` + route loader data —
230
+ * no React Router route matches are emulated.
231
+ *
232
+ * In App Router, create/pass `client` only from a client component wrapper. A
233
+ * `WeaverseNextClient` contains functions and component references, so it is
234
+ * not serializable across a Server Component → Client Component boundary.
235
+ *
236
+ * @example
237
+ * ```tsx
238
+ * 'use client'
239
+ *
240
+ * <WeaverseNextProvider client={client} rootData={rootData} pageData={pageData} commerce={commerce}>
241
+ * <WeaverseNextRenderer />
242
+ * </WeaverseNextProvider>
243
+ * ```
244
+ */
245
+ declare function WeaverseNextProvider(props: WeaverseNextProviderProps): react_jsx_runtime.JSX.Element;
246
+
247
+ interface WeaverseNextRendererProps {
248
+ /** Client to render from. Defaults to the provider's client. */
249
+ client?: WeaverseNextClient;
250
+ /** Page payload to render. Defaults to `client.data`. */
251
+ data?: WeaverseNextLoaderData | null;
252
+ /** Data-connector context for `{{...}}` template replacement. */
253
+ dataContext?: Record<string, unknown>;
254
+ }
255
+ /**
256
+ * Render a serialized Weaverse page tree through `@weaverse/react` primitives.
257
+ *
258
+ * Reads the client/page data from {@link WeaverseNextContext} when no props are
259
+ * passed, or accepts an explicit `client` + `data` for standalone use. Builds a
260
+ * framework-neutral `Weaverse` core instance (no React Router hooks) and hands
261
+ * it to the shared `WeaverseRoot`.
262
+ */
263
+ declare const WeaverseNextRenderer: react.MemoExoticComponent<(props: WeaverseNextRendererProps) => react_jsx_runtime.JSX.Element | null>;
264
+
265
+ export { type RunComponentLoadersArgs, type WeaverseCollection, type WeaverseNextClient, type WeaverseNextClientConfig, type WeaverseNextCommerceContext, type WeaverseNextComponent, type WeaverseNextComponentData, type WeaverseNextComponentLoaderArgs, type WeaverseNextComponentProps, type WeaverseNextI18n, type WeaverseNextLoadPageInput, type WeaverseNextLoaderData, type WeaverseNextPageData, WeaverseNextProvider, type WeaverseNextProviderProps, WeaverseNextRenderer, type WeaverseNextRendererProps, type WeaverseNextRequestContext, type WeaverseNextStorefront, type WeaverseProduct, createWeaverseNextClient, runWeaverseComponentLoaders, useThemeSettings, useWeaverseCommerce, useWeaversePageData, useWeaverseRootData };
@@ -0,0 +1,265 @@
1
+ import { WeaverseElement, WeaverseResourcePickerData } from '@weaverse/react';
2
+ export { isBrowser, isIframe, useChildInstances, useItemInstance, useParentInstance, useWeaverse } from '@weaverse/react';
3
+ import { PageType, SchemaType } from '@weaverse/schema';
4
+ export { InspectorGroup, PageType, SchemaType, createSchema } from '@weaverse/schema';
5
+ import * as react from 'react';
6
+ import { ReactNode, ComponentType, ForwardRefExoticComponent } from 'react';
7
+ import * as react_jsx_runtime from 'react/jsx-runtime';
8
+
9
+ /**
10
+ * Locale/market info passed through to component loaders and the Storefront
11
+ * client. Kept structurally close to Hydrogen's `WeaverseI18n` but without the
12
+ * `@shopify/hydrogen` `I18nBase` dependency so the adapter stays framework
13
+ * neutral.
14
+ */
15
+ interface WeaverseNextI18n {
16
+ country?: string;
17
+ label?: string;
18
+ language?: string;
19
+ locale?: string;
20
+ pathPrefix?: string;
21
+ [key: string]: unknown;
22
+ }
23
+ /**
24
+ * Minimal Storefront client shape required by component loaders. The host app
25
+ * provides this (public or private token mode); Weaverse never owns it.
26
+ */
27
+ interface WeaverseNextStorefront {
28
+ i18n?: WeaverseNextI18n;
29
+ query: (query: string, options?: unknown) => Promise<unknown>;
30
+ [key: string]: unknown;
31
+ }
32
+ /**
33
+ * App-provided commerce context. `storefront` is the only v0 must-have; cart
34
+ * and customer-account stay app-owned and are passed through untouched.
35
+ */
36
+ interface WeaverseNextCommerceContext {
37
+ cart?: unknown;
38
+ customerAccount?: unknown;
39
+ storefront?: WeaverseNextStorefront;
40
+ [key: string]: unknown;
41
+ }
42
+ /**
43
+ * Explicit, framework-neutral replacement for React Router's
44
+ * `LoaderFunctionArgs`. Built by the Next route/page from params + headers +
45
+ * searchParams instead of an implicit loader context.
46
+ */
47
+ interface WeaverseNextRequestContext {
48
+ handle?: string;
49
+ headers?: Headers;
50
+ i18n?: WeaverseNextI18n;
51
+ isDesignMode?: boolean;
52
+ isPreviewMode?: boolean;
53
+ isRevisionPreview?: boolean;
54
+ pageType?: PageType;
55
+ pathname?: string;
56
+ searchParams?: URLSearchParams;
57
+ sectionType?: string;
58
+ url?: URL | string;
59
+ [key: string]: unknown;
60
+ }
61
+ /** A single serialized item in a Weaverse page tree. */
62
+ interface WeaverseNextComponentData {
63
+ children?: WeaverseNextComponentData[] | {
64
+ id: string;
65
+ }[];
66
+ data?: Record<string, unknown>;
67
+ id: string;
68
+ /** Attached by {@link runWeaverseComponentLoaders} after a loader runs. */
69
+ loaderData?: unknown;
70
+ type: string;
71
+ [key: string]: unknown;
72
+ }
73
+ /** Serialized page tree fetched from Weaverse. */
74
+ interface WeaverseNextPageData {
75
+ id: string;
76
+ items: WeaverseNextComponentData[];
77
+ name?: string;
78
+ rootId?: string;
79
+ [key: string]: unknown;
80
+ }
81
+ /**
82
+ * Top-level payload returned by `client.loadPage`. Kept close to Hydrogen's
83
+ * `WeaverseLoaderData` so registered components stay portable.
84
+ */
85
+ interface WeaverseNextLoaderData {
86
+ configs?: Record<string, unknown>;
87
+ page: WeaverseNextPageData;
88
+ pageAssignment?: Record<string, unknown>;
89
+ project?: Record<string, unknown>;
90
+ [key: string]: unknown;
91
+ }
92
+ /** Props injected into every registered Weaverse component. */
93
+ interface WeaverseNextComponentProps<L = unknown> extends Partial<WeaverseElement> {
94
+ children?: ReactNode;
95
+ className?: string;
96
+ loaderData?: L;
97
+ [key: string]: unknown;
98
+ }
99
+ /**
100
+ * Arguments passed to a component `loader`. `commerce.storefront` is the
101
+ * explicit contract; `weaverse.storefront` exists as a compatibility alias for
102
+ * Pilot-style loaders that call `weaverse.storefront.query(...)`.
103
+ */
104
+ interface WeaverseNextComponentLoaderArgs<TData = unknown> {
105
+ commerce?: WeaverseNextCommerceContext;
106
+ context?: WeaverseNextRequestContext;
107
+ data: TData;
108
+ weaverse: WeaverseNextClient;
109
+ }
110
+ /** Registered component module shape: `default` + `schema` + optional `loader`. */
111
+ interface WeaverseNextComponent<TProps extends WeaverseNextComponentProps = WeaverseNextComponentProps> {
112
+ default: ComponentType<TProps> | ForwardRefExoticComponent<TProps>;
113
+ loader?: (args: WeaverseNextComponentLoaderArgs) => Promise<unknown>;
114
+ schema: SchemaType;
115
+ }
116
+ /** Input for `client.loadPage`. The Next route maps `params` → `type/handle`. */
117
+ interface WeaverseNextLoadPageInput {
118
+ handle?: string;
119
+ locale?: string;
120
+ type?: PageType;
121
+ [key: string]: unknown;
122
+ }
123
+ interface WeaverseNextClientConfig {
124
+ commerce?: WeaverseNextCommerceContext;
125
+ components: WeaverseNextComponent[];
126
+ /**
127
+ * Injected page fetcher. v0 delegates network I/O to the host app so the
128
+ * adapter can be tested without real Weaverse API calls.
129
+ */
130
+ fetchPage?: (input: WeaverseNextLoadPageInput) => Promise<WeaverseNextLoaderData | null>;
131
+ /** Injected theme-settings fetcher. */
132
+ fetchThemeSettings?: (context?: WeaverseNextRequestContext) => Promise<unknown>;
133
+ projectId: string;
134
+ requestContext?: WeaverseNextRequestContext;
135
+ themeSchema?: unknown;
136
+ themeSettings?: Record<string, unknown>;
137
+ }
138
+ /**
139
+ * Request-safe client returned by {@link createWeaverseNextClient}. Holds the
140
+ * registry/config plus the currently loaded page data, and is the object passed
141
+ * to component loaders as `weaverse`.
142
+ */
143
+ interface WeaverseNextClient {
144
+ commerce?: WeaverseNextCommerceContext;
145
+ components: WeaverseNextComponent[];
146
+ /** Currently loaded page payload (set by `loadPage`). */
147
+ data: WeaverseNextLoaderData | null;
148
+ /** Data-connector context handed to the React renderer. */
149
+ dataContext: Record<string, unknown>;
150
+ loadPage: (input?: WeaverseNextLoadPageInput) => Promise<WeaverseNextLoaderData | null>;
151
+ loadThemeSettings: (context?: WeaverseNextRequestContext) => Promise<unknown>;
152
+ projectId: string;
153
+ requestContext?: WeaverseNextRequestContext;
154
+ /** Compatibility alias for `commerce.storefront`. */
155
+ storefront?: WeaverseNextStorefront;
156
+ themeSchema?: unknown;
157
+ themeSettings: Record<string, unknown>;
158
+ }
159
+ type WeaverseProduct = WeaverseResourcePickerData;
160
+ type WeaverseCollection = WeaverseResourcePickerData;
161
+
162
+ /**
163
+ * Create a {@link WeaverseNextClient} from explicit config.
164
+ *
165
+ * @example
166
+ * ```ts
167
+ * let client = createWeaverseNextClient({
168
+ * projectId: process.env.WEAVERSE_PROJECT_ID!,
169
+ * components,
170
+ * commerce: { storefront },
171
+ * fetchPage: async ({ type, handle }) => fetchWeaversePage({ type, handle }),
172
+ * })
173
+ * ```
174
+ */
175
+ declare function createWeaverseNextClient(config: WeaverseNextClientConfig): WeaverseNextClient;
176
+
177
+ /**
178
+ * Read explicit root/global data passed to the provider. Next-native
179
+ * replacement for `useRouteLoaderData('root')`.
180
+ */
181
+ declare function useWeaverseRootData<T = unknown>(): T;
182
+ /**
183
+ * Read explicit page/route commerce data passed to the provider. Next-native
184
+ * replacement for section-level `useLoaderData()`.
185
+ */
186
+ declare function useWeaversePageData<T = unknown>(): T;
187
+ /** Read the app-provided commerce context (storefront/cart/customer). */
188
+ declare function useWeaverseCommerce<T = WeaverseNextCommerceContext>(): T;
189
+ /**
190
+ * Read Weaverse theme settings. Next version backed by provider root/theme
191
+ * data (`client.themeSettings`), not the Hydrogen theme-settings store.
192
+ */
193
+ declare function useThemeSettings<T = Record<string, unknown>>(): T;
194
+
195
+ interface RunComponentLoadersArgs {
196
+ client: WeaverseNextClient;
197
+ commerce?: WeaverseNextCommerceContext;
198
+ context?: WeaverseNextRequestContext;
199
+ /** Page payload to walk; defaults to `client.data`. */
200
+ data?: WeaverseNextLoaderData | null;
201
+ }
202
+ /**
203
+ * Walk a serialized page tree and run each registered component's `loader`,
204
+ * attaching the result to the item as `loaderData`.
205
+ *
206
+ * Loaders receive explicit `commerce.storefront` (and `weaverse.storefront` as
207
+ * a compatibility alias via the client). Children are walked recursively when
208
+ * they are inline item objects; flat `items` arrays are covered by the
209
+ * top-level walk.
210
+ *
211
+ * @returns a cloned `data` object with `loaderData` attached to cloned items.
212
+ */
213
+ declare function runWeaverseComponentLoaders(args: RunComponentLoadersArgs): Promise<WeaverseNextLoaderData | null>;
214
+
215
+ interface WeaverseNextProviderProps {
216
+ children: ReactNode;
217
+ client?: WeaverseNextClient;
218
+ /** App-provided commerce context (storefront/cart/customer). */
219
+ commerce?: WeaverseNextCommerceContext;
220
+ /** Explicit page/route commerce data (replaces section-level `useLoaderData`). */
221
+ pageData?: unknown;
222
+ /** Explicit root/global data (replaces `useRouteLoaderData('root')`). */
223
+ rootData?: unknown;
224
+ /** Theme settings override; falls back to `client.themeSettings`. */
225
+ themeSettings?: Record<string, unknown>;
226
+ }
227
+ /**
228
+ * Client boundary that supplies explicit root/page/commerce data to Weaverse
229
+ * sections. Next-native replacement for `withWeaverse` + route loader data —
230
+ * no React Router route matches are emulated.
231
+ *
232
+ * In App Router, create/pass `client` only from a client component wrapper. A
233
+ * `WeaverseNextClient` contains functions and component references, so it is
234
+ * not serializable across a Server Component → Client Component boundary.
235
+ *
236
+ * @example
237
+ * ```tsx
238
+ * 'use client'
239
+ *
240
+ * <WeaverseNextProvider client={client} rootData={rootData} pageData={pageData} commerce={commerce}>
241
+ * <WeaverseNextRenderer />
242
+ * </WeaverseNextProvider>
243
+ * ```
244
+ */
245
+ declare function WeaverseNextProvider(props: WeaverseNextProviderProps): react_jsx_runtime.JSX.Element;
246
+
247
+ interface WeaverseNextRendererProps {
248
+ /** Client to render from. Defaults to the provider's client. */
249
+ client?: WeaverseNextClient;
250
+ /** Page payload to render. Defaults to `client.data`. */
251
+ data?: WeaverseNextLoaderData | null;
252
+ /** Data-connector context for `{{...}}` template replacement. */
253
+ dataContext?: Record<string, unknown>;
254
+ }
255
+ /**
256
+ * Render a serialized Weaverse page tree through `@weaverse/react` primitives.
257
+ *
258
+ * Reads the client/page data from {@link WeaverseNextContext} when no props are
259
+ * passed, or accepts an explicit `client` + `data` for standalone use. Builds a
260
+ * framework-neutral `Weaverse` core instance (no React Router hooks) and hands
261
+ * it to the shared `WeaverseRoot`.
262
+ */
263
+ declare const WeaverseNextRenderer: react.MemoExoticComponent<(props: WeaverseNextRendererProps) => react_jsx_runtime.JSX.Element | null>;
264
+
265
+ export { type RunComponentLoadersArgs, type WeaverseCollection, type WeaverseNextClient, type WeaverseNextClientConfig, type WeaverseNextCommerceContext, type WeaverseNextComponent, type WeaverseNextComponentData, type WeaverseNextComponentLoaderArgs, type WeaverseNextComponentProps, type WeaverseNextI18n, type WeaverseNextLoadPageInput, type WeaverseNextLoaderData, type WeaverseNextPageData, WeaverseNextProvider, type WeaverseNextProviderProps, WeaverseNextRenderer, type WeaverseNextRendererProps, type WeaverseNextRequestContext, type WeaverseNextStorefront, type WeaverseProduct, createWeaverseNextClient, runWeaverseComponentLoaders, useThemeSettings, useWeaverseCommerce, useWeaversePageData, useWeaverseRootData };
package/dist/index.js ADDED
@@ -0,0 +1,324 @@
1
+ 'use strict';
2
+
3
+ var react = require('@weaverse/react');
4
+ var schema = require('@weaverse/schema');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var react$1 = require('react');
7
+
8
+ // src/index.ts
9
+
10
+ // src/utils.ts
11
+ function generateDataFromSchema(schema) {
12
+ let data = {};
13
+ if (!schema) {
14
+ return data;
15
+ }
16
+ let groups = schema.settings ?? schema.inspector ?? [];
17
+ for (let group of groups) {
18
+ for (let input of group?.inputs ?? []) {
19
+ let { name, defaultValue } = input;
20
+ if (name && defaultValue !== null && defaultValue !== void 0) {
21
+ data[name] = defaultValue;
22
+ }
23
+ }
24
+ }
25
+ return data;
26
+ }
27
+
28
+ // src/item.ts
29
+ var WeaverseNextItem = class extends react.WeaverseItemStore {
30
+ constructor(initialData, weaverse) {
31
+ super(initialData, weaverse);
32
+ let { data, ...rest } = initialData;
33
+ let schemaData = generateDataFromSchema(this.Element?.schema);
34
+ Object.assign(this._store, schemaData, data, rest);
35
+ }
36
+ };
37
+ function ensureNextItemConstructor() {
38
+ if (!react.Weaverse.ItemConstructor || react.Weaverse.ItemConstructor === react.WeaverseItemStore || react.Weaverse.ItemConstructor === WeaverseNextItem) {
39
+ react.Weaverse.ItemConstructor = WeaverseNextItem;
40
+ }
41
+ }
42
+ function Main(props) {
43
+ let { children, loaderData, ...rest } = props;
44
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, children });
45
+ }
46
+ Main.displayName = "main";
47
+ var mainSchema = schema.createSchema({
48
+ type: "main",
49
+ title: "Main"
50
+ });
51
+ var defaultMainComponent = {
52
+ default: Main,
53
+ schema: mainSchema
54
+ };
55
+
56
+ // src/registry.ts
57
+ var MAIN_TYPE = "main";
58
+ var registeredComponentTypes = /* @__PURE__ */ new Set();
59
+ function registerWeaverseNextComponents(components) {
60
+ ensureNextItemConstructor();
61
+ let hasUserMain = components.some(
62
+ (component) => component.schema?.type === MAIN_TYPE
63
+ );
64
+ let effectiveComponents = hasUserMain ? components : [defaultMainComponent, ...components];
65
+ for (let component of effectiveComponents) {
66
+ let type = component.schema.type;
67
+ let element = {
68
+ type,
69
+ Component: component.default,
70
+ schema: component.schema,
71
+ loader: component.loader
72
+ };
73
+ if (type === MAIN_TYPE && hasUserMain) {
74
+ react.Weaverse.elementRegistry.set(type, element);
75
+ registeredComponentTypes.add(type);
76
+ continue;
77
+ }
78
+ if (type && !registeredComponentTypes.has(type)) {
79
+ react.Weaverse.registerElement(element);
80
+ registeredComponentTypes.add(type);
81
+ }
82
+ }
83
+ }
84
+
85
+ // src/client.ts
86
+ var NextClient = class {
87
+ projectId;
88
+ components;
89
+ themeSchema;
90
+ themeSettings;
91
+ requestContext;
92
+ commerce;
93
+ data = null;
94
+ dataContext = {};
95
+ _fetchPage;
96
+ _fetchThemeSettings;
97
+ constructor(config) {
98
+ this.projectId = config.projectId;
99
+ this.components = config.components;
100
+ registerWeaverseNextComponents(this.components);
101
+ this.themeSchema = config.themeSchema;
102
+ this.themeSettings = {
103
+ ...generateDataFromSchema(config.themeSchema),
104
+ ...config.themeSettings
105
+ };
106
+ this.requestContext = config.requestContext;
107
+ this.commerce = config.commerce;
108
+ this._fetchPage = config.fetchPage;
109
+ this._fetchThemeSettings = config.fetchThemeSettings;
110
+ }
111
+ /** Compatibility alias so loaders can call `weaverse.storefront.query(...)`. */
112
+ get storefront() {
113
+ return this.commerce?.storefront;
114
+ }
115
+ loadPage = (input = {}) => {
116
+ if (!this._fetchPage) {
117
+ throw new Error(
118
+ "[WeaverseNextClient] loadPage requires a `fetchPage` function in client config."
119
+ );
120
+ }
121
+ return this._fetchPage(input);
122
+ };
123
+ loadThemeSettings = (context) => {
124
+ if (!this._fetchThemeSettings) {
125
+ throw new Error(
126
+ "[WeaverseNextClient] loadThemeSettings requires a `fetchThemeSettings` function in client config."
127
+ );
128
+ }
129
+ return this._fetchThemeSettings(context ?? this.requestContext);
130
+ };
131
+ };
132
+ function createWeaverseNextClient(config) {
133
+ return new NextClient(config);
134
+ }
135
+ var WeaverseNextContext = react$1.createContext(null);
136
+ function WeaverseNextProvider(props) {
137
+ let { children, client, rootData, pageData, commerce, themeSettings } = props;
138
+ let value = react$1.useMemo(
139
+ () => ({
140
+ client,
141
+ rootData,
142
+ pageData,
143
+ commerce: commerce ?? client?.commerce,
144
+ themeSettings: themeSettings ?? client?.themeSettings ?? {}
145
+ }),
146
+ [client, rootData, pageData, commerce, themeSettings]
147
+ );
148
+ return /* @__PURE__ */ jsxRuntime.jsx(WeaverseNextContext.Provider, { value, children });
149
+ }
150
+
151
+ // src/hooks.ts
152
+ var OUTSIDE_PROVIDER_ERROR = "must be used inside a <WeaverseNextProvider>.";
153
+ function useWeaverseNextContext(hookName) {
154
+ let context = react$1.useContext(WeaverseNextContext);
155
+ if (!context) {
156
+ throw new Error(`[@weaverse/next] ${hookName} ${OUTSIDE_PROVIDER_ERROR}`);
157
+ }
158
+ return context;
159
+ }
160
+ function useWeaverseRootData() {
161
+ return useWeaverseNextContext("useWeaverseRootData").rootData;
162
+ }
163
+ function useWeaversePageData() {
164
+ return useWeaverseNextContext("useWeaversePageData").pageData;
165
+ }
166
+ function useWeaverseCommerce() {
167
+ return useWeaverseNextContext("useWeaverseCommerce").commerce;
168
+ }
169
+ function useThemeSettings() {
170
+ return useWeaverseNextContext("useThemeSettings").themeSettings;
171
+ }
172
+
173
+ // src/loader.ts
174
+ function isItemNode(node) {
175
+ return typeof node === "object" && node !== null && typeof node.type === "string";
176
+ }
177
+ function cloneItem(item) {
178
+ return {
179
+ ...item,
180
+ children: Array.isArray(item.children) ? item.children.map(
181
+ (child) => isItemNode(child) ? cloneItem(child) : { ...child }
182
+ ) : item.children
183
+ };
184
+ }
185
+ async function runWeaverseComponentLoaders(args) {
186
+ let { client, context, commerce } = args;
187
+ let sourceData = args.data ?? client.data;
188
+ if (!sourceData) {
189
+ return null;
190
+ }
191
+ if (!sourceData.page.items.length) {
192
+ return sourceData;
193
+ }
194
+ let data = {
195
+ ...sourceData,
196
+ page: {
197
+ ...sourceData.page,
198
+ items: sourceData.page.items.map(cloneItem)
199
+ }
200
+ };
201
+ let items = data.page.items;
202
+ let componentMap = /* @__PURE__ */ new Map();
203
+ for (let component of client.components) {
204
+ if (component?.schema?.type) {
205
+ componentMap.set(component.schema.type, component);
206
+ }
207
+ }
208
+ let visited = /* @__PURE__ */ new Set();
209
+ let resolvedContext = context ?? client.requestContext;
210
+ let resolvedCommerce = commerce ?? client.commerce;
211
+ let resolvedWeaverse = resolvedCommerce === client.commerce ? client : {
212
+ ...client,
213
+ commerce: resolvedCommerce,
214
+ storefront: resolvedCommerce?.storefront
215
+ };
216
+ async function walk(nodes) {
217
+ for (let item of nodes) {
218
+ if (!item || visited.has(item.id)) {
219
+ continue;
220
+ }
221
+ visited.add(item.id);
222
+ let component = componentMap.get(item.type);
223
+ if (component?.loader) {
224
+ try {
225
+ item.loaderData = await component.loader({
226
+ data: { ...generateDataFromSchema(component.schema), ...item.data },
227
+ weaverse: resolvedWeaverse,
228
+ context: resolvedContext,
229
+ commerce: resolvedCommerce
230
+ });
231
+ } catch (error) {
232
+ console.warn("\u274C Item loader run failed.", item.type, item.id, error);
233
+ }
234
+ }
235
+ let children = item.children;
236
+ if (Array.isArray(children)) {
237
+ let inlineChildren = children.filter(
238
+ isItemNode
239
+ );
240
+ if (inlineChildren.length) {
241
+ await walk(inlineChildren);
242
+ }
243
+ }
244
+ }
245
+ }
246
+ await walk(items);
247
+ return data;
248
+ }
249
+ var EMPTY_DATA_CONTEXT = {};
250
+ function getRenderablePage(data) {
251
+ let page = data?.page;
252
+ if (!page) {
253
+ return null;
254
+ }
255
+ let rootId = page.rootId ?? page.items.find((item) => item.type === "main")?.id ?? page.items[0]?.id ?? page.id;
256
+ return { ...page, rootId };
257
+ }
258
+ var WeaverseNextRenderer = react$1.memo(function WeaverseNextRendererComponent(props) {
259
+ let context = react$1.useContext(WeaverseNextContext);
260
+ let client = props.client ?? context?.client;
261
+ let data = props.data ?? client?.data ?? null;
262
+ let dataContext = props.dataContext ?? client?.dataContext ?? EMPTY_DATA_CONTEXT;
263
+ let page = react$1.useMemo(() => getRenderablePage(data), [data]);
264
+ let weaverse = react$1.useMemo(() => {
265
+ if (!page) {
266
+ return null;
267
+ }
268
+ let instance = new react.Weaverse({
269
+ projectId: client?.projectId || page.id || "weaverse-next",
270
+ data: page
271
+ });
272
+ instance.dataContext = dataContext;
273
+ instance.isDesignMode = client?.requestContext?.isDesignMode ?? false;
274
+ return instance;
275
+ }, [
276
+ client?.projectId,
277
+ client?.requestContext?.isDesignMode,
278
+ page,
279
+ dataContext
280
+ ]);
281
+ if (!weaverse) {
282
+ return null;
283
+ }
284
+ return /* @__PURE__ */ jsxRuntime.jsx(react.WeaverseRoot, { context: weaverse });
285
+ });
286
+
287
+ Object.defineProperty(exports, "isBrowser", {
288
+ enumerable: true,
289
+ get: function () { return react.isBrowser; }
290
+ });
291
+ Object.defineProperty(exports, "isIframe", {
292
+ enumerable: true,
293
+ get: function () { return react.isIframe; }
294
+ });
295
+ Object.defineProperty(exports, "useChildInstances", {
296
+ enumerable: true,
297
+ get: function () { return react.useChildInstances; }
298
+ });
299
+ Object.defineProperty(exports, "useItemInstance", {
300
+ enumerable: true,
301
+ get: function () { return react.useItemInstance; }
302
+ });
303
+ Object.defineProperty(exports, "useParentInstance", {
304
+ enumerable: true,
305
+ get: function () { return react.useParentInstance; }
306
+ });
307
+ Object.defineProperty(exports, "useWeaverse", {
308
+ enumerable: true,
309
+ get: function () { return react.useWeaverse; }
310
+ });
311
+ Object.defineProperty(exports, "createSchema", {
312
+ enumerable: true,
313
+ get: function () { return schema.createSchema; }
314
+ });
315
+ exports.WeaverseNextProvider = WeaverseNextProvider;
316
+ exports.WeaverseNextRenderer = WeaverseNextRenderer;
317
+ exports.createWeaverseNextClient = createWeaverseNextClient;
318
+ exports.runWeaverseComponentLoaders = runWeaverseComponentLoaders;
319
+ exports.useThemeSettings = useThemeSettings;
320
+ exports.useWeaverseCommerce = useWeaverseCommerce;
321
+ exports.useWeaversePageData = useWeaversePageData;
322
+ exports.useWeaverseRootData = useWeaverseRootData;
323
+ //# sourceMappingURL=index.js.map
324
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/item.ts","../src/main.tsx","../src/registry.ts","../src/client.ts","../src/provider.tsx","../src/hooks.ts","../src/loader.ts","../src/renderer.tsx"],"names":["WeaverseItemStore","Weaverse","jsx","createSchema","createContext","useMemo","useContext","memo","WeaverseRoot"],"mappings":";;;;;;;;;;AAUO,SAAS,uBACd,MAAA,EACyB;AACzB,EAAA,IAAI,OAAgC,EAAC;AACrC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAA,GACD,MAAA,CAAO,QAAA,IAGP,MAAA,CAAyC,aAC1C,EAAC;AAEH,EAAA,KAAA,IAAS,SAAS,MAAA,EAAQ;AACxB,IAAA,KAAA,IAAS,KAAA,IAAS,KAAA,EAAO,MAAA,IAAU,EAAC,EAAG;AACrC,MAAA,IAAI,EAAE,IAAA,EAAM,YAAA,EAAa,GAAI,KAAA;AAC7B,MAAA,IAAI,IAAA,IAAQ,YAAA,KAAiB,IAAA,IAAQ,YAAA,KAAiB,MAAA,EAAW;AAC/D,QAAA,IAAA,CAAK,IAAI,CAAA,GAAI,YAAA;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;;;ACzBO,IAAM,gBAAA,GAAN,cAA+BA,uBAAA,CAAkB;AAAA,EACtD,WAAA,CAAY,aAAwC,QAAA,EAAoB;AACtE,IAAA,KAAA,CAAM,aAA4B,QAAQ,CAAA;AAC1C,IAAA,IAAI,EAAE,IAAA,EAAM,GAAG,IAAA,EAAK,GAAI,WAAA;AACxB,IAAA,IAAI,UAAA,GAAa,sBAAA,CAAuB,IAAA,CAAK,OAAA,EAAS,MAAM,CAAA;AAC5D,IAAA,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,UAAA,EAAY,MAAM,IAAI,CAAA;AAAA,EACnD;AACF,CAAA;AAMO,SAAS,yBAAA,GAA4B;AAC1C,EAAA,IACE,CAACC,eAAS,eAAA,IACVA,cAAA,CAAS,oBAAoBD,uBAAA,IAC7BC,cAAA,CAAS,oBAAoB,gBAAA,EAC7B;AACA,IAAAA,cAAA,CAAS,eAAA,GAAkB,gBAAA;AAAA,EAC7B;AACF;ACbA,SAAS,KACP,KAAA,EAGA;AACA,EAAA,IAAI,EAAE,QAAA,EAAU,UAAA,EAAY,GAAG,MAAK,GAAI,KAAA;AAGxC,EAAA,uBAAOC,cAAA,CAAC,KAAA,EAAA,EAAK,GAAI,IAAA,EAA0C,QAAA,EAAS,CAAA;AACtE;AACA,IAAA,CAAK,WAAA,GAAc,MAAA;AAGZ,IAAM,aAAyBC,mBAAA,CAAa;AAAA,EACjD,IAAA,EAAM,MAAA;AAAA,EACN,KAAA,EAAO;AACT,CAAC,CAAA;AAOM,IAAM,oBAAA,GAA8C;AAAA,EACzD,OAAA,EAAS,IAAA;AAAA,EACT,MAAA,EAAQ;AACV,CAAA;;;ACvCA,IAAM,SAAA,GAAY,MAAA;AAOlB,IAAM,wBAAA,uBAA+B,GAAA,EAAY;AAc1C,SAAS,+BACd,UAAA,EACA;AACA,EAAA,yBAAA,EAA0B;AAE1B,EAAA,IAAI,cAAc,UAAA,CAAW,IAAA;AAAA,IAC3B,CAAC,SAAA,KAAc,SAAA,CAAU,MAAA,EAAQ,IAAA,KAAS;AAAA,GAC5C;AACA,EAAA,IAAI,sBAAsB,WAAA,GACtB,UAAA,GACA,CAAC,oBAAA,EAAsB,GAAG,UAAU,CAAA;AAExC,EAAA,KAAA,IAAS,aAAa,mBAAA,EAAqB;AACzC,IAAA,IAAI,IAAA,GAAO,UAAU,MAAA,CAAO,IAAA;AAC5B,IAAA,IAAI,OAAA,GAAU;AAAA,MACZ,IAAA;AAAA,MACA,WAAW,SAAA,CAAU,OAAA;AAAA,MACrB,QAAQ,SAAA,CAAU,MAAA;AAAA,MAClB,QAAQ,SAAA,CAAU;AAAA,KACpB;AAEA,IAAA,IAAI,IAAA,KAAS,aAAa,WAAA,EAAa;AAKrC,MAAAF,cAAAA,CAAS,eAAA,CAAgB,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AAC1C,MAAA,wBAAA,CAAyB,IAAI,IAAI,CAAA;AACjC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,IAAQ,CAAC,wBAAA,CAAyB,GAAA,CAAI,IAAI,CAAA,EAAG;AAC/C,MAAAA,cAAAA,CAAS,gBAAgB,OAAO,CAAA;AAChC,MAAA,wBAAA,CAAyB,IAAI,IAAI,CAAA;AAAA,IACnC;AAAA,EACF;AACF;;;ACvCA,IAAM,aAAN,MAA+C;AAAA,EAC7C,SAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA,GAAsC,IAAA;AAAA,EACtC,cAAuC,EAAC;AAAA,EAEvB,UAAA;AAAA,EACA,mBAAA;AAAA,EAEjB,YAAY,MAAA,EAAkC;AAC5C,IAAA,IAAA,CAAK,YAAY,MAAA,CAAO,SAAA;AACxB,IAAA,IAAA,CAAK,aAAa,MAAA,CAAO,UAAA;AACzB,IAAA,8BAAA,CAA+B,KAAK,UAAU,CAAA;AAC9C,IAAA,IAAA,CAAK,cAAc,MAAA,CAAO,WAAA;AAK1B,IAAA,IAAA,CAAK,aAAA,GAAgB;AAAA,MACnB,GAAG,sBAAA,CAAuB,MAAA,CAAO,WAAqC,CAAA;AAAA,MACtE,GAAG,MAAA,CAAO;AAAA,KACZ;AACA,IAAA,IAAA,CAAK,iBAAiB,MAAA,CAAO,cAAA;AAC7B,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,QAAA;AACvB,IAAA,IAAA,CAAK,aAAa,MAAA,CAAO,SAAA;AACzB,IAAA,IAAA,CAAK,sBAAsB,MAAA,CAAO,kBAAA;AAAA,EACpC;AAAA;AAAA,EAGA,IAAI,UAAA,GAAiD;AACnD,IAAA,OAAO,KAAK,QAAA,EAAU,UAAA;AAAA,EACxB;AAAA,EAEA,QAAA,GAAW,CACT,KAAA,GAAmC,EAAC,KACO;AAC3C,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO,IAAA,CAAK,WAAW,KAAK,CAAA;AAAA,EAC9B,CAAA;AAAA,EAEA,iBAAA,GAAoB,CAClB,OAAA,KACqB;AACrB,IAAA,IAAI,CAAC,KAAK,mBAAA,EAAqB;AAC7B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO,IAAA,CAAK,mBAAA,CAAoB,OAAA,IAAW,IAAA,CAAK,cAAc,CAAA;AAAA,EAChE,CAAA;AACF,CAAA;AAeO,SAAS,yBACd,MAAA,EACoB;AACpB,EAAA,OAAO,IAAI,WAAW,MAAM,CAAA;AAC9B;AC9EO,IAAM,mBAAA,GACXG,sBAA+C,IAAI,CAAA;AAiC9C,SAAS,qBAAqB,KAAA,EAAkC;AACrE,EAAA,IAAI,EAAE,QAAA,EAAU,MAAA,EAAQ,UAAU,QAAA,EAAU,QAAA,EAAU,eAAc,GAAI,KAAA;AAExE,EAAA,IAAI,KAAA,GAAQC,eAAA;AAAA,IACV,OAAO;AAAA,MACL,MAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA,EAAU,YAAY,MAAA,EAAQ,QAAA;AAAA,MAC9B,aAAA,EAAe,aAAA,IAAiB,MAAA,EAAQ,aAAA,IAAiB;AAAC,KAC5D,CAAA;AAAA,IACA,CAAC,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,UAAU,aAAa;AAAA,GACtD;AAEA,EAAA,uBACEH,cAAAA,CAAC,mBAAA,CAAoB,QAAA,EAApB,EAA6B,OAC3B,QAAA,EACH,CAAA;AAEJ;;;ACrEA,IAAM,sBAAA,GAAyB,+CAAA;AAE/B,SAAS,uBAAuB,QAAA,EAAkB;AAChD,EAAA,IAAI,OAAA,GAAUI,mBAAW,mBAAmB,CAAA;AAC5C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,QAAQ,CAAA,CAAA,EAAI,sBAAsB,CAAA,CAAE,CAAA;AAAA,EAC1E;AACA,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,mBAAA,GAAsC;AACpD,EAAA,OAAO,sBAAA,CAAuB,qBAAqB,CAAA,CAAE,QAAA;AACvD;AAMO,SAAS,mBAAA,GAAsC;AACpD,EAAA,OAAO,sBAAA,CAAuB,qBAAqB,CAAA,CAAE,QAAA;AACvD;AAGO,SAAS,mBAAA,GAA0D;AACxE,EAAA,OAAO,sBAAA,CAAuB,qBAAqB,CAAA,CAAE,QAAA;AACvD;AAMO,SAAS,gBAAA,GAAmD;AACjE,EAAA,OAAO,sBAAA,CAAuB,kBAAkB,CAAA,CAAE,aAAA;AACpD;;;ACzBA,SAAS,WAAW,IAAA,EAAkD;AACpE,EAAA,OACE,OAAO,IAAA,KAAS,QAAA,IAChB,SAAS,IAAA,IACT,OAAQ,KAAmC,IAAA,KAAS,QAAA;AAExD;AAEA,SAAS,UAAU,IAAA,EAA4D;AAC7E,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,UAAU,KAAA,CAAM,OAAA,CAAQ,KAAK,QAAQ,CAAA,GACjC,KAAK,QAAA,CAAS,GAAA;AAAA,MAAI,CAAC,KAAA,KACjB,UAAA,CAAW,KAAK,CAAA,GAAI,UAAU,KAAK,CAAA,GAAI,EAAE,GAAG,KAAA;AAAM,QAEpD,IAAA,CAAK;AAAA,GACX;AACF;AAaA,eAAsB,4BACpB,IAAA,EACwC;AACxC,EAAA,IAAI,EAAE,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAS,GAAI,IAAA;AACpC,EAAA,IAAI,UAAA,GAAa,IAAA,CAAK,IAAA,IAAQ,MAAA,CAAO,IAAA;AACrC,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,KAAA,CAAM,MAAA,EAAQ;AACjC,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,IAAI,IAAA,GAA+B;AAAA,IACjC,GAAG,UAAA;AAAA,IACH,IAAA,EAAM;AAAA,MACJ,GAAG,UAAA,CAAW,IAAA;AAAA,MACd,KAAA,EAAO,UAAA,CAAW,IAAA,CAAK,KAAA,CAAM,IAAI,SAAS;AAAA;AAC5C,GACF;AACA,EAAA,IAAI,KAAA,GAAQ,KAAK,IAAA,CAAK,KAAA;AAEtB,EAAA,IAAI,YAAA,uBAAmB,GAAA,EAAmC;AAC1D,EAAA,KAAA,IAAS,SAAA,IAAa,OAAO,UAAA,EAAY;AACvC,IAAA,IAAI,SAAA,EAAW,QAAQ,IAAA,EAAM;AAC3B,MAAA,YAAA,CAAa,GAAA,CAAI,SAAA,CAAU,MAAA,CAAO,IAAA,EAAM,SAAS,CAAA;AAAA,IACnD;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,uBAAc,GAAA,EAAY;AAC9B,EAAA,IAAI,eAAA,GAAkB,WAAW,MAAA,CAAO,cAAA;AACxC,EAAA,IAAI,gBAAA,GAAmB,YAAY,MAAA,CAAO,QAAA;AAQ1C,EAAA,IAAI,gBAAA,GACF,gBAAA,KAAqB,MAAA,CAAO,QAAA,GACxB,MAAA,GACA;AAAA,IACE,GAAG,MAAA;AAAA,IACH,QAAA,EAAU,gBAAA;AAAA,IACV,YAAY,gBAAA,EAAkB;AAAA,GAChC;AAEN,EAAA,eAAe,KAAK,KAAA,EAAoC;AACtD,IAAA,KAAA,IAAS,QAAQ,KAAA,EAAO;AACtB,MAAA,IAAI,CAAC,IAAA,IAAQ,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG;AACjC,QAAA;AAAA,MACF;AACA,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,EAAE,CAAA;AAEnB,MAAA,IAAI,SAAA,GAAY,YAAA,CAAa,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAC1C,MAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,QAAA,IAAI;AACF,UAAA,IAAA,CAAK,UAAA,GAAa,MAAM,SAAA,CAAU,MAAA,CAAO;AAAA,YACvC,IAAA,EAAM,EAAE,GAAG,sBAAA,CAAuB,UAAU,MAAM,CAAA,EAAG,GAAG,IAAA,CAAK,IAAA,EAAK;AAAA,YAClE,QAAA,EAAU,gBAAA;AAAA,YACV,OAAA,EAAS,eAAA;AAAA,YACT,QAAA,EAAU;AAAA,WACX,CAAA;AAAA,QACH,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAK,gCAAA,EAA6B,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,IAAI,KAAK,CAAA;AAAA,QACrE;AAAA,MACF;AAEA,MAAA,IAAI,WAAW,IAAA,CAAK,QAAA;AACpB,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC3B,QAAA,IAAI,iBAAiB,QAAA,CAAS,MAAA;AAAA,UAC5B;AAAA,SACF;AACA,QAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,UAAA,MAAM,KAAK,cAAc,CAAA;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,KAAK,KAAK,CAAA;AAChB,EAAA,OAAO,IAAA;AACT;ACvHA,IAAM,qBAA8C,EAAC;AAErD,SAAS,kBACP,IAAA,EACoD;AACpD,EAAA,IAAI,OAAO,IAAA,EAAM,IAAA;AACjB,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,SACF,IAAA,CAAK,MAAA,IACL,KAAK,KAAA,CAAM,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,KAAS,MAAM,GAAG,EAAA,IACjD,IAAA,CAAK,MAAM,CAAC,CAAA,EAAG,MACf,IAAA,CAAK,EAAA;AACP,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,MAAA,EAAO;AAC3B;AAmBO,IAAM,oBAAA,GAAuBC,YAAA,CAAK,SAAS,6BAAA,CAChD,KAAA,EACA;AACA,EAAA,IAAI,OAAA,GAAUD,mBAAW,mBAAmB,CAAA;AAC5C,EAAA,IAAI,MAAA,GAAS,KAAA,CAAM,MAAA,IAAU,OAAA,EAAS,MAAA;AACtC,EAAA,IAAI,IAAA,GAAO,KAAA,CAAM,IAAA,IAAQ,MAAA,EAAQ,IAAA,IAAQ,IAAA;AACzC,EAAA,IAAI,WAAA,GACF,KAAA,CAAM,WAAA,IAAe,MAAA,EAAQ,WAAA,IAAe,kBAAA;AAE9C,EAAA,IAAI,IAAA,GAAOD,gBAAQ,MAAM,iBAAA,CAAkB,IAAI,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAExD,EAAA,IAAI,QAAA,GAAWA,gBAAQ,MAAM;AAC3B,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,QAAA,GAAW,IAAIJ,cAAAA,CAAS;AAAA,MAC1B,SAAA,EAAW,MAAA,EAAQ,SAAA,IAAa,IAAA,CAAK,EAAA,IAAM,eAAA;AAAA,MAC3C,IAAA,EAAM;AAAA,KACP,CAAA;AACD,IAAA,QAAA,CAAS,WAAA,GAAc,WAAA;AACvB,IAAA,QAAA,CAAS,YAAA,GAAe,MAAA,EAAQ,cAAA,EAAgB,YAAA,IAAgB,KAAA;AAChE,IAAA,OAAO,QAAA;AAAA,EACT,CAAA,EAAG;AAAA,IACD,MAAA,EAAQ,SAAA;AAAA,IACR,QAAQ,cAAA,EAAgB,YAAA;AAAA,IACxB,IAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,uBAAOC,cAAAA,CAACM,kBAAA,EAAA,EAAa,OAAA,EAAS,QAAA,EAAU,CAAA;AAC1C,CAAC","file":"index.js","sourcesContent":["import type { SchemaType } from '@weaverse/schema'\n\n/**\n * Generate default component data from a schema's `settings` inputs.\n *\n * Mirrors Hydrogen's `generateDataFromSchema` (settings → `{ [name]:\n * defaultValue }`) but is kept local so `@weaverse/next` doesn't depend on\n * `@weaverse/hydrogen`. Falls back to the deprecated `inspector` array when a\n * schema predates `settings`.\n */\nexport function generateDataFromSchema(\n schema: SchemaType | undefined\n): Record<string, unknown> {\n let data: Record<string, unknown> = {}\n if (!schema) {\n return data\n }\n\n let groups =\n (schema.settings as {\n inputs?: { name?: string; defaultValue?: unknown }[]\n }[]) ??\n (schema as { inspector?: typeof groups }).inspector ??\n []\n\n for (let group of groups) {\n for (let input of group?.inputs ?? []) {\n let { name, defaultValue } = input\n if (name && defaultValue !== null && defaultValue !== undefined) {\n data[name] = defaultValue\n }\n }\n }\n\n return data\n}\n","import type { ElementData } from '@weaverse/react'\nimport { Weaverse, WeaverseItemStore } from '@weaverse/react'\nimport type { WeaverseNextComponentData } from './types'\nimport { generateDataFromSchema } from './utils'\n\n/**\n * Item store that flattens the serialized item's nested `data` field onto the\n * store and seeds schema defaults — same shape Hydrogen produces, so the\n * shared `@weaverse/react` renderer can spread props at the top level.\n */\nexport class WeaverseNextItem extends WeaverseItemStore {\n constructor(initialData: WeaverseNextComponentData, weaverse: Weaverse) {\n super(initialData as ElementData, weaverse)\n let { data, ...rest } = initialData\n let schemaData = generateDataFromSchema(this.Element?.schema)\n Object.assign(this._store, schemaData, data, rest)\n }\n}\n\n/**\n * Register the Next item constructor globally. Idempotent: calling it more than\n * once is safe. Invoked by the renderer before it builds a Weaverse instance.\n */\nexport function ensureNextItemConstructor() {\n if (\n !Weaverse.ItemConstructor ||\n Weaverse.ItemConstructor === WeaverseItemStore ||\n Weaverse.ItemConstructor === WeaverseNextItem\n ) {\n Weaverse.ItemConstructor = WeaverseNextItem\n }\n}\n","import { createSchema, type SchemaType } from '@weaverse/schema'\nimport type { HTMLAttributes, RefObject } from 'react'\nimport type { WeaverseNextComponent, WeaverseNextComponentProps } from './types'\n\n/**\n * Default `main` root component.\n *\n * A Weaverse page tree is a flat `items` array with a single root item of type\n * `main` whose `children` are the page's top-level sections. Hydrogen ships its\n * own `main`; the Next adapter provides this minimal, framework-neutral\n * equivalent so consumers don't have to register one just to render a basic\n * page tree (omitting it would leave child sections unrendered).\n *\n * It renders `children` and forwards the Weaverse DOM attributes the shared\n * renderer injects (`data-wv-id`, `data-wv-type`, `ref`, `className`, ...rest)\n * onto the root element. `loaderData` is adapter-internal and stripped so it\n * never lands on the DOM node.\n */\nfunction Main(\n props: WeaverseNextComponentProps & {\n ref?: RefObject<HTMLDivElement | null>\n }\n) {\n let { children, loaderData, ...rest } = props\n // `rest` carries the Weaverse-injected DOM attributes (data-wv-*, ref,\n // className). They are all valid div attributes, so the cast is safe.\n return <div {...(rest as HTMLAttributes<HTMLDivElement>)}>{children}</div>\n}\nMain.displayName = 'main'\n\n/** Schema for the default {@link Main} root component. Type is exactly `main`. */\nexport const mainSchema: SchemaType = createSchema({\n type: 'main',\n title: 'Main',\n})\n\n/**\n * Default `main` component module, registered ahead of user components by\n * {@link registerWeaverseNextComponents}. Kept package-internal — consumers\n * override it simply by registering their own component with `type: 'main'`.\n */\nexport const defaultMainComponent: WeaverseNextComponent = {\n default: Main,\n schema: mainSchema,\n}\n","import { Weaverse } from '@weaverse/react'\nimport { ensureNextItemConstructor } from './item'\nimport { defaultMainComponent } from './main'\nimport type { WeaverseNextComponent } from './types'\n\nconst MAIN_TYPE = 'main'\n\n/**\n * Component types already pushed into the element registry. Registration is\n * idempotent by `schema.type`, so callers may pass fresh arrays per request\n * without causing repeated global registry writes.\n */\nconst registeredComponentTypes = new Set<string>()\n\n/**\n * Register Next adapter components with the shared Weaverse element registry.\n *\n * This mutates global Weaverse runtime state, so callers should run it while\n * creating their app/client wiring, not from a React render body.\n *\n * A default `main` root component is always registered first so consumers don't\n * have to register one for basic page-tree rendering. If the consumer registers\n * their own `main`, that one is preferred: we only prepend the default when the\n * provided components don't already include a `main`, so a user-provided `main`\n * never collides with (or is shadowed by) the default.\n */\nexport function registerWeaverseNextComponents(\n components: WeaverseNextComponent[]\n) {\n ensureNextItemConstructor()\n\n let hasUserMain = components.some(\n (component) => component.schema?.type === MAIN_TYPE\n )\n let effectiveComponents = hasUserMain\n ? components\n : [defaultMainComponent, ...components]\n\n for (let component of effectiveComponents) {\n let type = component.schema.type\n let element = {\n type,\n Component: component.default,\n schema: component.schema,\n loader: component.loader,\n }\n\n if (type === MAIN_TYPE && hasUserMain) {\n // `main` is the only built-in default. If a consumer registers their own\n // root component after the default was already installed by another\n // client/test/request, prefer the consumer version by replacing the global\n // registry entry explicitly.\n Weaverse.elementRegistry.set(type, element)\n registeredComponentTypes.add(type)\n continue\n }\n\n if (type && !registeredComponentTypes.has(type)) {\n Weaverse.registerElement(element)\n registeredComponentTypes.add(type)\n }\n }\n}\n","import type { SchemaType } from '@weaverse/schema'\nimport { registerWeaverseNextComponents } from './registry'\nimport type {\n WeaverseNextClient,\n WeaverseNextClientConfig,\n WeaverseNextCommerceContext,\n WeaverseNextComponent,\n WeaverseNextLoaderData,\n WeaverseNextLoadPageInput,\n WeaverseNextRequestContext,\n WeaverseNextStorefront,\n} from './types'\nimport { generateDataFromSchema } from './utils'\n\n/**\n * Request-safe Weaverse client for Next.js. Holds the component registry, theme\n * data, request/commerce context, and the currently loaded page payload.\n *\n * Unlike Hydrogen's `WeaverseClient`, it never receives a React Router\n * `Request`/`LoaderFunctionArgs`. Network I/O is delegated to `fetchPage` /\n * `fetchThemeSettings` injected through config, keeping v0 testable without\n * real Weaverse API calls.\n */\nclass NextClient implements WeaverseNextClient {\n projectId: string\n components: WeaverseNextComponent[]\n themeSchema?: unknown\n themeSettings: Record<string, unknown>\n requestContext?: WeaverseNextRequestContext\n commerce?: WeaverseNextCommerceContext\n data: WeaverseNextLoaderData | null = null\n dataContext: Record<string, unknown> = {}\n\n private readonly _fetchPage?: WeaverseNextClientConfig['fetchPage']\n private readonly _fetchThemeSettings?: WeaverseNextClientConfig['fetchThemeSettings']\n\n constructor(config: WeaverseNextClientConfig) {\n this.projectId = config.projectId\n this.components = config.components\n registerWeaverseNextComponents(this.components)\n this.themeSchema = config.themeSchema\n // Seed `themeSchema` defaults before merchant-provided overrides, mirroring\n // Hydrogen's `loadThemeSettings` (schema defaults under remote `theme`).\n // Without this, `useThemeSettings()` would miss any setting the merchant\n // never explicitly overrode.\n this.themeSettings = {\n ...generateDataFromSchema(config.themeSchema as SchemaType | undefined),\n ...config.themeSettings,\n }\n this.requestContext = config.requestContext\n this.commerce = config.commerce\n this._fetchPage = config.fetchPage\n this._fetchThemeSettings = config.fetchThemeSettings\n }\n\n /** Compatibility alias so loaders can call `weaverse.storefront.query(...)`. */\n get storefront(): WeaverseNextStorefront | undefined {\n return this.commerce?.storefront\n }\n\n loadPage = (\n input: WeaverseNextLoadPageInput = {}\n ): Promise<WeaverseNextLoaderData | null> => {\n if (!this._fetchPage) {\n throw new Error(\n '[WeaverseNextClient] loadPage requires a `fetchPage` function in client config.'\n )\n }\n return this._fetchPage(input)\n }\n\n loadThemeSettings = (\n context?: WeaverseNextRequestContext\n ): Promise<unknown> => {\n if (!this._fetchThemeSettings) {\n throw new Error(\n '[WeaverseNextClient] loadThemeSettings requires a `fetchThemeSettings` function in client config.'\n )\n }\n return this._fetchThemeSettings(context ?? this.requestContext)\n }\n}\n\n/**\n * Create a {@link WeaverseNextClient} from explicit config.\n *\n * @example\n * ```ts\n * let client = createWeaverseNextClient({\n * projectId: process.env.WEAVERSE_PROJECT_ID!,\n * components,\n * commerce: { storefront },\n * fetchPage: async ({ type, handle }) => fetchWeaversePage({ type, handle }),\n * })\n * ```\n */\nexport function createWeaverseNextClient(\n config: WeaverseNextClientConfig\n): WeaverseNextClient {\n return new NextClient(config)\n}\n","'use client'\n\nimport { createContext, type ReactNode, useMemo } from 'react'\nimport type { WeaverseNextClient, WeaverseNextCommerceContext } from './types'\n\n/**\n * Value carried by {@link WeaverseNextContext}. Holds the explicit data\n * boundaries that replace React Router's `useLoaderData` /\n * `useRouteLoaderData` inside sections.\n */\nexport interface WeaverseNextContextValue {\n client?: WeaverseNextClient\n commerce?: WeaverseNextCommerceContext\n pageData?: unknown\n rootData?: unknown\n themeSettings: Record<string, unknown>\n}\n\n/**\n * Null sentinel default lets hooks detect usage outside the provider and throw\n * a clear error instead of silently returning empty data.\n */\nexport const WeaverseNextContext =\n createContext<WeaverseNextContextValue | null>(null)\n\nexport interface WeaverseNextProviderProps {\n children: ReactNode\n client?: WeaverseNextClient\n /** App-provided commerce context (storefront/cart/customer). */\n commerce?: WeaverseNextCommerceContext\n /** Explicit page/route commerce data (replaces section-level `useLoaderData`). */\n pageData?: unknown\n /** Explicit root/global data (replaces `useRouteLoaderData('root')`). */\n rootData?: unknown\n /** Theme settings override; falls back to `client.themeSettings`. */\n themeSettings?: Record<string, unknown>\n}\n\n/**\n * Client boundary that supplies explicit root/page/commerce data to Weaverse\n * sections. Next-native replacement for `withWeaverse` + route loader data —\n * no React Router route matches are emulated.\n *\n * In App Router, create/pass `client` only from a client component wrapper. A\n * `WeaverseNextClient` contains functions and component references, so it is\n * not serializable across a Server Component → Client Component boundary.\n *\n * @example\n * ```tsx\n * 'use client'\n *\n * <WeaverseNextProvider client={client} rootData={rootData} pageData={pageData} commerce={commerce}>\n * <WeaverseNextRenderer />\n * </WeaverseNextProvider>\n * ```\n */\nexport function WeaverseNextProvider(props: WeaverseNextProviderProps) {\n let { children, client, rootData, pageData, commerce, themeSettings } = props\n\n let value = useMemo<WeaverseNextContextValue>(\n () => ({\n client,\n rootData,\n pageData,\n commerce: commerce ?? client?.commerce,\n themeSettings: themeSettings ?? client?.themeSettings ?? {},\n }),\n [client, rootData, pageData, commerce, themeSettings]\n )\n\n return (\n <WeaverseNextContext.Provider value={value}>\n {children}\n </WeaverseNextContext.Provider>\n )\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { WeaverseNextContext } from './provider'\nimport type { WeaverseNextCommerceContext } from './types'\n\nconst OUTSIDE_PROVIDER_ERROR = 'must be used inside a <WeaverseNextProvider>.'\n\nfunction useWeaverseNextContext(hookName: string) {\n let context = useContext(WeaverseNextContext)\n if (!context) {\n throw new Error(`[@weaverse/next] ${hookName} ${OUTSIDE_PROVIDER_ERROR}`)\n }\n return context\n}\n\n/**\n * Read explicit root/global data passed to the provider. Next-native\n * replacement for `useRouteLoaderData('root')`.\n */\nexport function useWeaverseRootData<T = unknown>(): T {\n return useWeaverseNextContext('useWeaverseRootData').rootData as T\n}\n\n/**\n * Read explicit page/route commerce data passed to the provider. Next-native\n * replacement for section-level `useLoaderData()`.\n */\nexport function useWeaversePageData<T = unknown>(): T {\n return useWeaverseNextContext('useWeaversePageData').pageData as T\n}\n\n/** Read the app-provided commerce context (storefront/cart/customer). */\nexport function useWeaverseCommerce<T = WeaverseNextCommerceContext>(): T {\n return useWeaverseNextContext('useWeaverseCommerce').commerce as T\n}\n\n/**\n * Read Weaverse theme settings. Next version backed by provider root/theme\n * data (`client.themeSettings`), not the Hydrogen theme-settings store.\n */\nexport function useThemeSettings<T = Record<string, unknown>>(): T {\n return useWeaverseNextContext('useThemeSettings').themeSettings as T\n}\n","import type {\n WeaverseNextClient,\n WeaverseNextCommerceContext,\n WeaverseNextComponent,\n WeaverseNextComponentData,\n WeaverseNextLoaderData,\n WeaverseNextRequestContext,\n} from './types'\nimport { generateDataFromSchema } from './utils'\n\nexport interface RunComponentLoadersArgs {\n client: WeaverseNextClient\n commerce?: WeaverseNextCommerceContext\n context?: WeaverseNextRequestContext\n /** Page payload to walk; defaults to `client.data`. */\n data?: WeaverseNextLoaderData | null\n}\n\nfunction isItemNode(node: unknown): node is WeaverseNextComponentData {\n return (\n typeof node === 'object' &&\n node !== null &&\n typeof (node as WeaverseNextComponentData).type === 'string'\n )\n}\n\nfunction cloneItem(item: WeaverseNextComponentData): WeaverseNextComponentData {\n return {\n ...item,\n children: Array.isArray(item.children)\n ? item.children.map((child) =>\n isItemNode(child) ? cloneItem(child) : { ...child }\n )\n : item.children,\n }\n}\n\n/**\n * Walk a serialized page tree and run each registered component's `loader`,\n * attaching the result to the item as `loaderData`.\n *\n * Loaders receive explicit `commerce.storefront` (and `weaverse.storefront` as\n * a compatibility alias via the client). Children are walked recursively when\n * they are inline item objects; flat `items` arrays are covered by the\n * top-level walk.\n *\n * @returns a cloned `data` object with `loaderData` attached to cloned items.\n */\nexport async function runWeaverseComponentLoaders(\n args: RunComponentLoadersArgs\n): Promise<WeaverseNextLoaderData | null> {\n let { client, context, commerce } = args\n let sourceData = args.data ?? client.data\n if (!sourceData) {\n return null\n }\n if (!sourceData.page.items.length) {\n return sourceData\n }\n\n let data: WeaverseNextLoaderData = {\n ...sourceData,\n page: {\n ...sourceData.page,\n items: sourceData.page.items.map(cloneItem),\n },\n }\n let items = data.page.items\n\n let componentMap = new Map<string, WeaverseNextComponent>()\n for (let component of client.components) {\n if (component?.schema?.type) {\n componentMap.set(component.schema.type, component)\n }\n }\n\n let visited = new Set<string>()\n let resolvedContext = context ?? client.requestContext\n let resolvedCommerce = commerce ?? client.commerce\n\n // Per-call `weaverse` alias. When a request-scoped `commerce` is passed, the\n // `weaverse.storefront` compatibility alias must resolve to *that* storefront,\n // not the client's construction-time commerce. Pilot-style loaders call\n // `weaverse.storefront.query(...)`, so a stale alias would query the wrong\n // (or an undefined) storefront. When no override is given we reuse the client\n // as-is to preserve its prototype getters.\n let resolvedWeaverse: WeaverseNextClient =\n resolvedCommerce === client.commerce\n ? client\n : {\n ...client,\n commerce: resolvedCommerce,\n storefront: resolvedCommerce?.storefront,\n }\n\n async function walk(nodes: WeaverseNextComponentData[]) {\n for (let item of nodes) {\n if (!item || visited.has(item.id)) {\n continue\n }\n visited.add(item.id)\n\n let component = componentMap.get(item.type)\n if (component?.loader) {\n try {\n item.loaderData = await component.loader({\n data: { ...generateDataFromSchema(component.schema), ...item.data },\n weaverse: resolvedWeaverse,\n context: resolvedContext,\n commerce: resolvedCommerce,\n })\n } catch (error) {\n console.warn('❌ Item loader run failed.', item.type, item.id, error)\n }\n }\n\n let children = item.children\n if (Array.isArray(children)) {\n let inlineChildren = children.filter(\n isItemNode\n ) as WeaverseNextComponentData[]\n if (inlineChildren.length) {\n await walk(inlineChildren)\n }\n }\n }\n }\n\n await walk(items)\n return data\n}\n","'use client'\n\nimport { Weaverse, WeaverseRoot } from '@weaverse/react'\nimport { memo, useContext, useMemo } from 'react'\nimport { WeaverseNextContext } from './provider'\nimport type {\n WeaverseNextClient,\n WeaverseNextLoaderData,\n WeaverseNextPageData,\n} from './types'\n\nconst EMPTY_DATA_CONTEXT: Record<string, unknown> = {}\n\nfunction getRenderablePage(\n data: WeaverseNextLoaderData | null | undefined\n): (WeaverseNextPageData & { rootId: string }) | null {\n let page = data?.page\n if (!page) {\n return null\n }\n let rootId =\n page.rootId ??\n page.items.find((item) => item.type === 'main')?.id ??\n page.items[0]?.id ??\n page.id\n return { ...page, rootId }\n}\n\nexport interface WeaverseNextRendererProps {\n /** Client to render from. Defaults to the provider's client. */\n client?: WeaverseNextClient\n /** Page payload to render. Defaults to `client.data`. */\n data?: WeaverseNextLoaderData | null\n /** Data-connector context for `{{...}}` template replacement. */\n dataContext?: Record<string, unknown>\n}\n\n/**\n * Render a serialized Weaverse page tree through `@weaverse/react` primitives.\n *\n * Reads the client/page data from {@link WeaverseNextContext} when no props are\n * passed, or accepts an explicit `client` + `data` for standalone use. Builds a\n * framework-neutral `Weaverse` core instance (no React Router hooks) and hands\n * it to the shared `WeaverseRoot`.\n */\nexport const WeaverseNextRenderer = memo(function WeaverseNextRendererComponent(\n props: WeaverseNextRendererProps\n) {\n let context = useContext(WeaverseNextContext)\n let client = props.client ?? context?.client\n let data = props.data ?? client?.data ?? null\n let dataContext =\n props.dataContext ?? client?.dataContext ?? EMPTY_DATA_CONTEXT\n\n let page = useMemo(() => getRenderablePage(data), [data])\n\n let weaverse = useMemo(() => {\n if (!page) {\n return null\n }\n\n let instance = new Weaverse({\n projectId: client?.projectId || page.id || 'weaverse-next',\n data: page,\n })\n instance.dataContext = dataContext\n instance.isDesignMode = client?.requestContext?.isDesignMode ?? false\n return instance\n }, [\n client?.projectId,\n client?.requestContext?.isDesignMode,\n page,\n dataContext,\n ])\n\n if (!weaverse) {\n return null\n }\n\n return <WeaverseRoot context={weaverse} />\n})\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,289 @@
1
+ import { Weaverse, WeaverseRoot, WeaverseItemStore } from '@weaverse/react';
2
+ export { isBrowser, isIframe, useChildInstances, useItemInstance, useParentInstance, useWeaverse } from '@weaverse/react';
3
+ import { createSchema } from '@weaverse/schema';
4
+ export { createSchema } from '@weaverse/schema';
5
+ import { jsx } from 'react/jsx-runtime';
6
+ import { createContext, memo, useContext, useMemo } from 'react';
7
+
8
+ // src/index.ts
9
+
10
+ // src/utils.ts
11
+ function generateDataFromSchema(schema) {
12
+ let data = {};
13
+ if (!schema) {
14
+ return data;
15
+ }
16
+ let groups = schema.settings ?? schema.inspector ?? [];
17
+ for (let group of groups) {
18
+ for (let input of group?.inputs ?? []) {
19
+ let { name, defaultValue } = input;
20
+ if (name && defaultValue !== null && defaultValue !== void 0) {
21
+ data[name] = defaultValue;
22
+ }
23
+ }
24
+ }
25
+ return data;
26
+ }
27
+
28
+ // src/item.ts
29
+ var WeaverseNextItem = class extends WeaverseItemStore {
30
+ constructor(initialData, weaverse) {
31
+ super(initialData, weaverse);
32
+ let { data, ...rest } = initialData;
33
+ let schemaData = generateDataFromSchema(this.Element?.schema);
34
+ Object.assign(this._store, schemaData, data, rest);
35
+ }
36
+ };
37
+ function ensureNextItemConstructor() {
38
+ if (!Weaverse.ItemConstructor || Weaverse.ItemConstructor === WeaverseItemStore || Weaverse.ItemConstructor === WeaverseNextItem) {
39
+ Weaverse.ItemConstructor = WeaverseNextItem;
40
+ }
41
+ }
42
+ function Main(props) {
43
+ let { children, loaderData, ...rest } = props;
44
+ return /* @__PURE__ */ jsx("div", { ...rest, children });
45
+ }
46
+ Main.displayName = "main";
47
+ var mainSchema = createSchema({
48
+ type: "main",
49
+ title: "Main"
50
+ });
51
+ var defaultMainComponent = {
52
+ default: Main,
53
+ schema: mainSchema
54
+ };
55
+
56
+ // src/registry.ts
57
+ var MAIN_TYPE = "main";
58
+ var registeredComponentTypes = /* @__PURE__ */ new Set();
59
+ function registerWeaverseNextComponents(components) {
60
+ ensureNextItemConstructor();
61
+ let hasUserMain = components.some(
62
+ (component) => component.schema?.type === MAIN_TYPE
63
+ );
64
+ let effectiveComponents = hasUserMain ? components : [defaultMainComponent, ...components];
65
+ for (let component of effectiveComponents) {
66
+ let type = component.schema.type;
67
+ let element = {
68
+ type,
69
+ Component: component.default,
70
+ schema: component.schema,
71
+ loader: component.loader
72
+ };
73
+ if (type === MAIN_TYPE && hasUserMain) {
74
+ Weaverse.elementRegistry.set(type, element);
75
+ registeredComponentTypes.add(type);
76
+ continue;
77
+ }
78
+ if (type && !registeredComponentTypes.has(type)) {
79
+ Weaverse.registerElement(element);
80
+ registeredComponentTypes.add(type);
81
+ }
82
+ }
83
+ }
84
+
85
+ // src/client.ts
86
+ var NextClient = class {
87
+ projectId;
88
+ components;
89
+ themeSchema;
90
+ themeSettings;
91
+ requestContext;
92
+ commerce;
93
+ data = null;
94
+ dataContext = {};
95
+ _fetchPage;
96
+ _fetchThemeSettings;
97
+ constructor(config) {
98
+ this.projectId = config.projectId;
99
+ this.components = config.components;
100
+ registerWeaverseNextComponents(this.components);
101
+ this.themeSchema = config.themeSchema;
102
+ this.themeSettings = {
103
+ ...generateDataFromSchema(config.themeSchema),
104
+ ...config.themeSettings
105
+ };
106
+ this.requestContext = config.requestContext;
107
+ this.commerce = config.commerce;
108
+ this._fetchPage = config.fetchPage;
109
+ this._fetchThemeSettings = config.fetchThemeSettings;
110
+ }
111
+ /** Compatibility alias so loaders can call `weaverse.storefront.query(...)`. */
112
+ get storefront() {
113
+ return this.commerce?.storefront;
114
+ }
115
+ loadPage = (input = {}) => {
116
+ if (!this._fetchPage) {
117
+ throw new Error(
118
+ "[WeaverseNextClient] loadPage requires a `fetchPage` function in client config."
119
+ );
120
+ }
121
+ return this._fetchPage(input);
122
+ };
123
+ loadThemeSettings = (context) => {
124
+ if (!this._fetchThemeSettings) {
125
+ throw new Error(
126
+ "[WeaverseNextClient] loadThemeSettings requires a `fetchThemeSettings` function in client config."
127
+ );
128
+ }
129
+ return this._fetchThemeSettings(context ?? this.requestContext);
130
+ };
131
+ };
132
+ function createWeaverseNextClient(config) {
133
+ return new NextClient(config);
134
+ }
135
+ var WeaverseNextContext = createContext(null);
136
+ function WeaverseNextProvider(props) {
137
+ let { children, client, rootData, pageData, commerce, themeSettings } = props;
138
+ let value = useMemo(
139
+ () => ({
140
+ client,
141
+ rootData,
142
+ pageData,
143
+ commerce: commerce ?? client?.commerce,
144
+ themeSettings: themeSettings ?? client?.themeSettings ?? {}
145
+ }),
146
+ [client, rootData, pageData, commerce, themeSettings]
147
+ );
148
+ return /* @__PURE__ */ jsx(WeaverseNextContext.Provider, { value, children });
149
+ }
150
+
151
+ // src/hooks.ts
152
+ var OUTSIDE_PROVIDER_ERROR = "must be used inside a <WeaverseNextProvider>.";
153
+ function useWeaverseNextContext(hookName) {
154
+ let context = useContext(WeaverseNextContext);
155
+ if (!context) {
156
+ throw new Error(`[@weaverse/next] ${hookName} ${OUTSIDE_PROVIDER_ERROR}`);
157
+ }
158
+ return context;
159
+ }
160
+ function useWeaverseRootData() {
161
+ return useWeaverseNextContext("useWeaverseRootData").rootData;
162
+ }
163
+ function useWeaversePageData() {
164
+ return useWeaverseNextContext("useWeaversePageData").pageData;
165
+ }
166
+ function useWeaverseCommerce() {
167
+ return useWeaverseNextContext("useWeaverseCommerce").commerce;
168
+ }
169
+ function useThemeSettings() {
170
+ return useWeaverseNextContext("useThemeSettings").themeSettings;
171
+ }
172
+
173
+ // src/loader.ts
174
+ function isItemNode(node) {
175
+ return typeof node === "object" && node !== null && typeof node.type === "string";
176
+ }
177
+ function cloneItem(item) {
178
+ return {
179
+ ...item,
180
+ children: Array.isArray(item.children) ? item.children.map(
181
+ (child) => isItemNode(child) ? cloneItem(child) : { ...child }
182
+ ) : item.children
183
+ };
184
+ }
185
+ async function runWeaverseComponentLoaders(args) {
186
+ let { client, context, commerce } = args;
187
+ let sourceData = args.data ?? client.data;
188
+ if (!sourceData) {
189
+ return null;
190
+ }
191
+ if (!sourceData.page.items.length) {
192
+ return sourceData;
193
+ }
194
+ let data = {
195
+ ...sourceData,
196
+ page: {
197
+ ...sourceData.page,
198
+ items: sourceData.page.items.map(cloneItem)
199
+ }
200
+ };
201
+ let items = data.page.items;
202
+ let componentMap = /* @__PURE__ */ new Map();
203
+ for (let component of client.components) {
204
+ if (component?.schema?.type) {
205
+ componentMap.set(component.schema.type, component);
206
+ }
207
+ }
208
+ let visited = /* @__PURE__ */ new Set();
209
+ let resolvedContext = context ?? client.requestContext;
210
+ let resolvedCommerce = commerce ?? client.commerce;
211
+ let resolvedWeaverse = resolvedCommerce === client.commerce ? client : {
212
+ ...client,
213
+ commerce: resolvedCommerce,
214
+ storefront: resolvedCommerce?.storefront
215
+ };
216
+ async function walk(nodes) {
217
+ for (let item of nodes) {
218
+ if (!item || visited.has(item.id)) {
219
+ continue;
220
+ }
221
+ visited.add(item.id);
222
+ let component = componentMap.get(item.type);
223
+ if (component?.loader) {
224
+ try {
225
+ item.loaderData = await component.loader({
226
+ data: { ...generateDataFromSchema(component.schema), ...item.data },
227
+ weaverse: resolvedWeaverse,
228
+ context: resolvedContext,
229
+ commerce: resolvedCommerce
230
+ });
231
+ } catch (error) {
232
+ console.warn("\u274C Item loader run failed.", item.type, item.id, error);
233
+ }
234
+ }
235
+ let children = item.children;
236
+ if (Array.isArray(children)) {
237
+ let inlineChildren = children.filter(
238
+ isItemNode
239
+ );
240
+ if (inlineChildren.length) {
241
+ await walk(inlineChildren);
242
+ }
243
+ }
244
+ }
245
+ }
246
+ await walk(items);
247
+ return data;
248
+ }
249
+ var EMPTY_DATA_CONTEXT = {};
250
+ function getRenderablePage(data) {
251
+ let page = data?.page;
252
+ if (!page) {
253
+ return null;
254
+ }
255
+ let rootId = page.rootId ?? page.items.find((item) => item.type === "main")?.id ?? page.items[0]?.id ?? page.id;
256
+ return { ...page, rootId };
257
+ }
258
+ var WeaverseNextRenderer = memo(function WeaverseNextRendererComponent(props) {
259
+ let context = useContext(WeaverseNextContext);
260
+ let client = props.client ?? context?.client;
261
+ let data = props.data ?? client?.data ?? null;
262
+ let dataContext = props.dataContext ?? client?.dataContext ?? EMPTY_DATA_CONTEXT;
263
+ let page = useMemo(() => getRenderablePage(data), [data]);
264
+ let weaverse = useMemo(() => {
265
+ if (!page) {
266
+ return null;
267
+ }
268
+ let instance = new Weaverse({
269
+ projectId: client?.projectId || page.id || "weaverse-next",
270
+ data: page
271
+ });
272
+ instance.dataContext = dataContext;
273
+ instance.isDesignMode = client?.requestContext?.isDesignMode ?? false;
274
+ return instance;
275
+ }, [
276
+ client?.projectId,
277
+ client?.requestContext?.isDesignMode,
278
+ page,
279
+ dataContext
280
+ ]);
281
+ if (!weaverse) {
282
+ return null;
283
+ }
284
+ return /* @__PURE__ */ jsx(WeaverseRoot, { context: weaverse });
285
+ });
286
+
287
+ export { WeaverseNextProvider, WeaverseNextRenderer, createWeaverseNextClient, runWeaverseComponentLoaders, useThemeSettings, useWeaverseCommerce, useWeaversePageData, useWeaverseRootData };
288
+ //# sourceMappingURL=index.mjs.map
289
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/item.ts","../src/main.tsx","../src/registry.ts","../src/client.ts","../src/provider.tsx","../src/hooks.ts","../src/loader.ts","../src/renderer.tsx"],"names":["Weaverse","jsx","useContext","useMemo"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { SchemaType } from '@weaverse/schema'\n\n/**\n * Generate default component data from a schema's `settings` inputs.\n *\n * Mirrors Hydrogen's `generateDataFromSchema` (settings → `{ [name]:\n * defaultValue }`) but is kept local so `@weaverse/next` doesn't depend on\n * `@weaverse/hydrogen`. Falls back to the deprecated `inspector` array when a\n * schema predates `settings`.\n */\nexport function generateDataFromSchema(\n schema: SchemaType | undefined\n): Record<string, unknown> {\n let data: Record<string, unknown> = {}\n if (!schema) {\n return data\n }\n\n let groups =\n (schema.settings as {\n inputs?: { name?: string; defaultValue?: unknown }[]\n }[]) ??\n (schema as { inspector?: typeof groups }).inspector ??\n []\n\n for (let group of groups) {\n for (let input of group?.inputs ?? []) {\n let { name, defaultValue } = input\n if (name && defaultValue !== null && defaultValue !== undefined) {\n data[name] = defaultValue\n }\n }\n }\n\n return data\n}\n","import type { ElementData } from '@weaverse/react'\nimport { Weaverse, WeaverseItemStore } from '@weaverse/react'\nimport type { WeaverseNextComponentData } from './types'\nimport { generateDataFromSchema } from './utils'\n\n/**\n * Item store that flattens the serialized item's nested `data` field onto the\n * store and seeds schema defaults — same shape Hydrogen produces, so the\n * shared `@weaverse/react` renderer can spread props at the top level.\n */\nexport class WeaverseNextItem extends WeaverseItemStore {\n constructor(initialData: WeaverseNextComponentData, weaverse: Weaverse) {\n super(initialData as ElementData, weaverse)\n let { data, ...rest } = initialData\n let schemaData = generateDataFromSchema(this.Element?.schema)\n Object.assign(this._store, schemaData, data, rest)\n }\n}\n\n/**\n * Register the Next item constructor globally. Idempotent: calling it more than\n * once is safe. Invoked by the renderer before it builds a Weaverse instance.\n */\nexport function ensureNextItemConstructor() {\n if (\n !Weaverse.ItemConstructor ||\n Weaverse.ItemConstructor === WeaverseItemStore ||\n Weaverse.ItemConstructor === WeaverseNextItem\n ) {\n Weaverse.ItemConstructor = WeaverseNextItem\n }\n}\n","import { createSchema, type SchemaType } from '@weaverse/schema'\nimport type { HTMLAttributes, RefObject } from 'react'\nimport type { WeaverseNextComponent, WeaverseNextComponentProps } from './types'\n\n/**\n * Default `main` root component.\n *\n * A Weaverse page tree is a flat `items` array with a single root item of type\n * `main` whose `children` are the page's top-level sections. Hydrogen ships its\n * own `main`; the Next adapter provides this minimal, framework-neutral\n * equivalent so consumers don't have to register one just to render a basic\n * page tree (omitting it would leave child sections unrendered).\n *\n * It renders `children` and forwards the Weaverse DOM attributes the shared\n * renderer injects (`data-wv-id`, `data-wv-type`, `ref`, `className`, ...rest)\n * onto the root element. `loaderData` is adapter-internal and stripped so it\n * never lands on the DOM node.\n */\nfunction Main(\n props: WeaverseNextComponentProps & {\n ref?: RefObject<HTMLDivElement | null>\n }\n) {\n let { children, loaderData, ...rest } = props\n // `rest` carries the Weaverse-injected DOM attributes (data-wv-*, ref,\n // className). They are all valid div attributes, so the cast is safe.\n return <div {...(rest as HTMLAttributes<HTMLDivElement>)}>{children}</div>\n}\nMain.displayName = 'main'\n\n/** Schema for the default {@link Main} root component. Type is exactly `main`. */\nexport const mainSchema: SchemaType = createSchema({\n type: 'main',\n title: 'Main',\n})\n\n/**\n * Default `main` component module, registered ahead of user components by\n * {@link registerWeaverseNextComponents}. Kept package-internal — consumers\n * override it simply by registering their own component with `type: 'main'`.\n */\nexport const defaultMainComponent: WeaverseNextComponent = {\n default: Main,\n schema: mainSchema,\n}\n","import { Weaverse } from '@weaverse/react'\nimport { ensureNextItemConstructor } from './item'\nimport { defaultMainComponent } from './main'\nimport type { WeaverseNextComponent } from './types'\n\nconst MAIN_TYPE = 'main'\n\n/**\n * Component types already pushed into the element registry. Registration is\n * idempotent by `schema.type`, so callers may pass fresh arrays per request\n * without causing repeated global registry writes.\n */\nconst registeredComponentTypes = new Set<string>()\n\n/**\n * Register Next adapter components with the shared Weaverse element registry.\n *\n * This mutates global Weaverse runtime state, so callers should run it while\n * creating their app/client wiring, not from a React render body.\n *\n * A default `main` root component is always registered first so consumers don't\n * have to register one for basic page-tree rendering. If the consumer registers\n * their own `main`, that one is preferred: we only prepend the default when the\n * provided components don't already include a `main`, so a user-provided `main`\n * never collides with (or is shadowed by) the default.\n */\nexport function registerWeaverseNextComponents(\n components: WeaverseNextComponent[]\n) {\n ensureNextItemConstructor()\n\n let hasUserMain = components.some(\n (component) => component.schema?.type === MAIN_TYPE\n )\n let effectiveComponents = hasUserMain\n ? components\n : [defaultMainComponent, ...components]\n\n for (let component of effectiveComponents) {\n let type = component.schema.type\n let element = {\n type,\n Component: component.default,\n schema: component.schema,\n loader: component.loader,\n }\n\n if (type === MAIN_TYPE && hasUserMain) {\n // `main` is the only built-in default. If a consumer registers their own\n // root component after the default was already installed by another\n // client/test/request, prefer the consumer version by replacing the global\n // registry entry explicitly.\n Weaverse.elementRegistry.set(type, element)\n registeredComponentTypes.add(type)\n continue\n }\n\n if (type && !registeredComponentTypes.has(type)) {\n Weaverse.registerElement(element)\n registeredComponentTypes.add(type)\n }\n }\n}\n","import type { SchemaType } from '@weaverse/schema'\nimport { registerWeaverseNextComponents } from './registry'\nimport type {\n WeaverseNextClient,\n WeaverseNextClientConfig,\n WeaverseNextCommerceContext,\n WeaverseNextComponent,\n WeaverseNextLoaderData,\n WeaverseNextLoadPageInput,\n WeaverseNextRequestContext,\n WeaverseNextStorefront,\n} from './types'\nimport { generateDataFromSchema } from './utils'\n\n/**\n * Request-safe Weaverse client for Next.js. Holds the component registry, theme\n * data, request/commerce context, and the currently loaded page payload.\n *\n * Unlike Hydrogen's `WeaverseClient`, it never receives a React Router\n * `Request`/`LoaderFunctionArgs`. Network I/O is delegated to `fetchPage` /\n * `fetchThemeSettings` injected through config, keeping v0 testable without\n * real Weaverse API calls.\n */\nclass NextClient implements WeaverseNextClient {\n projectId: string\n components: WeaverseNextComponent[]\n themeSchema?: unknown\n themeSettings: Record<string, unknown>\n requestContext?: WeaverseNextRequestContext\n commerce?: WeaverseNextCommerceContext\n data: WeaverseNextLoaderData | null = null\n dataContext: Record<string, unknown> = {}\n\n private readonly _fetchPage?: WeaverseNextClientConfig['fetchPage']\n private readonly _fetchThemeSettings?: WeaverseNextClientConfig['fetchThemeSettings']\n\n constructor(config: WeaverseNextClientConfig) {\n this.projectId = config.projectId\n this.components = config.components\n registerWeaverseNextComponents(this.components)\n this.themeSchema = config.themeSchema\n // Seed `themeSchema` defaults before merchant-provided overrides, mirroring\n // Hydrogen's `loadThemeSettings` (schema defaults under remote `theme`).\n // Without this, `useThemeSettings()` would miss any setting the merchant\n // never explicitly overrode.\n this.themeSettings = {\n ...generateDataFromSchema(config.themeSchema as SchemaType | undefined),\n ...config.themeSettings,\n }\n this.requestContext = config.requestContext\n this.commerce = config.commerce\n this._fetchPage = config.fetchPage\n this._fetchThemeSettings = config.fetchThemeSettings\n }\n\n /** Compatibility alias so loaders can call `weaverse.storefront.query(...)`. */\n get storefront(): WeaverseNextStorefront | undefined {\n return this.commerce?.storefront\n }\n\n loadPage = (\n input: WeaverseNextLoadPageInput = {}\n ): Promise<WeaverseNextLoaderData | null> => {\n if (!this._fetchPage) {\n throw new Error(\n '[WeaverseNextClient] loadPage requires a `fetchPage` function in client config.'\n )\n }\n return this._fetchPage(input)\n }\n\n loadThemeSettings = (\n context?: WeaverseNextRequestContext\n ): Promise<unknown> => {\n if (!this._fetchThemeSettings) {\n throw new Error(\n '[WeaverseNextClient] loadThemeSettings requires a `fetchThemeSettings` function in client config.'\n )\n }\n return this._fetchThemeSettings(context ?? this.requestContext)\n }\n}\n\n/**\n * Create a {@link WeaverseNextClient} from explicit config.\n *\n * @example\n * ```ts\n * let client = createWeaverseNextClient({\n * projectId: process.env.WEAVERSE_PROJECT_ID!,\n * components,\n * commerce: { storefront },\n * fetchPage: async ({ type, handle }) => fetchWeaversePage({ type, handle }),\n * })\n * ```\n */\nexport function createWeaverseNextClient(\n config: WeaverseNextClientConfig\n): WeaverseNextClient {\n return new NextClient(config)\n}\n","'use client'\n\nimport { createContext, type ReactNode, useMemo } from 'react'\nimport type { WeaverseNextClient, WeaverseNextCommerceContext } from './types'\n\n/**\n * Value carried by {@link WeaverseNextContext}. Holds the explicit data\n * boundaries that replace React Router's `useLoaderData` /\n * `useRouteLoaderData` inside sections.\n */\nexport interface WeaverseNextContextValue {\n client?: WeaverseNextClient\n commerce?: WeaverseNextCommerceContext\n pageData?: unknown\n rootData?: unknown\n themeSettings: Record<string, unknown>\n}\n\n/**\n * Null sentinel default lets hooks detect usage outside the provider and throw\n * a clear error instead of silently returning empty data.\n */\nexport const WeaverseNextContext =\n createContext<WeaverseNextContextValue | null>(null)\n\nexport interface WeaverseNextProviderProps {\n children: ReactNode\n client?: WeaverseNextClient\n /** App-provided commerce context (storefront/cart/customer). */\n commerce?: WeaverseNextCommerceContext\n /** Explicit page/route commerce data (replaces section-level `useLoaderData`). */\n pageData?: unknown\n /** Explicit root/global data (replaces `useRouteLoaderData('root')`). */\n rootData?: unknown\n /** Theme settings override; falls back to `client.themeSettings`. */\n themeSettings?: Record<string, unknown>\n}\n\n/**\n * Client boundary that supplies explicit root/page/commerce data to Weaverse\n * sections. Next-native replacement for `withWeaverse` + route loader data —\n * no React Router route matches are emulated.\n *\n * In App Router, create/pass `client` only from a client component wrapper. A\n * `WeaverseNextClient` contains functions and component references, so it is\n * not serializable across a Server Component → Client Component boundary.\n *\n * @example\n * ```tsx\n * 'use client'\n *\n * <WeaverseNextProvider client={client} rootData={rootData} pageData={pageData} commerce={commerce}>\n * <WeaverseNextRenderer />\n * </WeaverseNextProvider>\n * ```\n */\nexport function WeaverseNextProvider(props: WeaverseNextProviderProps) {\n let { children, client, rootData, pageData, commerce, themeSettings } = props\n\n let value = useMemo<WeaverseNextContextValue>(\n () => ({\n client,\n rootData,\n pageData,\n commerce: commerce ?? client?.commerce,\n themeSettings: themeSettings ?? client?.themeSettings ?? {},\n }),\n [client, rootData, pageData, commerce, themeSettings]\n )\n\n return (\n <WeaverseNextContext.Provider value={value}>\n {children}\n </WeaverseNextContext.Provider>\n )\n}\n","'use client'\n\nimport { useContext } from 'react'\nimport { WeaverseNextContext } from './provider'\nimport type { WeaverseNextCommerceContext } from './types'\n\nconst OUTSIDE_PROVIDER_ERROR = 'must be used inside a <WeaverseNextProvider>.'\n\nfunction useWeaverseNextContext(hookName: string) {\n let context = useContext(WeaverseNextContext)\n if (!context) {\n throw new Error(`[@weaverse/next] ${hookName} ${OUTSIDE_PROVIDER_ERROR}`)\n }\n return context\n}\n\n/**\n * Read explicit root/global data passed to the provider. Next-native\n * replacement for `useRouteLoaderData('root')`.\n */\nexport function useWeaverseRootData<T = unknown>(): T {\n return useWeaverseNextContext('useWeaverseRootData').rootData as T\n}\n\n/**\n * Read explicit page/route commerce data passed to the provider. Next-native\n * replacement for section-level `useLoaderData()`.\n */\nexport function useWeaversePageData<T = unknown>(): T {\n return useWeaverseNextContext('useWeaversePageData').pageData as T\n}\n\n/** Read the app-provided commerce context (storefront/cart/customer). */\nexport function useWeaverseCommerce<T = WeaverseNextCommerceContext>(): T {\n return useWeaverseNextContext('useWeaverseCommerce').commerce as T\n}\n\n/**\n * Read Weaverse theme settings. Next version backed by provider root/theme\n * data (`client.themeSettings`), not the Hydrogen theme-settings store.\n */\nexport function useThemeSettings<T = Record<string, unknown>>(): T {\n return useWeaverseNextContext('useThemeSettings').themeSettings as T\n}\n","import type {\n WeaverseNextClient,\n WeaverseNextCommerceContext,\n WeaverseNextComponent,\n WeaverseNextComponentData,\n WeaverseNextLoaderData,\n WeaverseNextRequestContext,\n} from './types'\nimport { generateDataFromSchema } from './utils'\n\nexport interface RunComponentLoadersArgs {\n client: WeaverseNextClient\n commerce?: WeaverseNextCommerceContext\n context?: WeaverseNextRequestContext\n /** Page payload to walk; defaults to `client.data`. */\n data?: WeaverseNextLoaderData | null\n}\n\nfunction isItemNode(node: unknown): node is WeaverseNextComponentData {\n return (\n typeof node === 'object' &&\n node !== null &&\n typeof (node as WeaverseNextComponentData).type === 'string'\n )\n}\n\nfunction cloneItem(item: WeaverseNextComponentData): WeaverseNextComponentData {\n return {\n ...item,\n children: Array.isArray(item.children)\n ? item.children.map((child) =>\n isItemNode(child) ? cloneItem(child) : { ...child }\n )\n : item.children,\n }\n}\n\n/**\n * Walk a serialized page tree and run each registered component's `loader`,\n * attaching the result to the item as `loaderData`.\n *\n * Loaders receive explicit `commerce.storefront` (and `weaverse.storefront` as\n * a compatibility alias via the client). Children are walked recursively when\n * they are inline item objects; flat `items` arrays are covered by the\n * top-level walk.\n *\n * @returns a cloned `data` object with `loaderData` attached to cloned items.\n */\nexport async function runWeaverseComponentLoaders(\n args: RunComponentLoadersArgs\n): Promise<WeaverseNextLoaderData | null> {\n let { client, context, commerce } = args\n let sourceData = args.data ?? client.data\n if (!sourceData) {\n return null\n }\n if (!sourceData.page.items.length) {\n return sourceData\n }\n\n let data: WeaverseNextLoaderData = {\n ...sourceData,\n page: {\n ...sourceData.page,\n items: sourceData.page.items.map(cloneItem),\n },\n }\n let items = data.page.items\n\n let componentMap = new Map<string, WeaverseNextComponent>()\n for (let component of client.components) {\n if (component?.schema?.type) {\n componentMap.set(component.schema.type, component)\n }\n }\n\n let visited = new Set<string>()\n let resolvedContext = context ?? client.requestContext\n let resolvedCommerce = commerce ?? client.commerce\n\n // Per-call `weaverse` alias. When a request-scoped `commerce` is passed, the\n // `weaverse.storefront` compatibility alias must resolve to *that* storefront,\n // not the client's construction-time commerce. Pilot-style loaders call\n // `weaverse.storefront.query(...)`, so a stale alias would query the wrong\n // (or an undefined) storefront. When no override is given we reuse the client\n // as-is to preserve its prototype getters.\n let resolvedWeaverse: WeaverseNextClient =\n resolvedCommerce === client.commerce\n ? client\n : {\n ...client,\n commerce: resolvedCommerce,\n storefront: resolvedCommerce?.storefront,\n }\n\n async function walk(nodes: WeaverseNextComponentData[]) {\n for (let item of nodes) {\n if (!item || visited.has(item.id)) {\n continue\n }\n visited.add(item.id)\n\n let component = componentMap.get(item.type)\n if (component?.loader) {\n try {\n item.loaderData = await component.loader({\n data: { ...generateDataFromSchema(component.schema), ...item.data },\n weaverse: resolvedWeaverse,\n context: resolvedContext,\n commerce: resolvedCommerce,\n })\n } catch (error) {\n console.warn('❌ Item loader run failed.', item.type, item.id, error)\n }\n }\n\n let children = item.children\n if (Array.isArray(children)) {\n let inlineChildren = children.filter(\n isItemNode\n ) as WeaverseNextComponentData[]\n if (inlineChildren.length) {\n await walk(inlineChildren)\n }\n }\n }\n }\n\n await walk(items)\n return data\n}\n","'use client'\n\nimport { Weaverse, WeaverseRoot } from '@weaverse/react'\nimport { memo, useContext, useMemo } from 'react'\nimport { WeaverseNextContext } from './provider'\nimport type {\n WeaverseNextClient,\n WeaverseNextLoaderData,\n WeaverseNextPageData,\n} from './types'\n\nconst EMPTY_DATA_CONTEXT: Record<string, unknown> = {}\n\nfunction getRenderablePage(\n data: WeaverseNextLoaderData | null | undefined\n): (WeaverseNextPageData & { rootId: string }) | null {\n let page = data?.page\n if (!page) {\n return null\n }\n let rootId =\n page.rootId ??\n page.items.find((item) => item.type === 'main')?.id ??\n page.items[0]?.id ??\n page.id\n return { ...page, rootId }\n}\n\nexport interface WeaverseNextRendererProps {\n /** Client to render from. Defaults to the provider's client. */\n client?: WeaverseNextClient\n /** Page payload to render. Defaults to `client.data`. */\n data?: WeaverseNextLoaderData | null\n /** Data-connector context for `{{...}}` template replacement. */\n dataContext?: Record<string, unknown>\n}\n\n/**\n * Render a serialized Weaverse page tree through `@weaverse/react` primitives.\n *\n * Reads the client/page data from {@link WeaverseNextContext} when no props are\n * passed, or accepts an explicit `client` + `data` for standalone use. Builds a\n * framework-neutral `Weaverse` core instance (no React Router hooks) and hands\n * it to the shared `WeaverseRoot`.\n */\nexport const WeaverseNextRenderer = memo(function WeaverseNextRendererComponent(\n props: WeaverseNextRendererProps\n) {\n let context = useContext(WeaverseNextContext)\n let client = props.client ?? context?.client\n let data = props.data ?? client?.data ?? null\n let dataContext =\n props.dataContext ?? client?.dataContext ?? EMPTY_DATA_CONTEXT\n\n let page = useMemo(() => getRenderablePage(data), [data])\n\n let weaverse = useMemo(() => {\n if (!page) {\n return null\n }\n\n let instance = new Weaverse({\n projectId: client?.projectId || page.id || 'weaverse-next',\n data: page,\n })\n instance.dataContext = dataContext\n instance.isDesignMode = client?.requestContext?.isDesignMode ?? false\n return instance\n }, [\n client?.projectId,\n client?.requestContext?.isDesignMode,\n page,\n dataContext,\n ])\n\n if (!weaverse) {\n return null\n }\n\n return <WeaverseRoot context={weaverse} />\n})\n"]}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@weaverse/next",
3
+ "author": "Weaverse Team",
4
+ "description": "Next.js App Router integration for building Weaverse-powered storefronts",
5
+ "version": "0.1.0-alpha.0",
6
+ "license": "MIT",
7
+ "main": "dist/index.js",
8
+ "typings": "dist/index.d.ts",
9
+ "module": "dist/index.mjs",
10
+ "publishConfig": {
11
+ "access": "public",
12
+ "@weaverse:registry": "https://registry.npmjs.org"
13
+ },
14
+ "repository": {
15
+ "url": "git+https://github.com/Weaverse/weaverse.git",
16
+ "directory": "packages/next"
17
+ },
18
+ "files": [
19
+ "dist/*"
20
+ ],
21
+ "engines": {
22
+ "node": ">=20"
23
+ },
24
+ "scripts": {
25
+ "dev": "tsup --watch",
26
+ "build": "tsup",
27
+ "clean": "rimraf dist",
28
+ "test": "vp test --run --config vitest.config.ts",
29
+ "typecheck": "tsc --noEmit"
30
+ },
31
+ "tsup": {
32
+ "entry": [
33
+ "src/index.ts"
34
+ ],
35
+ "format": [
36
+ "esm",
37
+ "cjs"
38
+ ],
39
+ "dts": true,
40
+ "sourcemap": true,
41
+ "clean": true,
42
+ "outDir": "dist",
43
+ "treeshake": true
44
+ },
45
+ "dependencies": {
46
+ "@weaverse/react": "5.16.3",
47
+ "@weaverse/schema": "0.10.0"
48
+ },
49
+ "peerDependencies": {
50
+ "react": ">=19",
51
+ "react-dom": ">=19"
52
+ }
53
+ }