@uniformdev/canvas-next-rsc 19.29.1-alpha.19

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 (121) hide show
  1. package/LICENSE.txt +2 -0
  2. package/README.md +5 -0
  3. package/dist/client/canvasClient.d.ts +5 -0
  4. package/dist/client/canvasClient.js +24 -0
  5. package/dist/client/manifestClient.d.ts +161 -0
  6. package/dist/client/manifestClient.js +32 -0
  7. package/dist/client/projectMapClient.d.ts +5 -0
  8. package/dist/client/projectMapClient.js +17 -0
  9. package/dist/client/routeClient.d.ts +5 -0
  10. package/dist/client/routeClient.js +48 -0
  11. package/dist/components/DefaultNotImplementedComponent.d.ts +2 -0
  12. package/dist/components/DefaultNotImplementedComponent.js +45 -0
  13. package/dist/components/GoogleTagManagerAnalytics.d.ts +3 -0
  14. package/dist/components/GoogleTagManagerAnalytics.js +44 -0
  15. package/dist/components/UniformComponent.d.ts +12 -0
  16. package/dist/components/UniformComponent.js +13 -0
  17. package/dist/components/UniformComposition.d.ts +35 -0
  18. package/dist/components/UniformComposition.js +55 -0
  19. package/dist/components/UniformContext.d.ts +11 -0
  20. package/dist/components/UniformContext.js +19 -0
  21. package/dist/components/UniformScript.d.ts +3 -0
  22. package/dist/components/UniformScript.js +73 -0
  23. package/dist/components/UniformSlot.d.ts +24 -0
  24. package/dist/components/UniformSlot.js +32 -0
  25. package/dist/components/UniformText.d.ts +14 -0
  26. package/dist/components/UniformText.js +9 -0
  27. package/dist/components/convertComponentToProps.d.ts +11 -0
  28. package/dist/components/convertComponentToProps.js +21 -0
  29. package/dist/components/evaluateComposition.d.ts +15 -0
  30. package/dist/components/evaluateComposition.js +167 -0
  31. package/dist/components/getEnrichmentTags.d.ts +3 -0
  32. package/dist/components/getEnrichmentTags.js +13 -0
  33. package/dist/components/renderComponent.d.ts +13 -0
  34. package/dist/components/renderComponent.js +45 -0
  35. package/dist/components/resolvePath.d.ts +5 -0
  36. package/dist/components/resolvePath.js +34 -0
  37. package/dist/components/resolveRoute.d.ts +26 -0
  38. package/dist/components/resolveRoute.js +59 -0
  39. package/dist/config/helpers.d.ts +15 -0
  40. package/dist/config/helpers.js +20 -0
  41. package/dist/config/models.d.ts +26 -0
  42. package/dist/config/models.js +1 -0
  43. package/dist/config/uniform.server.config.d.ts +3 -0
  44. package/dist/config/uniform.server.config.js +3 -0
  45. package/dist/config.d.ts +1 -0
  46. package/dist/config.js +42 -0
  47. package/dist/cookie/index.d.ts +12 -0
  48. package/dist/cookie/index.js +21 -0
  49. package/dist/handler/createPreviewGETRouteHandler.d.ts +1 -0
  50. package/dist/handler/createPreviewGETRouteHandler.js +43 -0
  51. package/dist/handler/createPreviewPOSTRouteHandler.d.ts +1 -0
  52. package/dist/handler/createPreviewPOSTRouteHandler.js +87 -0
  53. package/dist/handler/createUniformRouteHandler.d.ts +4 -0
  54. package/dist/handler/createUniformRouteHandler.js +10 -0
  55. package/dist/handler/helpers.d.ts +14 -0
  56. package/dist/handler/helpers.js +60 -0
  57. package/dist/handler/messages/handleCompositionChanged.d.ts +2 -0
  58. package/dist/handler/messages/handleCompositionChanged.js +9 -0
  59. package/dist/handler/messages/handleCompositionDeleted.d.ts +2 -0
  60. package/dist/handler/messages/handleCompositionDeleted.js +9 -0
  61. package/dist/handler/messages/handleCompositionPublished.d.ts +2 -0
  62. package/dist/handler/messages/handleCompositionPublished.js +9 -0
  63. package/dist/handler/messages/handleManifestPublished.d.ts +2 -0
  64. package/dist/handler/messages/handleManifestPublished.js +10 -0
  65. package/dist/handler/messages/handleProjectMapNodeDelete.d.ts +2 -0
  66. package/dist/handler/messages/handleProjectMapNodeDelete.js +13 -0
  67. package/dist/handler/messages/handleProjectMapNodeInsert.d.ts +2 -0
  68. package/dist/handler/messages/handleProjectMapNodeInsert.js +13 -0
  69. package/dist/handler/messages/handleProjectMapNodeUpdate.d.ts +2 -0
  70. package/dist/handler/messages/handleProjectMapNodeUpdate.js +14 -0
  71. package/dist/handler/messages/handleRedirectDelete.d.ts +2 -0
  72. package/dist/handler/messages/handleRedirectDelete.js +9 -0
  73. package/dist/handler/messages/handleRedirectInsert.d.ts +2 -0
  74. package/dist/handler/messages/handleRedirectInsert.js +9 -0
  75. package/dist/handler/messages/handleRedirectUpdate.d.ts +2 -0
  76. package/dist/handler/messages/handleRedirectUpdate.js +9 -0
  77. package/dist/handler.d.ts +2 -0
  78. package/dist/handler.js +2 -0
  79. package/dist/hooks/useForgetMe.d.ts +4 -0
  80. package/dist/hooks/useForgetMe.js +10 -0
  81. package/dist/hooks/useToggleConsent.d.ts +7 -0
  82. package/dist/hooks/useToggleConsent.js +22 -0
  83. package/dist/hooks/useUniformContext.d.ts +1 -0
  84. package/dist/hooks/useUniformContext.js +3 -0
  85. package/dist/index.d.ts +16 -0
  86. package/dist/index.js +20 -0
  87. package/dist/models/index.d.ts +30 -0
  88. package/dist/models/index.js +1 -0
  89. package/dist/register/componentStore.d.ts +1 -0
  90. package/dist/register/componentStore.js +2 -0
  91. package/dist/register/componentStoreResolver.d.ts +2 -0
  92. package/dist/register/componentStoreResolver.js +5 -0
  93. package/dist/register/createComponentStore.d.ts +12 -0
  94. package/dist/register/createComponentStore.js +13 -0
  95. package/dist/register/createComponentStoreResolver.d.ts +9 -0
  96. package/dist/register/createComponentStoreResolver.js +8 -0
  97. package/dist/register/getTypeWithVariant.d.ts +1 -0
  98. package/dist/register/getTypeWithVariant.js +1 -0
  99. package/dist/register/registerUniformComponent.d.ts +6 -0
  100. package/dist/register/registerUniformComponent.js +8 -0
  101. package/dist/resolve/resolveChildren.d.ts +9 -0
  102. package/dist/resolve/resolveChildren.js +18 -0
  103. package/dist/score/index.d.ts +3 -0
  104. package/dist/score/index.js +114 -0
  105. package/dist/utils/__tests__/apply.spec.d.ts +1 -0
  106. package/dist/utils/__tests__/apply.spec.js +358 -0
  107. package/dist/utils/__tests__/diff.spec.d.ts +1 -0
  108. package/dist/utils/__tests__/diff.spec.js +394 -0
  109. package/dist/utils/apply.d.ts +6 -0
  110. package/dist/utils/apply.js +124 -0
  111. package/dist/utils/comp.d.ts +16 -0
  112. package/dist/utils/comp.js +47 -0
  113. package/dist/utils/diff.d.ts +44 -0
  114. package/dist/utils/diff.js +144 -0
  115. package/dist/utils/draft.d.ts +11 -0
  116. package/dist/utils/draft.js +23 -0
  117. package/dist/utils/tag.d.ts +1 -0
  118. package/dist/utils/tag.js +3 -0
  119. package/dist/utils/url.d.ts +1 -0
  120. package/dist/utils/url.js +10 -0
  121. package/package.json +78 -0
