@uniweb/runtime 1.5.3 → 1.5.5
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 +89 -11
- package/dist/ssr.js.map +1 -1
- package/package.json +3 -3
- package/src/page-renderer.js +12 -3
- package/src/prepare-props.js +42 -7
- package/src/section-records.js +120 -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 { 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,69 @@ 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 out = [];
|
|
1434
|
+
for (const block of page?.getBodyBlocks?.() ?? []) visit(block, sectionDomId(block), out);
|
|
1435
|
+
return out;
|
|
1436
|
+
}
|
|
1437
|
+
function visit(block, id, out) {
|
|
1438
|
+
if (!block) return;
|
|
1439
|
+
const data = recordsOf(block);
|
|
1440
|
+
if (data) out.push({ id, data });
|
|
1441
|
+
for (const inset of block.insets || []) visit(inset, id, out);
|
|
1442
|
+
for (const child of block.childBlocks || []) visit(child, sectionDomId(child), out);
|
|
1443
|
+
}
|
|
1444
|
+
function recordsOf(block) {
|
|
1445
|
+
if (!globalThis.uniweb?.getComponent?.(block.type)) return null;
|
|
1446
|
+
const meta = getComponentMeta(block.type);
|
|
1447
|
+
const own = declaredKeys(meta?.data);
|
|
1448
|
+
if (own.length === 0) return null;
|
|
1449
|
+
const resolved = block.website?.entityStore?.resolve(block, meta);
|
|
1450
|
+
const { data } = receivedData(block, meta, resolved?.status === "ready" ? resolved.data : null);
|
|
1451
|
+
const held = block.heldData || {};
|
|
1452
|
+
let fills = null;
|
|
1453
|
+
let route = null;
|
|
1454
|
+
let tagged = null;
|
|
1455
|
+
const out = {};
|
|
1456
|
+
for (const [key] of own) {
|
|
1457
|
+
const value = data[key];
|
|
1458
|
+
if (value === void 0 || value === null) continue;
|
|
1459
|
+
let name;
|
|
1460
|
+
if (held[key] !== void 0) {
|
|
1461
|
+
tagged ??= taggedKeys(block);
|
|
1462
|
+
if (tagged.has(key)) continue;
|
|
1463
|
+
name = key;
|
|
1464
|
+
} else {
|
|
1465
|
+
if (!fills) {
|
|
1466
|
+
route = blockRouteQuery(block);
|
|
1467
|
+
fills = blockFillsOf(block, meta, route);
|
|
1468
|
+
}
|
|
1469
|
+
const cfg = fills.get(key)?.cfg;
|
|
1470
|
+
if (!cfg?.as || fillIsPageRecord(block, cfg, route)) continue;
|
|
1471
|
+
name = cfg.as;
|
|
1472
|
+
}
|
|
1473
|
+
if (Object.hasOwn(out, name) && !sameValue(out[name], value)) name = key;
|
|
1474
|
+
if (Object.hasOwn(out, name) && !sameValue(out[name], value)) continue;
|
|
1475
|
+
out[name] = value;
|
|
1476
|
+
}
|
|
1477
|
+
return Object.keys(out).length ? out : null;
|
|
1478
|
+
}
|
|
1479
|
+
function taggedKeys(block) {
|
|
1480
|
+
const parsed = typeof block.parseContent === "function" && block.rawContent ? block.parseContent(block.rawContent) : null;
|
|
1481
|
+
return new Set(Object.keys(parsed?.data || {}));
|
|
1482
|
+
}
|
|
1483
|
+
function sameValue(a, b) {
|
|
1484
|
+
if (a === b) return true;
|
|
1485
|
+
try {
|
|
1486
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
1487
|
+
} catch {
|
|
1488
|
+
return false;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1415
1491
|
function createPageRenderer({ website, shell }) {
|
|
1416
1492
|
if (!website) throw new Error("createPageRenderer: `website` is required");
|
|
1417
1493
|
if (typeof shell !== "string") throw new Error("createPageRenderer: `shell` must be an HTML string");
|
|
1418
|
-
function render(target, { inject = {}, fetchedData } = {}) {
|
|
1494
|
+
function render(target, { inject = {}, fetchedData, sectionData = false } = {}) {
|
|
1419
1495
|
if (fetchedData !== void 0 && !Array.isArray(fetchedData)) {
|
|
1420
1496
|
throw new Error("createPageRenderer: `fetchedData` must be the array of entries the page carries");
|
|
1421
1497
|
}
|
|
@@ -1442,7 +1518,9 @@ function createPageRenderer({ website, shell }) {
|
|
|
1442
1518
|
sectionOverrideCSS: result.sectionOverrideCSS,
|
|
1443
1519
|
icons
|
|
1444
1520
|
});
|
|
1445
|
-
|
|
1521
|
+
const rendered = { outcome: missing ? "notFound" : "rendered", html, page, error: null };
|
|
1522
|
+
if (sectionData) rendered.sections = sectionRecords(page);
|
|
1523
|
+
return rendered;
|
|
1446
1524
|
}
|
|
1447
1525
|
return { website, render, failingSection: (page, message) => failingSectionOf(page, message) };
|
|
1448
1526
|
}
|