@alpaca-headless/alpaca-headless 1.0.3397

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.
Files changed (97) hide show
  1. package/.eslintrc.json +3 -0
  2. package/dist/client-components/ClientLink.d.ts +7 -0
  3. package/dist/client-components/ClientLink.js +20 -0
  4. package/dist/client-components/index.d.ts +1 -0
  5. package/dist/client-components/index.js +1 -0
  6. package/dist/components/Error.d.ts +1 -0
  7. package/dist/components/Error.js +7 -0
  8. package/dist/components/LazyPlaceholder.d.ts +6 -0
  9. package/dist/components/LazyPlaceholder.js +15 -0
  10. package/dist/components/Placeholder.d.ts +30 -0
  11. package/dist/components/Placeholder.js +123 -0
  12. package/dist/components/Slot.d.ts +7 -0
  13. package/dist/components/Slot.js +6 -0
  14. package/dist/components/Translate.d.ts +7 -0
  15. package/dist/components/Translate.js +17 -0
  16. package/dist/components/field-renderers/Link.d.ts +8 -0
  17. package/dist/components/field-renderers/Link.js +29 -0
  18. package/dist/components/field-renderers/Picture.d.ts +22 -0
  19. package/dist/components/field-renderers/Picture.js +140 -0
  20. package/dist/components/field-renderers/RichText.d.ts +7 -0
  21. package/dist/components/field-renderers/RichText.js +30 -0
  22. package/dist/components/field-renderers/Text.d.ts +7 -0
  23. package/dist/components/field-renderers/Text.js +24 -0
  24. package/dist/configuration.d.ts +17 -0
  25. package/dist/configuration.js +4 -0
  26. package/dist/index.d.ts +23 -0
  27. package/dist/index.js +15 -0
  28. package/dist/internals/index.d.ts +5 -0
  29. package/dist/internals/index.js +2 -0
  30. package/dist/middleware/handleRequest.d.ts +7 -0
  31. package/dist/middleware/handleRequest.js +38 -0
  32. package/dist/middleware/index.d.ts +1 -0
  33. package/dist/middleware/index.js +1 -0
  34. package/dist/picture-shared.d.ts +16 -0
  35. package/dist/picture-shared.js +26 -0
  36. package/dist/render-context.d.ts +47 -0
  37. package/dist/render-context.js +33 -0
  38. package/dist/renderings/renderings.d.ts +7 -0
  39. package/dist/renderings/renderings.js +22 -0
  40. package/dist/renderings/tailwind.d.ts +1 -0
  41. package/dist/renderings/tailwind.js +43 -0
  42. package/dist/route-data/dictionary.d.ts +2 -0
  43. package/dist/route-data/dictionary.js +31 -0
  44. package/dist/route-data/resolve-route.d.ts +44 -0
  45. package/dist/route-data/resolve-route.js +123 -0
  46. package/dist/route-data/route-data.d.ts +41 -0
  47. package/dist/route-data/route-data.js +1 -0
  48. package/dist/services/api.d.ts +18 -0
  49. package/dist/services/api.js +103 -0
  50. package/dist/services/graphQL.d.ts +29 -0
  51. package/dist/services/graphQL.js +54 -0
  52. package/dist/types/fetch.d.ts +7 -0
  53. package/dist/types/fetch.js +1 -0
  54. package/dist/types/fieldTypes.d.ts +106 -0
  55. package/dist/types/fieldTypes.js +1 -0
  56. package/dist/types/items.d.ts +56 -0
  57. package/dist/types/items.js +1 -0
  58. package/dist/types/layoutDataTypes.d.ts +142 -0
  59. package/dist/types/layoutDataTypes.js +1 -0
  60. package/dist/utils/media-protection.d.ts +3 -0
  61. package/dist/utils/media-protection.js +49 -0
  62. package/next.config.mjs +4 -0
  63. package/package.json +61 -0
  64. package/postcss.config.js +6 -0
  65. package/src/client-components/ClientLink.tsx +33 -0
  66. package/src/client-components/index.ts +1 -0
  67. package/src/components/Error.tsx +56 -0
  68. package/src/components/LazyPlaceholder.tsx +35 -0
  69. package/src/components/Placeholder.tsx +312 -0
  70. package/src/components/Slot.tsx +22 -0
  71. package/src/components/Translate.tsx +32 -0
  72. package/src/components/field-renderers/Link.tsx +38 -0
  73. package/src/components/field-renderers/Picture.tsx +251 -0
  74. package/src/components/field-renderers/RichText.tsx +48 -0
  75. package/src/components/field-renderers/Text.tsx +32 -0
  76. package/src/configuration.ts +30 -0
  77. package/src/index.ts +84 -0
  78. package/src/internals/index.ts +7 -0
  79. package/src/middleware/handleRequest.ts +54 -0
  80. package/src/middleware/index.ts +1 -0
  81. package/src/picture-shared.ts +53 -0
  82. package/src/render-context.ts +123 -0
  83. package/src/renderings/renderings.tsx +44 -0
  84. package/src/renderings/tailwind.ts +53 -0
  85. package/src/route-data/dictionary.ts +56 -0
  86. package/src/route-data/resolve-route.ts +332 -0
  87. package/src/route-data/route-data.ts +51 -0
  88. package/src/services/api.ts +142 -0
  89. package/src/services/graphQL.ts +106 -0
  90. package/src/types/fetch.ts +8 -0
  91. package/src/types/fieldTypes.ts +127 -0
  92. package/src/types/items.ts +66 -0
  93. package/src/types/layoutDataTypes.ts +145 -0
  94. package/src/utils/media-protection.ts +61 -0
  95. package/tailwind.config.js +17 -0
  96. package/tailwind.config.ts +20 -0
  97. package/tsconfig.json +28 -0
