scrivito
Version:
Scrivito is a professional, yet easy to use SaaS Enterprise Content Management Service, built for digital agencies and medium to large businesses. It is completely maintenance-free, cost-effective, and has unprecedented performance and security.
117 lines (103 loc) • 3.06 kB
text/typescript
// @rewire
import isEqual from 'lodash-es/isEqual';
import type {
AttributeJson,
HtmlAttributeJson,
LinkAttributeJson,
LinklistAttributeJson,
} from 'scrivito_sdk/client';
import { ObjData } from 'scrivito_sdk/data';
import {
convertHtml,
convertLink,
convertLinklist,
} from 'scrivito_sdk/link_resolution/content_conversion';
import { load, loadableWithDefault } from 'scrivito_sdk/loadable';
export type AnyLinkResolutionAttributeJson =
| HtmlAttributeJson
| LinkAttributeJson
| LinklistAttributeJson;
export function isAnyLinkResolutionAttributeJson(
attributeData: AttributeJson
): attributeData is AnyLinkResolutionAttributeJson {
return ['html', 'link', 'linklist'].includes(attributeData[0]);
}
export async function runWorker(
attributeDataToConvert: AnyLinkResolutionAttributeJson,
objData: ObjData,
attributeName: string,
widgetId?: string
): Promise<void> {
const convertValue = getConversion(attributeDataToConvert);
const convertedDataWithoutLoading = loadableWithDefault(
undefined,
convertValue
);
if (convertedDataWithoutLoading !== undefined) {
if (!isEqual(convertedDataWithoutLoading, attributeDataToConvert)) {
update(objData, attributeName, widgetId, convertedDataWithoutLoading);
}
return;
}
const convertedData = await load(convertValue);
if (isEqual(convertedData, attributeDataToConvert)) return;
if (
hasDataToConvertBeenChangedConcurrently(
attributeDataToConvert,
objData,
attributeName,
widgetId
)
) {
return;
}
update(objData, attributeName, widgetId, convertedData);
}
function hasDataToConvertBeenChangedConcurrently(
attributeData: AnyLinkResolutionAttributeJson,
objData: ObjData,
attributeName: string,
widgetId: string | undefined
) {
const currentAttributeData = widgetId
? objData.getWidgetAttribute(widgetId, attributeName)
: objData.getAttribute(attributeName);
return !isEqual(attributeData, currentAttributeData);
}
function update(
objData: ObjData,
attributeName: string,
widgetId: string | undefined,
newData: AnyLinkResolutionAttributeJson
) {
const patch = { [attributeName]: newData };
if (widgetId) {
objData.update({
_widget_pool: {
[widgetId]: patch,
},
});
} else {
objData.update(patch);
}
}
// The precise type is getConversion<T extends_oneof AnyLinkResolutionAttributeJson>(attributeData: T): () => T
// See https://github.com/microsoft/TypeScript/issues/27808
function getConversion(
attributeData: AnyLinkResolutionAttributeJson
): () => typeof attributeData {
switch (attributeData[0]) {
case 'html': {
const attributeValue = attributeData[1];
return () => ['html', convertHtml(attributeValue)];
}
case 'link': {
const attributeValue = attributeData[1];
return () => ['link', convertLink(attributeValue)];
}
case 'linklist': {
const attributeValue = attributeData[1];
return () => ['linklist', convertLinklist(attributeValue)];
}
}
}