@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 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.website?.declaredKeys ? block.website.declaredKeys(meta) : [];
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
- warnUndeclaredBlocks(block, Object.keys(held).filter((key) => !Object.hasOwn(data, key)));
111
- block.parsedContent.data = data;
112
- return declared;
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
- const data = block.parsedContent.data;
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
- if (out) block.parsedContent.data = out;
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
- return { outcome: missing ? "notFound" : "rendered", html, page, error: null };
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
  }