@@ -0,0 +1,54 @@
1
+ import { apiGet, apiPostObject } from "./api";
2
+ export async function executeGraphQLQuery({ query, host, path, language, mode, itemId, version,
3
+ // tags,
4
+ // revalidate,
5
+ siteName, schema, sessionId, apiConfig, }) {
6
+ var _a, _b, _c;
7
+ let url = "/alpaca/headless/graphql";
8
+ if (sessionId)
9
+ url += "?sessionId=" + sessionId;
10
+ //console.log(`GraphQL query:`, query);
11
+ const request = {
12
+ Query: query,
13
+ Host: host,
14
+ Path: path,
15
+ ItemId: itemId,
16
+ Language: language,
17
+ Version: version,
18
+ Mode: mode,
19
+ SiteName: siteName,
20
+ Schema: schema,
21
+ };
22
+ //TODO: cache:
23
+ const response = await apiPostObject(url, request, apiConfig);
24
+ if (response.status !== 200) {
25
+ return { status: response.status, errors: getErrors(response) };
26
+ }
27
+ if ((_a = response.data) === null || _a === void 0 ? void 0 : _a.errors) {
28
+ return {
29
+ status: 400,
30
+ errors: (_b = response.data) === null || _b === void 0 ? void 0 : _b.errors,
31
+ };
32
+ }
33
+ return {
34
+ data: (_c = response.data) === null || _c === void 0 ? void 0 : _c.data,
35
+ status: response.status,
36
+ errors: getErrors(response),
37
+ };
38
+ }
39
+ function getErrors(response) {
40
+ var _a, _b;
41
+ if ((_a = response.data) === null || _a === void 0 ? void 0 : _a.errors)
42
+ return (_b = response.data) === null || _b === void 0 ? void 0 : _b.errors;
43
+ if (response.error)
44
+ return [{ message: response.error }];
45
+ return undefined;
46
+ }
47
+ export async function getGraphQLSchema({ id, apiConfig, }) {
48
+ let url = "/alpaca/headless/graphql/schema?id=" + id;
49
+ const response = await apiGet(url, apiConfig);
50
+ if (response.status !== 200) {
51
+ return { status: response.status, error: response.error };
52
+ }
53
+ return response.data;
54
+ }
@@ -0,0 +1,7 @@
1
+ export interface AlpacaFetchRequestConfig {
2
+ revalidate?: number | false;
3
+ tags?: string[];
4
+ }
5
+ export interface AlpacaRequestInit extends RequestInit {
6
+ alpaca?: AlpacaFetchRequestConfig | undefined;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ import { Field } from "./items";
2
+ export type TextField = Field & {
3
+ value: string;
4
+ };
5
+ export type PictureField = Field & {
6
+ value: PictureValue | null;
7
+ };
8
+ export type LinkField = Field & {
9
+ value: LinkValue;
10
+ };
11
+ export type InternalLinkField = Field & {
12
+ value: LinkValue;
13
+ };
14
+ export type PictureValue = {
15
+ name: string;
16
+ alt: string;
17
+ variants: PictureVariant[];
18
+ loopVideos: boolean;
19
+ };
20
+ export type PictureVariant = {
21
+ mediaItemName: string;
22
+ name: string;
23
+ src: string;
24
+ videoUrl?: string;
25
+ width: number;
26
+ height: number;
27
+ aspectRatio: number;
28
+ aspectRatioLock?: number;
29
+ aspectRatioLockText?: string;
30
+ minWidth?: number;
31
+ minHeight?: number;
32
+ thumbSrc?: string;
33
+ originalSrc?: string;
34
+ mediaId?: string;
35
+ idPath?: string;
36
+ region: PictureRegion;
37
+ };
38
+ export type PictureRegion = {
39
+ x: number;
40
+ y: number;
41
+ width: number;
42
+ height: number;
43
+ };
44
+ export type PictureRawValue = {
45
+ Variants: PictureRawVariant[];
46
+ AltText?: string;
47
+ };
48
+ export type PictureRawVariant = {
49
+ Name: string;
50
+ MediaId: string;
51
+ Region?: PictureRawRegion;
52
+ };
53
+ export type PictureRawRegion = {
54
+ X: number;
55
+ Y: number;
56
+ Width: number;
57
+ Height: number;
58
+ };
59
+ export type ImageField = Field & {
60
+ value: ImageValue | null;
61
+ };
62
+ export type ImageValue = {
63
+ altText: string;
64
+ src: string;
65
+ };
66
+ export type LinkValue = {
67
+ url: string;
68
+ type: "internal" | "external";
69
+ target?: string;
70
+ targetItemLongId?: string;
71
+ targetItemName?: string;
72
+ queryString?: string;
73
+ targetItemId?: string;
74
+ };
75
+ export interface KeyValuePair {
76
+ key: string;
77
+ value: string;
78
+ }
79
+ export type EnhancedNameValueListField = {
80
+ value: KeyValuePair[];
81
+ };
82
+ export type ReferencedItem = {
83
+ id: string;
84
+ name: string;
85
+ path: string;
86
+ };
87
+ export type TreeListField = Field & {
88
+ value: ReferencedItem[];
89
+ _editor: {
90
+ customEditorProperties: {
91
+ datasources: string[];
92
+ };
93
+ };
94
+ };
95
+ export type CheckboxField = Field & {
96
+ value: boolean;
97
+ };
98
+ export type DateField = Field & {
99
+ value: DateFieldValue;
100
+ };
101
+ export type DateFieldValue = Field & {
102
+ date: string;
103
+ };
104
+ export type NumberField = Field & {
105
+ value: number;
106
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,56 @@
1
+ import { ItemEditorProps } from "./layoutDataTypes";
2
+ export type ItemRef = {
3
+ id: string;
4
+ name?: string;
5
+ };
6
+ export type ItemDescriptor = {
7
+ id: string;
8
+ language: string;
9
+ version: number;
10
+ name?: string;
11
+ hasLayout?: boolean;
12
+ };
13
+ export interface Item extends ItemDescriptor {
14
+ fields: Fields;
15
+ templateId: string;
16
+ templateName: string;
17
+ _editor?: ItemEditorProps;
18
+ }
19
+ export interface Fields {
20
+ [name: string]: Field;
21
+ }
22
+ export interface Field {
23
+ id: string;
24
+ value: unknown;
25
+ jsonValue?: Field;
26
+ descriptor?: FieldDescriptor;
27
+ name?: string;
28
+ displayName?: string;
29
+ }
30
+ export type FieldButton = {
31
+ id: string;
32
+ label: string;
33
+ description: string;
34
+ action?: string;
35
+ icon?: string;
36
+ isGenerator: boolean;
37
+ };
38
+ export type LockSession = {
39
+ sessionId: string;
40
+ name: string;
41
+ };
42
+ export type FieldDescriptor = {
43
+ item: ItemDescriptor;
44
+ fieldId: string;
45
+ };
46
+ export type Language = {
47
+ name: string;
48
+ versions: number;
49
+ icon: string;
50
+ languageCode: string;
51
+ };
52
+ export type Version = {
53
+ version: number;
54
+ updated: Date;
55
+ updatedBy: string;
56
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,142 @@
1
+ /// <reference types="react" />
2
+ import { ServerRenderContext } from "../render-context";
3
+ import { Rendering } from "../renderings/renderings";
4
+ import { Item, ItemDescriptor, Language, Version } from "./items";
5
+ export interface PlaceholderData {
6
+ context: ServerRenderContext;
7
+ name: string;
8
+ key: string;
9
+ components: ComponentData[];
10
+ hasMore?: boolean;
11
+ parentComponent?: ComponentData | Page;
12
+ _editor?: {
13
+ insertOptions?: InsertOption[];
14
+ canSynchronize?: boolean;
15
+ };
16
+ }
17
+ export interface ComponentData extends Item {
18
+ context: ServerRenderContext;
19
+ componentType: string;
20
+ rendering?: RenderingReference;
21
+ defaultRendering?: RenderingReference;
22
+ graphql: any;
23
+ placeholders: PlaceholderData[];
24
+ type: "component";
25
+ visible?: boolean;
26
+ _editor: ItemEditorProps & {
27
+ linkItemId: string;
28
+ placeholderReference?: PlaceholderData;
29
+ messages?: Message[];
30
+ linkedComponentItem: ItemDescriptor & {
31
+ path: string;
32
+ };
33
+ isRemoved?: boolean;
34
+ canSynchronize?: boolean;
35
+ isInheritedFromMasterLanguage?: boolean;
36
+ isRemovedFromMasterLanguage?: boolean;
37
+ translations?: string[];
38
+ graphql_query: string;
39
+ compatibleRenderings?: Rendering[];
40
+ hostingPageItem?: {
41
+ id: string;
42
+ language: string;
43
+ version: number;
44
+ path: string;
45
+ editUrl: string;
46
+ };
47
+ };
48
+ }
49
+ export interface RenderingReference {
50
+ id: string;
51
+ revision: string;
52
+ }
53
+ export type RenderMode = "normal" | "edit" | "preview";
54
+ export interface Page extends Item {
55
+ context: ServerRenderContext;
56
+ mode: RenderMode;
57
+ placeholders: PlaceholderData[];
58
+ graphql: any;
59
+ site: {
60
+ name: string;
61
+ };
62
+ meta: {
63
+ title: string;
64
+ description: string;
65
+ canonical: string;
66
+ keywords: string;
67
+ hrefLangTags: {
68
+ [language: string]: string;
69
+ };
70
+ "og:title": string;
71
+ "og:description": string;
72
+ "og:url": string;
73
+ "og:type": string;
74
+ "og:image": string;
75
+ };
76
+ _editor?: ItemEditorProps & {
77
+ graphql_query: string;
78
+ workbox: Workbox;
79
+ };
80
+ }
81
+ export interface DictionaryEntry {
82
+ value: string;
83
+ }
84
+ export interface Dictionary {
85
+ [key: string]: DictionaryEntry;
86
+ }
87
+ export type RenderingsMap = {
88
+ [key: string]: React.ComponentType<any>;
89
+ };
90
+ export type InsertOption = {
91
+ templateId: string;
92
+ name: string;
93
+ icon: string;
94
+ group?: string;
95
+ svg?: string;
96
+ isComponent: boolean;
97
+ isHidden: any;
98
+ compatibleTemplates?: string[];
99
+ };
100
+ export interface ItemEditorProps {
101
+ translations?: string[];
102
+ path: string;
103
+ languages: Language[];
104
+ versions: Version[];
105
+ idPath: string;
106
+ parentId: string;
107
+ masterLanguages?: string[];
108
+ hasLock: boolean;
109
+ canLock: boolean;
110
+ canWrite: boolean;
111
+ canWriteLanguage: boolean;
112
+ canWriteItem: boolean;
113
+ canWriteWorkflow: boolean;
114
+ workflowState: boolean;
115
+ lockedBy: string;
116
+ hasLayout: boolean;
117
+ icon: string;
118
+ }
119
+ export type Message = {
120
+ text: string;
121
+ };
122
+ export type Workbox = {
123
+ items: WorkboxItem[];
124
+ };
125
+ export type WorkboxItem = {
126
+ item: ItemDescriptor;
127
+ lockedBy: string;
128
+ canLock: boolean;
129
+ hasLock: boolean;
130
+ publishStatus: {
131
+ [target: string]: string;
132
+ };
133
+ workflowState: string;
134
+ isFinalState: boolean;
135
+ isPublishable: boolean;
136
+ isPublished: boolean;
137
+ path: string;
138
+ commands: {
139
+ name: string;
140
+ id: string;
141
+ }[];
142
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import "url";
3
+ export declare function hashImageUrl(url: string): string;
@@ -0,0 +1,49 @@
1
+ import crypto from "crypto";
2
+ import "url";
3
+ const protectedParams = [
4
+ "w",
5
+ "h",
6
+ "mw",
7
+ "mh",
8
+ "sc",
9
+ "as",
10
+ "bc",
11
+ "db",
12
+ "iar",
13
+ "la",
14
+ "thn",
15
+ "vs",
16
+ "sc_content",
17
+ "sc_lang",
18
+ "sc_site",
19
+ "gray",
20
+ "rev",
21
+ "devicepixelratio",
22
+ "encodequality",
23
+ "rx",
24
+ "ry",
25
+ "rw",
26
+ "rh",
27
+ "crop",
28
+ ];
29
+ export function hashImageUrl(url) {
30
+ if (!process.env.MEDIA_REQUESTPROTECTION_SHAREDSECRET)
31
+ return url;
32
+ if (!url)
33
+ return url;
34
+ const baseURL = 'http://temp-base-url.com'; // This will serve as a placeholder.
35
+ const uri = new URL(url.toLowerCase(), baseURL);
36
+ uri.searchParams.delete("hash");
37
+ const searchParams = protectedParams
38
+ .map((x) => ({ name: x, val: uri.searchParams.get(x) }))
39
+ .filter((x) => x.val)
40
+ .map((x) => x.name + "=" + x.val)
41
+ .join("&");
42
+ const stringToProtect = uri.pathname.substring(1) + "?" + searchParams;
43
+ const hash = crypto
44
+ .createHash("md5")
45
+ .update(stringToProtect + process.env.MEDIA_REQUESTPROTECTION_SHAREDSECRET, "utf16le")
46
+ .digest("hex");
47
+ uri.searchParams.set("hash", hash);
48
+ return url.startsWith('http') ? uri.toString() : uri.pathname + uri.search;
49
+ }
@@ -0,0 +1,4 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {};
3
+
4
+ export default nextConfig;
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@alpaca-headless/alpaca-headless",
3
+ "version": "1.0.3397",
4
+ "type": "module",
5
+ "description": "Alpaca Headless",
6
+ "main": "dist/index.js",
7
+ "exports": {
8
+ ".": "./dist/index.js",
9
+ "./client-components": "./dist/client-components/index.js",
10
+ "./middleware": "./dist/middleware/index.js",
11
+ "./internals": "./dist/internals/index.js"
12
+ },
13
+ "typesVersions": {
14
+ "*": {
15
+ "client-components": [
16
+ "dist/client-components/index.d.ts"
17
+ ],
18
+ "middleware": [
19
+ "dist/middleware/index.d.ts"
20
+ ],
21
+ "internals": [
22
+ "dist/internals/index.d.ts"
23
+ ]
24
+ }
25
+ },
26
+ "scripts": {
27
+ "build": "tsc -b",
28
+ "test": "echo \"Error: no test specified\" && exit 1"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/yourusername/your-module-name.git"
33
+ },
34
+ "keywords": [
35
+ "esm",
36
+ "module"
37
+ ],
38
+ "author": "Canvas REPLY DE GmbH",
39
+ "license": "MIT",
40
+ "bugs": {
41
+ "url": "https://github.com/yourusername/your-module-name/issues"
42
+ },
43
+ "homepage": "https://github.com/yourusername/your-module-name#readme",
44
+ "devDependencies": {
45
+ "@types/node": "^20.12.11",
46
+ "@types/react": "18.3.3",
47
+ "@types/react-dom": "18.3.0",
48
+ "@types/uuid": "^10.0.0",
49
+ "eslint": "^8",
50
+ "eslint-config-next": "14.1.3",
51
+ "typescript": "^5"
52
+ },
53
+ "dependencies": {
54
+ "axios": "^1.7.2",
55
+ "next": "^14.2.10",
56
+ "react": "^18.3.1",
57
+ "react-dom": "^18.3.1",
58
+ "react-error-boundary": "^4.0.13",
59
+ "uuid": "^10.0.0"
60
+ }
61
+ }
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ };
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { LinkField } from "../types/fieldTypes";
3
+
4
+ export function ClientLink({
5
+ field,
6
+ children,
7
+ ...props
8
+ }: {
9
+ field: LinkField;
10
+ children: React.ReactNode;
11
+ editable?: boolean;
12
+ } & React.AnchorHTMLAttributes<HTMLAnchorElement>) {
13
+ const descriptor = field.descriptor;
14
+
15
+ const editProps = descriptor
16
+ ? {
17
+ ...props,
18
+ "data-fieldid": descriptor.fieldId,
19
+ "data-itemid": descriptor.item.id,
20
+ "data-language": descriptor.item.language,
21
+ "data-version": descriptor.item.version,
22
+ }
23
+ : props;
24
+ return (
25
+ <a
26
+ href={field.value.url}
27
+ {...editProps}
28
+ onClick={(e: any) => e.preventDefault()}
29
+ >
30
+ {children}
31
+ </a>
32
+ );
33
+ }
@@ -0,0 +1 @@
1
+ export { ClientLink } from "./ClientLink";
@@ -0,0 +1,56 @@
1
+ "use client";
2
+
3
+ // import { EditContextType } from "../editor/editContext";
4
+
5
+ export function ErrorFallback() {
6
+ // Call resetErrorBoundary() to reset the error boundary and retry the render.
7
+
8
+ return (
9
+ <div role="alert">
10
+ <p>Something went wrong.</p>
11
+ </div>
12
+ );
13
+ }
14
+
15
+ // export function ErrorFallbackWithDetails({
16
+ // error,
17
+ // component,
18
+ // editContext,
19
+ // }: {
20
+ // error: Error;
21
+ // component: ComponentData;
22
+ // editContext?: EditContextType;
23
+ // }) {
24
+ // // Call resetErrorBoundary() to reset the error boundary and retry the render.
25
+
26
+ // return (
27
+ // <div
28
+ // role="alert"
29
+ // className="a-cursor-pointer"
30
+ // onClick={(ev) => {
31
+ // if (!editContext) return;
32
+ // ev.stopPropagation();
33
+ // ev.preventDefault();
34
+ // editContext.select([component.id]);
35
+ // if (!editContext.configuration.chrome.editor.views) return;
36
+ // const designerView = editContext.configuration.chrome.editor.views.find(
37
+ // (x) => x.name === "component-designer"
38
+ // );
39
+ // if (component.rendering && designerView)
40
+ // editContext.setView(designerView);
41
+ // }}
42
+ // >
43
+ // <div className="a-text-xs a-bg-gray-100 a-p-3">
44
+ // <div className="a-font-bold a-mb-1">Something went wrong</div>
45
+ // <div>Component id: {component.id}</div>
46
+ // <div>Component type: {component.componentType}</div>
47
+ // {component.rendering && (
48
+ // <div>Rendering id: {component.rendering.id}</div>
49
+ // )}
50
+ // <pre className="a-overflow-x-auto a-text-red-500 a-py-2">
51
+ // {error.message} {error.stack}
52
+ // </pre>
53
+ // </div>
54
+ // </div>
55
+ // );
56
+ // }
@@ -0,0 +1,35 @@
1
+ import { ServerRenderContext } from "../render-context";
2
+ import { loadPartialLayout } from "../route-data/resolve-route";
3
+ import { PlaceholderData } from "../types/layoutDataTypes";
4
+ import { Placeholder } from "./Placeholder";
5
+
6
+ export async function LazyPlaceholder({
7
+ placeholder,
8
+ context,
9
+ }: {
10
+ context: ServerRenderContext;
11
+ placeholder: PlaceholderData;
12
+ }) {
13
+ const data = await loadPartialLayout(
14
+ context.page.id,
15
+ context.page.language,
16
+ context.page.version,
17
+ placeholder.parentComponent
18
+ ? {
19
+ id: placeholder.parentComponent.id,
20
+ language: placeholder.parentComponent.language,
21
+ version: placeholder.parentComponent.version,
22
+ }
23
+ : undefined,
24
+ placeholder.key,
25
+ context.renderOptions,
26
+ context.page.site.name,
27
+ context.mode
28
+ );
29
+
30
+ if (data == null) return null;
31
+
32
+ return (
33
+ <Placeholder name={placeholder.key} content={data.page} context={context} />
34
+ );
35
+ }