@uniweb/runtime 1.5.4 → 1.5.6
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/ssr.js +117 -11
- package/dist/ssr.js.map +1 -1
- package/package.json +3 -3
- package/src/page-renderer.js +18 -3
- package/src/prepare-props.js +42 -7
- package/src/section-records.js +160 -0
package/dist/ssr.js
CHANGED
|
@@ -15,6 +15,8 @@ import { jsonForScript } from "@uniweb/core/data-script";
|
|
|
15
15
|
import { dataScript, jsonForScript as jsonForScript2 } from "@uniweb/core/data-script";
|
|
16
16
|
import DataStore, { deriveCacheKey as deriveCacheKey$1 } from "@uniweb/core/datastore";
|
|
17
17
|
import { RESOLUTION_STATUS, carryQuery, localeOfPath, localeUrl, resolveRoute, routeIndex } from "@uniweb/core/resolve-route";
|
|
18
|
+
import { declaredKeys } from "@uniweb/core/data-keys";
|
|
19
|
+
import { heldPageRecord, blockRouteQuery, blockFillsOf, fillIsPageRecord } from "@uniweb/core/page-data";
|
|
18
20
|
import { resolveFetchConfigs } from "@uniweb/core/fetch-config";
|
|
19
21
|
import { resolveRecordsService } from "@uniweb/core/records-service";
|
|
20
22
|
function guaranteeItemStructure(item) {
|
|
@@ -99,7 +101,16 @@ function applyDefaults(params, defaults) {
|
|
|
99
101
|
};
|
|
100
102
|
}
|
|
101
103
|
function assembleData(block, meta, entityData) {
|
|
102
|
-
const declared = block
|
|
104
|
+
const declared = declaredOf(block, meta);
|
|
105
|
+
const data = collectDeclared(block, declared, entityData);
|
|
106
|
+
warnUndeclaredBlocks(block, Object.keys(block.heldData || {}).filter((key) => !Object.hasOwn(data, key)));
|
|
107
|
+
block.parsedContent.data = data;
|
|
108
|
+
return declared;
|
|
109
|
+
}
|
|
110
|
+
function declaredOf(block, meta) {
|
|
111
|
+
return block.website?.declaredKeys ? block.website.declaredKeys(meta) : [];
|
|
112
|
+
}
|
|
113
|
+
function collectDeclared(block, declared, entityData) {
|
|
103
114
|
const held = block.heldData || {};
|
|
104
115
|
const data = {};
|
|
105
116
|
for (const [key] of declared) {
|
|
@@ -107,19 +118,25 @@ function assembleData(block, meta, entityData) {
|
|
|
107
118
|
else if (entityData && entityData[key] !== void 0) data[key] = entityData[key];
|
|
108
119
|
else data[key] = null;
|
|
109
120
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
121
|
+
return data;
|
|
122
|
+
}
|
|
123
|
+
function receivedData(block, meta, entityData = null) {
|
|
124
|
+
const declared = declaredOf(block, meta);
|
|
125
|
+
const probe = { parsedContent: { data: collectDeclared(block, declared, entityData) }, fetch: block.fetch, website: block.website };
|
|
126
|
+
block.website?.entityStore?.linkOwnRecords?.(probe);
|
|
127
|
+
return { declared, data: oneRecordEach(probe.parsedContent.data, declared) };
|
|
113
128
|
}
|
|
114
129
|
function holdOneRecord(block, declared) {
|
|
115
|
-
|
|
130
|
+
block.parsedContent.data = oneRecordEach(block.parsedContent.data, declared);
|
|
131
|
+
}
|
|
132
|
+
function oneRecordEach(data, declared) {
|
|
116
133
|
let out = null;
|
|
117
134
|
for (const [key, , , single] of declared) {
|
|
118
135
|
if (single !== true || !Array.isArray(data?.[key])) continue;
|
|
119
136
|
out = out || { ...data };
|
|
120
137
|
out[key] = data[key][0] ?? null;
|
|
121
138
|
}
|
|
122
|
-
|
|
139
|
+
return out || data;
|
|
123
140
|
}
|
|
124
141
|
const warnedBlocks = /* @__PURE__ */ new Set();
|
|
125
142
|
function warnUndeclaredBlocks(block, leftOut) {
|
|
@@ -1260,14 +1277,14 @@ function iconValue(value) {
|
|
|
1260
1277
|
const ref = parseIconReference(value);
|
|
1261
1278
|
return ref && ICON_FAMILY_MAP[ref.library.toLowerCase()] && ICON_NAME.test(ref.name) ? ref : null;
|
|
1262
1279
|
}
|
|
1263
|
-
function visit(node, found) {
|
|
1280
|
+
function visit$1(node, found) {
|
|
1264
1281
|
if (!node || typeof node !== "object") return;
|
|
1265
1282
|
if (node.type === "image" && node.attrs?.role === "icon") found.push(node.attrs);
|
|
1266
1283
|
for (const mark of node.marks || []) {
|
|
1267
1284
|
const ref = parseIconReference(mark?.attrs?.icon);
|
|
1268
1285
|
if (ref) found.push(ref);
|
|
1269
1286
|
}
|
|
1270
|
-
if (Array.isArray(node.content)) for (const child of node.content) visit(child, found);
|
|
1287
|
+
if (Array.isArray(node.content)) for (const child of node.content) visit$1(child, found);
|
|
1271
1288
|
}
|
|
1272
1289
|
function visitValue(value, found, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1273
1290
|
if (typeof value === "string") {
|
|
@@ -1290,7 +1307,7 @@ function addressed(named) {
|
|
|
1290
1307
|
}
|
|
1291
1308
|
function pageIcons(blocks) {
|
|
1292
1309
|
const named = [];
|
|
1293
|
-
for (const block of blocks) visit(block.rawContent?.doc ?? block.rawContent, named);
|
|
1310
|
+
for (const block of blocks) visit$1(block.rawContent?.doc ?? block.rawContent, named);
|
|
1294
1311
|
for (const block of blocks) {
|
|
1295
1312
|
visitValue(block.properties, named);
|
|
1296
1313
|
visitValue(getComponentMeta(block.type)?.defaults, named);
|
|
@@ -1412,10 +1429,93 @@ async function loadPageData({ website, route, fetch: fetch2, dev = false, locale
|
|
|
1412
1429
|
if (askIcons) await askIcons(dataIcons([...entries.values()].map((entry) => entry.data)));
|
|
1413
1430
|
return [...entries.values()];
|
|
1414
1431
|
}
|
|
1432
|
+
function sectionRecords(page) {
|
|
1433
|
+
const sections = [];
|
|
1434
|
+
const shown = [];
|
|
1435
|
+
for (const block of page?.getBodyBlocks?.() ?? []) visit(block, sectionDomId(block), sections, shown);
|
|
1436
|
+
return { sections, record: pageRecordOf(page, shown) };
|
|
1437
|
+
}
|
|
1438
|
+
function visit(block, id, sections, shown) {
|
|
1439
|
+
if (!block) return;
|
|
1440
|
+
const data = recordsOf(block, shown);
|
|
1441
|
+
if (data) sections.push({ id, data });
|
|
1442
|
+
for (const inset of block.insets || []) visit(inset, id, sections, shown);
|
|
1443
|
+
for (const child of block.childBlocks || []) visit(child, sectionDomId(child), sections, shown);
|
|
1444
|
+
}
|
|
1445
|
+
function pageRecordOf(page, shown) {
|
|
1446
|
+
if (!page?.dynamicContext) return void 0;
|
|
1447
|
+
const one = (value) => Array.isArray(value) ? value[0] ?? null : value;
|
|
1448
|
+
const whole = shown.find((s) => s.whole && one(s.value));
|
|
1449
|
+
if (whole) return one(whole.value);
|
|
1450
|
+
const website = page.website;
|
|
1451
|
+
const fetcher = website?.fetcher;
|
|
1452
|
+
const own = heldPageRecord(page, {
|
|
1453
|
+
website,
|
|
1454
|
+
peek: (request) => fetcher?.peek?.(request, { website, page, block: null }),
|
|
1455
|
+
peekRecord: (id2) => fetcher?.peekRecord?.(id2)
|
|
1456
|
+
});
|
|
1457
|
+
const seen = shown.map((s) => one(s.value)).find(Boolean) ?? null;
|
|
1458
|
+
const id = (own ?? seen)?.$uuid;
|
|
1459
|
+
const held = typeof id === "string" && id ? fetcher?.peekRecord?.(id) : null;
|
|
1460
|
+
if (held?.whole === true && held.record) return held.record;
|
|
1461
|
+
return seen ?? own;
|
|
1462
|
+
}
|
|
1463
|
+
function recordsOf(block, shown) {
|
|
1464
|
+
if (!globalThis.uniweb?.getComponent?.(block.type)) return null;
|
|
1465
|
+
const meta = getComponentMeta(block.type);
|
|
1466
|
+
const own = declaredKeys(meta?.data);
|
|
1467
|
+
if (own.length === 0) return null;
|
|
1468
|
+
const resolved = block.website?.entityStore?.resolve(block, meta);
|
|
1469
|
+
const { data } = receivedData(block, meta, resolved?.status === "ready" ? resolved.data : null);
|
|
1470
|
+
const held = block.heldData || {};
|
|
1471
|
+
let fills = null;
|
|
1472
|
+
let route = null;
|
|
1473
|
+
let tagged = null;
|
|
1474
|
+
const out = {};
|
|
1475
|
+
for (const [key] of own) {
|
|
1476
|
+
const value = data[key];
|
|
1477
|
+
if (value === void 0 || value === null) continue;
|
|
1478
|
+
let name;
|
|
1479
|
+
if (held[key] !== void 0) {
|
|
1480
|
+
tagged ??= taggedKeys(block);
|
|
1481
|
+
if (tagged.has(key)) continue;
|
|
1482
|
+
name = key;
|
|
1483
|
+
} else {
|
|
1484
|
+
if (!fills) {
|
|
1485
|
+
route = blockRouteQuery(block);
|
|
1486
|
+
fills = blockFillsOf(block, meta, route);
|
|
1487
|
+
}
|
|
1488
|
+
const fill = fills.get(key);
|
|
1489
|
+
const cfg = fill?.cfg;
|
|
1490
|
+
if (!cfg?.as) continue;
|
|
1491
|
+
if (fillIsPageRecord(block, cfg, route)) {
|
|
1492
|
+
shown.push({ value, whole: fill.whole === true });
|
|
1493
|
+
continue;
|
|
1494
|
+
}
|
|
1495
|
+
name = cfg.as;
|
|
1496
|
+
}
|
|
1497
|
+
if (Object.hasOwn(out, name) && !sameValue(out[name], value)) name = key;
|
|
1498
|
+
if (Object.hasOwn(out, name) && !sameValue(out[name], value)) continue;
|
|
1499
|
+
out[name] = value;
|
|
1500
|
+
}
|
|
1501
|
+
return Object.keys(out).length ? out : null;
|
|
1502
|
+
}
|
|
1503
|
+
function taggedKeys(block) {
|
|
1504
|
+
const parsed = typeof block.parseContent === "function" && block.rawContent ? block.parseContent(block.rawContent) : null;
|
|
1505
|
+
return new Set(Object.keys(parsed?.data || {}));
|
|
1506
|
+
}
|
|
1507
|
+
function sameValue(a, b) {
|
|
1508
|
+
if (a === b) return true;
|
|
1509
|
+
try {
|
|
1510
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
1511
|
+
} catch {
|
|
1512
|
+
return false;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1415
1515
|
function createPageRenderer({ website, shell }) {
|
|
1416
1516
|
if (!website) throw new Error("createPageRenderer: `website` is required");
|
|
1417
1517
|
if (typeof shell !== "string") throw new Error("createPageRenderer: `shell` must be an HTML string");
|
|
1418
|
-
function render(target, { inject = {}, fetchedData } = {}) {
|
|
1518
|
+
function render(target, { inject = {}, fetchedData, sectionData = false } = {}) {
|
|
1419
1519
|
if (fetchedData !== void 0 && !Array.isArray(fetchedData)) {
|
|
1420
1520
|
throw new Error("createPageRenderer: `fetchedData` must be the array of entries the page carries");
|
|
1421
1521
|
}
|
|
@@ -1442,7 +1542,13 @@ function createPageRenderer({ website, shell }) {
|
|
|
1442
1542
|
sectionOverrideCSS: result.sectionOverrideCSS,
|
|
1443
1543
|
icons
|
|
1444
1544
|
});
|
|
1445
|
-
|
|
1545
|
+
const rendered = { outcome: missing ? "notFound" : "rendered", html, page, error: null };
|
|
1546
|
+
if (sectionData) {
|
|
1547
|
+
const shown = sectionRecords(page);
|
|
1548
|
+
rendered.sections = shown.sections;
|
|
1549
|
+
if (shown.record !== void 0) rendered.record = shown.record;
|
|
1550
|
+
}
|
|
1551
|
+
return rendered;
|
|
1446
1552
|
}
|
|
1447
1553
|
return { website, render, failingSection: (page, message) => failingSectionOf(page, message) };
|
|
1448
1554
|
}
|