package/LICENSE.txt ADDED
@@ -0,0 +1,2 @@
1
+ © 2023 Uniform Systems, Inc. All Rights Reserved.
2
+ See details of Uniform Systems, Inc. Master Subscription Agreement here: https://uniform.dev/eula
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ Next.js RSC SDK for Uniform Canvas
2
+
3
+ **Note:** This package is in public preview.
4
+
5
+ part of the [Uniform Platform](https://uniform.app). See our [documentation](https://docs.uniform.app) for more details.
@@ -0,0 +1,5 @@
1
+ import { CanvasClient } from '@uniformdev/canvas';
2
+ export type GetCanvasClientOptions = {
3
+ revalidate?: number;
4
+ };
5
+ export declare const getCanvasClient: (options?: GetCanvasClientOptions) => CanvasClient;
@@ -0,0 +1,24 @@
1
+ import { CanvasClient } from '@uniformdev/canvas';
2
+ export const getCanvasClient = (options) => {
3
+ return new CanvasClient({
4
+ projectId: process.env.UNIFORM_PROJECT_ID,
5
+ apiHost: process.env.UNIFORM_API_HOST,
6
+ apiKey: process.env.UNIFORM_API_KEY,
7
+ edgeApiHost: process.env.UNIFORM_EDGE_API_HOST,
8
+ fetch: (req, init) => {
9
+ let revalidate = options === null || options === void 0 ? void 0 : options.revalidate;
10
+ let noCache = false;
11
+ if (revalidate === -1) {
12
+ noCache = true;
13
+ revalidate = undefined;
14
+ }
15
+ return fetch(req, {
16
+ ...init,
17
+ cache: noCache ? 'no-cache' : 'force-cache',
18
+ next: {
19
+ revalidate,
20
+ },
21
+ });
22
+ },
23
+ });
24
+ };
@@ -0,0 +1,161 @@
1
+ import { ManifestClient } from '@uniformdev/context/api';
2
+ export type GetManifestClientOptions = {
3
+ revalidate?: number;
4
+ };
5
+ export declare const getManifestClient: (options?: GetManifestClientOptions) => ManifestClient;
6
+ export declare const getManifestFromApi: (options: {
7
+ searchParams: {
8
+ [key: string]: string | undefined;
9
+ } | undefined;
10
+ }) => Promise<{
11
+ project: {
12
+ id?: string | undefined;
13
+ name?: string | undefined;
14
+ ui_version?: number | undefined;
15
+ pz?: {
16
+ sig?: {
17
+ [key: string]: {
18
+ str: number;
19
+ cap: number;
20
+ dur: "p" | "s" | "t";
21
+ crit: {
22
+ type: "G";
23
+ op?: "&" | "|" | undefined;
24
+ clauses: ({
25
+ type: "G";
26
+ op?: "&" | "|" | undefined;
27
+ clauses: (any | {
28
+ type: "CK";
29
+ cookieName: string;
30
+ match: {
31
+ rhs: string;
32
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
33
+ cs?: boolean | undefined;
34
+ } | {
35
+ op: "*" | "!*";
36
+ };
37
+ } | {
38
+ type: "QS";
39
+ queryName: string;
40
+ match: {
41
+ rhs: string;
42
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
43
+ cs?: boolean | undefined;
44
+ } | {
45
+ op: "*" | "!*";
46
+ };
47
+ } | {
48
+ type: "QK";
49
+ key: string;
50
+ match: {
51
+ rhs: string;
52
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
53
+ cs?: boolean | undefined;
54
+ } | {
55
+ op: "*" | "!*";
56
+ };
57
+ } | {
58
+ type: "EVT";
59
+ event: {
60
+ rhs: string;
61
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
62
+ cs?: boolean | undefined;
63
+ } | {
64
+ op: "*" | "!*";
65
+ };
66
+ } | {
67
+ type: "PV";
68
+ path: {
69
+ rhs: string;
70
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
71
+ cs?: boolean | undefined;
72
+ } | {
73
+ op: "*" | "!*";
74
+ };
75
+ } | {
76
+ type: "PVC";
77
+ match: {
78
+ rhs: number;
79
+ op: "=" | "!=" | "<" | ">";
80
+ };
81
+ })[];
82
+ } | {
83
+ type: "CK";
84
+ cookieName: string;
85
+ match: {
86
+ rhs: string;
87
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
88
+ cs?: boolean | undefined;
89
+ } | {
90
+ op: "*" | "!*";
91
+ };
92
+ } | {
93
+ type: "QS";
94
+ queryName: string;
95
+ match: {
96
+ rhs: string;
97
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
98
+ cs?: boolean | undefined;
99
+ } | {
100
+ op: "*" | "!*";
101
+ };
102
+ } | {
103
+ type: "QK";
104
+ key: string;
105
+ match: {
106
+ rhs: string;
107
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
108
+ cs?: boolean | undefined;
109
+ } | {
110
+ op: "*" | "!*";
111
+ };
112
+ } | {
113
+ type: "EVT";
114
+ event: {
115
+ rhs: string;
116
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
117
+ cs?: boolean | undefined;
118
+ } | {
119
+ op: "*" | "!*";
120
+ };
121
+ } | {
122
+ type: "PV";
123
+ path: {
124
+ rhs: string;
125
+ op: "~" | "=" | "//" | "!=" | "!~" | "!//";
126
+ cs?: boolean | undefined;
127
+ } | {
128
+ op: "*" | "!*";
129
+ };
130
+ } | {
131
+ type: "PVC";
132
+ match: {
133
+ rhs: number;
134
+ op: "=" | "!=" | "<" | ">";
135
+ };
136
+ })[];
137
+ };
138
+ };
139
+ } | undefined;
140
+ enr?: {
141
+ [key: string]: {
142
+ cap: number;
143
+ };
144
+ } | undefined;
145
+ agg?: {
146
+ [key: string]: {
147
+ inputs: {
148
+ dim: string;
149
+ sign?: "-" | "+" | "c" | undefined;
150
+ }[];
151
+ };
152
+ } | undefined;
153
+ control?: number | undefined;
154
+ } | undefined;
155
+ test?: {
156
+ [key: string]: {
157
+ wv?: string | undefined;
158
+ };
159
+ } | undefined;
160
+ };
161
+ }>;
@@ -0,0 +1,32 @@
1
+ import { ManifestClient } from '@uniformdev/context/api';
2
+ import { getManifestRevalidateInterval } from '../config/helpers';
3
+ export const getManifestClient = (options) => {
4
+ const manifestClient = new ManifestClient({
5
+ apiHost: process.env.UNIFORM_API_HOST || process.env.UNIFORM_CLI_BASE_URL,
6
+ apiKey: process.env.UNIFORM_API_KEY,
7
+ projectId: process.env.UNIFORM_PROJECT_ID,
8
+ fetch: (req, init) => {
9
+ let revalidate = options === null || options === void 0 ? void 0 : options.revalidate;
10
+ let noCache = false;
11
+ if (revalidate === -1) {
12
+ noCache = true;
13
+ revalidate = undefined;
14
+ }
15
+ return fetch(req, {
16
+ ...init,
17
+ cache: noCache ? 'no-cache' : 'force-cache',
18
+ next: {
19
+ revalidate,
20
+ tags: ['manifest'],
21
+ },
22
+ });
23
+ },
24
+ });
25
+ return manifestClient;
26
+ };
27
+ export const getManifestFromApi = (options) => {
28
+ const manifestClient = getManifestClient({
29
+ revalidate: getManifestRevalidateInterval(options),
30
+ });
31
+ return manifestClient.get();
32
+ };
@@ -0,0 +1,5 @@
1
+ import { ProjectMapClient } from '@uniformdev/project-map';
2
+ export type GetProjectMapClientOptions = {
3
+ revalidate?: number;
4
+ };
5
+ export declare const getProjectMapClient: (options?: GetProjectMapClientOptions) => ProjectMapClient;
@@ -0,0 +1,17 @@
1
+ import { ProjectMapClient } from '@uniformdev/project-map';
2
+ export const getProjectMapClient = (options) => {
3
+ const manifestClient = new ProjectMapClient({
4
+ apiHost: process.env.UNIFORM_API_HOST || process.env.UNIFORM_CLI_BASE_URL,
5
+ apiKey: process.env.UNIFORM_API_KEY,
6
+ projectId: process.env.UNIFORM_PROJECT_ID,
7
+ fetch: (req, init) => {
8
+ return fetch(req, {
9
+ ...init,
10
+ next: {
11
+ revalidate: options === null || options === void 0 ? void 0 : options.revalidate,
12
+ },
13
+ });
14
+ },
15
+ });
16
+ return manifestClient;
17
+ };
@@ -0,0 +1,5 @@
1
+ import { RouteClient } from '@uniformdev/canvas';
2
+ export type GetRouteClientOptions = {
3
+ revalidate?: number;
4
+ };
5
+ export declare const getRouteClient: (options?: GetRouteClientOptions) => RouteClient;
@@ -0,0 +1,48 @@
1
+ import { RouteClient } from '@uniformdev/canvas';
2
+ import { buildPathTag } from '../utils/tag';
3
+ export const getRouteClient = (options) => {
4
+ const client = new RouteClient({
5
+ projectId: process.env.UNIFORM_PROJECT_ID,
6
+ apiKey: process.env.UNIFORM_API_KEY,
7
+ edgeApiHost: process.env.UNIFORM_EDGE_API_HOST,
8
+ fetch: (req, init) => {
9
+ let requestedUrl;
10
+ if (typeof req === 'string') {
11
+ requestedUrl = new URL(req);
12
+ }
13
+ else if (req instanceof URL) {
14
+ requestedUrl = req;
15
+ }
16
+ else {
17
+ requestedUrl = new URL(req.url);
18
+ }
19
+ const tags = [];
20
+ if (requestedUrl) {
21
+ // this is here so this code breaks if parameters change here
22
+ const pathKey = 'path';
23
+ const path = requestedUrl.searchParams.get(pathKey);
24
+ if (path) {
25
+ tags.push(buildPathTag(path));
26
+ }
27
+ }
28
+ let revalidate;
29
+ let noCache = false;
30
+ if (options === null || options === void 0 ? void 0 : options.revalidate) {
31
+ revalidate = options.revalidate;
32
+ }
33
+ if (revalidate === -1) {
34
+ noCache = true;
35
+ revalidate = undefined;
36
+ }
37
+ return fetch(req, {
38
+ ...init,
39
+ cache: noCache ? 'no-cache' : 'force-cache',
40
+ next: {
41
+ revalidate,
42
+ tags: tags.length ? tags : undefined,
43
+ },
44
+ });
45
+ },
46
+ });
47
+ return client;
48
+ };
@@ -0,0 +1,2 @@
1
+ import { ComponentProps } from './UniformComponent';
2
+ export declare function DefaultNotImplementedComponent(props: ComponentProps): JSX.Element | null;
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CANVAS_LOCALIZATION_TYPE } from '@uniformdev/canvas';
3
+ const wrapperStyles = {
4
+ display: 'flex',
5
+ flexDirection: 'column',
6
+ gap: '0.5rem',
7
+ borderLeft: '4px solid #e42535',
8
+ padding: '16px',
9
+ fontSize: '16px',
10
+ borderRadius: '0 8px 8px 0',
11
+ margin: '8px',
12
+ backgroundColor: 'rgba(255, 255, 255, 0.45)',
13
+ color: '#1d3557',
14
+ };
15
+ export function DefaultNotImplementedComponent(props) {
16
+ var _a, _b, _c;
17
+ const componentType = (_a = props.component) === null || _a === void 0 ? void 0 : _a.type;
18
+ if (!componentType) {
19
+ return null;
20
+ }
21
+ if (componentType === CANVAS_LOCALIZATION_TYPE) {
22
+ return (_jsx("div", { style: wrapperStyles, children: _jsxs("p", { children: ["Seems like localization is not enabled in your application. Please read our documentation on how to", ' ', _jsx("a", { href: "https://docs.uniform.app/guides/composition/localization#activate-front-end", target: "_blank", style: { fontWeight: 'bolder', textDecoration: 'underline' }, rel: "noreferrer", children: "enable localization in your front-end application." })] }) }));
23
+ }
24
+ const proposedFileName = `${componentType[0].toUpperCase()}${componentType.substring(1)}`;
25
+ const probableProps = Object.keys((_b = props.component.parameters) !== null && _b !== void 0 ? _b : {});
26
+ const probableSlots = Object.keys((_c = props.component.slots) !== null && _c !== void 0 ? _c : {});
27
+ return (_jsxs("div", { style: wrapperStyles, children: [_jsx("h2", { style: { fontSize: '1.2rem' }, children: "Unknown Component" }), _jsxs("p", { children: ["Received request from Uniform to render a component with the public ID: ", _jsx("code", { children: componentType }), "."] }), _jsxs("p", { children: [_jsx("code", { children: "<UniformComposition />" }), " does not have ", _jsx("code", { children: componentType }), " mapped to a React component yet."] }), _jsx("p", { children: "To teach your app how to render this component:" }), ' ', _jsxs("ul", { style: {
28
+ listStyleType: 'disc',
29
+ marginLeft: '1rem',
30
+ display: 'flex',
31
+ flexDirection: 'column',
32
+ gap: '0.5rem',
33
+ }, children: [_jsxs("li", { children: ["Create a React component and register it with Uniform, for example", _jsx("pre", { children: `function ${proposedFileName}(${probableProps.length > 0 ? `{ ${probableProps.join(', ')} }` : ''}) {
34
+ return (
35
+ <div>
36
+ ${proposedFileName}!
37
+ ${probableSlots.length > 0
38
+ ? probableSlots.map((slot) => `<UniformSlot name="${slot}" />`).join('\n ')
39
+ : ''}
40
+ </div>
41
+ )
42
+ }
43
+
44
+ registerUniformComponent({ type: "${componentType}", component: ${proposedFileName} })` }), _jsxs("details", { children: [_jsx("summary", { style: { cursor: 'pointer' }, children: "Props that your React component will receive" }), _jsx("pre", { children: JSON.stringify(props, null, 2) })] })] }), _jsxs("li", { children: ["Import the component into the file where ", _jsx("code", { children: "<UniformComposition />" }), " is defined, for example ", _jsx("pre", { children: `import "../components/${proposedFileName}.tsx"` })] })] }), ' ', _jsxs("p", { children: ["Need more help?", ' ', _jsx("a", { href: "https://docs.uniform.app/docs/guides/composition/rendering", target: "_blank", rel: "noreferrer", style: { textDecoration: 'underline' }, children: "Check out the documentation." })] })] }));
45
+ }
@@ -0,0 +1,3 @@
1
+ export declare const GoogleTagManagerAnalytics: (props?: {
2
+ measurementId?: string;
3
+ }) => JSX.Element;
@@ -0,0 +1,44 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import Script from 'next/script';
4
+ import { useEffect } from 'react';
5
+ import { useUniformContext } from '../hooks/useUniformContext';
6
+ const isGtagConfigured = () => {
7
+ return typeof window !== 'undefined' && typeof window.gtag === 'function';
8
+ };
9
+ export const GoogleTagManagerAnalytics = (props) => {
10
+ const { seenComponents } = useUniformContext();
11
+ useEffect(() => {
12
+ if (!(seenComponents === null || seenComponents === void 0 ? void 0 : seenComponents.length)) {
13
+ return;
14
+ }
15
+ if (!isGtagConfigured()) {
16
+ // eslint-disable-next-line no-console
17
+ console.warn('Google Tag Manager is not configured. Please add the gtag script to your site.');
18
+ return;
19
+ }
20
+ seenComponents.forEach((component) => {
21
+ var _a, _b, _c, _d, _e;
22
+ if (component.type === 'personalization') {
23
+ (_b = (_a = window).gtag) === null || _b === void 0 ? void 0 : _b.call(_a, 'event', component.id, {
24
+ event_category: 'Uniform Personalization',
25
+ event_label: component.variants.join(', '),
26
+ is_control_group: component.control ? 1 : 0,
27
+ });
28
+ }
29
+ else if (component.type === 'test') {
30
+ (_d = (_c = window).gtag) === null || _d === void 0 ? void 0 : _d.call(_c, 'event', component.id, {
31
+ event_category: 'Uniform AB Testing',
32
+ event_label: (_e = component.variant) !== null && _e !== void 0 ? _e : 'No Variant',
33
+ });
34
+ }
35
+ });
36
+ }, [seenComponents]);
37
+ return (_jsx(_Fragment, { children: Boolean(props === null || props === void 0 ? void 0 : props.measurementId) && (_jsxs(_Fragment, { children: [_jsx(Script, { src: `https://www.googletagmanager.com/gtag/js?id=${props.measurementId}`, strategy: "afterInteractive" }), _jsx(Script, { id: "google-analytics", strategy: "afterInteractive", children: `
38
+ window.dataLayer = window.dataLayer || [];
39
+ function gtag(){window.dataLayer.push(arguments);}
40
+ gtag('js', new Date());
41
+
42
+ gtag('config', '${props.measurementId}');
43
+ ` })] })) }));
44
+ };
@@ -0,0 +1,12 @@
1
+ import { type ComponentInstance } from '@uniformdev/canvas';
2
+ import { ReactNode } from 'react';
3
+ export type ComponentProps<TProps = unknown> = TProps & {
4
+ component: ComponentInstance;
5
+ };
6
+ export type UniformComponentProps<TRenderProps = unknown> = {
7
+ data: ComponentInstance;
8
+ children?: ReactNode | ((props: ComponentProps<TRenderProps>) => JSX.Element);
9
+ };
10
+ export declare function UniformComponent({ data, children }: UniformComponentProps): import("react").FunctionComponentElement<{
11
+ children?: ReactNode;
12
+ }>;
@@ -0,0 +1,13 @@
1
+ import { createElement, Fragment } from 'react';
2
+ import { componentStoreResolver } from '../register/componentStoreResolver';
3
+ import { resolveChildren } from '../resolve/resolveChildren';
4
+ export function UniformComponent({ data, children }) {
5
+ const resolvedChildren = resolveChildren({
6
+ children,
7
+ data,
8
+ hasParentLayout: false,
9
+ resolveRenderer: componentStoreResolver,
10
+ });
11
+ const childrenToRender = [resolvedChildren];
12
+ return createElement(Fragment, {}, childrenToRender);
13
+ }
@@ -0,0 +1,35 @@
1
+ import { ReactNode } from 'react';
2
+ export type SuspenseOptions = {
3
+ mode: 'off';
4
+ } | {
5
+ mode: 'fallback';
6
+ fallback: React.ReactNode;
7
+ };
8
+ export type UniformCompositionProps = {
9
+ /**
10
+ * The params object from Next.js router. Used to resolve a composition.
11
+ */
12
+ params: {
13
+ slug: string | string[];
14
+ };
15
+ /**
16
+ * The searchParams object from Next.js router. Used for signal evaluation.
17
+ */
18
+ searchParams?: {
19
+ [key: string]: string | undefined;
20
+ };
21
+ /**
22
+ * Behavior of root Suspense component.
23
+ */
24
+ suspense?: {
25
+ mode: 'off';
26
+ } | {
27
+ mode: 'fallback';
28
+ fallback: React.ReactNode;
29
+ };
30
+ /**
31
+ * The children of the UniformComposition component.
32
+ */
33
+ children?: ReactNode;
34
+ };
35
+ export declare const UniformComposition: ({ suspense, ...props }: UniformCompositionProps) => JSX.Element;
@@ -0,0 +1,55 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CANVAS_DRAFT_STATE, CANVAS_PUBLISHED_STATE } from '@uniformdev/canvas';
3
+ import { notFound, redirect } from 'next/navigation';
4
+ import { Suspense } from 'react';
5
+ import { getManifestFromApi } from '../client/manifestClient';
6
+ import { isDraftModeEnabled, isOnVercelPreviewEnvironment } from '../utils/draft';
7
+ import { evaluateComposition } from './evaluateComposition';
8
+ import { resolvePath } from './resolvePath';
9
+ import { resolveRoute } from './resolveRoute';
10
+ import { UniformComponent } from './UniformComponent';
11
+ import { UniformProvider } from './UniformContext';
12
+ import { UniformScript } from './UniformScript';
13
+ export const UniformComposition = ({ suspense = {
14
+ mode: 'fallback',
15
+ fallback: _jsx(_Fragment, {}),
16
+ }, ...props }) => (_jsx(ConditionalWrapper, { options: suspense, children: _jsx(UniformCompositionInner, { ...props }) }));
17
+ const ConditionalWrapper = ({ children, options }) => {
18
+ if (options.mode === 'off') {
19
+ return _jsx(_Fragment, { children: children });
20
+ }
21
+ return _jsx(Suspense, { fallback: options.fallback, children: children });
22
+ };
23
+ const UniformCompositionInner = async ({ params, searchParams, children }) => {
24
+ // prefetch manifest immediately
25
+ void getManifestFromApi({
26
+ searchParams,
27
+ });
28
+ const draftMode = isDraftModeEnabled({ searchParams });
29
+ const previewEnvironment = isOnVercelPreviewEnvironment();
30
+ // resolve the path from provided params
31
+ const path = resolvePath({
32
+ params,
33
+ });
34
+ // resolve the route from the path
35
+ const resolveResult = await resolveRoute({
36
+ path,
37
+ state: draftMode || previewEnvironment ? CANVAS_DRAFT_STATE : CANVAS_PUBLISHED_STATE,
38
+ searchParams,
39
+ });
40
+ // if the route is a redirect, redirect
41
+ if (resolveResult.type === 'redirect') {
42
+ redirect(resolveResult.redirect.href);
43
+ }
44
+ // if the route is not found, return 404
45
+ if (resolveResult.type === 'notFound') {
46
+ notFound();
47
+ }
48
+ // evaluate the composition
49
+ const { cookieValue, composition: evaluatedComposition, seenComponents, } = await evaluateComposition({
50
+ root: resolveResult.composition,
51
+ params,
52
+ searchParams: searchParams !== null && searchParams !== void 0 ? searchParams : {},
53
+ });
54
+ return (_jsxs(UniformProvider, { cookieValue: cookieValue, seenComponents: seenComponents, children: [_jsx(UniformScript, { enabled: draftMode }), _jsx(UniformComponent, { data: evaluatedComposition }), Boolean(children) && children] }));
55
+ };
@@ -0,0 +1,11 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { SeenUniformComponent } from '../models';
3
+ export type UniformContextProps = {
4
+ cookieValue: string | undefined;
5
+ seenComponents: SeenUniformComponent[] | undefined;
6
+ };
7
+ export declare const UniformContext: import("react").Context<UniformContextProps>;
8
+ export declare const UniformProvider: ({ children, cookieValue, seenComponents, }: PropsWithChildren<{
9
+ cookieValue: string | undefined;
10
+ seenComponents: SeenUniformComponent[] | undefined;
11
+ }>) => JSX.Element;
@@ -0,0 +1,19 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useEffect } from 'react';
4
+ import { removeUniformCookie, setUniformCookie } from '../cookie';
5
+ export const UniformContext = createContext({
6
+ cookieValue: undefined,
7
+ seenComponents: undefined,
8
+ });
9
+ export const UniformProvider = ({ children, cookieValue, seenComponents, }) => {
10
+ useEffect(() => {
11
+ if (cookieValue) {
12
+ setUniformCookie(cookieValue);
13
+ }
14
+ else {
15
+ removeUniformCookie();
16
+ }
17
+ }, [cookieValue]);
18
+ return (_jsx(UniformContext.Provider, { value: { cookieValue, seenComponents }, children: children }));
19
+ };
@@ -0,0 +1,3 @@
1
+ export declare const UniformScript: ({ enabled }: {
2
+ enabled: boolean;
3
+ }) => JSX.Element;
@@ -0,0 +1,73 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
+ import { createCanvasChannel, isUpdateCompositionInternalMessage } from '@uniformdev/canvas';
4
+ import { useEffect, useMemo } from 'react';
5
+ export const UniformScript = ({ enabled }) => {
6
+ const channel = useMemo(() => {
7
+ var _a;
8
+ if (typeof window === 'undefined') {
9
+ return;
10
+ }
11
+ const instance = createCanvasChannel({
12
+ broadcastTo: [(_a = window.opener) !== null && _a !== void 0 ? _a : window.top],
13
+ listenTo: [window],
14
+ });
15
+ return instance;
16
+ }, []);
17
+ useEffect(() => {
18
+ if (!channel) {
19
+ return;
20
+ }
21
+ const unsubscribeFromCompositionUpdates = channel.on('update-composition-internal', async (data) => {
22
+ var _a, _b, _c;
23
+ if (isUpdateCompositionInternalMessage(data)) {
24
+ const url = new URL(window.location.href);
25
+ if (url.searchParams.get('vcdiffhash') === ((_a = data.hash) === null || _a === void 0 ? void 0 : _a.toString())) {
26
+ // eslint-disable-next-line no-console
27
+ console.log("Skipping composition update because it's already been applied.");
28
+ return;
29
+ }
30
+ const response = await fetch('/api/uniform', {
31
+ method: 'POST',
32
+ body: JSON.stringify(data),
33
+ });
34
+ if (!response.ok) {
35
+ // eslint-disable-next-line no-console
36
+ console.error(response);
37
+ return;
38
+ }
39
+ const json = (await response.json());
40
+ if (json.diff.length) {
41
+ const serialized = Buffer.from(JSON.stringify(json.diff)).toString('base64');
42
+ // set serialized as query string param
43
+ url.searchParams.set('vcdiff', serialized);
44
+ url.searchParams.set('vcdiffhash', (_c = (_b = data.hash) === null || _b === void 0 ? void 0 : _b.toString()) !== null && _c !== void 0 ? _c : '');
45
+ // set url
46
+ window.location.href = url.toString();
47
+ }
48
+ }
49
+ });
50
+ return () => {
51
+ unsubscribeFromCompositionUpdates();
52
+ };
53
+ }, [channel]);
54
+ useEffect(() => {
55
+ if (typeof window === 'undefined') {
56
+ return;
57
+ }
58
+ const existing = document.getElementById('uniform-script');
59
+ if (enabled) {
60
+ if (!existing) {
61
+ const script = document.createElement('script');
62
+ script.id = 'uniform-script';
63
+ script.src = `https://uniform.app/files/canvas-in-context-embed/index.js`;
64
+ script.async = true;
65
+ document.head.appendChild(script);
66
+ }
67
+ }
68
+ else if (existing) {
69
+ existing.remove();
70
+ }
71
+ }, [enabled]);
72
+ return _jsx(_Fragment, {});
73
+ };