@contentful/experiences-core 1.30.0-dev-20250124T1739-560b81b.0 → 1.30.0-dev-20250128T1255-64f728a.0
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/entity/EntityStore.d.ts +5 -2
- package/dist/index.js +83 -27
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -10,13 +10,15 @@ type EntityStoreArgs = {
|
|
|
10
10
|
locale: string;
|
|
11
11
|
};
|
|
12
12
|
declare class EntityStore extends EntityStoreBase {
|
|
13
|
-
private
|
|
13
|
+
private _experienceEntryFields;
|
|
14
|
+
private _experienceEntryId;
|
|
14
15
|
private _unboundValues;
|
|
15
16
|
private _usedComponentsWithDeepReferences;
|
|
16
17
|
constructor(json: string);
|
|
17
18
|
constructor({ experienceEntry, entities, locale }: EntityStoreArgs);
|
|
18
19
|
getCurrentLocale(): string;
|
|
19
20
|
get experienceEntryFields(): ExperienceFields | undefined;
|
|
21
|
+
get experienceEntryId(): string | undefined;
|
|
20
22
|
get schemaVersion(): "2023-09-28" | undefined;
|
|
21
23
|
get breakpoints(): {
|
|
22
24
|
id: string;
|
|
@@ -54,7 +56,8 @@ declare class EntityStore extends EntityStoreBase {
|
|
|
54
56
|
[k: string]: Asset<contentful.ChainModifiers, string>;
|
|
55
57
|
};
|
|
56
58
|
locale: string;
|
|
57
|
-
|
|
59
|
+
_experienceEntryFields: ExperienceFields | undefined;
|
|
60
|
+
_experienceEntryId: string | undefined;
|
|
58
61
|
_unboundValues: Record<string, {
|
|
59
62
|
value?: string | number | boolean | Record<any, any> | undefined;
|
|
60
63
|
}> | undefined;
|
package/dist/index.js
CHANGED
|
@@ -1563,7 +1563,7 @@ const detachExperienceStyles = (experience) => {
|
|
|
1563
1563
|
}, {});
|
|
1564
1564
|
// getting the breakpoint ids
|
|
1565
1565
|
const breakpointIds = Object.keys(mediaQueriesTemplate);
|
|
1566
|
-
const iterateOverTreeAndExtractStyles = ({ componentTree, dataSource, unboundValues, componentSettings, componentVariablesOverwrites, patternWrapper, }) => {
|
|
1566
|
+
const iterateOverTreeAndExtractStyles = ({ componentTree, dataSource, unboundValues, componentSettings, componentVariablesOverwrites, patternWrapper, wrappingPatternIds, }) => {
|
|
1567
1567
|
// traversing the tree
|
|
1568
1568
|
const queue = [];
|
|
1569
1569
|
queue.push(...componentTree.children);
|
|
@@ -1580,6 +1580,10 @@ const detachExperienceStyles = (experience) => {
|
|
|
1580
1580
|
usedComponents,
|
|
1581
1581
|
});
|
|
1582
1582
|
if (isPatternNode) {
|
|
1583
|
+
// When detecting a circular dependency among patterns, stop to avoid an infinite loop
|
|
1584
|
+
if (wrappingPatternIds.has(currentNode.definitionId)) {
|
|
1585
|
+
continue;
|
|
1586
|
+
}
|
|
1583
1587
|
const patternEntry = usedComponents.find((component) => component.sys.id === currentNode.definitionId);
|
|
1584
1588
|
if (!patternEntry || !('fields' in patternEntry)) {
|
|
1585
1589
|
continue;
|
|
@@ -1620,6 +1624,7 @@ const detachExperienceStyles = (experience) => {
|
|
|
1620
1624
|
componentVariablesOverwrites: currentNode.variables,
|
|
1621
1625
|
// pass top-level pattern node to store instance-specific child styles for rendering
|
|
1622
1626
|
patternWrapper: currentNode,
|
|
1627
|
+
wrappingPatternIds: new Set([...wrappingPatternIds, currentNode.definitionId]),
|
|
1623
1628
|
});
|
|
1624
1629
|
continue;
|
|
1625
1630
|
}
|
|
@@ -1776,6 +1781,7 @@ const detachExperienceStyles = (experience) => {
|
|
|
1776
1781
|
dataSource: experience.entityStore?.dataSource ?? {},
|
|
1777
1782
|
unboundValues: experience.entityStore?.unboundValues ?? {},
|
|
1778
1783
|
componentSettings: experience.entityStore?.experienceEntryFields?.componentSettings,
|
|
1784
|
+
wrappingPatternIds: new Set(experience.entityStore?.experienceEntryId ? [experience.entityStore.experienceEntryId] : []),
|
|
1779
1785
|
});
|
|
1780
1786
|
// once the whole tree was traversed, for each breakpoint, I aggregate the styles
|
|
1781
1787
|
// for each generated className into one css string
|
|
@@ -3138,64 +3144,76 @@ class EditorModeEntityStore extends EditorEntityStore {
|
|
|
3138
3144
|
}
|
|
3139
3145
|
}
|
|
3140
3146
|
|
|
3141
|
-
const
|
|
3142
|
-
const
|
|
3147
|
+
const resolveDeepUsedComponents = ({ experienceEntryFields, parentComponents, }) => {
|
|
3148
|
+
const totalUsedComponents = [];
|
|
3143
3149
|
const usedComponents = experienceEntryFields?.usedComponents;
|
|
3144
3150
|
if (!usedComponents || usedComponents.length === 0) {
|
|
3145
3151
|
return [];
|
|
3146
3152
|
}
|
|
3147
3153
|
for (const component of usedComponents) {
|
|
3148
3154
|
if ('fields' in component) {
|
|
3149
|
-
|
|
3150
|
-
|
|
3155
|
+
totalUsedComponents.push(component);
|
|
3156
|
+
if (parentComponents.has(component.sys.id)) {
|
|
3157
|
+
continue;
|
|
3158
|
+
}
|
|
3159
|
+
totalUsedComponents.push(...resolveDeepUsedComponents({
|
|
3160
|
+
experienceEntryFields: component.fields,
|
|
3161
|
+
parentComponents: new Set([...parentComponents, component.sys.id]),
|
|
3162
|
+
}));
|
|
3151
3163
|
}
|
|
3152
3164
|
}
|
|
3153
|
-
return
|
|
3165
|
+
return totalUsedComponents;
|
|
3154
3166
|
};
|
|
3155
3167
|
|
|
3156
3168
|
class EntityStore extends EntityStoreBase {
|
|
3157
3169
|
constructor(options) {
|
|
3158
3170
|
if (typeof options === 'string') {
|
|
3159
|
-
|
|
3160
|
-
|
|
3171
|
+
// For SSR/SSG, the entity store is created server-side and passed to the client as a serialised JSON.
|
|
3172
|
+
// So the properties in data.entityStore are equal to the attributes of this class (see `toJSON()`)
|
|
3173
|
+
const serializedAttributes = JSON.parse(options).entityStore;
|
|
3161
3174
|
super({
|
|
3162
3175
|
entities: [
|
|
3163
|
-
...Object.values(entryMap),
|
|
3164
|
-
...Object.values(assetMap),
|
|
3176
|
+
...Object.values(serializedAttributes.entryMap),
|
|
3177
|
+
...Object.values(serializedAttributes.assetMap),
|
|
3165
3178
|
],
|
|
3166
|
-
locale,
|
|
3179
|
+
locale: serializedAttributes.locale,
|
|
3167
3180
|
});
|
|
3168
|
-
this.
|
|
3169
|
-
this.
|
|
3170
|
-
this.
|
|
3181
|
+
this._experienceEntryFields = serializedAttributes._experienceEntryFields;
|
|
3182
|
+
this._experienceEntryId = serializedAttributes._experienceEntryId;
|
|
3183
|
+
this._unboundValues = serializedAttributes._unboundValues;
|
|
3171
3184
|
}
|
|
3172
3185
|
else {
|
|
3173
3186
|
const { experienceEntry, entities, locale } = options;
|
|
3174
|
-
|
|
3175
|
-
if (isExperienceEntry(experienceEntry)) {
|
|
3176
|
-
this._experienceEntry = experienceEntry.fields;
|
|
3177
|
-
this._unboundValues = experienceEntry.fields.unboundValues;
|
|
3178
|
-
this._usedComponentsWithDeepReferences = gatherUsedComponentsWithDeepRefernces(this._experienceEntry);
|
|
3179
|
-
}
|
|
3180
|
-
else {
|
|
3187
|
+
if (!isExperienceEntry(experienceEntry)) {
|
|
3181
3188
|
throw new Error('Provided entry is not experience entry');
|
|
3182
3189
|
}
|
|
3190
|
+
super({ entities, locale });
|
|
3191
|
+
this._experienceEntryFields = experienceEntry.fields;
|
|
3192
|
+
this._experienceEntryId = experienceEntry.sys.id;
|
|
3193
|
+
this._unboundValues = experienceEntry.fields.unboundValues;
|
|
3183
3194
|
}
|
|
3195
|
+
this._usedComponentsWithDeepReferences = resolveDeepUsedComponents({
|
|
3196
|
+
experienceEntryFields: this._experienceEntryFields,
|
|
3197
|
+
parentComponents: new Set([this._experienceEntryId]),
|
|
3198
|
+
});
|
|
3184
3199
|
}
|
|
3185
3200
|
getCurrentLocale() {
|
|
3186
3201
|
return this.locale;
|
|
3187
3202
|
}
|
|
3188
3203
|
get experienceEntryFields() {
|
|
3189
|
-
return this.
|
|
3204
|
+
return this._experienceEntryFields;
|
|
3205
|
+
}
|
|
3206
|
+
get experienceEntryId() {
|
|
3207
|
+
return this._experienceEntryId;
|
|
3190
3208
|
}
|
|
3191
3209
|
get schemaVersion() {
|
|
3192
|
-
return this.
|
|
3210
|
+
return this._experienceEntryFields?.componentTree.schemaVersion;
|
|
3193
3211
|
}
|
|
3194
3212
|
get breakpoints() {
|
|
3195
|
-
return this.
|
|
3213
|
+
return this._experienceEntryFields?.componentTree.breakpoints ?? [];
|
|
3196
3214
|
}
|
|
3197
3215
|
get dataSource() {
|
|
3198
|
-
return this.
|
|
3216
|
+
return this._experienceEntryFields?.dataSource ?? {};
|
|
3199
3217
|
}
|
|
3200
3218
|
get unboundValues() {
|
|
3201
3219
|
return this._unboundValues ?? {};
|
|
@@ -3226,7 +3244,8 @@ class EntityStore extends EntityStoreBase {
|
|
|
3226
3244
|
}
|
|
3227
3245
|
toJSON() {
|
|
3228
3246
|
return {
|
|
3229
|
-
|
|
3247
|
+
_experienceEntryFields: this._experienceEntryFields,
|
|
3248
|
+
_experienceEntryId: this._experienceEntryId,
|
|
3230
3249
|
_unboundValues: this._unboundValues,
|
|
3231
3250
|
...super.toJSON(),
|
|
3232
3251
|
};
|
|
@@ -3587,6 +3606,41 @@ const fetchReferencedEntities = async ({ client, experienceEntry, locale, }) =>
|
|
|
3587
3606
|
};
|
|
3588
3607
|
};
|
|
3589
3608
|
|
|
3609
|
+
/**
|
|
3610
|
+
* The CMA client will automatically replace links with entry references.
|
|
3611
|
+
* As we're including all referenced pattern entries in usedComponents, this can lead
|
|
3612
|
+
* to a circular reference. This function replaces those with plain links inplace (!).
|
|
3613
|
+
*
|
|
3614
|
+
* @see https://github.com/contentful/contentful.js/issues/377
|
|
3615
|
+
*/
|
|
3616
|
+
const removeCircularPatternReferences = (experienceEntry, _parentIds) => {
|
|
3617
|
+
const parentIds = _parentIds ?? new Set([experienceEntry.sys.id]);
|
|
3618
|
+
const usedComponents = experienceEntry.fields.usedComponents;
|
|
3619
|
+
const newUsedComponents = usedComponents?.reduce((acc, linkOrEntry) => {
|
|
3620
|
+
if (!('fields' in linkOrEntry)) {
|
|
3621
|
+
// It is a link, we're good
|
|
3622
|
+
return [...acc, linkOrEntry];
|
|
3623
|
+
}
|
|
3624
|
+
const entry = linkOrEntry;
|
|
3625
|
+
if (parentIds.has(entry.sys.id)) {
|
|
3626
|
+
// It is an entry that already occurred -> turn it into a link to remove the circularity
|
|
3627
|
+
const link = {
|
|
3628
|
+
sys: {
|
|
3629
|
+
id: entry.sys.id,
|
|
3630
|
+
linkType: 'Entry',
|
|
3631
|
+
type: 'Link',
|
|
3632
|
+
},
|
|
3633
|
+
};
|
|
3634
|
+
return [...acc, link];
|
|
3635
|
+
}
|
|
3636
|
+
// Remove circularity for its usedComponents as well (inplace)
|
|
3637
|
+
removeCircularPatternReferences(entry, new Set([...parentIds, entry.sys.id]));
|
|
3638
|
+
return [...acc, entry];
|
|
3639
|
+
}, []);
|
|
3640
|
+
// @ts-expect-error - type of usedComponents doesn't yet allow a mixed list of both links and entries
|
|
3641
|
+
experienceEntry.fields.usedComponents = newUsedComponents;
|
|
3642
|
+
};
|
|
3643
|
+
|
|
3590
3644
|
const errorMessagesWhileFetching$1 = {
|
|
3591
3645
|
experience: 'Failed to fetch experience',
|
|
3592
3646
|
experienceReferences: 'Failed to fetch entities, referenced in experience',
|
|
@@ -3600,7 +3654,7 @@ const handleError$1 = (generalMessage, error) => {
|
|
|
3600
3654
|
* @param {FetchBySlugParams} options - options to fetch the experience
|
|
3601
3655
|
*/
|
|
3602
3656
|
async function fetchBySlug({ client, experienceTypeId, slug, localeCode, isEditorMode, }) {
|
|
3603
|
-
//Be a no-op if in editor mode
|
|
3657
|
+
// Be a no-op if in editor mode
|
|
3604
3658
|
if (isEditorMode)
|
|
3605
3659
|
return;
|
|
3606
3660
|
let experienceEntry = undefined;
|
|
@@ -3616,6 +3670,7 @@ async function fetchBySlug({ client, experienceTypeId, slug, localeCode, isEdito
|
|
|
3616
3670
|
if (!experienceEntry) {
|
|
3617
3671
|
throw new Error(`No experience entry with slug: ${slug} exists`);
|
|
3618
3672
|
}
|
|
3673
|
+
removeCircularPatternReferences(experienceEntry);
|
|
3619
3674
|
try {
|
|
3620
3675
|
const { entries, assets } = await fetchReferencedEntities({
|
|
3621
3676
|
client,
|
|
@@ -3668,6 +3723,7 @@ async function fetchById({ client, experienceTypeId, id, localeCode, isEditorMod
|
|
|
3668
3723
|
if (!experienceEntry) {
|
|
3669
3724
|
throw new Error(`No experience entry with id: ${id} exists`);
|
|
3670
3725
|
}
|
|
3726
|
+
removeCircularPatternReferences(experienceEntry);
|
|
3671
3727
|
try {
|
|
3672
3728
|
const { entries, assets } = await fetchReferencedEntities({
|
|
3673
3729
|
client,
|