@elytracms/next 0.0.90 → 0.0.91
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.ts +189 -225
- package/dist/index.js +131 -109
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,34 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { basePrimitives, getImplementation, registerImplementations, renderDocumentBodyItems, documentBodyItems, ImageManifest, serializeListingQuery, RenderErrorBoundary, documentBodyRichTextValues, documentBodyCompositionNodes, richTextEmbedsInValue, collectReferencedAssetIds, collectRichTextRefsInValue, collectReferencedRelations, collectReferencedListings, collectReferencedRichTextLinks, normalizeImageSource } from '@elytracms/core/runtime-renderer';
|
|
4
|
-
import { isValidElement } from 'react';
|
|
1
|
+
import { registerComponents, renderDocumentBodyItems, documentBodyItems, serializeListingQuery, documentBodyRichTextValues, documentBodyCompositionNodes, richTextEmbedsInValue, collectReferencedAssetIds, collectRichTextRefsInValue, collectReferencedRelations, collectReferencedListings, collectReferencedRichTextLinks, RenderErrorBoundary, nodeListingOf, listingRequestOf } from '@elytracms/core/runtime-renderer';
|
|
2
|
+
import { Fragment as Fragment$1, isValidElement } from 'react';
|
|
5
3
|
import { isBlockSequenceValueShape } from '@elytracms/core/rich-text';
|
|
6
|
-
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
7
5
|
import { cacheTags, isDocumentHistory, resolvedAsset, createContentClient, createContentContext } from '@elytracms/core/content';
|
|
8
6
|
import { parseLocaleConfig, documentKey, splitLocalePath, hierarchyMount, composePath, localeUrlPath, mergeRouteRecords, fallbackHomeRoutes, presentationBodyFields, splitPath, documentSchema, redirectRecordSchema } from '@elytracms/core/cms-core';
|
|
9
7
|
export { documentSchema, fallbackHomeRoutes, localeConfigSchema, localeUrlPath, mergeRouteRecords, parseLocaleConfig, redirectRecordSchema, resolveLocale, routeRecordSchema, splitLocalePath, textDirection } from '@elytracms/core/cms-core';
|
|
10
|
-
import { revalidateTag,
|
|
8
|
+
import { revalidateTag, cacheLife, cacheTag } from 'next/cache';
|
|
11
9
|
import { draftMode } from 'next/headers';
|
|
12
10
|
import { redirect, notFound, permanentRedirect } from 'next/navigation';
|
|
13
11
|
import { COMPOSITE_KEY_SEPARATOR } from '@elytracms/core/project-graph';
|
|
14
12
|
import { verifyRevalidationSignature, readRevalidationBody, REVALIDATE_SIGNATURE_HEADER } from '@elytracms/core/revalidation';
|
|
15
13
|
export { REVALIDATE_SIGNATURE_HEADER, revalidationEventSchema, signRevalidationBody, signedRevalidationRequest } from '@elytracms/core/revalidation';
|
|
16
14
|
import NextImage from 'next/image';
|
|
15
|
+
import { normalizeImageSource } from '@elytracms/components';
|
|
16
|
+
export { defineComponent } from '@elytracms/core/component-registry';
|
|
17
17
|
export { z } from 'zod';
|
|
18
18
|
|
|
19
19
|
// src/components.ts
|
|
20
|
-
function defineHostComponents(components = []
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const registry = new ComponentRegistry([...base.manifests, ...components.map((c) => c.manifest)]);
|
|
24
|
-
const implementations = {};
|
|
25
|
-
for (const manifest of base.manifests) {
|
|
26
|
-
const implementation = getImplementation(base.implementations, manifest.id);
|
|
27
|
-
if (implementation) implementations[manifest.id] = implementation;
|
|
28
|
-
}
|
|
29
|
-
const host = registerImplementations(components);
|
|
30
|
-
Object.assign(implementations, host.implementations);
|
|
31
|
-
return { registry, implementations, issues: [...registry.issues, ...host.issues] };
|
|
20
|
+
function defineHostComponents(components = []) {
|
|
21
|
+
const { registry, implementations } = registerComponents(components);
|
|
22
|
+
return { registry, implementations };
|
|
32
23
|
}
|
|
33
24
|
function relationResolver(relations) {
|
|
34
25
|
return (ref) => relations[`${ref.collection}:${ref.id}`] ?? null;
|
|
@@ -37,7 +28,22 @@ function linkResolver(links) {
|
|
|
37
28
|
return (ref) => links[`${ref.collection}:${ref.id}`] ?? null;
|
|
38
29
|
}
|
|
39
30
|
function listingResolver(listings) {
|
|
40
|
-
return (query) =>
|
|
31
|
+
return (query) => {
|
|
32
|
+
const baked = listings[serializeListingQuery(query)];
|
|
33
|
+
return Array.isArray(baked) ? baked : null;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function listingFailureOf(node, components, listings) {
|
|
37
|
+
const manifest = components.registry.getManifest(node.componentId);
|
|
38
|
+
if (!manifest) return null;
|
|
39
|
+
const listing = nodeListingOf(node, manifest, components.registry);
|
|
40
|
+
if (!listing || listing.state === "awaiting") return null;
|
|
41
|
+
if (listing.state === "invalid") return listing.messages;
|
|
42
|
+
const baked = listings?.[serializeListingQuery(listing.query)];
|
|
43
|
+
return baked && !Array.isArray(baked) ? baked.errors.map((error) => error.message) : null;
|
|
44
|
+
}
|
|
45
|
+
function InvalidListingNotice(props) {
|
|
46
|
+
return /* @__PURE__ */ jsx("div", { "data-ec-fallback": "invalid-listing", "data-ec-node-id": props.nodeId, role: "note", children: `This listing can't run: ${props.messages.join(" ")}` });
|
|
41
47
|
}
|
|
42
48
|
function assetResolver(assets) {
|
|
43
49
|
const byId = new Map(assets.map((asset) => [asset.id, asset]));
|
|
@@ -49,7 +55,7 @@ function assetResolver(assets) {
|
|
|
49
55
|
height: asset.height,
|
|
50
56
|
alt: asset.alt,
|
|
51
57
|
focalPoint: asset.focalPoint,
|
|
52
|
-
// EC-420: carry the LQIP so a placed
|
|
58
|
+
// EC-420: carry the LQIP so a placed Image blurs up on delivery.
|
|
53
59
|
lqip: asset.lqip,
|
|
54
60
|
meta: asset.meta
|
|
55
61
|
} : null;
|
|
@@ -86,7 +92,15 @@ async function CanvasRenderer(props) {
|
|
|
86
92
|
// so a host that did not opt in degrades a reference link to the visible
|
|
87
93
|
// `unresolved-ref` issue (EC-290) rather than a wrong href.
|
|
88
94
|
...props.links ? { resolveLink: linkResolver(props.links) } : {},
|
|
89
|
-
decorateNode:
|
|
95
|
+
decorateNode: (node, rendered) => {
|
|
96
|
+
const stripped = stripServerErrorBoundary(node, rendered);
|
|
97
|
+
const failure = listingFailureOf(node, components, props.listings);
|
|
98
|
+
if (!failure) return stripped;
|
|
99
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
100
|
+
/* @__PURE__ */ jsx(InvalidListingNotice, { nodeId: node.id, messages: failure }),
|
|
101
|
+
stripped
|
|
102
|
+
] }, node.id);
|
|
103
|
+
}
|
|
90
104
|
};
|
|
91
105
|
const document = result.document;
|
|
92
106
|
if (document) {
|
|
@@ -235,6 +249,7 @@ function canvasWrapContext(result, info) {
|
|
|
235
249
|
function pathFromSlug(slug) {
|
|
236
250
|
return "/" + (slug ?? []).join("/");
|
|
237
251
|
}
|
|
252
|
+
var systemClock = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
238
253
|
function scopeAssetsToPage(allAssets, registry, result, body, resolveRelation) {
|
|
239
254
|
if (allAssets.length === 0) return allAssets;
|
|
240
255
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -281,27 +296,33 @@ function populatePageRelations(body, client, registry) {
|
|
|
281
296
|
);
|
|
282
297
|
return { relations, docKeys: [...refKeys] };
|
|
283
298
|
}
|
|
284
|
-
function populatePageListings(body, client, registry) {
|
|
285
|
-
if (!registry) return { listings: {}, tags: [] };
|
|
299
|
+
function populatePageListings(body, client, registry, clock) {
|
|
300
|
+
if (!registry) return { listings: {}, tags: [], readsNow: false };
|
|
286
301
|
const tags = [];
|
|
302
|
+
let instant;
|
|
303
|
+
const now = () => instant ??= clock();
|
|
287
304
|
const listings = collectReferencedListings(
|
|
288
305
|
body.nodes,
|
|
289
306
|
registry,
|
|
290
307
|
(query) => {
|
|
291
|
-
const listed = client.listDocuments(query.collection,
|
|
292
|
-
where: query.where,
|
|
293
|
-
...query.sort ? { sort: query.sort } : {},
|
|
294
|
-
...query.limit !== void 0 ? { limit: query.limit } : {}
|
|
295
|
-
});
|
|
308
|
+
const listed = client.listDocuments(query.collection, listDocumentsQueryOf(query, now));
|
|
296
309
|
tags.push(listed.tags);
|
|
297
|
-
return listed.ok ? listed.documents :
|
|
310
|
+
return listed.ok ? listed.documents : { errors: listed.errors };
|
|
298
311
|
},
|
|
299
312
|
// EC-255: reach listings nested inside transcluded reusable content (the same
|
|
300
313
|
// depth-1 populate the relation bake uses), so a grid inside a reusable bakes —
|
|
301
314
|
// and its membership tag is folded in — instead of rendering empty on the host.
|
|
302
315
|
(ref) => client.resolveRelation(ref)
|
|
303
316
|
);
|
|
304
|
-
return { listings, tags };
|
|
317
|
+
return { listings, tags, readsNow: instant !== void 0 };
|
|
318
|
+
}
|
|
319
|
+
function listDocumentsQueryOf(query, now) {
|
|
320
|
+
const request = listingRequestOf(query, now);
|
|
321
|
+
return {
|
|
322
|
+
where: request.where,
|
|
323
|
+
...request.sort ? { sort: request.sort } : {},
|
|
324
|
+
...request.limit !== void 0 ? { limit: request.limit } : {}
|
|
325
|
+
};
|
|
305
326
|
}
|
|
306
327
|
function populatePageLinks(body, client, registry) {
|
|
307
328
|
if (!registry) return { links: {}, docKeys: [] };
|
|
@@ -359,11 +380,11 @@ async function resolveCanvasPage(source, url, perspective, options = {}) {
|
|
|
359
380
|
options.registry
|
|
360
381
|
);
|
|
361
382
|
const relationTags = cacheTags({ docs: relationDocKeys, locale: result.tags.locale });
|
|
362
|
-
const {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
);
|
|
383
|
+
const {
|
|
384
|
+
listings,
|
|
385
|
+
tags: listingTags,
|
|
386
|
+
readsNow
|
|
387
|
+
} = populatePageListings(body, client, options.registry, options.clock ?? systemClock);
|
|
367
388
|
const { links, docKeys: linkDocKeys } = populatePageLinks(body, client, options.registry);
|
|
368
389
|
const linkTags = cacheTags({ docs: linkDocKeys, locale: result.tags.locale });
|
|
369
390
|
return {
|
|
@@ -372,6 +393,7 @@ async function resolveCanvasPage(source, url, perspective, options = {}) {
|
|
|
372
393
|
assets: bakedAssets,
|
|
373
394
|
relations,
|
|
374
395
|
listings,
|
|
396
|
+
readsNow,
|
|
375
397
|
links,
|
|
376
398
|
...presentation ? { presentation } : {},
|
|
377
399
|
tags: mergeCacheTags(
|
|
@@ -423,7 +445,6 @@ function revalidationTags(event, project) {
|
|
|
423
445
|
case "delete":
|
|
424
446
|
tags.add(docCacheTag(`${event.collection}:${event.id}`, scope));
|
|
425
447
|
for (const locale of project.locales) tags.add(collectionCacheTag(event.collection, locale, scope));
|
|
426
|
-
tags.add(projectSweepTag(scope));
|
|
427
448
|
break;
|
|
428
449
|
case "redirects":
|
|
429
450
|
tags.add(projectSweepTag(scope));
|
|
@@ -436,39 +457,40 @@ function revalidationTags(event, project) {
|
|
|
436
457
|
return [...tags].sort();
|
|
437
458
|
}
|
|
438
459
|
function canvasCacheKey({ scope, mode, url }) {
|
|
439
|
-
return [
|
|
440
|
-
}
|
|
441
|
-
var
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
460
|
+
return [scope ?? "", mode ?? "", url];
|
|
461
|
+
}
|
|
462
|
+
var CANVAS_CACHE_LIFE = { revalidate: Infinity, expire: Infinity };
|
|
463
|
+
var CANVAS_DEV_CACHE_LIFE = { revalidate: 1, expire: 300 };
|
|
464
|
+
var CANVAS_CLOCK_CACHE_LIFE = { revalidate: 60, expire: Infinity };
|
|
465
|
+
function canvasEntryLife(nodeEnv, readsClock = false) {
|
|
466
|
+
if (nodeEnv === "development") return CANVAS_DEV_CACHE_LIFE;
|
|
467
|
+
return readsClock ? CANVAS_CLOCK_CACHE_LIFE : CANVAS_CACHE_LIFE;
|
|
468
|
+
}
|
|
469
|
+
var NEXT_CACHE_TAG_CALL_LIMIT = 128;
|
|
470
|
+
function entryTagCalls(tags, scope) {
|
|
471
|
+
const sweep = projectSweepTag(scope);
|
|
472
|
+
const rest = nextCacheTags(tags, scope).filter((tag) => tag !== sweep);
|
|
473
|
+
const calls = [[sweep]];
|
|
474
|
+
for (let start = 0; start < rest.length; start += NEXT_CACHE_TAG_CALL_LIMIT) {
|
|
475
|
+
calls.push(rest.slice(start, start + NEXT_CACHE_TAG_CALL_LIMIT));
|
|
445
476
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
return await probe();
|
|
462
|
-
} catch (error) {
|
|
463
|
-
if (!(error instanceof CacheDiscoveryBail)) throw error;
|
|
477
|
+
return calls;
|
|
478
|
+
}
|
|
479
|
+
var canvasResolvers = /* @__PURE__ */ new Map();
|
|
480
|
+
function resolverKey(scope, mode) {
|
|
481
|
+
return JSON.stringify([scope, mode]);
|
|
482
|
+
}
|
|
483
|
+
function registerCanvasResolver(scope, mode, resolve) {
|
|
484
|
+
canvasResolvers.set(resolverKey(scope, mode), resolve);
|
|
485
|
+
}
|
|
486
|
+
function canvasResolverFor(scope, mode) {
|
|
487
|
+
const resolve = canvasResolvers.get(resolverKey(scope, mode));
|
|
488
|
+
if (!resolve) {
|
|
489
|
+
throw new Error(
|
|
490
|
+
`Elytra delivery cache: no canvas route registered for scope "${scope}" and content mode "${mode}" in this server process \u2014 the cached route function has no loader to run. This is a wiring defect: create the route with createCanvasRoute / elytra.canvasRoute() before its Page renders.`
|
|
491
|
+
);
|
|
464
492
|
}
|
|
465
|
-
|
|
466
|
-
const write = cache(
|
|
467
|
-
passthrough(async () => entry),
|
|
468
|
-
keyParts,
|
|
469
|
-
{ tags: entry.tags, revalidate: false }
|
|
470
|
-
);
|
|
471
|
-
return write();
|
|
493
|
+
return resolve;
|
|
472
494
|
}
|
|
473
495
|
|
|
474
496
|
// src/metadata.ts
|
|
@@ -531,6 +553,8 @@ function mergeMetadataOverParent(parent, page) {
|
|
|
531
553
|
function isPlainObject(value) {
|
|
532
554
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
533
555
|
}
|
|
556
|
+
var CANVAS_VALIDATION_SLUG = ["_elytra"];
|
|
557
|
+
var CANVAS_VALIDATION_PATH = pathFromSlug([...CANVAS_VALIDATION_SLUG]);
|
|
534
558
|
function defaultMetadata(result, assets) {
|
|
535
559
|
return canvasPageMetadata(result, assets);
|
|
536
560
|
}
|
|
@@ -538,33 +562,35 @@ async function requestPerspective() {
|
|
|
538
562
|
const { isEnabled } = await draftMode();
|
|
539
563
|
return isEnabled ? "draft" : "published";
|
|
540
564
|
}
|
|
541
|
-
|
|
565
|
+
async function cachedCanvasOutcome(scope, mode, url) {
|
|
566
|
+
"use cache";
|
|
567
|
+
const outcome = await canvasResolverFor(scope, mode)(url);
|
|
568
|
+
cacheLife(canvasEntryLife(process.env.NODE_ENV, outcome.kind === "render" && outcome.readsNow));
|
|
569
|
+
for (const tags of entryTagCalls(outcome.tags, scope)) cacheTag(...tags);
|
|
570
|
+
return outcome;
|
|
571
|
+
}
|
|
542
572
|
function createCanvasRoute(options) {
|
|
573
|
+
const resolveFresh = async (url, perspective) => {
|
|
574
|
+
const source = await options.loadContent({ perspective });
|
|
575
|
+
return resolveCanvasPage(source, url, perspective, {
|
|
576
|
+
// EC-205: page-scope the baked assets to what the page actually uses.
|
|
577
|
+
registry: options.components.registry
|
|
578
|
+
});
|
|
579
|
+
};
|
|
580
|
+
const cache = options.cache;
|
|
581
|
+
const entryKey = (url) => canvasCacheKey({ scope: cache?.scope, mode: cache?.mode, url });
|
|
582
|
+
if (cache) {
|
|
583
|
+
const [scope, mode] = entryKey("");
|
|
584
|
+
registerCanvasResolver(scope, mode, (url) => resolveFresh(url, "published"));
|
|
585
|
+
}
|
|
543
586
|
const loadOutcome = async (url, perspective) => {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
return resolveCanvasPage(source, url, perspective, {
|
|
547
|
-
// EC-205: page-scope the baked assets to what the page actually uses.
|
|
548
|
-
registry: options.components.registry
|
|
549
|
-
});
|
|
550
|
-
};
|
|
551
|
-
const devBypass = process.env.NODE_ENV === "development";
|
|
552
|
-
if (!options.cache || perspective !== "published" || devBypass) return resolveFresh();
|
|
553
|
-
const scope = options.cache.scope;
|
|
554
|
-
const entry = await loadCachedEntry(
|
|
555
|
-
nextCacheWrapper,
|
|
556
|
-
canvasCacheKey({ scope, mode: options.cache.mode, url }),
|
|
557
|
-
[projectSweepTag(scope)],
|
|
558
|
-
async () => {
|
|
559
|
-
const outcome = await resolveFresh();
|
|
560
|
-
return { value: outcome, tags: nextCacheTags(outcome.tags, scope) };
|
|
561
|
-
}
|
|
562
|
-
);
|
|
563
|
-
return entry.value;
|
|
587
|
+
if (!cache || perspective !== "published") return resolveFresh(url, perspective);
|
|
588
|
+
return cachedCanvasOutcome(...entryKey(url));
|
|
564
589
|
};
|
|
565
590
|
const Page = async (props) => {
|
|
566
591
|
const { slug } = await props.params;
|
|
567
592
|
const url = pathFromSlug(slug);
|
|
593
|
+
if (url === CANVAS_VALIDATION_PATH) return notFound();
|
|
568
594
|
const perspective = await requestPerspective();
|
|
569
595
|
const outcome = await loadOutcome(url, perspective);
|
|
570
596
|
options.onTags?.(outcome.tags, { url, perspective });
|
|
@@ -594,8 +620,9 @@ function createCanvasRoute(options) {
|
|
|
594
620
|
const pageMetadata = async (props) => {
|
|
595
621
|
const { slug } = await props.params;
|
|
596
622
|
const url = pathFromSlug(slug);
|
|
623
|
+
if (url === CANVAS_VALIDATION_PATH) return {};
|
|
597
624
|
const perspective = await requestPerspective();
|
|
598
|
-
if (
|
|
625
|
+
if (cache && perspective === "published") {
|
|
599
626
|
const outcome2 = await loadOutcome(url, perspective);
|
|
600
627
|
if (outcome2.kind !== "render") return {};
|
|
601
628
|
return options.metadata ? options.metadata(outcome2.result, { url, perspective }) : defaultMetadata(outcome2.result, outcome2.assets);
|
|
@@ -609,7 +636,10 @@ function createCanvasRoute(options) {
|
|
|
609
636
|
const [page, resolvedParent] = await Promise.all([pageMetadata(props), parent]);
|
|
610
637
|
return mergeMetadataOverParent(resolvedParent, page);
|
|
611
638
|
};
|
|
612
|
-
|
|
639
|
+
const generateStaticParams = async () => [
|
|
640
|
+
{ slug: [...CANVAS_VALIDATION_SLUG] }
|
|
641
|
+
];
|
|
642
|
+
return { Page, generateMetadata, generateStaticParams };
|
|
613
643
|
}
|
|
614
644
|
function paramNamesOf(pattern) {
|
|
615
645
|
return splitPath(pattern).filter((segment) => segment.startsWith(":")).map((segment) => segment.slice(1));
|
|
@@ -828,8 +858,8 @@ function createAssetImageLoader(options = {}) {
|
|
|
828
858
|
return `${src}${separator}${widthParam}=${width}&${qualityParam}=${quality ?? defaultQuality}`;
|
|
829
859
|
};
|
|
830
860
|
}
|
|
831
|
-
function
|
|
832
|
-
return function
|
|
861
|
+
function createNextImage(options) {
|
|
862
|
+
return function ElytraNextImage(props) {
|
|
833
863
|
const { url, width, height, alt, focalPoint, lqip } = normalizeImageSource(props);
|
|
834
864
|
if (url.length === 0) return null;
|
|
835
865
|
return /* @__PURE__ */ jsx(
|
|
@@ -844,11 +874,12 @@ function createNextImagePrimitive(options) {
|
|
|
844
874
|
);
|
|
845
875
|
};
|
|
846
876
|
}
|
|
847
|
-
function
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
877
|
+
function withNextImage(components, options = {}) {
|
|
878
|
+
const list = [...components ?? []];
|
|
879
|
+
const image = registerComponents(list).registry.roleComponent("image");
|
|
880
|
+
if (!image) return list;
|
|
881
|
+
const implementation = createNextImage(options);
|
|
882
|
+
return list.map((entry) => entry.manifest === image ? { manifest: entry.manifest, implementation } : entry);
|
|
852
883
|
}
|
|
853
884
|
function elytraHostImage(options = {}) {
|
|
854
885
|
return ({ asset, alt, className, priority, sizes, loading }) => /* @__PURE__ */ jsx(
|
|
@@ -1171,17 +1202,7 @@ function createElytraHost(options) {
|
|
|
1171
1202
|
}
|
|
1172
1203
|
const contentMode = live ? "live" : options.fallbackContent ? "fallback" : "empty";
|
|
1173
1204
|
const contentScope = live ? env.projectId : options.slug;
|
|
1174
|
-
const components = defineHostComponents([
|
|
1175
|
-
// Batteries included (EC-368 image defaults): graph `base.Image` nodes render
|
|
1176
|
-
// through next/image — resized variants via the host's own optimizer. The
|
|
1177
|
-
// canonical manifest stays (first registration wins in defineHostComponents).
|
|
1178
|
-
...options.image === false ? [] : [nextImagePrimitive(options.image ?? {})],
|
|
1179
|
-
// EC-539: the option is the CONFIG's entry shape (`implementation: unknown`)
|
|
1180
|
-
// so the recommended `{ ...site }` spread compiles; EC-541: registration
|
|
1181
|
-
// takes that shape too and checks each implementation at runtime (see the
|
|
1182
|
-
// option's doc comment) — no narrowing cast here.
|
|
1183
|
-
...options.components ?? []
|
|
1184
|
-
]);
|
|
1205
|
+
const components = defineHostComponents(options.components ?? []);
|
|
1185
1206
|
const emptySource = createStaticContentSource({
|
|
1186
1207
|
projectId: contentScope,
|
|
1187
1208
|
locales: options.locales,
|
|
@@ -1252,6 +1273,7 @@ function createElytraHost(options) {
|
|
|
1252
1273
|
return firstBlockFullBleed(resolved.document, components.registry);
|
|
1253
1274
|
};
|
|
1254
1275
|
return {
|
|
1276
|
+
collections: options.collections,
|
|
1255
1277
|
contentScope,
|
|
1256
1278
|
contentMode,
|
|
1257
1279
|
env,
|
|
@@ -1269,6 +1291,6 @@ function createElytraHost(options) {
|
|
|
1269
1291
|
}
|
|
1270
1292
|
var PACKAGE = "@elytracms/next";
|
|
1271
1293
|
|
|
1272
|
-
export { CanvasRenderer, ELYTRA_HOST_ENV_KEYS, ElytraImage, PACKAGE, assembleLiveSource, bodyItemsOf, canvasPageMetadata, canvasSitemapEntries, collectionCacheTag, createAssetImageLoader, createCanvasRoute, createCanvasSitemap, createContentSnapshot, createElytraHost, createPreviewDisableRoute, createPreviewRoute, createRevalidateRoute, createStaticContentSource, defineHostComponents, docCacheTag, elytraHostImage, evaluatePreviewRequest, evaluateRevalidateRequest, firstBlockFullBleed,
|
|
1294
|
+
export { CANVAS_VALIDATION_SLUG, CanvasRenderer, ELYTRA_HOST_ENV_KEYS, ElytraImage, PACKAGE, assembleLiveSource, bodyItemsOf, canvasPageMetadata, canvasSitemapEntries, collectionCacheTag, createAssetImageLoader, createCanvasRoute, createCanvasSitemap, createContentSnapshot, createElytraHost, createPreviewDisableRoute, createPreviewRoute, createRevalidateRoute, createStaticContentSource, defineHostComponents, docCacheTag, elytraHostImage, evaluatePreviewRequest, evaluateRevalidateRequest, firstBlockFullBleed, loadLiveContent, mergeCacheTags, mergeMetadataOverParent, nextCacheTags, openGraphLocale, pathFromSlug, projectSweepTag, resolveCanvasPage, resolveGlobals, resolveHostEnv, revalidationTags, routeCacheTag, safeRedirectTarget, scopeCacheTag, withNextImage };
|
|
1273
1295
|
//# sourceMappingURL=index.js.map
|
|
1274
1296
|
//# sourceMappingURL=index.js.map
|