@weaverse/next 0.1.0-alpha.2 → 0.1.0-alpha.4

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.
@@ -133,8 +133,22 @@ function toQueryRecord(searchParams) {
133
133
  }
134
134
  return queries;
135
135
  }
136
+ var TRANSIENT_STUDIO_PARAMS = /* @__PURE__ */ new Set([
137
+ "weaverseDraftItem",
138
+ // Legacy name from the original design-mode draft-item spike. Keep it out of
139
+ // runtime requestInfo too, in case an older Builder bundle is in front of a
140
+ // newer Next storefront.
141
+ "__weaverseDraftItem"
142
+ ]);
143
+ function getRequestInfoSearchParams(context) {
144
+ let searchParams = new URLSearchParams(getSearchParamsFromContext(context));
145
+ for (let key of TRANSIENT_STUDIO_PARAMS) {
146
+ searchParams.delete(key);
147
+ }
148
+ return searchParams;
149
+ }
136
150
  function buildWeaverseNextRequestInfo(context) {
137
- let searchParams = getSearchParamsFromContext(context);
151
+ let searchParams = getRequestInfoSearchParams(context);
138
152
  let search = searchParams.toString();
139
153
  return {
140
154
  pathname: getPathnameFromContext(context),
@@ -145,5 +159,5 @@ function buildWeaverseNextRequestInfo(context) {
145
159
  }
146
160
 
147
161
  export { buildWeaverseNextRequestInfo, generateDataFromSchema, runWeaverseComponentLoaders };
148
- //# sourceMappingURL=chunk-SS6QUKYY.mjs.map
149
- //# sourceMappingURL=chunk-SS6QUKYY.mjs.map
162
+ //# sourceMappingURL=chunk-O2TG2NYL.mjs.map
163
+ //# sourceMappingURL=chunk-O2TG2NYL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/loader.ts","../src/request-info.ts"],"names":[],"mappings":"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","file":"chunk-O2TG2NYL.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 {\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","import type {\n WeaverseNextRequestContext,\n WeaverseNextRequestInfo,\n} from './types'\n\nfunction toUrl(value: string | URL): URL {\n return typeof value === 'string' ? new URL(value, 'http://localhost') : value\n}\n\nfunction getSearchParamsFromContext(\n context?: WeaverseNextRequestContext\n): URLSearchParams {\n if (context?.searchParams) {\n return new URLSearchParams(context.searchParams)\n }\n\n if (context?.url) {\n let url = toUrl(context.url)\n return new URLSearchParams(url.searchParams)\n }\n\n return new URLSearchParams()\n}\n\nfunction getPathnameFromContext(context?: WeaverseNextRequestContext): string {\n if (context?.pathname) {\n return context.pathname\n }\n\n if (context?.url) {\n let url = toUrl(context.url)\n return url.pathname || '/'\n }\n\n return '/'\n}\n\nfunction coerceQueryValue(value: string): string | boolean {\n if (value === 'true') {\n return true\n }\n if (value === 'false') {\n return false\n }\n return value\n}\n\nfunction toQueryRecord(\n searchParams: URLSearchParams\n): Record<string, string | boolean> {\n let queries: Record<string, string | boolean> = {}\n for (let [key, value] of searchParams.entries()) {\n queries[key] = coerceQueryValue(value)\n }\n return queries\n}\n\nconst TRANSIENT_STUDIO_PARAMS = new Set([\n 'weaverseDraftItem',\n // Legacy name from the original design-mode draft-item spike. Keep it out of\n // runtime requestInfo too, in case an older Builder bundle is in front of a\n // newer Next storefront.\n '__weaverseDraftItem',\n])\n\nfunction getRequestInfoSearchParams(\n context?: WeaverseNextRequestContext\n): URLSearchParams {\n let searchParams = new URLSearchParams(getSearchParamsFromContext(context))\n for (let key of TRANSIENT_STUDIO_PARAMS) {\n searchParams.delete(key)\n }\n return searchParams\n}\n\n/**\n * Build the Hydrogen-like request info shape consumed by the Studio bridge.\n * Duplicate query keys keep the last value, matching `URLSearchParams` iteration\n * assignment and Hydrogen's practical query-object behavior.\n */\nexport function buildWeaverseNextRequestInfo(\n context?: WeaverseNextRequestContext\n): WeaverseNextRequestInfo {\n let searchParams = getRequestInfoSearchParams(context)\n let search = searchParams.toString()\n\n return {\n pathname: getPathnameFromContext(context),\n search: search ? `?${search}` : '',\n queries: toQueryRecord(searchParams),\n ...(context?.i18n ? { i18n: context.i18n } : {}),\n }\n}\n"]}
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Weaverse } from '@weaverse/react';
2
2
  export { isBrowser, isIframe, useChildInstances, useItemInstance, useParentInstance, useWeaverse } from '@weaverse/react';
3
3
  export { InspectorGroup, PageType, SchemaType, createSchema } from '@weaverse/schema';
4
- import { d as WeaverseNextClientConfig, c as WeaverseNextClient, e as WeaverseNextCommerceContext, q as WeaverseNextRequestContext, n as WeaverseNextLoaderData, r as WeaverseNextRequestInfo, t as WeaverseNextRuntimeInternal, s as WeaverseNextRuntimeConfig, A as WeaverseNextThemeSettingsStore } from './types-DvEeLX6L.mjs';
5
- export { W as WeaverseCollection, f as WeaverseNextComponent, g as WeaverseNextComponentData, h as WeaverseNextComponentLoaderArgs, i as WeaverseNextComponentProps, l as WeaverseNextI18n, m as WeaverseNextLoadPageInput, o as WeaverseNextPageData, x as WeaverseNextStorefront, B as WeaverseProduct } from './types-DvEeLX6L.mjs';
4
+ import { d as WeaverseNextClientConfig, c as WeaverseNextClient, e as WeaverseNextCommerceContext, q as WeaverseNextRequestContext, n as WeaverseNextLoaderData, r as WeaverseNextRequestInfo, g as WeaverseNextComponentData, t as WeaverseNextRuntimeInternal, s as WeaverseNextRuntimeConfig, A as WeaverseNextThemeSettingsStore } from './types-DvwaU20C.mjs';
5
+ export { W as WeaverseCollection, f as WeaverseNextComponent, h as WeaverseNextComponentLoaderArgs, i as WeaverseNextComponentProps, l as WeaverseNextI18n, m as WeaverseNextLoadPageInput, o as WeaverseNextPageData, x as WeaverseNextStorefront, B as WeaverseProduct } from './types-DvwaU20C.mjs';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
7
  import * as react from 'react';
8
8
  import { ReactNode } from 'react';
@@ -118,6 +118,31 @@ declare const WeaverseNextRenderer: react.MemoExoticComponent<(props: WeaverseNe
118
118
  */
119
119
  declare function buildWeaverseNextRequestInfo(context?: WeaverseNextRequestContext): WeaverseNextRequestInfo;
120
120
 
121
+ declare const DEFAULT_REVALIDATE_ENDPOINT = "/api/weaverse/revalidate";
122
+ /**
123
+ * Minimal runtime surface the in-place apply needs. Structural (not the
124
+ * concrete `WeaverseNextRuntime` class) so unit tests can drive it with a
125
+ * plain mock.
126
+ */
127
+ interface RevalidateItemRuntimeLike {
128
+ itemInstances: Map<string, {
129
+ setData: (update: Record<string, unknown>) => unknown;
130
+ }>;
131
+ }
132
+ /**
133
+ * Studio per-item loader revalidation: POST the unsaved draft item to the
134
+ * app's revalidate route (see `createWeaverseNextRevalidateHandler`) and apply
135
+ * the returned `loaderData` to the live item instance in place.
136
+ *
137
+ * No `router.refresh()` is involved, so the RSC tree is never re-applied — no
138
+ * page remount, no scroll reset, and the draft payload never touches the URL.
139
+ *
140
+ * Throws on any failure (missing route, non-OK response, unknown item) so the
141
+ * Builder Studio bridge can detect the miss and fall back to its legacy
142
+ * refresh-based revalidation for this window.
143
+ */
144
+ declare function revalidateWeaverseNextItem(runtime: RevalidateItemRuntimeLike, draftItem: WeaverseNextComponentData, endpoint?: string): Promise<void>;
145
+
121
146
  declare global {
122
147
  interface Window {
123
148
  __weaverse?: WeaverseNextRuntime;
@@ -146,6 +171,7 @@ declare function bindWeaverseNextStudioRuntime(runtime: WeaverseNextRuntime): bo
146
171
  interface WeaverseNextStudioBridgeProps {
147
172
  navigate?: WeaverseNextRuntimeInternal['navigate'];
148
173
  revalidate?: WeaverseNextRuntimeInternal['revalidate'];
174
+ revalidateItem?: WeaverseNextRuntimeInternal['revalidateItem'];
149
175
  runtime: WeaverseNextRuntime;
150
176
  }
151
177
  /** Page-level Studio runtime binder. */
@@ -231,6 +257,11 @@ declare function createWeaverseNextThemeSettingsStore(options?: CreateWeaverseNe
231
257
  */
232
258
  declare function useWeaverseNextStudioInternals(options?: CreateWeaverseNextStudioInternalsOptions): WeaverseNextStudioInternals;
233
259
  interface WeaverseNextStudioProps extends CreateWeaverseNextStudioInternalsOptions {
260
+ /**
261
+ * Route the app mounted with `createWeaverseNextRevalidateHandler`.
262
+ * Defaults to `/api/weaverse/revalidate`.
263
+ */
264
+ revalidateEndpoint?: string;
234
265
  runtime: WeaverseNextRuntime;
235
266
  }
236
267
  /**
@@ -247,4 +278,4 @@ interface WeaverseNextStudioProps extends CreateWeaverseNextStudioInternalsOptio
247
278
  */
248
279
  declare function WeaverseNextStudio(props: WeaverseNextStudioProps): react_jsx_runtime.JSX.Element;
249
280
 
250
- export { type CreateWeaverseNextStudioInternalsOptions, type CreateWeaverseNextThemeSettingsStoreOptions, type ResolveWeaverseNextStudioScriptSrcOptions, type RunComponentLoadersArgs, WeaverseNextClient, WeaverseNextClientConfig, WeaverseNextCommerceContext, WeaverseNextLoaderData, WeaverseNextProvider, type WeaverseNextProviderProps, WeaverseNextRenderer, type WeaverseNextRendererProps, WeaverseNextRequestContext, WeaverseNextRequestInfo, type WeaverseNextRouterLike, WeaverseNextRuntime, WeaverseNextRuntimeConfig, WeaverseNextRuntimeInternal, WeaverseNextStudio, WeaverseNextStudioBridge, type WeaverseNextStudioBridgeProps, WeaverseNextStudioConnect, type WeaverseNextStudioConnectProps, type WeaverseNextStudioInternals, type WeaverseNextStudioProps, WeaverseNextThemeSettingsStore, bindWeaverseNextStudioRuntime, buildWeaverseNextRequestInfo, createWeaverseNextClient, createWeaverseNextRuntime, createWeaverseNextStudioInternals, createWeaverseNextThemeSettingsStore, resolveWeaverseNextStudioScriptSrc, runWeaverseComponentLoaders, useThemeSettings, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData };
281
+ export { type CreateWeaverseNextStudioInternalsOptions, type CreateWeaverseNextThemeSettingsStoreOptions, DEFAULT_REVALIDATE_ENDPOINT, type ResolveWeaverseNextStudioScriptSrcOptions, type RevalidateItemRuntimeLike, type RunComponentLoadersArgs, WeaverseNextClient, WeaverseNextClientConfig, WeaverseNextCommerceContext, WeaverseNextComponentData, WeaverseNextLoaderData, WeaverseNextProvider, type WeaverseNextProviderProps, WeaverseNextRenderer, type WeaverseNextRendererProps, WeaverseNextRequestContext, WeaverseNextRequestInfo, type WeaverseNextRouterLike, WeaverseNextRuntime, WeaverseNextRuntimeConfig, WeaverseNextRuntimeInternal, WeaverseNextStudio, WeaverseNextStudioBridge, type WeaverseNextStudioBridgeProps, WeaverseNextStudioConnect, type WeaverseNextStudioConnectProps, type WeaverseNextStudioInternals, type WeaverseNextStudioProps, WeaverseNextThemeSettingsStore, bindWeaverseNextStudioRuntime, buildWeaverseNextRequestInfo, createWeaverseNextClient, createWeaverseNextRuntime, createWeaverseNextStudioInternals, createWeaverseNextThemeSettingsStore, resolveWeaverseNextStudioScriptSrc, revalidateWeaverseNextItem, runWeaverseComponentLoaders, useThemeSettings, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Weaverse } from '@weaverse/react';
2
2
  export { isBrowser, isIframe, useChildInstances, useItemInstance, useParentInstance, useWeaverse } from '@weaverse/react';
3
3
  export { InspectorGroup, PageType, SchemaType, createSchema } from '@weaverse/schema';
4
- import { d as WeaverseNextClientConfig, c as WeaverseNextClient, e as WeaverseNextCommerceContext, q as WeaverseNextRequestContext, n as WeaverseNextLoaderData, r as WeaverseNextRequestInfo, t as WeaverseNextRuntimeInternal, s as WeaverseNextRuntimeConfig, A as WeaverseNextThemeSettingsStore } from './types-DvEeLX6L.js';
5
- export { W as WeaverseCollection, f as WeaverseNextComponent, g as WeaverseNextComponentData, h as WeaverseNextComponentLoaderArgs, i as WeaverseNextComponentProps, l as WeaverseNextI18n, m as WeaverseNextLoadPageInput, o as WeaverseNextPageData, x as WeaverseNextStorefront, B as WeaverseProduct } from './types-DvEeLX6L.js';
4
+ import { d as WeaverseNextClientConfig, c as WeaverseNextClient, e as WeaverseNextCommerceContext, q as WeaverseNextRequestContext, n as WeaverseNextLoaderData, r as WeaverseNextRequestInfo, g as WeaverseNextComponentData, t as WeaverseNextRuntimeInternal, s as WeaverseNextRuntimeConfig, A as WeaverseNextThemeSettingsStore } from './types-DvwaU20C.js';
5
+ export { W as WeaverseCollection, f as WeaverseNextComponent, h as WeaverseNextComponentLoaderArgs, i as WeaverseNextComponentProps, l as WeaverseNextI18n, m as WeaverseNextLoadPageInput, o as WeaverseNextPageData, x as WeaverseNextStorefront, B as WeaverseProduct } from './types-DvwaU20C.js';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
7
  import * as react from 'react';
8
8
  import { ReactNode } from 'react';
@@ -118,6 +118,31 @@ declare const WeaverseNextRenderer: react.MemoExoticComponent<(props: WeaverseNe
118
118
  */
119
119
  declare function buildWeaverseNextRequestInfo(context?: WeaverseNextRequestContext): WeaverseNextRequestInfo;
120
120
 
121
+ declare const DEFAULT_REVALIDATE_ENDPOINT = "/api/weaverse/revalidate";
122
+ /**
123
+ * Minimal runtime surface the in-place apply needs. Structural (not the
124
+ * concrete `WeaverseNextRuntime` class) so unit tests can drive it with a
125
+ * plain mock.
126
+ */
127
+ interface RevalidateItemRuntimeLike {
128
+ itemInstances: Map<string, {
129
+ setData: (update: Record<string, unknown>) => unknown;
130
+ }>;
131
+ }
132
+ /**
133
+ * Studio per-item loader revalidation: POST the unsaved draft item to the
134
+ * app's revalidate route (see `createWeaverseNextRevalidateHandler`) and apply
135
+ * the returned `loaderData` to the live item instance in place.
136
+ *
137
+ * No `router.refresh()` is involved, so the RSC tree is never re-applied — no
138
+ * page remount, no scroll reset, and the draft payload never touches the URL.
139
+ *
140
+ * Throws on any failure (missing route, non-OK response, unknown item) so the
141
+ * Builder Studio bridge can detect the miss and fall back to its legacy
142
+ * refresh-based revalidation for this window.
143
+ */
144
+ declare function revalidateWeaverseNextItem(runtime: RevalidateItemRuntimeLike, draftItem: WeaverseNextComponentData, endpoint?: string): Promise<void>;
145
+
121
146
  declare global {
122
147
  interface Window {
123
148
  __weaverse?: WeaverseNextRuntime;
@@ -146,6 +171,7 @@ declare function bindWeaverseNextStudioRuntime(runtime: WeaverseNextRuntime): bo
146
171
  interface WeaverseNextStudioBridgeProps {
147
172
  navigate?: WeaverseNextRuntimeInternal['navigate'];
148
173
  revalidate?: WeaverseNextRuntimeInternal['revalidate'];
174
+ revalidateItem?: WeaverseNextRuntimeInternal['revalidateItem'];
149
175
  runtime: WeaverseNextRuntime;
150
176
  }
151
177
  /** Page-level Studio runtime binder. */
@@ -231,6 +257,11 @@ declare function createWeaverseNextThemeSettingsStore(options?: CreateWeaverseNe
231
257
  */
232
258
  declare function useWeaverseNextStudioInternals(options?: CreateWeaverseNextStudioInternalsOptions): WeaverseNextStudioInternals;
233
259
  interface WeaverseNextStudioProps extends CreateWeaverseNextStudioInternalsOptions {
260
+ /**
261
+ * Route the app mounted with `createWeaverseNextRevalidateHandler`.
262
+ * Defaults to `/api/weaverse/revalidate`.
263
+ */
264
+ revalidateEndpoint?: string;
234
265
  runtime: WeaverseNextRuntime;
235
266
  }
236
267
  /**
@@ -247,4 +278,4 @@ interface WeaverseNextStudioProps extends CreateWeaverseNextStudioInternalsOptio
247
278
  */
248
279
  declare function WeaverseNextStudio(props: WeaverseNextStudioProps): react_jsx_runtime.JSX.Element;
249
280
 
250
- export { type CreateWeaverseNextStudioInternalsOptions, type CreateWeaverseNextThemeSettingsStoreOptions, type ResolveWeaverseNextStudioScriptSrcOptions, type RunComponentLoadersArgs, WeaverseNextClient, WeaverseNextClientConfig, WeaverseNextCommerceContext, WeaverseNextLoaderData, WeaverseNextProvider, type WeaverseNextProviderProps, WeaverseNextRenderer, type WeaverseNextRendererProps, WeaverseNextRequestContext, WeaverseNextRequestInfo, type WeaverseNextRouterLike, WeaverseNextRuntime, WeaverseNextRuntimeConfig, WeaverseNextRuntimeInternal, WeaverseNextStudio, WeaverseNextStudioBridge, type WeaverseNextStudioBridgeProps, WeaverseNextStudioConnect, type WeaverseNextStudioConnectProps, type WeaverseNextStudioInternals, type WeaverseNextStudioProps, WeaverseNextThemeSettingsStore, bindWeaverseNextStudioRuntime, buildWeaverseNextRequestInfo, createWeaverseNextClient, createWeaverseNextRuntime, createWeaverseNextStudioInternals, createWeaverseNextThemeSettingsStore, resolveWeaverseNextStudioScriptSrc, runWeaverseComponentLoaders, useThemeSettings, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData };
281
+ export { type CreateWeaverseNextStudioInternalsOptions, type CreateWeaverseNextThemeSettingsStoreOptions, DEFAULT_REVALIDATE_ENDPOINT, type ResolveWeaverseNextStudioScriptSrcOptions, type RevalidateItemRuntimeLike, type RunComponentLoadersArgs, WeaverseNextClient, WeaverseNextClientConfig, WeaverseNextCommerceContext, WeaverseNextComponentData, WeaverseNextLoaderData, WeaverseNextProvider, type WeaverseNextProviderProps, WeaverseNextRenderer, type WeaverseNextRendererProps, WeaverseNextRequestContext, WeaverseNextRequestInfo, type WeaverseNextRouterLike, WeaverseNextRuntime, WeaverseNextRuntimeConfig, WeaverseNextRuntimeInternal, WeaverseNextStudio, WeaverseNextStudioBridge, type WeaverseNextStudioBridgeProps, WeaverseNextStudioConnect, type WeaverseNextStudioConnectProps, type WeaverseNextStudioInternals, type WeaverseNextStudioProps, WeaverseNextThemeSettingsStore, bindWeaverseNextStudioRuntime, buildWeaverseNextRequestInfo, createWeaverseNextClient, createWeaverseNextRuntime, createWeaverseNextStudioInternals, createWeaverseNextThemeSettingsStore, resolveWeaverseNextStudioScriptSrc, revalidateWeaverseNextItem, runWeaverseComponentLoaders, useThemeSettings, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData };
package/dist/index.js CHANGED
@@ -328,8 +328,22 @@ function toQueryRecord(searchParams) {
328
328
  }
329
329
  return queries;
330
330
  }
331
+ var TRANSIENT_STUDIO_PARAMS = /* @__PURE__ */ new Set([
332
+ "weaverseDraftItem",
333
+ // Legacy name from the original design-mode draft-item spike. Keep it out of
334
+ // runtime requestInfo too, in case an older Builder bundle is in front of a
335
+ // newer Next storefront.
336
+ "__weaverseDraftItem"
337
+ ]);
338
+ function getRequestInfoSearchParams(context) {
339
+ let searchParams = new URLSearchParams(getSearchParamsFromContext(context));
340
+ for (let key of TRANSIENT_STUDIO_PARAMS) {
341
+ searchParams.delete(key);
342
+ }
343
+ return searchParams;
344
+ }
331
345
  function buildWeaverseNextRequestInfo(context) {
332
- let searchParams = getSearchParamsFromContext(context);
346
+ let searchParams = getRequestInfoSearchParams(context);
333
347
  let search = searchParams.toString();
334
348
  return {
335
349
  pathname: getPathnameFromContext(context),
@@ -450,6 +464,7 @@ function createWeaverseNextRuntime(config) {
450
464
  if (!(existing.isDesignMode || nextIsDesignMode)) {
451
465
  existing.setProjectData(page);
452
466
  }
467
+ existing.__weaverseNextLatestData = page;
453
468
  existing.dataContext = resolveDataContext(config);
454
469
  existing.requestInfo = requestInfo;
455
470
  existing.projectId = resolveProjectId(config.client, config.data, page.id);
@@ -475,6 +490,7 @@ function createWeaverseNextRuntime(config) {
475
490
  }
476
491
  let runtime = new WeaverseNextRuntime(config);
477
492
  runtime.__weaverseNextRequestKey = requestKey;
493
+ runtime.__weaverseNextLatestData = page;
478
494
  registerRuntime(runtime);
479
495
  return runtime;
480
496
  }
@@ -493,16 +509,39 @@ function bindWeaverseNextStudioRuntime(runtime) {
493
509
  return true;
494
510
  }
495
511
  studio.refreshStudio?.({
496
- data: runtime.data,
512
+ data: boundRuntime.__weaverseNextLatestData ?? runtime.data,
497
513
  pageId: runtime.pageId,
498
514
  requestInfo: runtime.requestInfo
499
515
  });
500
516
  return true;
501
517
  }
518
+
519
+ // src/revalidate-item.ts
520
+ var DEFAULT_REVALIDATE_ENDPOINT = "/api/weaverse/revalidate";
521
+ async function revalidateWeaverseNextItem(runtime, draftItem, endpoint = DEFAULT_REVALIDATE_ENDPOINT) {
522
+ let instance = runtime.itemInstances.get(draftItem.id);
523
+ if (!instance) {
524
+ throw new Error(
525
+ `[weaverse-next] No live item instance for "${draftItem.id}".`
526
+ );
527
+ }
528
+ let response = await fetch(endpoint, {
529
+ method: "POST",
530
+ headers: { "Content-Type": "application/json" },
531
+ body: JSON.stringify({ draftItem })
532
+ });
533
+ if (!response.ok) {
534
+ throw new Error(
535
+ `[weaverse-next] Revalidate endpoint responded ${response.status}.`
536
+ );
537
+ }
538
+ let { loaderData } = await response.json();
539
+ instance.setData({ loaderData: loaderData ?? null });
540
+ }
502
541
  var STUDIO_BIND_RETRY_INTERVAL_MS = 50;
503
542
  var STUDIO_BIND_MAX_ATTEMPTS = 100;
504
543
  function WeaverseNextStudioBridge(props) {
505
- let { runtime, navigate, revalidate } = props;
544
+ let { runtime, navigate, revalidate, revalidateItem } = props;
506
545
  let lastRuntimeRef = react$1.useRef(runtime);
507
546
  let lastRuntimeDataRef = react$1.useRef(runtime.data);
508
547
  let lastRequestInfoRef = react$1.useRef(runtime.requestInfo);
@@ -513,6 +552,9 @@ function WeaverseNextStudioBridge(props) {
513
552
  if (revalidate) {
514
553
  runtime.internal.revalidate = revalidate;
515
554
  }
555
+ if (revalidateItem) {
556
+ runtime.internal.revalidateItem = revalidateItem;
557
+ }
516
558
  if (bindWeaverseNextStudioRuntime(runtime) || !runtime.isDesignMode) {
517
559
  return;
518
560
  }
@@ -524,7 +566,7 @@ function WeaverseNextStudioBridge(props) {
524
566
  }
525
567
  }, STUDIO_BIND_RETRY_INTERVAL_MS);
526
568
  return () => window.clearInterval(interval);
527
- }, [runtime, navigate, revalidate]);
569
+ }, [runtime, navigate, revalidate, revalidateItem]);
528
570
  react$1.useEffect(() => {
529
571
  if (lastRuntimeRef.current !== runtime) {
530
572
  lastRuntimeRef.current = runtime;
@@ -577,13 +619,23 @@ function useWeaverseNextStudioInternals(options) {
577
619
  return ref.current.internals;
578
620
  }
579
621
  function WeaverseNextStudio(props) {
580
- let { runtime, replace } = props;
622
+ let { runtime, replace, revalidateEndpoint } = props;
581
623
  let { navigate, revalidate } = useWeaverseNextStudioInternals({ replace });
624
+ let endpoint = revalidateEndpoint ?? DEFAULT_REVALIDATE_ENDPOINT;
625
+ let revalidateItemRef = react$1.useRef(null);
626
+ if (revalidateItemRef.current?.endpoint !== endpoint || revalidateItemRef.current.runtime !== runtime) {
627
+ revalidateItemRef.current = {
628
+ endpoint,
629
+ revalidateItem: (draftItem) => revalidateWeaverseNextItem(runtime, draftItem, endpoint),
630
+ runtime
631
+ };
632
+ }
582
633
  return /* @__PURE__ */ jsxRuntime.jsx(
583
634
  WeaverseNextStudioBridge,
584
635
  {
585
636
  navigate,
586
637
  revalidate,
638
+ revalidateItem: revalidateItemRef.current.revalidateItem,
587
639
  runtime
588
640
  }
589
641
  );
@@ -760,6 +812,7 @@ Object.defineProperty(exports, "createSchema", {
760
812
  enumerable: true,
761
813
  get: function () { return schema.createSchema; }
762
814
  });
815
+ exports.DEFAULT_REVALIDATE_ENDPOINT = DEFAULT_REVALIDATE_ENDPOINT;
763
816
  exports.WeaverseNextProvider = WeaverseNextProvider;
764
817
  exports.WeaverseNextRenderer = WeaverseNextRenderer;
765
818
  exports.WeaverseNextRuntime = WeaverseNextRuntime;
@@ -773,6 +826,7 @@ exports.createWeaverseNextRuntime = createWeaverseNextRuntime;
773
826
  exports.createWeaverseNextStudioInternals = createWeaverseNextStudioInternals;
774
827
  exports.createWeaverseNextThemeSettingsStore = createWeaverseNextThemeSettingsStore;
775
828
  exports.resolveWeaverseNextStudioScriptSrc = resolveWeaverseNextStudioScriptSrc;
829
+ exports.revalidateWeaverseNextItem = revalidateWeaverseNextItem;
776
830
  exports.runWeaverseComponentLoaders = runWeaverseComponentLoaders;
777
831
  exports.useThemeSettings = useThemeSettings;
778
832
  exports.useWeaverseCommerce = useWeaverseCommerce;