@weaverse/next 0.1.0-alpha.7 → 0.1.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +265 -9
- package/dist/index.d.ts +265 -9
- package/dist/index.js +437 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +431 -25
- package/dist/index.mjs.map +1 -1
- package/dist/{seo-B9yNko4W.d.mts → seo-Dos9t22_.d.mts} +84 -2
- package/dist/{seo-B9yNko4W.d.ts → seo-Dos9t22_.d.ts} +84 -2
- package/dist/server.d.mts +2 -2
- package/dist/server.d.ts +2 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,20 +1,91 @@
|
|
|
1
1
|
import { buildWeaverseNextRequestInfo, generateDataFromSchema } from './chunk-6PMZ77RA.mjs';
|
|
2
2
|
export { buildWeaverseNextRequestInfo, formatWeaverseNextSeoMetadata, getWeaverseNextSeoMetadata, runWeaverseComponentLoaders } from './chunk-6PMZ77RA.mjs';
|
|
3
|
-
import { WeaverseRoot, Weaverse, WeaverseItemStore } from '@weaverse/react';
|
|
3
|
+
import { WeaverseRoot, Weaverse, WeaverseItemStore, useSafeExternalStore } from '@weaverse/react';
|
|
4
4
|
export { isBrowser, isIframe, useChildInstances, useItemInstance, useParentInstance, useWeaverse } from '@weaverse/react';
|
|
5
5
|
import { createSchema } from '@weaverse/schema';
|
|
6
6
|
export { createSchema } from '@weaverse/schema';
|
|
7
7
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
8
|
-
import { createContext, memo, useContext, useMemo,
|
|
8
|
+
import { createContext, memo, useContext, useMemo, useEffect, useLayoutEffect, useRef, useSyncExternalStore } from 'react';
|
|
9
9
|
import { useRouter } from 'next/navigation';
|
|
10
10
|
|
|
11
|
+
function flattenItemData(update) {
|
|
12
|
+
let { data, ...rest } = update;
|
|
13
|
+
if (!(data && typeof data === "object" && !Array.isArray(data))) {
|
|
14
|
+
return rest;
|
|
15
|
+
}
|
|
16
|
+
return { ...data, ...rest };
|
|
17
|
+
}
|
|
18
|
+
var deferredItemUpdates = null;
|
|
19
|
+
function collectDeferredItemUpdates(create) {
|
|
20
|
+
let previousQueue = deferredItemUpdates;
|
|
21
|
+
let queue = /* @__PURE__ */ new Set();
|
|
22
|
+
deferredItemUpdates = queue;
|
|
23
|
+
try {
|
|
24
|
+
return [create(), [...queue]];
|
|
25
|
+
} finally {
|
|
26
|
+
deferredItemUpdates = previousQueue;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
11
29
|
var WeaverseNextItem = class extends WeaverseItemStore {
|
|
30
|
+
/**
|
|
31
|
+
* Cached merged snapshot (base `_store` + translations). Reset whenever the
|
|
32
|
+
* `_store` ref or the item's translation entry ref changes, so
|
|
33
|
+
* `useSyncExternalStore` sees a stable object between unrelated re-renders.
|
|
34
|
+
*/
|
|
35
|
+
_cachedSnapshot = null;
|
|
36
|
+
_snapshotStoreRef = null;
|
|
37
|
+
_snapshotTranslationRef = null;
|
|
12
38
|
constructor(initialData, weaverse) {
|
|
13
39
|
super(initialData, weaverse);
|
|
14
|
-
let { data, ...rest } = initialData;
|
|
15
40
|
let schemaData = generateDataFromSchema(this.Element?.schema);
|
|
16
|
-
Object.assign(this._store, schemaData,
|
|
41
|
+
Object.assign(this._store, schemaData, flattenItemData(initialData));
|
|
17
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Flatten nested `data` on updates exactly like the constructor does. Core's
|
|
45
|
+
* `initProject()` calls `setData(item)` when a new runtime serves a page
|
|
46
|
+
* whose item instances already exist (e.g. locale/client navigation), and
|
|
47
|
+
* the inherited shallow merge would leave stale top-level props behind.
|
|
48
|
+
* Assigning through the inherited `data` setter swaps the `_store` ref,
|
|
49
|
+
* which invalidates the memoized snapshot below. The subscriber emit is
|
|
50
|
+
* queued instead of fired when a render-phase deferral is active (see
|
|
51
|
+
* `collectDeferredItemUpdates`).
|
|
52
|
+
*/
|
|
53
|
+
setData = (update) => {
|
|
54
|
+
this.data = flattenItemData(update);
|
|
55
|
+
if (deferredItemUpdates) {
|
|
56
|
+
deferredItemUpdates.add(this);
|
|
57
|
+
} else {
|
|
58
|
+
this.triggerUpdate();
|
|
59
|
+
}
|
|
60
|
+
return this.data;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Overlay item-level translations onto the base store when the runtime is in
|
|
64
|
+
* translation mode. Mirrors Hydrogen's `WeaverseHydrogenItem.getSnapShot()`:
|
|
65
|
+
* memoized by `_store` ref + translation entry ref so the returned object is
|
|
66
|
+
* referentially stable, and a fast path that returns the base store untouched
|
|
67
|
+
* when the item has no translations.
|
|
68
|
+
*/
|
|
69
|
+
getSnapShot = () => {
|
|
70
|
+
let base = this._store;
|
|
71
|
+
let translations = this.weaverse.translationMap[this._id];
|
|
72
|
+
if (!translations) {
|
|
73
|
+
return base;
|
|
74
|
+
}
|
|
75
|
+
if (this._cachedSnapshot && this._snapshotStoreRef === base && this._snapshotTranslationRef === translations) {
|
|
76
|
+
return this._cachedSnapshot;
|
|
77
|
+
}
|
|
78
|
+
let merged = { ...base };
|
|
79
|
+
for (let [key, entry] of Object.entries(translations)) {
|
|
80
|
+
if (entry.translatedValue !== void 0) {
|
|
81
|
+
merged[key] = entry.translatedValue;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
this._cachedSnapshot = merged;
|
|
85
|
+
this._snapshotStoreRef = base;
|
|
86
|
+
this._snapshotTranslationRef = translations;
|
|
87
|
+
return merged;
|
|
88
|
+
};
|
|
18
89
|
};
|
|
19
90
|
function ensureNextItemConstructor() {
|
|
20
91
|
if (!Weaverse.ItemConstructor || Weaverse.ItemConstructor === WeaverseItemStore || Weaverse.ItemConstructor === WeaverseNextItem) {
|
|
@@ -139,9 +210,136 @@ function createWeaverseNextThemeSettingsStore(options = {}) {
|
|
|
139
210
|
};
|
|
140
211
|
return store;
|
|
141
212
|
}
|
|
213
|
+
function getNestedKey(obj, path, fallback) {
|
|
214
|
+
let keys = path.split(".");
|
|
215
|
+
let current = obj;
|
|
216
|
+
for (let key of keys) {
|
|
217
|
+
if (current == null || typeof current !== "object") {
|
|
218
|
+
return fallback;
|
|
219
|
+
}
|
|
220
|
+
current = current[key];
|
|
221
|
+
}
|
|
222
|
+
if (typeof current === "string") {
|
|
223
|
+
return current;
|
|
224
|
+
}
|
|
225
|
+
return fallback;
|
|
226
|
+
}
|
|
227
|
+
function interpolate(template, variables) {
|
|
228
|
+
if (!variables) {
|
|
229
|
+
return template;
|
|
230
|
+
}
|
|
231
|
+
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
232
|
+
let value = variables[key];
|
|
233
|
+
return value === void 0 ? match : String(value);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
var TranslationContext = createContext(null);
|
|
237
|
+
TranslationContext.displayName = "WeaverseNextTranslationContext";
|
|
238
|
+
function createTranslate(sources) {
|
|
239
|
+
let { staticContent, merchantOverrides, designOverrides, externalT } = sources;
|
|
240
|
+
return (key, variables) => {
|
|
241
|
+
if (externalT) {
|
|
242
|
+
let external = externalT(key, variables);
|
|
243
|
+
if (external && external !== key) {
|
|
244
|
+
return external;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
let design = designOverrides && Object.hasOwn(designOverrides, key) ? designOverrides[key] : void 0;
|
|
248
|
+
let override = merchantOverrides ? getNestedKey(merchantOverrides, key) : void 0;
|
|
249
|
+
let staticValue = getNestedKey(staticContent, key);
|
|
250
|
+
let raw = design ?? override ?? staticValue ?? key;
|
|
251
|
+
return interpolate(raw, variables);
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
var EMPTY = {};
|
|
255
|
+
var NOOP_SUBSCRIBE = () => () => {
|
|
256
|
+
};
|
|
257
|
+
var NOOP_SNAPSHOT = () => EMPTY;
|
|
258
|
+
function TranslationProvider({
|
|
259
|
+
staticContent,
|
|
260
|
+
merchantOverrides,
|
|
261
|
+
t: externalT,
|
|
262
|
+
translationStore,
|
|
263
|
+
themeTextStore,
|
|
264
|
+
children
|
|
265
|
+
}) {
|
|
266
|
+
let store = translationStore ?? themeTextStore ?? null;
|
|
267
|
+
let designOverrides = useSafeExternalStore(
|
|
268
|
+
store?.subscribe ?? NOOP_SUBSCRIBE,
|
|
269
|
+
store?.getSnapshot ?? NOOP_SNAPSHOT,
|
|
270
|
+
store?.getServerSnapshot ?? NOOP_SNAPSHOT
|
|
271
|
+
);
|
|
272
|
+
let value = useMemo(
|
|
273
|
+
() => ({
|
|
274
|
+
t: createTranslate({
|
|
275
|
+
staticContent,
|
|
276
|
+
merchantOverrides,
|
|
277
|
+
designOverrides,
|
|
278
|
+
externalT
|
|
279
|
+
}),
|
|
280
|
+
translationStore: store,
|
|
281
|
+
// Deprecated alias — same instance, kept for backward compatibility.
|
|
282
|
+
themeTextStore: store,
|
|
283
|
+
merchantOverrides: merchantOverrides ?? null
|
|
284
|
+
}),
|
|
285
|
+
[staticContent, merchantOverrides, designOverrides, externalT, store]
|
|
286
|
+
);
|
|
287
|
+
return /* @__PURE__ */ jsx(TranslationContext.Provider, { value, children });
|
|
288
|
+
}
|
|
289
|
+
function useTranslation() {
|
|
290
|
+
let ctx = useContext(TranslationContext);
|
|
291
|
+
if (!ctx) {
|
|
292
|
+
throw new Error(
|
|
293
|
+
"useTranslation must be used within <TranslationProvider>. Wrap your app with <WeaverseNextRootProvider>."
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
return ctx;
|
|
297
|
+
}
|
|
298
|
+
var ThemeTextProvider = TranslationProvider;
|
|
299
|
+
var useThemeText = useTranslation;
|
|
300
|
+
|
|
301
|
+
// src/translation-store.ts
|
|
302
|
+
var TranslationStore = class {
|
|
303
|
+
overrides = {};
|
|
304
|
+
listeners = /* @__PURE__ */ new Set();
|
|
305
|
+
setOverrides = (overrides) => {
|
|
306
|
+
this.overrides = { ...overrides };
|
|
307
|
+
this.emit();
|
|
308
|
+
};
|
|
309
|
+
updateOverrides = (newOverrides) => {
|
|
310
|
+
this.overrides = { ...this.overrides, ...newOverrides };
|
|
311
|
+
this.emit();
|
|
312
|
+
};
|
|
313
|
+
getSnapshot = () => this.overrides;
|
|
314
|
+
getServerSnapshot = () => this.overrides;
|
|
315
|
+
subscribe = (callback) => {
|
|
316
|
+
this.listeners.add(callback);
|
|
317
|
+
return () => {
|
|
318
|
+
this.listeners.delete(callback);
|
|
319
|
+
};
|
|
320
|
+
};
|
|
321
|
+
emit = () => {
|
|
322
|
+
for (const listener of Array.from(this.listeners)) {
|
|
323
|
+
try {
|
|
324
|
+
listener();
|
|
325
|
+
} catch (error) {
|
|
326
|
+
console.error("TranslationStore: Listener error", error);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
var ThemeTextStore = TranslationStore;
|
|
142
332
|
var WeaverseNextRootContext = createContext(null);
|
|
143
333
|
function WeaverseNextRootProvider(props) {
|
|
144
|
-
let {
|
|
334
|
+
let {
|
|
335
|
+
children,
|
|
336
|
+
initialThemeSettings,
|
|
337
|
+
merchantOverrides,
|
|
338
|
+
staticContent,
|
|
339
|
+
t,
|
|
340
|
+
themeSchema,
|
|
341
|
+
publicEnv
|
|
342
|
+
} = props;
|
|
145
343
|
let storeRef = useRef(null);
|
|
146
344
|
if (!storeRef.current) {
|
|
147
345
|
storeRef.current = createWeaverseNextThemeSettingsStore({
|
|
@@ -151,6 +349,11 @@ function WeaverseNextRootProvider(props) {
|
|
|
151
349
|
});
|
|
152
350
|
}
|
|
153
351
|
let themeSettingsStore = storeRef.current;
|
|
352
|
+
let translationStoreRef = useRef(null);
|
|
353
|
+
if (!translationStoreRef.current) {
|
|
354
|
+
translationStoreRef.current = new TranslationStore();
|
|
355
|
+
}
|
|
356
|
+
let translationStore = translationStoreRef.current;
|
|
154
357
|
let appliedThemeSettingsRef = useRef(initialThemeSettings);
|
|
155
358
|
useEffect(() => {
|
|
156
359
|
if (initialThemeSettings && appliedThemeSettingsRef.current !== initialThemeSettings) {
|
|
@@ -158,25 +361,59 @@ function WeaverseNextRootProvider(props) {
|
|
|
158
361
|
appliedThemeSettingsRef.current = initialThemeSettings;
|
|
159
362
|
}
|
|
160
363
|
}, [initialThemeSettings, themeSettingsStore]);
|
|
364
|
+
let resolvedStaticContent = staticContent ?? getSchemaStaticContent(themeSchema);
|
|
161
365
|
let rootContextValue = useMemo(
|
|
162
|
-
() => ({
|
|
163
|
-
|
|
366
|
+
() => ({
|
|
367
|
+
merchantOverrides,
|
|
368
|
+
staticContent: resolvedStaticContent,
|
|
369
|
+
themeSettingsStore,
|
|
370
|
+
translationStore
|
|
371
|
+
}),
|
|
372
|
+
[
|
|
373
|
+
merchantOverrides,
|
|
374
|
+
resolvedStaticContent,
|
|
375
|
+
themeSettingsStore,
|
|
376
|
+
translationStore
|
|
377
|
+
]
|
|
164
378
|
);
|
|
165
379
|
let contextValue = useMemo(
|
|
166
380
|
() => ({
|
|
381
|
+
merchantOverrides,
|
|
167
382
|
themeSettings: themeSettingsStore.getSnapshot(),
|
|
168
|
-
themeSettingsStore
|
|
383
|
+
themeSettingsStore,
|
|
384
|
+
translationStore
|
|
169
385
|
}),
|
|
170
|
-
[themeSettingsStore]
|
|
386
|
+
[merchantOverrides, themeSettingsStore, translationStore]
|
|
171
387
|
);
|
|
172
|
-
return /* @__PURE__ */ jsx(WeaverseNextRootContext.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(WeaverseNextContext.Provider, { value: contextValue, children
|
|
388
|
+
return /* @__PURE__ */ jsx(WeaverseNextRootContext.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(WeaverseNextContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
|
|
389
|
+
TranslationProvider,
|
|
390
|
+
{
|
|
391
|
+
merchantOverrides,
|
|
392
|
+
staticContent: resolvedStaticContent,
|
|
393
|
+
t,
|
|
394
|
+
translationStore,
|
|
395
|
+
children
|
|
396
|
+
}
|
|
397
|
+
) }) });
|
|
173
398
|
}
|
|
174
399
|
var EMPTY_THEME_SETTINGS = {};
|
|
400
|
+
var EMPTY_STATIC_CONTENT = {};
|
|
401
|
+
function getSchemaStaticContent(schema) {
|
|
402
|
+
let i18n = schema?.i18n;
|
|
403
|
+
return i18n?.staticContent ?? EMPTY_STATIC_CONTENT;
|
|
404
|
+
}
|
|
175
405
|
var WeaverseNextContext = createContext(null);
|
|
176
406
|
function WeaverseNextProvider(props) {
|
|
177
407
|
let { children, client, rootData, pageData, commerce, themeSettings } = props;
|
|
178
408
|
let rootContext = useContext(WeaverseNextRootContext);
|
|
179
409
|
let themeSettingsValue = themeSettings ?? client?.themeSettings ?? EMPTY_THEME_SETTINGS;
|
|
410
|
+
let ownTranslationStoreRef = useRef(null);
|
|
411
|
+
if (!(rootContext || ownTranslationStoreRef.current)) {
|
|
412
|
+
ownTranslationStoreRef.current = new TranslationStore();
|
|
413
|
+
}
|
|
414
|
+
let translationStore = rootContext?.translationStore ?? ownTranslationStoreRef.current;
|
|
415
|
+
let staticContent = props.staticContent ?? rootContext?.staticContent ?? getSchemaStaticContent(client?.themeSchema);
|
|
416
|
+
let merchantOverrides = props.merchantOverrides ?? rootContext?.merchantOverrides;
|
|
180
417
|
let ownThemeSettingsStore = useMemo(() => {
|
|
181
418
|
if (rootContext) {
|
|
182
419
|
return null;
|
|
@@ -200,12 +437,31 @@ function WeaverseNextProvider(props) {
|
|
|
200
437
|
rootData,
|
|
201
438
|
pageData,
|
|
202
439
|
commerce: commerce ?? client?.commerce,
|
|
440
|
+
merchantOverrides,
|
|
203
441
|
themeSettings: themeSettingsStore.getSnapshot(),
|
|
204
|
-
themeSettingsStore
|
|
442
|
+
themeSettingsStore,
|
|
443
|
+
translationStore
|
|
205
444
|
}),
|
|
206
|
-
[
|
|
445
|
+
[
|
|
446
|
+
client,
|
|
447
|
+
rootData,
|
|
448
|
+
pageData,
|
|
449
|
+
commerce,
|
|
450
|
+
merchantOverrides,
|
|
451
|
+
themeSettingsStore,
|
|
452
|
+
translationStore
|
|
453
|
+
]
|
|
207
454
|
);
|
|
208
|
-
return /* @__PURE__ */ jsx(WeaverseNextContext.Provider, { value, children
|
|
455
|
+
return /* @__PURE__ */ jsx(WeaverseNextContext.Provider, { value, children: /* @__PURE__ */ jsx(
|
|
456
|
+
TranslationProvider,
|
|
457
|
+
{
|
|
458
|
+
merchantOverrides,
|
|
459
|
+
staticContent,
|
|
460
|
+
t: props.t,
|
|
461
|
+
translationStore,
|
|
462
|
+
children
|
|
463
|
+
}
|
|
464
|
+
) });
|
|
209
465
|
}
|
|
210
466
|
|
|
211
467
|
// src/hooks.ts
|
|
@@ -289,9 +545,31 @@ var WeaverseNextRuntime = class extends Weaverse {
|
|
|
289
545
|
isPreviewMode;
|
|
290
546
|
isRevisionPreview;
|
|
291
547
|
sectionType;
|
|
548
|
+
// ─── Item-level translation sidecar (design mode only) ─────────────
|
|
549
|
+
/**
|
|
550
|
+
* Translation map received from Builder in design mode, keyed by item ID.
|
|
551
|
+
* `WeaverseNextItem.getSnapShot()` overlays these onto the data handed to
|
|
552
|
+
* components, so translations render without mutating the base `_store`.
|
|
553
|
+
*/
|
|
292
554
|
translationMap = {};
|
|
293
|
-
translationLocale =
|
|
294
|
-
translationLanguageId =
|
|
555
|
+
translationLocale = String();
|
|
556
|
+
translationLanguageId = String();
|
|
557
|
+
/**
|
|
558
|
+
* Fresh page data captured while React was rendering. Runtime reuse happens
|
|
559
|
+
* inside the renderer's render phase (`useMemo`), where applying it through
|
|
560
|
+
* `setProjectData()` would emit item updates to `useSyncExternalStore`
|
|
561
|
+
* subscribers mid-render. The renderer applies it post-commit via
|
|
562
|
+
* `flushRenderPhaseUpdates()`. Never set on design-mode runtimes — the live
|
|
563
|
+
* Studio tree owns the page data there.
|
|
564
|
+
*/
|
|
565
|
+
pendingProjectData;
|
|
566
|
+
/**
|
|
567
|
+
* Reused item instances whose data was refreshed while this runtime was
|
|
568
|
+
* constructed during render (core `initProject()` calls `setData()` on
|
|
569
|
+
* them). Their data is already fresh; only the subscriber notification was
|
|
570
|
+
* deferred to `flushRenderPhaseUpdates()`.
|
|
571
|
+
*/
|
|
572
|
+
pendingItemUpdates = [];
|
|
295
573
|
constructor(config) {
|
|
296
574
|
let { client, data } = config;
|
|
297
575
|
let page = getRenderablePage(data);
|
|
@@ -313,7 +591,9 @@ var WeaverseNextRuntime = class extends Weaverse {
|
|
|
313
591
|
this.isPreviewMode = requestContext?.isPreviewMode ?? false;
|
|
314
592
|
this.isRevisionPreview = requestContext?.isRevisionPreview ?? false;
|
|
315
593
|
this.sectionType = requestContext?.sectionType;
|
|
594
|
+
let translationStore = config.translationStore ?? new TranslationStore();
|
|
316
595
|
this.internal = {
|
|
596
|
+
merchantOverrides: config.merchantOverrides,
|
|
317
597
|
navigate: config.navigate,
|
|
318
598
|
pageAssignment: data.pageAssignment,
|
|
319
599
|
project: data.project,
|
|
@@ -321,17 +601,119 @@ var WeaverseNextRuntime = class extends Weaverse {
|
|
|
321
601
|
themeSettingsStore: config.themeSettingsStore ?? createWeaverseNextThemeSettingsStore({
|
|
322
602
|
schema: client?.themeSchema,
|
|
323
603
|
settings: client?.themeSettings
|
|
324
|
-
})
|
|
604
|
+
}),
|
|
605
|
+
translationStore,
|
|
606
|
+
themeTextStore: translationStore
|
|
325
607
|
};
|
|
608
|
+
this.extractTranslationSidecar();
|
|
326
609
|
}
|
|
327
|
-
|
|
610
|
+
/**
|
|
611
|
+
* Pull `translationMap` / `translationLocale` / `translationLanguageId` off
|
|
612
|
+
* the current page data (Builder attaches them in design mode). Unlike
|
|
613
|
+
* Hydrogen, this also clears the sidecar to defaults when the new page data
|
|
614
|
+
* carries none, so a reused runtime / project-data swap can't leave a stale
|
|
615
|
+
* map overlaying the fresh tree.
|
|
616
|
+
*/
|
|
617
|
+
extractTranslationSidecar = () => {
|
|
618
|
+
let pageData = this.data;
|
|
619
|
+
let translationMap = pageData?.translationMap;
|
|
620
|
+
if (translationMap) {
|
|
621
|
+
this.translationMap = translationMap;
|
|
622
|
+
this.translationLocale = pageData?.translationLocale || "";
|
|
623
|
+
this.translationLanguageId = pageData?.translationLanguageId || "";
|
|
624
|
+
} else {
|
|
625
|
+
this.translationMap = {};
|
|
626
|
+
this.translationLocale = "";
|
|
627
|
+
this.translationLanguageId = "";
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
/**
|
|
631
|
+
* Replace the translation sidecar (Builder pushes this when translation data
|
|
632
|
+
* arrives or the active language changes) and refresh every item so their
|
|
633
|
+
* merged snapshots recompute.
|
|
634
|
+
*/
|
|
328
635
|
setTranslationSidecar = (map = {}, locale = "", languageId = "") => {
|
|
329
636
|
this.translationMap = map;
|
|
330
637
|
this.translationLocale = locale;
|
|
331
638
|
this.translationLanguageId = languageId;
|
|
639
|
+
this.refreshAllItems();
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* Update a single translatable field for one item. Assigns a new per-item
|
|
643
|
+
* entry object so `WeaverseNextItem.getSnapShot()`'s translation-ref cache
|
|
644
|
+
* invalidates, then triggers only that item's subscribers.
|
|
645
|
+
*/
|
|
646
|
+
updateTranslation = (itemId, key, originalValue, translatedValue) => {
|
|
647
|
+
if (!this.translationMap[itemId]) {
|
|
648
|
+
this.translationMap[itemId] = {};
|
|
649
|
+
}
|
|
650
|
+
this.translationMap[itemId] = {
|
|
651
|
+
...this.translationMap[itemId],
|
|
652
|
+
[key]: { originalValue, translatedValue }
|
|
653
|
+
};
|
|
654
|
+
let instance = this.itemInstances.get(itemId);
|
|
655
|
+
if (instance) {
|
|
656
|
+
instance.triggerUpdate();
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
/**
|
|
660
|
+
* Collect translation changes for the save flow. Returns `undefined` unless
|
|
661
|
+
* both the locale and language ID are set and at least one entry exists;
|
|
662
|
+
* each entry key is namespaced as `data.<field>` to match Builder.
|
|
663
|
+
*/
|
|
664
|
+
getTranslationChanges = () => {
|
|
665
|
+
let languageId = this.translationLanguageId;
|
|
666
|
+
if (!(this.translationLocale && languageId)) {
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
let entries = [];
|
|
670
|
+
for (let [itemId, fields] of Object.entries(this.translationMap)) {
|
|
671
|
+
for (let [key, entry] of Object.entries(fields)) {
|
|
672
|
+
entries.push({
|
|
673
|
+
itemId,
|
|
674
|
+
key: `data.${key}`,
|
|
675
|
+
originalValue: entry.originalValue,
|
|
676
|
+
translatedValue: entry.translatedValue
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
if (entries.length === 0) {
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
return { languageId, entries };
|
|
684
|
+
};
|
|
685
|
+
/**
|
|
686
|
+
* Re-extract the translation sidecar whenever project data is replaced (route
|
|
687
|
+
* change / non-design reuse), before rebuilding item stores. Takes the
|
|
688
|
+
* renderable page shape (`rootId` resolved) that `getRenderablePage()` and
|
|
689
|
+
* the reuse branch pass in.
|
|
690
|
+
*/
|
|
691
|
+
setProjectData = (data) => {
|
|
692
|
+
this.data = data;
|
|
693
|
+
this.extractTranslationSidecar();
|
|
694
|
+
this.initProject();
|
|
695
|
+
};
|
|
696
|
+
/**
|
|
697
|
+
* Apply updates deferred off the render phase: swap in any pending page data
|
|
698
|
+
* captured on runtime reuse, then notify items whose data was refreshed
|
|
699
|
+
* during construction. The renderer calls this from a layout effect right
|
|
700
|
+
* after commit, so subscribers re-render before paint (no content flash) and
|
|
701
|
+
* without React's setState-in-render warning.
|
|
702
|
+
*/
|
|
703
|
+
flushRenderPhaseUpdates = () => {
|
|
704
|
+
let pendingData = this.pendingProjectData;
|
|
705
|
+
if (pendingData) {
|
|
706
|
+
this.pendingProjectData = void 0;
|
|
707
|
+
this.setProjectData(pendingData);
|
|
708
|
+
}
|
|
709
|
+
let pendingItems = this.pendingItemUpdates;
|
|
710
|
+
if (pendingItems.length > 0) {
|
|
711
|
+
this.pendingItemUpdates = [];
|
|
712
|
+
for (let item of pendingItems) {
|
|
713
|
+
item.triggerUpdate();
|
|
714
|
+
}
|
|
715
|
+
}
|
|
332
716
|
};
|
|
333
|
-
updateTranslation = () => void 0;
|
|
334
|
-
getTranslationChanges = () => void 0;
|
|
335
717
|
};
|
|
336
718
|
function createWeaverseNextRuntime(config) {
|
|
337
719
|
let requestInfo = buildWeaverseNextRequestInfo(config.client?.requestContext);
|
|
@@ -341,8 +723,10 @@ function createWeaverseNextRuntime(config) {
|
|
|
341
723
|
let requestKey = getRuntimeKey(page.id, requestInfo);
|
|
342
724
|
if (existing?.__weaverseNextRequestKey === requestKey) {
|
|
343
725
|
let nextIsDesignMode = config.client?.requestContext?.isDesignMode ?? false;
|
|
344
|
-
if (
|
|
345
|
-
existing.
|
|
726
|
+
if (existing.isDesignMode || nextIsDesignMode) {
|
|
727
|
+
existing.pendingProjectData = void 0;
|
|
728
|
+
} else {
|
|
729
|
+
existing.pendingProjectData = page;
|
|
346
730
|
}
|
|
347
731
|
existing.__weaverseNextLatestData = page;
|
|
348
732
|
existing.dataContext = resolveDataContext(config);
|
|
@@ -365,10 +749,18 @@ function createWeaverseNextRuntime(config) {
|
|
|
365
749
|
if (config.themeSettingsStore) {
|
|
366
750
|
existing.internal.themeSettingsStore = config.themeSettingsStore;
|
|
367
751
|
}
|
|
752
|
+
if (config.translationStore) {
|
|
753
|
+
existing.internal.translationStore = config.translationStore;
|
|
754
|
+
existing.internal.themeTextStore = config.translationStore;
|
|
755
|
+
}
|
|
756
|
+
existing.internal.merchantOverrides = config.merchantOverrides;
|
|
368
757
|
registerRuntime(existing);
|
|
369
758
|
return existing;
|
|
370
759
|
}
|
|
371
|
-
let runtime =
|
|
760
|
+
let [runtime, refreshedItems] = collectDeferredItemUpdates(
|
|
761
|
+
() => new WeaverseNextRuntime(config)
|
|
762
|
+
);
|
|
763
|
+
runtime.pendingItemUpdates = refreshedItems;
|
|
372
764
|
runtime.__weaverseNextRequestKey = requestKey;
|
|
373
765
|
runtime.__weaverseNextLatestData = page;
|
|
374
766
|
registerRuntime(runtime);
|
|
@@ -521,6 +913,7 @@ function WeaverseNextStudio(props) {
|
|
|
521
913
|
);
|
|
522
914
|
}
|
|
523
915
|
var EMPTY_DATA_CONTEXT = {};
|
|
916
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
524
917
|
function getRenderablePage2(data) {
|
|
525
918
|
let page = data?.page;
|
|
526
919
|
if (!page) {
|
|
@@ -543,9 +936,22 @@ var WeaverseNextRenderer = memo(function WeaverseNextRendererComponent(props) {
|
|
|
543
936
|
client,
|
|
544
937
|
data: { ...data, page },
|
|
545
938
|
dataContext,
|
|
546
|
-
|
|
939
|
+
merchantOverrides: context?.merchantOverrides,
|
|
940
|
+
themeSettingsStore: context?.themeSettingsStore,
|
|
941
|
+
translationStore: context?.translationStore
|
|
547
942
|
});
|
|
548
|
-
}, [
|
|
943
|
+
}, [
|
|
944
|
+
client,
|
|
945
|
+
page,
|
|
946
|
+
data,
|
|
947
|
+
dataContext,
|
|
948
|
+
context?.merchantOverrides,
|
|
949
|
+
context?.themeSettingsStore,
|
|
950
|
+
context?.translationStore
|
|
951
|
+
]);
|
|
952
|
+
useIsomorphicLayoutEffect(() => {
|
|
953
|
+
weaverse?.flushRenderPhaseUpdates();
|
|
954
|
+
}, [weaverse]);
|
|
549
955
|
if (!weaverse) {
|
|
550
956
|
return null;
|
|
551
957
|
}
|
|
@@ -668,6 +1074,6 @@ function WeaverseNextStudioConnect(props) {
|
|
|
668
1074
|
return null;
|
|
669
1075
|
}
|
|
670
1076
|
|
|
671
|
-
export { DEFAULT_REVALIDATE_ENDPOINT, WeaverseNextProvider, WeaverseNextRenderer, WeaverseNextRootProvider, WeaverseNextRuntime, WeaverseNextStudio, WeaverseNextStudioBridge, WeaverseNextStudioConnect, bindWeaverseNextStudioRuntime, createWeaverseNextClient, createWeaverseNextRuntime, createWeaverseNextStudioInternals, createWeaverseNextThemeSettingsStore, loadWeaverseNextStudioScript, resolveWeaverseNextStudioScriptSrc, revalidateWeaverseNextItem, useThemeSettings, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData };
|
|
1077
|
+
export { DEFAULT_REVALIDATE_ENDPOINT, ThemeTextProvider, ThemeTextStore, TranslationProvider, TranslationStore, WeaverseNextProvider, WeaverseNextRenderer, WeaverseNextRootProvider, WeaverseNextRuntime, WeaverseNextStudio, WeaverseNextStudioBridge, WeaverseNextStudioConnect, bindWeaverseNextStudioRuntime, createTranslate, createWeaverseNextClient, createWeaverseNextRuntime, createWeaverseNextStudioInternals, createWeaverseNextThemeSettingsStore, getNestedKey, interpolate, loadWeaverseNextStudioScript, resolveWeaverseNextStudioScriptSrc, revalidateWeaverseNextItem, useThemeSettings, useThemeText, useTranslation, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData };
|
|
672
1078
|
//# sourceMappingURL=index.mjs.map
|
|
673
1079
|
//# sourceMappingURL=index.mjs.map
|