@amplifyup/sdk 0.1.43 → 0.1.45
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/README.md +21 -0
- package/dist/AmplifyRenderer.d.mts +1 -1
- package/dist/AmplifyRenderer.d.ts +1 -1
- package/dist/AmplifyRenderer.js +197 -3
- package/dist/AmplifyRenderer.js.map +1 -1
- package/dist/AmplifyRenderer.mjs +197 -3
- package/dist/AmplifyRenderer.mjs.map +1 -1
- package/dist/index.d.mts +23 -4
- package/dist/index.d.ts +23 -4
- package/dist/index.js +199 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +199 -4
- package/dist/index.mjs.map +1 -1
- package/dist/{query-CraXKhi7.d.mts → query-2-zPPrMI.d.mts} +1 -1
- package/dist/{query-BMsorj0k.d.ts → query-CFpvzSZT.d.ts} +1 -1
- package/dist/react.d.mts +9 -4
- package/dist/react.d.ts +9 -4
- package/dist/react.js +275 -8
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +275 -8
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +3 -3
- package/dist/server.d.ts +3 -3
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +2 -1
- package/dist/server.mjs.map +1 -1
- package/dist/{types-DUP8Lb7R.d.mts → types-NdLzHxZo.d.mts} +56 -5
- package/dist/{types-DUP8Lb7R.d.ts → types-NdLzHxZo.d.ts} +56 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -88,6 +88,27 @@ Field names must match the component registry in AmplifyUp. Connect CMS document
|
|
|
88
88
|
| Composer preview | Orchestrator layout provider | `?preview=true` / Composer iframe |
|
|
89
89
|
| Runtime queries | Edge `/v1/query` | `queryContent` — search, load more, pickers |
|
|
90
90
|
|
|
91
|
+
## Pattern pages (From page)
|
|
92
|
+
|
|
93
|
+
Components using Composer **From page** require `pageContext` on the provider (or `init`) so the first paint and first page view include fields. Late `setPageContext` is fine for subsequent events, not for rendering those components.
|
|
94
|
+
|
|
95
|
+
`resource.key` is the URL param value. If a mapped entity field (for example `post.slug`) does not match that param, the SDK warns and uses the URL param.
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
<AmplifyUpProvider
|
|
99
|
+
config={{ trackingId: 'your-tracking-id' }}
|
|
100
|
+
pageContext={{
|
|
101
|
+
resourceType: 'post',
|
|
102
|
+
key: slug,
|
|
103
|
+
fields: { title: post.title, slug: post.slug, category: post.category },
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
{children}
|
|
107
|
+
</AmplifyUpProvider>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Pass `pageContext` at provider/init for From-page components. Do not wait until after first paint. Fixed (static) page fields still attach to events when `pageContext` is omitted.
|
|
111
|
+
|
|
91
112
|
The SDK maps Edge’s resolved tree into `layoutTree` and renders it. Edge already applies personalization and CMS projection — the site does not call CMS or Decision APIs for layout. After paint, the overlay calls `POST /v1/select` (or `selectVariants()`) then `/v1/resolve?variants=` so decisions stay on the edge (`clientPersonalization`).
|
|
92
113
|
|
|
93
114
|
## Runtime queries
|
package/dist/AmplifyRenderer.js
CHANGED
|
@@ -407,6 +407,153 @@ function isComposerPreview() {
|
|
|
407
407
|
return false;
|
|
408
408
|
}
|
|
409
409
|
|
|
410
|
+
// src/page-context.ts
|
|
411
|
+
var defaultLog = {
|
|
412
|
+
warn: (...args) => {
|
|
413
|
+
if (typeof console !== "undefined") console.warn(...args);
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
function coerceField(def, raw, log) {
|
|
417
|
+
if (raw == null) return void 0;
|
|
418
|
+
if (def.multiValue) {
|
|
419
|
+
const list = Array.isArray(raw) ? raw : [raw];
|
|
420
|
+
const out = [];
|
|
421
|
+
for (const item of list) {
|
|
422
|
+
const coerced = coerceScalar(def, item, log);
|
|
423
|
+
if (coerced !== void 0) out.push(coerced);
|
|
424
|
+
}
|
|
425
|
+
return out;
|
|
426
|
+
}
|
|
427
|
+
return coerceScalar(def, raw, log);
|
|
428
|
+
}
|
|
429
|
+
function coerceScalar(def, raw, log) {
|
|
430
|
+
switch (def.dataType) {
|
|
431
|
+
case "string":
|
|
432
|
+
if (typeof raw === "string") return raw;
|
|
433
|
+
if (typeof raw === "number" || typeof raw === "boolean") return String(raw);
|
|
434
|
+
log.warn(`AmplifyUp: dropped field "${def.key}" (expected string)`);
|
|
435
|
+
return void 0;
|
|
436
|
+
case "number": {
|
|
437
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
438
|
+
if (typeof raw === "string" && raw.trim() !== "" && Number.isFinite(Number(raw))) {
|
|
439
|
+
return Number(raw);
|
|
440
|
+
}
|
|
441
|
+
log.warn(`AmplifyUp: dropped field "${def.key}" (expected number)`);
|
|
442
|
+
return void 0;
|
|
443
|
+
}
|
|
444
|
+
case "boolean": {
|
|
445
|
+
if (typeof raw === "boolean") return raw;
|
|
446
|
+
if (raw === "true") return true;
|
|
447
|
+
if (raw === "false") return false;
|
|
448
|
+
log.warn(`AmplifyUp: dropped field "${def.key}" (expected boolean)`);
|
|
449
|
+
return void 0;
|
|
450
|
+
}
|
|
451
|
+
case "date": {
|
|
452
|
+
if (typeof raw === "string" && !Number.isNaN(Date.parse(raw))) return raw;
|
|
453
|
+
log.warn(`AmplifyUp: dropped field "${def.key}" (expected date)`);
|
|
454
|
+
return void 0;
|
|
455
|
+
}
|
|
456
|
+
default:
|
|
457
|
+
return void 0;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
function applyPageContext(input, opts) {
|
|
461
|
+
const log = opts.log || defaultLog;
|
|
462
|
+
const key = String(input.key || "").trim();
|
|
463
|
+
if (!key || !input.resourceType) {
|
|
464
|
+
log.warn("AmplifyUp: pageContext needs resourceType and key");
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
const resource = opts.pageData?.resources?.[0];
|
|
468
|
+
if (resource && resource.type && resource.type !== input.resourceType) {
|
|
469
|
+
log.warn(
|
|
470
|
+
`AmplifyUp: pageContext resourceType "${input.resourceType}" does not match page resource "${resource.type}"`
|
|
471
|
+
);
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
const fieldDefs = resource?.fields || [];
|
|
475
|
+
const defByKey = new Map(fieldDefs.map((f) => [f.key, f]));
|
|
476
|
+
const rawFields = input.fields && typeof input.fields === "object" ? input.fields : {};
|
|
477
|
+
const fields = {};
|
|
478
|
+
if (fieldDefs.length === 0) {
|
|
479
|
+
Object.assign(fields, rawFields);
|
|
480
|
+
} else {
|
|
481
|
+
for (const [k, v] of Object.entries(rawFields)) {
|
|
482
|
+
const def = defByKey.get(k);
|
|
483
|
+
if (!def) {
|
|
484
|
+
log.warn(`AmplifyUp: unknown resource field "${k}" dropped`);
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
const coerced = coerceField(def, v, log);
|
|
488
|
+
if (coerced !== void 0) fields[k] = coerced;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
const params = { ...opts.routeParams || {} };
|
|
492
|
+
const mapping = resource?.urlParamMapping;
|
|
493
|
+
let resourceKey = key;
|
|
494
|
+
if (mapping) {
|
|
495
|
+
const fromUrl = params[mapping.param];
|
|
496
|
+
const fromField = fields[mapping.field];
|
|
497
|
+
if (fromUrl) resourceKey = String(fromUrl);
|
|
498
|
+
if (fromUrl && fromField != null && String(fromField) !== String(fromUrl)) {
|
|
499
|
+
log.warn(
|
|
500
|
+
`AmplifyUp: resource key mismatch \u2014 URL :${mapping.param} is "${fromUrl}" but ${mapping.field} is "${String(fromField)}". Using the URL param.`
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
const pageFields = {};
|
|
505
|
+
for (const pf of opts.pageData?.pageFields || []) {
|
|
506
|
+
if (pf.source === "static") {
|
|
507
|
+
if (pf.value !== void 0) pageFields[pf.key] = pf.value;
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
if (pf.source === "mapped" && pf.resource && pf.field) {
|
|
511
|
+
pageFields[pf.key] = fields[pf.field];
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return {
|
|
515
|
+
resource: {
|
|
516
|
+
type: input.resourceType,
|
|
517
|
+
key: resourceKey,
|
|
518
|
+
params,
|
|
519
|
+
fields
|
|
520
|
+
},
|
|
521
|
+
page: { fields: pageFields },
|
|
522
|
+
pageRoute: opts.pageRoute || ""
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
function staticPageFieldsFromSnapshot(pageData) {
|
|
526
|
+
const pageFields = {};
|
|
527
|
+
for (const pf of pageData?.pageFields || []) {
|
|
528
|
+
if (pf.source === "static" && pf.value !== void 0) {
|
|
529
|
+
pageFields[pf.key] = pf.value;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
return pageFields;
|
|
533
|
+
}
|
|
534
|
+
function attachStaticPageContext(pageData, pageRoute) {
|
|
535
|
+
if (!pageData) return null;
|
|
536
|
+
const fields = staticPageFieldsFromSnapshot(pageData);
|
|
537
|
+
const hasStatic = Object.keys(fields).length > 0;
|
|
538
|
+
const hasRoute = !!pageRoute;
|
|
539
|
+
if (!hasStatic && !hasRoute) return null;
|
|
540
|
+
return {
|
|
541
|
+
page: { fields },
|
|
542
|
+
pageRoute: pageRoute || ""
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function mergeEventContext(properties, attached) {
|
|
546
|
+
if (!attached) return properties;
|
|
547
|
+
return {
|
|
548
|
+
...properties,
|
|
549
|
+
...attached.resource ? { resource: attached.resource } : {},
|
|
550
|
+
page: attached.page,
|
|
551
|
+
...attached.pageRoute ? { pageRoute: attached.pageRoute } : {}
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
function setPageResourceFields(fields) {
|
|
555
|
+
}
|
|
556
|
+
|
|
410
557
|
// src/index.ts
|
|
411
558
|
var DWELL_ACTIVITY_IDLE_MS = 2 * 60 * 1e3;
|
|
412
559
|
var DWELL_POLL_MS = 5e3;
|
|
@@ -475,6 +622,11 @@ var AmplifyUpSDK = class {
|
|
|
475
622
|
this.pageEngagementActive = false;
|
|
476
623
|
/** Path of the last page() / routeChange — avoids duplicate SPA fires. */
|
|
477
624
|
this.lastTrackedPath = null;
|
|
625
|
+
this.pendingPageContext = null;
|
|
626
|
+
this.attachedPageContext = null;
|
|
627
|
+
this.resolvedPageData = null;
|
|
628
|
+
this.resolvedPageRoute = "";
|
|
629
|
+
this.resolvedRouteParams = {};
|
|
478
630
|
this.historyHooksInstalled = false;
|
|
479
631
|
this.pageEngagementState = {
|
|
480
632
|
reached: /* @__PURE__ */ new Set(),
|
|
@@ -637,8 +789,13 @@ var AmplifyUpSDK = class {
|
|
|
637
789
|
// Enable debug by default
|
|
638
790
|
target: this.target,
|
|
639
791
|
dev: config.dev,
|
|
640
|
-
...config.siteId ? { siteId: config.siteId } : {}
|
|
792
|
+
...config.siteId ? { siteId: config.siteId } : {},
|
|
793
|
+
...config.pageContext ? { pageContext: config.pageContext } : {}
|
|
641
794
|
};
|
|
795
|
+
if (config.pageContext) {
|
|
796
|
+
this.pendingPageContext = config.pageContext;
|
|
797
|
+
this.recomputeAttachedContext();
|
|
798
|
+
}
|
|
642
799
|
try {
|
|
643
800
|
const adapterConfig = {
|
|
644
801
|
...this.config,
|
|
@@ -995,6 +1152,43 @@ var AmplifyUpSDK = class {
|
|
|
995
1152
|
this.componentViewObservers.forEach((obs) => obs.disconnect());
|
|
996
1153
|
this.componentViewObservers = [];
|
|
997
1154
|
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Set resource context for this page. Prefer passing `pageContext` on
|
|
1157
|
+
* AmplifyUpProvider / init — required for components using From page.
|
|
1158
|
+
* Late calls still attach to subsequent events (not a second page view).
|
|
1159
|
+
*/
|
|
1160
|
+
setPageContext(input) {
|
|
1161
|
+
this.pendingPageContext = input;
|
|
1162
|
+
this.recomputeAttachedContext();
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Apply published pageData (from /v1/resolve) so field validation and
|
|
1166
|
+
* mapped page fields can run.
|
|
1167
|
+
*/
|
|
1168
|
+
applyResolvedPageData(pageData, pageRoute, routeParams) {
|
|
1169
|
+
this.resolvedPageData = pageData || null;
|
|
1170
|
+
if (pageRoute) this.resolvedPageRoute = pageRoute;
|
|
1171
|
+
if (routeParams) this.resolvedRouteParams = routeParams;
|
|
1172
|
+
this.recomputeAttachedContext();
|
|
1173
|
+
}
|
|
1174
|
+
recomputeAttachedContext() {
|
|
1175
|
+
if (!this.pendingPageContext) {
|
|
1176
|
+
this.attachedPageContext = attachStaticPageContext(
|
|
1177
|
+
this.resolvedPageData,
|
|
1178
|
+
this.resolvedPageRoute
|
|
1179
|
+
);
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
this.attachedPageContext = applyPageContext(this.pendingPageContext, {
|
|
1183
|
+
pageData: this.resolvedPageData,
|
|
1184
|
+
routeParams: this.resolvedRouteParams,
|
|
1185
|
+
pageRoute: this.resolvedPageRoute
|
|
1186
|
+
});
|
|
1187
|
+
setPageResourceFields(this.attachedPageContext?.resource?.fields || null);
|
|
1188
|
+
}
|
|
1189
|
+
getAttachedPageContext() {
|
|
1190
|
+
return this.attachedPageContext;
|
|
1191
|
+
}
|
|
998
1192
|
/**
|
|
999
1193
|
* Track a page view
|
|
1000
1194
|
*/
|
|
@@ -1016,7 +1210,7 @@ var AmplifyUpSDK = class {
|
|
|
1016
1210
|
sessionId,
|
|
1017
1211
|
trackingId: this.config?.trackingId,
|
|
1018
1212
|
// Timestamp is included in event payload
|
|
1019
|
-
...properties
|
|
1213
|
+
...mergeEventContext(properties || {}, this.attachedPageContext)
|
|
1020
1214
|
};
|
|
1021
1215
|
this.adapter.page(pageProperties);
|
|
1022
1216
|
this.lastTrackedPath = url;
|
|
@@ -1040,7 +1234,7 @@ var AmplifyUpSDK = class {
|
|
|
1040
1234
|
url: typeof window !== "undefined" ? window.location.href : void 0,
|
|
1041
1235
|
path: properties?.path || (typeof window !== "undefined" ? window.location.pathname : void 0),
|
|
1042
1236
|
// Timestamp is included in event payload
|
|
1043
|
-
...properties
|
|
1237
|
+
...mergeEventContext(properties || {}, this.attachedPageContext)
|
|
1044
1238
|
};
|
|
1045
1239
|
if (!trackProperties.path && typeof window !== "undefined") {
|
|
1046
1240
|
trackProperties.path = window.location.pathname;
|