@uniformdev/next-app-router-shared 20.7.1-alpha.118

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.mjs ADDED
@@ -0,0 +1,297 @@
1
+ // src/placements/evaluatePersonalization.ts
2
+ var evaluatePersonalization = ({
3
+ personalization,
4
+ context,
5
+ compositionContext
6
+ }) => {
7
+ const indexes = [];
8
+ const variantIds = [];
9
+ const componentIds = [];
10
+ const { variations } = context.personalize(personalization);
11
+ for (const v of variations) {
12
+ indexes.push(v.index);
13
+ variantIds.push({
14
+ id: v.id,
15
+ control: v.control
16
+ });
17
+ componentIds.push(v.componentId);
18
+ }
19
+ const event = {
20
+ name: personalization.name,
21
+ variantIds,
22
+ changed: true,
23
+ control: context.storage.data.controlGroup || variantIds.every((v) => v.control),
24
+ compositionMetadata: {
25
+ compositionId: compositionContext._id,
26
+ matchedRoute: compositionContext.matchedRoute,
27
+ dynamicInputs: compositionContext.dynamicInputs
28
+ }
29
+ };
30
+ return {
31
+ indexes,
32
+ event,
33
+ componentIds
34
+ };
35
+ };
36
+
37
+ // src/placements/evaluateTest.ts
38
+ var evaluateTest = ({
39
+ test,
40
+ context,
41
+ compositionContext
42
+ }) => {
43
+ var _a, _b, _c;
44
+ const isTestDefined = Boolean((_a = context == null ? void 0 : context.manifest.data.project.test) == null ? void 0 : _a[test.name]);
45
+ if (!isTestDefined && process.env.NODE_ENV !== "production") {
46
+ console.warn(`Test "${test}" is not defined in Uniform manifest.`);
47
+ return {
48
+ index: null,
49
+ componentId: null,
50
+ event: null
51
+ };
52
+ }
53
+ let index = null;
54
+ let variantId = null;
55
+ let componentId = null;
56
+ if (context) {
57
+ const { result } = context.test(test);
58
+ if (result) {
59
+ index = result.index;
60
+ variantId = result.id;
61
+ componentId = result.componentId;
62
+ }
63
+ }
64
+ if (!variantId) {
65
+ const [first] = test.variations;
66
+ if (first) {
67
+ index = first.index;
68
+ variantId = first.id;
69
+ componentId = first.componentId;
70
+ }
71
+ }
72
+ const event = {
73
+ name: test.name,
74
+ control: (_c = (_b = test.variations.find((v) => v.id === variantId)) == null ? void 0 : _b.control) != null ? _c : false,
75
+ variantAssigned: true,
76
+ variantId: variantId != null ? variantId : "NO_VARIANTS",
77
+ compositionMetadata: {
78
+ compositionId: compositionContext._id,
79
+ matchedRoute: compositionContext.matchedRoute,
80
+ dynamicInputs: compositionContext.dynamicInputs
81
+ }
82
+ };
83
+ return {
84
+ index,
85
+ componentId,
86
+ event
87
+ };
88
+ };
89
+
90
+ // src/placements/extractPersonalizationName.ts
91
+ var extractPersonalizationName = ({
92
+ component
93
+ }) => {
94
+ var _a;
95
+ const trackingEventNameParameter = (_a = component.parameters) == null ? void 0 : _a.trackingEventName;
96
+ return (trackingEventNameParameter == null ? void 0 : trackingEventNameParameter.value) || "unknown";
97
+ };
98
+
99
+ // src/placements/extractTestName.ts
100
+ var extractTestName = ({ component }) => {
101
+ var _a, _b;
102
+ const testName = (_a = component.parameters) == null ? void 0 : _a.test;
103
+ return (_b = testName == null ? void 0 : testName.value) != null ? _b : "unknown";
104
+ };
105
+
106
+ // src/serialization.ts
107
+ import { v5 } from "uuid";
108
+ var ENCODED_RESERVED_CHARACTERS = [
109
+ {
110
+ character: "/",
111
+ replacement: "_"
112
+ },
113
+ {
114
+ character: "+",
115
+ replacement: "-"
116
+ }
117
+ ];
118
+ var isNotARegularUuid = (id) => {
119
+ return id.length !== 36;
120
+ };
121
+ var resolveComponentFromPageState = ({
122
+ pageState,
123
+ componentId: providedComponentId
124
+ }) => {
125
+ const componentId = isNotARegularUuid(providedComponentId) ? v5(providedComponentId, NAMESPACE_UUID) : providedComponentId;
126
+ let component = pageState.components[componentId];
127
+ if (!component) {
128
+ const componentIds = Object.keys(pageState.components);
129
+ for (let i = 0; i < componentIds.length; i++) {
130
+ const id = componentIds[i];
131
+ if (componentId.startsWith(id)) {
132
+ component = pageState.components[id];
133
+ break;
134
+ }
135
+ }
136
+ }
137
+ return component;
138
+ };
139
+ var getRuleId = (rule) => {
140
+ return v5(JSON.stringify(rule), NAMESPACE_UUID);
141
+ };
142
+ var resolveRuleFromPageState = ({
143
+ pageState,
144
+ rule
145
+ }) => {
146
+ if (!pageState.rules) {
147
+ return void 0;
148
+ }
149
+ const ruleId = getRuleId(rule);
150
+ let value = pageState.rules[ruleId];
151
+ if (typeof value === "undefined") {
152
+ const ruleIds = Object.keys(pageState.rules);
153
+ for (let i = 0; i < ruleIds.length; i++) {
154
+ const id = ruleIds[i];
155
+ if (ruleId.startsWith(id)) {
156
+ value = pageState.rules[id];
157
+ break;
158
+ }
159
+ }
160
+ }
161
+ return value;
162
+ };
163
+ var replaceReservedCharacters = (value) => {
164
+ return ENCODED_RESERVED_CHARACTERS.reduce((acc, char) => {
165
+ return acc.replaceAll(char.character, char.replacement);
166
+ }, value);
167
+ };
168
+ var unreplaceReservedCharacters = (value) => {
169
+ return ENCODED_RESERVED_CHARACTERS.reduce((acc, char) => {
170
+ return acc.replaceAll(char.replacement, char.character);
171
+ }, value);
172
+ };
173
+ var encodeWithReplacements = (value) => {
174
+ return replaceReservedCharacters(btoa(value));
175
+ };
176
+ var decodeWithReplacements = (value) => {
177
+ const urlDecoded = decodeURIComponent(value);
178
+ return atob(unreplaceReservedCharacters(urlDecoded));
179
+ };
180
+ var compressIds = (ids) => {
181
+ const uuidV4Length = 36;
182
+ let compressedRegistry;
183
+ for (let i = 0; i < uuidV4Length; i++) {
184
+ const registry = {};
185
+ let success = true;
186
+ for (let j = 0; j < ids.length; j++) {
187
+ const listId = ids[j];
188
+ const id = listId.slice(0, i + 1);
189
+ if (registry[id]) {
190
+ success = false;
191
+ break;
192
+ }
193
+ registry[id] = listId;
194
+ }
195
+ if (success) {
196
+ compressedRegistry = registry;
197
+ break;
198
+ }
199
+ }
200
+ return compressedRegistry != null ? compressedRegistry : ids.reduce(
201
+ (acc, listId) => {
202
+ acc[listId] = listId;
203
+ return acc;
204
+ },
205
+ {}
206
+ );
207
+ };
208
+ var NAMESPACE_UUID = "00000000-0000-0000-0000-000000000000";
209
+ var serializeEvaluationResult = ({
210
+ payload,
211
+ encode = true
212
+ }) => {
213
+ const compressedPageState = {
214
+ cs: payload.compositionState,
215
+ r: payload.routePath,
216
+ c: {},
217
+ k: payload.keys,
218
+ ri: payload.releaseId,
219
+ dc: typeof payload.defaultConsent !== "undefined" ? payload.defaultConsent ? 1 : 0 : void 0,
220
+ pm: payload.previewMode === "editor" ? "e" : payload.previewMode === "preview" ? "p" : void 0,
221
+ rl: void 0
222
+ };
223
+ const componentKeys = Object.keys(payload.components);
224
+ const sortedKeys = componentKeys.sort();
225
+ const sortedComponents = sortedKeys.map((key) => ({
226
+ _id: isNotARegularUuid(key) ? v5(key, NAMESPACE_UUID) : key,
227
+ ...payload.components[key]
228
+ }));
229
+ const compressedComponentIds = compressIds(sortedComponents.map((c) => c._id));
230
+ Object.keys(compressedComponentIds).forEach((compressedId) => {
231
+ var _a;
232
+ const originalId = compressedComponentIds[compressedId];
233
+ const component = sortedComponents.find((c) => c._id === originalId);
234
+ if (!component) {
235
+ throw new Error(`Component ${originalId} not found`);
236
+ }
237
+ compressedPageState.c[compressedId] = {
238
+ i: ((_a = component.indexes) == null ? void 0 : _a.length) ? component.indexes : void 0
239
+ };
240
+ });
241
+ if (typeof payload.rules !== "undefined") {
242
+ const ruleKeys = Object.keys(payload.rules);
243
+ if (ruleKeys.length !== 0) {
244
+ compressedPageState.rl = {};
245
+ const sortedRuleKeys = ruleKeys.sort();
246
+ const compressedRuleKeys = compressIds(sortedRuleKeys);
247
+ Object.keys(compressedRuleKeys).forEach((compressedId) => {
248
+ const originalId = compressedRuleKeys[compressedId];
249
+ compressedPageState.rl[compressedId] = payload.rules[originalId] ? 1 : 0;
250
+ });
251
+ }
252
+ }
253
+ const result = JSON.stringify(compressedPageState);
254
+ return encode ? encodeWithReplacements(result) : result;
255
+ };
256
+ var deserializeEvaluationResult = ({
257
+ input: providedInput,
258
+ decode = true
259
+ }) => {
260
+ var _a, _b;
261
+ const input = decode ? decodeWithReplacements(providedInput) : providedInput;
262
+ const parsed = JSON.parse(input);
263
+ const pageState = {
264
+ compositionState: parsed.cs,
265
+ routePath: parsed.r,
266
+ components: {},
267
+ keys: (_a = parsed.k) != null ? _a : {},
268
+ releaseId: (_b = parsed.ri) != null ? _b : void 0,
269
+ defaultConsent: typeof parsed.dc !== "undefined" ? parsed.dc === 1 : void 0,
270
+ previewMode: parsed.pm === "e" ? "editor" : parsed.pm === "p" ? "preview" : void 0,
271
+ rules: parsed.rl ? Object.fromEntries(Object.entries(parsed.rl).map(([key, value]) => [key, value === 1])) : void 0
272
+ };
273
+ Object.keys(parsed.c).forEach((id) => {
274
+ const component = parsed.c[id];
275
+ pageState.components[id] = {
276
+ indexes: component.i
277
+ };
278
+ });
279
+ return pageState;
280
+ };
281
+
282
+ // src/index.ts
283
+ var UNIFORM_MIDDLEWARE_SCORE_COOKIE_NAME = "ufsc";
284
+ var UNIFORM_MIDDLEWARE_QUIRK_COOKIE_NAME = "ufqc";
285
+ export {
286
+ UNIFORM_MIDDLEWARE_QUIRK_COOKIE_NAME,
287
+ UNIFORM_MIDDLEWARE_SCORE_COOKIE_NAME,
288
+ deserializeEvaluationResult,
289
+ evaluatePersonalization,
290
+ evaluateTest,
291
+ extractPersonalizationName,
292
+ extractTestName,
293
+ getRuleId,
294
+ resolveComponentFromPageState,
295
+ resolveRuleFromPageState,
296
+ serializeEvaluationResult
297
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@uniformdev/next-app-router-shared",
3
+ "version": "20.7.1-alpha.118+5483f1e4cc",
4
+ "license": "SEE LICENSE IN LICENSE.txt",
5
+ "scripts": {
6
+ "build": "tsup",
7
+ "dev": "tsup --watch",
8
+ "lint": "eslint \"src/**/*.{ts,tsx}\" --fix",
9
+ "test": "jest --maxWorkers=1 --passWithNoTests"
10
+ },
11
+ "sideEffects": false,
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/index.esm.js",
14
+ "exports": {
15
+ "import": {
16
+ "types": "./dist/index.d.mts",
17
+ "node": "./dist/index.mjs",
18
+ "default": "./dist/index.esm.js"
19
+ },
20
+ "require": "./dist/index.js"
21
+ },
22
+ "types": "./dist/index.d.ts",
23
+ "files": [
24
+ "/dist"
25
+ ],
26
+ "devDependencies": {
27
+ "@types/node": "20.19.25",
28
+ "@types/react": "19.0.8",
29
+ "@types/react-dom": "19.0.3",
30
+ "@types/uuid": "9.0.4",
31
+ "next": "16.0.7",
32
+ "react": "19.2.0",
33
+ "react-dom": "19.2.0",
34
+ "typescript": "5.9.2"
35
+ },
36
+ "dependencies": {
37
+ "@uniformdev/canvas": "20.7.1-alpha.118+5483f1e4cc",
38
+ "@uniformdev/context": "20.7.1-alpha.118+5483f1e4cc",
39
+ "uuid": "9.0.1"
40
+ },
41
+ "engines": {
42
+ "node": ">=20.9.0"
43
+ },
44
+ "peerDependencies": {
45
+ "next": ">=16.0.7",
46
+ "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
47
+ "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "gitHead": "5483f1e4ccb621d21848f58878cda17f14a86dea"
53
+ }