@atlaskit/editor-core 239.0.3 → 240.0.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/CHANGELOG.md +24 -0
- package/dist/cjs/composable-editor/hooks/useMemoEditorProps.js +1 -3
- package/dist/cjs/ui/Appearance/FullPage/FullPageContentArea.js +3 -9
- package/dist/cjs/ui/quick-insert/ExtensionQuickInsertMenuItem.js +22 -2
- package/dist/cjs/ui/quick-insert/app-vendor/AppVendorRequestError.js +31 -0
- package/dist/cjs/ui/quick-insert/app-vendor/appVendorCache.js +14 -0
- package/dist/cjs/ui/quick-insert/app-vendor/fetchAppVendors.js +112 -0
- package/dist/cjs/ui/quick-insert/app-vendor/fetchAppVendorsInBatches.js +101 -0
- package/dist/cjs/ui/quick-insert/app-vendor/getAppVendorLookup.js +33 -0
- package/dist/cjs/ui/quick-insert/app-vendor/prefetchAppVendors.js +129 -0
- package/dist/cjs/ui/quick-insert/app-vendor/useAppVendorName.js +26 -0
- package/dist/cjs/ui/quick-insert/getExtensionQuickInsertComponents.js +13 -2
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/es2019/composable-editor/hooks/useMemoEditorProps.js +1 -3
- package/dist/es2019/ui/Appearance/FullPage/FullPageContentArea.js +3 -9
- package/dist/es2019/ui/quick-insert/ExtensionQuickInsertMenuItem.js +20 -3
- package/dist/es2019/ui/quick-insert/app-vendor/AppVendorRequestError.js +11 -0
- package/dist/es2019/ui/quick-insert/app-vendor/appVendorCache.js +8 -0
- package/dist/es2019/ui/quick-insert/app-vendor/fetchAppVendors.js +69 -0
- package/dist/es2019/ui/quick-insert/app-vendor/fetchAppVendorsInBatches.js +51 -0
- package/dist/es2019/ui/quick-insert/app-vendor/getAppVendorLookup.js +28 -0
- package/dist/es2019/ui/quick-insert/app-vendor/prefetchAppVendors.js +109 -0
- package/dist/es2019/ui/quick-insert/app-vendor/useAppVendorName.js +18 -0
- package/dist/es2019/ui/quick-insert/getExtensionQuickInsertComponents.js +17 -10
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/esm/composable-editor/hooks/useMemoEditorProps.js +1 -3
- package/dist/esm/ui/Appearance/FullPage/FullPageContentArea.js +3 -9
- package/dist/esm/ui/quick-insert/ExtensionQuickInsertMenuItem.js +22 -3
- package/dist/esm/ui/quick-insert/app-vendor/AppVendorRequestError.js +24 -0
- package/dist/esm/ui/quick-insert/app-vendor/appVendorCache.js +8 -0
- package/dist/esm/ui/quick-insert/app-vendor/fetchAppVendors.js +105 -0
- package/dist/esm/ui/quick-insert/app-vendor/fetchAppVendorsInBatches.js +94 -0
- package/dist/esm/ui/quick-insert/app-vendor/getAppVendorLookup.js +27 -0
- package/dist/esm/ui/quick-insert/app-vendor/prefetchAppVendors.js +119 -0
- package/dist/esm/ui/quick-insert/app-vendor/useAppVendorName.js +20 -0
- package/dist/esm/ui/quick-insert/getExtensionQuickInsertComponents.js +13 -2
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/types/editor-appearances/ChromelessEditor.d.ts +1 -1
- package/dist/types/editor-appearances/CommentEditor.d.ts +1 -1
- package/dist/types/editor-appearances/FullPageEditor.d.ts +1 -1
- package/dist/types/editor-appearances/FullWidthEditor.d.ts +1 -1
- package/dist/types/types/editor-props.d.ts +1 -13
- package/dist/types/ui/quick-insert/ExtensionQuickInsertMenuItem.d.ts +3 -1
- package/dist/types/ui/quick-insert/app-vendor/AppVendorRequestError.d.ts +5 -0
- package/dist/types/ui/quick-insert/app-vendor/appVendorCache.d.ts +17 -0
- package/dist/types/ui/quick-insert/app-vendor/fetchAppVendors.d.ts +8 -0
- package/dist/types/ui/quick-insert/app-vendor/fetchAppVendorsInBatches.d.ts +23 -0
- package/dist/types/ui/quick-insert/app-vendor/getAppVendorLookup.d.ts +11 -0
- package/dist/types/ui/quick-insert/app-vendor/prefetchAppVendors.d.ts +7 -0
- package/dist/types/ui/quick-insert/app-vendor/useAppVendorName.d.ts +2 -0
- package/package.json +10 -10
|
@@ -41,8 +41,6 @@ export const useMemoEditorProps = passedProps => {
|
|
|
41
41
|
media: passedProps.media,
|
|
42
42
|
collabEdit: passedProps.collabEdit,
|
|
43
43
|
primaryToolbarComponents: passedProps.primaryToolbarComponents,
|
|
44
|
-
performanceTracking: passedProps.performanceTracking,
|
|
45
|
-
inputSamplingLimit: passedProps.inputSamplingLimit,
|
|
46
44
|
allowUndoRedoButtons: passedProps.allowUndoRedoButtons,
|
|
47
45
|
linking: passedProps.linking,
|
|
48
46
|
activityProvider: passedProps.activityProvider,
|
|
@@ -114,7 +112,7 @@ export const useMemoEditorProps = passedProps => {
|
|
|
114
112
|
...allProps
|
|
115
113
|
};
|
|
116
114
|
return nextProps;
|
|
117
|
-
}, [passedProps.preset, passedProps.appearance, passedProps.contentMode, passedProps.contentComponents, passedProps.primaryToolbarIconBefore, passedProps.secondaryToolbarComponents, passedProps.persistScrollGutter, passedProps.quickInsert, passedProps.shouldFocus, passedProps.disabled, passedProps.contextPanel, passedProps.errorReporterHandler, passedProps.contentTransformerProvider, passedProps.maxHeight, passedProps.minHeight, passedProps.placeholder, passedProps.placeholderBracketHint, passedProps.
|
|
115
|
+
}, [passedProps.preset, passedProps.appearance, passedProps.contentMode, passedProps.contentComponents, passedProps.primaryToolbarIconBefore, passedProps.secondaryToolbarComponents, passedProps.persistScrollGutter, passedProps.quickInsert, passedProps.shouldFocus, passedProps.disabled, passedProps.contextPanel, passedProps.errorReporterHandler, passedProps.contentTransformerProvider, passedProps.maxHeight, passedProps.minHeight, passedProps.placeholder, passedProps.placeholderBracketHint, passedProps.defaultValue, passedProps.assistiveLabel, passedProps.assistiveDescribedBy, passedProps.popupsMountPoint, passedProps.popupsBoundariesElement, passedProps.popupsScrollableElement, passedProps.editorActions, passedProps.onEditorReady, passedProps.onDestroy, passedProps.onChange, passedProps.onCancel, passedProps.onSSRMeasure, passedProps.extensionProviders, passedProps.UNSAFE_useAnalyticsContext, passedProps.useStickyToolbar, passedProps.isEditorModernisationEnabled, passedProps.featureFlags, passedProps.onSave, passedProps.sanitizePrivateContent, passedProps.media, passedProps.collabEdit, passedProps.primaryToolbarComponents, passedProps.allowUndoRedoButtons, passedProps.linking, passedProps.activityProvider, passedProps.searchProvider, passedProps.annotationProviders, passedProps.collabEditProvider, passedProps.presenceProvider, passedProps.emojiProvider, passedProps.taskDecisionProvider, passedProps.legacyImageUploadProvider, passedProps.mentionProvider, passedProps.autoformattingProvider, passedProps.macroProvider, passedProps.contextIdentifierProvider, passedProps.allowExpand, passedProps.allowNestedTasks, passedProps.allowBlockType, passedProps.allowTasksAndDecisions, passedProps.allowBreakout, passedProps.allowRule, passedProps.allowHelpDialog, passedProps.allowPanel, passedProps.allowExtension, passedProps.allowConfluenceInlineComment, passedProps.allowTemplatePlaceholders, passedProps.allowDate, passedProps.allowLayouts, passedProps.allowStatus, passedProps.allowTextAlignment, passedProps.allowIndentation, passedProps.showIndentationButtons, passedProps.allowFindReplace, passedProps.allowBorderMark, passedProps.allowFragmentMark, passedProps.autoScrollIntoView, passedProps.elementBrowser, passedProps.maxContentSize, passedProps.saveOnEnter, passedProps.feedbackInfo, passedProps.mention, passedProps.mentionInsertDisplayName, passedProps.uploadErrorHandler, passedProps.waitForMediaUpload, passedProps.extensionHandlers, passedProps.allowTextColor, passedProps.allowTables, passedProps.insertMenuItems, passedProps.UNSAFE_cards, passedProps.smartLinks, passedProps.allowAnalyticsGASV3, passedProps.codeBlock, passedProps.textFormatting, passedProps.__livePage, passedProps.AppearanceComponent, passedProps.skipValidation, passedProps.syncBlock, passedProps.syncedBlockProvider, passedProps.pasteWarningOptions, passedProps.UNSAFE_containLayout]);
|
|
118
116
|
return memodProps;
|
|
119
117
|
};
|
|
120
118
|
|
|
@@ -51,7 +51,7 @@ const compiledStyles = {
|
|
|
51
51
|
export const CONTENT_AREA_TEST_ID = 'ak-editor-fp-content-area';
|
|
52
52
|
const EDITOR_CONTAINER = 'ak-editor-container';
|
|
53
53
|
const Content = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
54
|
-
var _props$editorAPI, _props$editorAPI$base, _props$editorAPI$base2, _props$editorAPI$bloc, _props$editorAPI2, _props$editorAPI2$blo, _props$editorAPI2$blo2, _props$editorAPI2$blo3, _contentAreaRef$curre, _allowScrollGutter$gu
|
|
54
|
+
var _props$editorAPI, _props$editorAPI$base, _props$editorAPI$base2, _props$editorAPI$bloc, _props$editorAPI2, _props$editorAPI2$blo, _props$editorAPI2$blo2, _props$editorAPI2$blo3, _contentAreaRef$curre, _allowScrollGutter$gu;
|
|
55
55
|
const fullWidthMode = props.appearance === 'full-width';
|
|
56
56
|
const maxWidthMode = props.appearance === 'max';
|
|
57
57
|
const scrollContainerRef = useRef(null);
|
|
@@ -127,20 +127,14 @@ const Content = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
127
127
|
containerElement: scrollContainerRef.current,
|
|
128
128
|
dispatchAnalyticsEvent: props.dispatchAnalyticsEvent,
|
|
129
129
|
wrapperElement: props.wrapperElement
|
|
130
|
-
}), props.editorDOMElement, !!props.customContentComponents && 'after' in props.customContentComponents ? contentComponentClickWrapper(props.customContentComponents.after) : null, allowScrollGutter &&
|
|
130
|
+
}), props.editorDOMElement, !!props.customContentComponents && 'after' in props.customContentComponents ? contentComponentClickWrapper(props.customContentComponents.after) : null, allowScrollGutter && /*#__PURE__*/React.createElement("div", {
|
|
131
131
|
id: "editor-scroll-gutter",
|
|
132
132
|
style: {
|
|
133
133
|
paddingBottom: `${(_allowScrollGutter$gu = allowScrollGutter.gutterSize) !== null && _allowScrollGutter$gu !== void 0 ? _allowScrollGutter$gu : '120'}px`
|
|
134
134
|
},
|
|
135
135
|
"data-vc": "scroll-gutter",
|
|
136
136
|
"data-editor-scroll-gutter": "true"
|
|
137
|
-
})
|
|
138
|
-
id: "editor-scroll-gutter",
|
|
139
|
-
style: {
|
|
140
|
-
paddingBottom: `${(_allowScrollGutter$gu2 = allowScrollGutter.gutterSize) !== null && _allowScrollGutter$gu2 !== void 0 ? _allowScrollGutter$gu2 : '120'}px`
|
|
141
|
-
},
|
|
142
|
-
"data-vc": "scroll-gutter"
|
|
143
|
-
}))))));
|
|
137
|
+
})))));
|
|
144
138
|
return /*#__PURE__*/React.createElement("div", {
|
|
145
139
|
"data-testid": CONTENT_AREA_TEST_ID,
|
|
146
140
|
ref: containerRef,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import React, { useCallback } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useMemo } from 'react';
|
|
2
2
|
import { QuickInsertMenuItem } from '@atlaskit/editor-common/quick-insert/menu-item';
|
|
3
3
|
import { useQuickInsertContext } from '@atlaskit/editor-common/quick-insert/use-quick-insert-context';
|
|
4
|
+
import { getAppVendorLookup } from './app-vendor/getAppVendorLookup';
|
|
5
|
+
import { useAppVendorName } from './app-vendor/useAppVendorName';
|
|
4
6
|
import { executeExtensionQuickInsertItem } from './executeExtensionQuickInsertItem';
|
|
5
7
|
import { ExtensionQuickInsertIcon } from './ExtensionQuickInsertIcon';
|
|
6
8
|
export const ExtensionQuickInsertMenuItem = ({
|
|
@@ -8,12 +10,27 @@ export const ExtensionQuickInsertMenuItem = ({
|
|
|
8
10
|
createAnalyticsEvent,
|
|
9
11
|
editorActions,
|
|
10
12
|
item,
|
|
11
|
-
onInsert
|
|
13
|
+
onInsert,
|
|
14
|
+
prefetchVendors
|
|
12
15
|
}) => {
|
|
16
|
+
var _getAppVendorLookup;
|
|
13
17
|
const {
|
|
14
18
|
editorView,
|
|
15
19
|
isOffline
|
|
16
20
|
} = useQuickInsertContext();
|
|
21
|
+
const vendorName = useAppVendorName((_getAppVendorLookup = getAppVendorLookup(item)) === null || _getAppVendorLookup === void 0 ? void 0 : _getAppVendorLookup.id);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
prefetchVendors === null || prefetchVendors === void 0 ? void 0 : prefetchVendors();
|
|
24
|
+
}, [prefetchVendors]);
|
|
25
|
+
const preview = useMemo(() => {
|
|
26
|
+
var _item$preview;
|
|
27
|
+
return vendorName && !((_item$preview = item.preview) !== null && _item$preview !== void 0 && _item$preview.attribution) ? {
|
|
28
|
+
...item.preview,
|
|
29
|
+
attribution: {
|
|
30
|
+
name: vendorName
|
|
31
|
+
}
|
|
32
|
+
} : item.preview;
|
|
33
|
+
}, [item.preview, vendorName]);
|
|
17
34
|
const onSelect = useCallback(({
|
|
18
35
|
insert,
|
|
19
36
|
source
|
|
@@ -41,7 +58,7 @@ export const ExtensionQuickInsertMenuItem = ({
|
|
|
41
58
|
isDisabled: isOffline,
|
|
42
59
|
lozenge: item.lozenge,
|
|
43
60
|
onSelect: onSelect,
|
|
44
|
-
preview:
|
|
61
|
+
preview: preview,
|
|
45
62
|
description: item.description,
|
|
46
63
|
title: item.title
|
|
47
64
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Statuses where retrying cannot succeed, or would add load to a throttled gateway. */
|
|
2
|
+
const BLOCKING_STATUSES = new Set([401, 403, 429]);
|
|
3
|
+
export class AppVendorRequestError extends Error {
|
|
4
|
+
/** Whether every remaining lookup should stop rather than retry. */
|
|
5
|
+
|
|
6
|
+
constructor(message, status) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'AppVendorRequestError';
|
|
9
|
+
this.isBlocking = status !== undefined && BLOCKING_STATUSES.has(status);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendor names keyed by lookup id, plus the subscribers to notify when they change.
|
|
3
|
+
* Module scope so names survive editor and provider rebuilds for the rest of the page load.
|
|
4
|
+
*/
|
|
5
|
+
export const appVendorCache = {
|
|
6
|
+
entries: new Map(),
|
|
7
|
+
listeners: new Set()
|
|
8
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { AppVendorRequestError } from './AppVendorRequestError';
|
|
2
|
+
const AGG_PATH = '/gateway/api/graphql';
|
|
3
|
+
const OPERATION_NAME = 'QuickInsertAppVendorsQuery';
|
|
4
|
+
const getField = ({
|
|
5
|
+
kind
|
|
6
|
+
}, variable) => kind === 'forge' ? `marketplaceAppByCloudAppId(cloudAppId: $${variable})` : `marketplaceAppByKey(appKey: $${variable})`;
|
|
7
|
+
const getVariableType = ({
|
|
8
|
+
kind
|
|
9
|
+
}) => kind === 'forge' ? 'ID!' : 'String!';
|
|
10
|
+
const buildQuery = lookups => {
|
|
11
|
+
const variables = lookups.map((lookup, index) => `$a${index}: ${getVariableType(lookup)}`);
|
|
12
|
+
const fields = lookups.map((lookup, index) => `a${index}: ${getField(lookup, `a${index}`)} { partner { name } }`);
|
|
13
|
+
return `query ${OPERATION_NAME}(${variables.join(', ')}) { ${fields.join(' ')} }`;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** A request that never settles would otherwise leave its lookups pending for the page load. */
|
|
17
|
+
const REQUEST_TIMEOUT_MS = 10_000;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Fetches Marketplace partner names for at most one batch of lookups.
|
|
21
|
+
* Resolves `null` for apps without a listed partner and omits lookups whose field errored, so they
|
|
22
|
+
* can be retried; rejects with `AppVendorRequestError` when the request itself fails, or with an
|
|
23
|
+
* `AbortError` when it takes longer than `REQUEST_TIMEOUT_MS`.
|
|
24
|
+
*/
|
|
25
|
+
export const fetchAppVendors = async lookups => {
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
28
|
+
try {
|
|
29
|
+
const response = await fetch(AGG_PATH, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: {
|
|
32
|
+
'Content-Type': 'application/json'
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({
|
|
35
|
+
operationName: OPERATION_NAME,
|
|
36
|
+
query: buildQuery(lookups),
|
|
37
|
+
variables: Object.fromEntries(lookups.map(({
|
|
38
|
+
value
|
|
39
|
+
}, index) => [`a${index}`, value]))
|
|
40
|
+
}),
|
|
41
|
+
// Also aborts reading the body, so a slow response cannot hang either.
|
|
42
|
+
signal: controller.signal
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new AppVendorRequestError(`App vendor request failed: ${response.status}`, response.status);
|
|
46
|
+
}
|
|
47
|
+
const {
|
|
48
|
+
data,
|
|
49
|
+
errors
|
|
50
|
+
} = await response.json();
|
|
51
|
+
if (!data) {
|
|
52
|
+
throw new AppVendorRequestError('App vendor request returned no data');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// A field that errored or timed out also returns null, which must not be cached as unlisted.
|
|
56
|
+
const erroredAliases = new Set(errors === null || errors === void 0 ? void 0 : errors.map(({
|
|
57
|
+
path
|
|
58
|
+
}) => path === null || path === void 0 ? void 0 : path[0]));
|
|
59
|
+
return new Map(lookups.flatMap(({
|
|
60
|
+
id
|
|
61
|
+
}, index) => {
|
|
62
|
+
var _data$alias, _data$alias$partner;
|
|
63
|
+
const alias = `a${index}`;
|
|
64
|
+
return erroredAliases.has(alias) ? [] : [[id, ((_data$alias = data[alias]) === null || _data$alias === void 0 ? void 0 : (_data$alias$partner = _data$alias.partner) === null || _data$alias$partner === void 0 ? void 0 : _data$alias$partner.name) || null]];
|
|
65
|
+
}));
|
|
66
|
+
} finally {
|
|
67
|
+
clearTimeout(timeout);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { AppVendorRequestError } from './AppVendorRequestError';
|
|
2
|
+
import { fetchAppVendors } from './fetchAppVendors';
|
|
3
|
+
/** Marketplace has no bulk lookup; larger aliased requests time out. */
|
|
4
|
+
const BATCH_SIZE = 15;
|
|
5
|
+
const MAX_CONCURRENT_BATCHES = 3;
|
|
6
|
+
/**
|
|
7
|
+
* Fetches lookups in batches, at most `MAX_CONCURRENT_BATCHES` at a time, reporting each batch as it
|
|
8
|
+
* settles. Batches that have not started when `shouldContinue` returns false are reported as skipped.
|
|
9
|
+
* Loaded on demand so editors without ecosystem apps never download the fetching code.
|
|
10
|
+
*/
|
|
11
|
+
export const fetchAppVendorsInBatches = async (lookups, {
|
|
12
|
+
onBatch,
|
|
13
|
+
shouldContinue
|
|
14
|
+
}) => {
|
|
15
|
+
const batches = [];
|
|
16
|
+
for (let start = 0; start < lookups.length; start += BATCH_SIZE) {
|
|
17
|
+
batches.push(lookups.slice(start, start + BATCH_SIZE));
|
|
18
|
+
}
|
|
19
|
+
let nextBatch = 0;
|
|
20
|
+
const runWorker = async () => {
|
|
21
|
+
while (nextBatch < batches.length) {
|
|
22
|
+
const batch = batches[nextBatch++];
|
|
23
|
+
if (!shouldContinue()) {
|
|
24
|
+
onBatch(batch, {
|
|
25
|
+
status: 'skipped'
|
|
26
|
+
});
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// Only the request is caught, so a batch is never reported twice.
|
|
30
|
+
let names;
|
|
31
|
+
try {
|
|
32
|
+
names = await fetchAppVendors(batch);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
const isBlocking = error instanceof AppVendorRequestError && error.isBlocking;
|
|
35
|
+
onBatch(batch, {
|
|
36
|
+
error,
|
|
37
|
+
isBlocking,
|
|
38
|
+
status: 'rejected'
|
|
39
|
+
});
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
onBatch(batch, {
|
|
43
|
+
names,
|
|
44
|
+
status: 'fulfilled'
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
await Promise.all(Array.from({
|
|
49
|
+
length: Math.min(MAX_CONCURRENT_BATCHES, batches.length)
|
|
50
|
+
}, runWorker));
|
|
51
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { FORGE_EXTENSION_TYPE } from '@atlaskit/editor-common/extensions/manifest-helpers';
|
|
2
|
+
const FORGE_APP_ARI_PREFIX = 'ari:cloud:ecosystem::app/';
|
|
3
|
+
|
|
4
|
+
/** How to look up the Marketplace partner of the app that contributes an extension item. */
|
|
5
|
+
|
|
6
|
+
/** Returns a lookup only for ecosystem apps; Atlassian-owned items have no Marketplace partner. */
|
|
7
|
+
export const getAppVendorLookup = ({
|
|
8
|
+
app,
|
|
9
|
+
extensionType
|
|
10
|
+
}) => {
|
|
11
|
+
if ((app === null || app === void 0 ? void 0 : app.source) !== 'ecosystem' || !app.key) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
if (extensionType === FORGE_EXTENSION_TYPE) {
|
|
15
|
+
// Marketplace returns null for a bare Forge app UUID, so always send the full ARI.
|
|
16
|
+
const value = app.key.startsWith(FORGE_APP_ARI_PREFIX) ? app.key : `${FORGE_APP_ARI_PREFIX}${app.key}`;
|
|
17
|
+
return {
|
|
18
|
+
id: `forge:${value}`,
|
|
19
|
+
kind: 'forge',
|
|
20
|
+
value
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
id: `connect:${app.key}`,
|
|
25
|
+
kind: 'connect',
|
|
26
|
+
value: app.key
|
|
27
|
+
};
|
|
28
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { logException } from '@atlaskit/editor-common/monitoring/error';
|
|
2
|
+
import { appVendorCache } from './appVendorCache';
|
|
3
|
+
import { getAppVendorLookup } from './getAppVendorLookup';
|
|
4
|
+
|
|
5
|
+
/** Failed lookups are retried on later menu opens, up to this many attempts per page load. */
|
|
6
|
+
const MAX_ATTEMPTS = 3;
|
|
7
|
+
const LOG_LOCATION = 'editor-core/quick-insert/prefetchAppVendors';
|
|
8
|
+
const {
|
|
9
|
+
entries,
|
|
10
|
+
listeners
|
|
11
|
+
} = appVendorCache;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Set once any batch fails with 401, 403, or 429. Those mean the session cannot read Marketplace
|
|
15
|
+
* data or the gateway is throttling, which applies to every editor on the page, so all further
|
|
16
|
+
* lookups stop until the page reloads.
|
|
17
|
+
*/
|
|
18
|
+
let isBlocked = false;
|
|
19
|
+
const shouldFetch = entry => !entry || entry.status === 'failed' && entry.attempts < MAX_ATTEMPTS;
|
|
20
|
+
const getAttempts = entry => (entry === null || entry === void 0 ? void 0 : entry.status) === 'failed' ? entry.attempts : 0;
|
|
21
|
+
|
|
22
|
+
// A throwing subscriber must not stop the others or abort the batch that is being settled.
|
|
23
|
+
const notify = () => listeners.forEach(listener => {
|
|
24
|
+
try {
|
|
25
|
+
listener();
|
|
26
|
+
} catch (error) {
|
|
27
|
+
logException(error, {
|
|
28
|
+
location: LOG_LOCATION
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const markFailed = ({
|
|
33
|
+
attempts,
|
|
34
|
+
id
|
|
35
|
+
}) => entries.set(id, {
|
|
36
|
+
attempts,
|
|
37
|
+
status: 'failed'
|
|
38
|
+
});
|
|
39
|
+
const settleBatch = (batch, result) => {
|
|
40
|
+
if (result.status !== 'fulfilled') {
|
|
41
|
+
if (result.status === 'rejected') {
|
|
42
|
+
isBlocked ||= result.isBlocking;
|
|
43
|
+
logException(result.error, {
|
|
44
|
+
location: LOG_LOCATION
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
batch.forEach(markFailed);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Lookups missing from the result errored individually and stay retryable.
|
|
52
|
+
batch.forEach(lookup => {
|
|
53
|
+
const name = result.names.get(lookup.id);
|
|
54
|
+
if (name === undefined) {
|
|
55
|
+
markFailed(lookup);
|
|
56
|
+
} else {
|
|
57
|
+
entries.set(lookup.id, {
|
|
58
|
+
name,
|
|
59
|
+
status: 'resolved'
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
notify();
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Starts fetching Marketplace partner names for every ecosystem app among `items`.
|
|
68
|
+
* Safe to call repeatedly: cached, in-flight, and exhausted lookups are skipped. The fetching code
|
|
69
|
+
* is loaded only once a lookup is queued.
|
|
70
|
+
*/
|
|
71
|
+
export const prefetchAppVendors = items => {
|
|
72
|
+
if (isBlocked) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const lookups = [];
|
|
76
|
+
items.forEach(item => {
|
|
77
|
+
const lookup = getAppVendorLookup(item);
|
|
78
|
+
const entry = lookup && entries.get(lookup.id);
|
|
79
|
+
if (lookup && shouldFetch(entry)) {
|
|
80
|
+
lookups.push({
|
|
81
|
+
...lookup,
|
|
82
|
+
attempts: getAttempts(entry) + 1
|
|
83
|
+
});
|
|
84
|
+
entries.set(lookup.id, {
|
|
85
|
+
status: 'pending'
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
if (lookups.length === 0) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
void import( /* webpackChunkName: "@atlaskit-internal_editor-core-quick-insert-app-vendor" */'./fetchAppVendorsInBatches').then(({
|
|
93
|
+
fetchAppVendorsInBatches
|
|
94
|
+
}) => fetchAppVendorsInBatches(lookups, {
|
|
95
|
+
onBatch: settleBatch,
|
|
96
|
+
shouldContinue: () => !isBlocked
|
|
97
|
+
}), error => {
|
|
98
|
+
// The chunk failed to load; nothing was requested, so every queued lookup can retry.
|
|
99
|
+
lookups.forEach(markFailed);
|
|
100
|
+
logException(error, {
|
|
101
|
+
location: LOG_LOCATION
|
|
102
|
+
});
|
|
103
|
+
}).catch(error => {
|
|
104
|
+
// Fetch errors are reported per batch; this only catches an unexpected throw while settling.
|
|
105
|
+
logException(error, {
|
|
106
|
+
location: LOG_LOCATION
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useSyncExternalStore } from 'react';
|
|
2
|
+
import { appVendorCache } from './appVendorCache';
|
|
3
|
+
const subscribe = listener => {
|
|
4
|
+
appVendorCache.listeners.add(listener);
|
|
5
|
+
return () => {
|
|
6
|
+
appVendorCache.listeners.delete(listener);
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
const getServerSnapshot = () => undefined;
|
|
10
|
+
|
|
11
|
+
/** Returns the partner name, `null` for unlisted apps, or `undefined` while unknown. */
|
|
12
|
+
export const useAppVendorName = id => {
|
|
13
|
+
const getSnapshot = () => {
|
|
14
|
+
const entry = id ? appVendorCache.entries.get(id) : undefined;
|
|
15
|
+
return (entry === null || entry === void 0 ? void 0 : entry.status) === 'resolved' ? entry.name : undefined;
|
|
16
|
+
};
|
|
17
|
+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
18
|
+
};
|
|
@@ -3,6 +3,7 @@ import { createQuickInsertMatcher } from '@atlaskit/editor-common/quick-insert/c
|
|
|
3
3
|
import { getQuickInsertMenuItemParents } from '@atlaskit/editor-common/quick-insert/get-menu-item-parents';
|
|
4
4
|
import { BLOCK_TEMPLATES_SECTION, DATA_AND_CHARTS_SECTION, EMBED_SECTION, MEDIA_SECTION, OTHER_SECTION, STRUCTURE_SECTION, TABS_MENU_ITEM } from '@atlaskit/editor-common/quick-insert/keys';
|
|
5
5
|
import { CREATE_SECTION_RANK, EXTENSION_ITEM_RANK, MEDIA_SECTION_RANK } from '@atlaskit/editor-common/quick-insert/rank';
|
|
6
|
+
import { prefetchAppVendors } from './app-vendor/prefetchAppVendors';
|
|
6
7
|
import { ExtensionQuickInsertMenuItem } from './ExtensionQuickInsertMenuItem';
|
|
7
8
|
import { QuickInsertSkillMenuItem } from './QuickInsertSkillMenuItem';
|
|
8
9
|
const structureExtensionItemKeyRanks = {
|
|
@@ -59,6 +60,8 @@ export const getExtensionQuickInsertComponents = ({
|
|
|
59
60
|
items
|
|
60
61
|
}) => {
|
|
61
62
|
const getExtensionItemRank = createExtensionItemRanker(items);
|
|
63
|
+
// Every row prefetches all items so the first row to mount fetches vendors in one batch.
|
|
64
|
+
const prefetchVendors = () => prefetchAppVendors(items);
|
|
62
65
|
return items.map((item, index) => {
|
|
63
66
|
const structureRank = getStructureExtensionItemRank(item);
|
|
64
67
|
const isStructureItem = structureRank !== undefined;
|
|
@@ -90,16 +93,20 @@ export const getExtensionQuickInsertComponents = ({
|
|
|
90
93
|
keywords: item.keywords,
|
|
91
94
|
title: item.title
|
|
92
95
|
})),
|
|
93
|
-
component: props => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
component: props => item.extensionType === 'com.atlassian.rovo.skill' ? /*#__PURE__*/React.createElement(QuickInsertSkillMenuItem, {
|
|
97
|
+
apiRef: apiRef,
|
|
98
|
+
createAnalyticsEvent: createAnalyticsEvent,
|
|
99
|
+
editorActions: editorActions,
|
|
100
|
+
item: item,
|
|
101
|
+
onInsert: props.onInsert
|
|
102
|
+
}) : /*#__PURE__*/React.createElement(ExtensionQuickInsertMenuItem, {
|
|
103
|
+
apiRef: apiRef,
|
|
104
|
+
createAnalyticsEvent: createAnalyticsEvent,
|
|
105
|
+
editorActions: editorActions,
|
|
106
|
+
item: item,
|
|
107
|
+
onInsert: props.onInsert,
|
|
108
|
+
prefetchVendors: prefetchVendors
|
|
109
|
+
})
|
|
103
110
|
};
|
|
104
111
|
});
|
|
105
112
|
};
|
|
@@ -44,8 +44,6 @@ export var useMemoEditorProps = function useMemoEditorProps(passedProps) {
|
|
|
44
44
|
media: passedProps.media,
|
|
45
45
|
collabEdit: passedProps.collabEdit,
|
|
46
46
|
primaryToolbarComponents: passedProps.primaryToolbarComponents,
|
|
47
|
-
performanceTracking: passedProps.performanceTracking,
|
|
48
|
-
inputSamplingLimit: passedProps.inputSamplingLimit,
|
|
49
47
|
allowUndoRedoButtons: passedProps.allowUndoRedoButtons,
|
|
50
48
|
linking: passedProps.linking,
|
|
51
49
|
activityProvider: passedProps.activityProvider,
|
|
@@ -114,7 +112,7 @@ export var useMemoEditorProps = function useMemoEditorProps(passedProps) {
|
|
|
114
112
|
};
|
|
115
113
|
var nextProps = _objectSpread(_objectSpread({}, defaultProps), allProps);
|
|
116
114
|
return nextProps;
|
|
117
|
-
}, [passedProps.preset, passedProps.appearance, passedProps.contentMode, passedProps.contentComponents, passedProps.primaryToolbarIconBefore, passedProps.secondaryToolbarComponents, passedProps.persistScrollGutter, passedProps.quickInsert, passedProps.shouldFocus, passedProps.disabled, passedProps.contextPanel, passedProps.errorReporterHandler, passedProps.contentTransformerProvider, passedProps.maxHeight, passedProps.minHeight, passedProps.placeholder, passedProps.placeholderBracketHint, passedProps.
|
|
115
|
+
}, [passedProps.preset, passedProps.appearance, passedProps.contentMode, passedProps.contentComponents, passedProps.primaryToolbarIconBefore, passedProps.secondaryToolbarComponents, passedProps.persistScrollGutter, passedProps.quickInsert, passedProps.shouldFocus, passedProps.disabled, passedProps.contextPanel, passedProps.errorReporterHandler, passedProps.contentTransformerProvider, passedProps.maxHeight, passedProps.minHeight, passedProps.placeholder, passedProps.placeholderBracketHint, passedProps.defaultValue, passedProps.assistiveLabel, passedProps.assistiveDescribedBy, passedProps.popupsMountPoint, passedProps.popupsBoundariesElement, passedProps.popupsScrollableElement, passedProps.editorActions, passedProps.onEditorReady, passedProps.onDestroy, passedProps.onChange, passedProps.onCancel, passedProps.onSSRMeasure, passedProps.extensionProviders, passedProps.UNSAFE_useAnalyticsContext, passedProps.useStickyToolbar, passedProps.isEditorModernisationEnabled, passedProps.featureFlags, passedProps.onSave, passedProps.sanitizePrivateContent, passedProps.media, passedProps.collabEdit, passedProps.primaryToolbarComponents, passedProps.allowUndoRedoButtons, passedProps.linking, passedProps.activityProvider, passedProps.searchProvider, passedProps.annotationProviders, passedProps.collabEditProvider, passedProps.presenceProvider, passedProps.emojiProvider, passedProps.taskDecisionProvider, passedProps.legacyImageUploadProvider, passedProps.mentionProvider, passedProps.autoformattingProvider, passedProps.macroProvider, passedProps.contextIdentifierProvider, passedProps.allowExpand, passedProps.allowNestedTasks, passedProps.allowBlockType, passedProps.allowTasksAndDecisions, passedProps.allowBreakout, passedProps.allowRule, passedProps.allowHelpDialog, passedProps.allowPanel, passedProps.allowExtension, passedProps.allowConfluenceInlineComment, passedProps.allowTemplatePlaceholders, passedProps.allowDate, passedProps.allowLayouts, passedProps.allowStatus, passedProps.allowTextAlignment, passedProps.allowIndentation, passedProps.showIndentationButtons, passedProps.allowFindReplace, passedProps.allowBorderMark, passedProps.allowFragmentMark, passedProps.autoScrollIntoView, passedProps.elementBrowser, passedProps.maxContentSize, passedProps.saveOnEnter, passedProps.feedbackInfo, passedProps.mention, passedProps.mentionInsertDisplayName, passedProps.uploadErrorHandler, passedProps.waitForMediaUpload, passedProps.extensionHandlers, passedProps.allowTextColor, passedProps.allowTables, passedProps.insertMenuItems, passedProps.UNSAFE_cards, passedProps.smartLinks, passedProps.allowAnalyticsGASV3, passedProps.codeBlock, passedProps.textFormatting, passedProps.__livePage, passedProps.AppearanceComponent, passedProps.skipValidation, passedProps.syncBlock, passedProps.syncedBlockProvider, passedProps.pasteWarningOptions, passedProps.UNSAFE_containLayout]);
|
|
118
116
|
return memodProps;
|
|
119
117
|
};
|
|
120
118
|
|
|
@@ -53,7 +53,7 @@ var compiledStyles = {
|
|
|
53
53
|
export var CONTENT_AREA_TEST_ID = 'ak-editor-fp-content-area';
|
|
54
54
|
var EDITOR_CONTAINER = 'ak-editor-container';
|
|
55
55
|
var Content = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
56
|
-
var _props$editorAPI, _props$editorAPI$bloc, _props$editorAPI2, _contentAreaRef$curre, _allowScrollGutter$gu
|
|
56
|
+
var _props$editorAPI, _props$editorAPI$bloc, _props$editorAPI2, _contentAreaRef$curre, _allowScrollGutter$gu;
|
|
57
57
|
var fullWidthMode = props.appearance === 'full-width';
|
|
58
58
|
var maxWidthMode = props.appearance === 'max';
|
|
59
59
|
var scrollContainerRef = useRef(null);
|
|
@@ -131,20 +131,14 @@ var Content = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
131
131
|
containerElement: scrollContainerRef.current,
|
|
132
132
|
dispatchAnalyticsEvent: props.dispatchAnalyticsEvent,
|
|
133
133
|
wrapperElement: props.wrapperElement
|
|
134
|
-
}), props.editorDOMElement, !!props.customContentComponents && 'after' in props.customContentComponents ? contentComponentClickWrapper(props.customContentComponents.after) : null, allowScrollGutter &&
|
|
134
|
+
}), props.editorDOMElement, !!props.customContentComponents && 'after' in props.customContentComponents ? contentComponentClickWrapper(props.customContentComponents.after) : null, allowScrollGutter && /*#__PURE__*/React.createElement("div", {
|
|
135
135
|
id: "editor-scroll-gutter",
|
|
136
136
|
style: {
|
|
137
137
|
paddingBottom: "".concat((_allowScrollGutter$gu = allowScrollGutter.gutterSize) !== null && _allowScrollGutter$gu !== void 0 ? _allowScrollGutter$gu : '120', "px")
|
|
138
138
|
},
|
|
139
139
|
"data-vc": "scroll-gutter",
|
|
140
140
|
"data-editor-scroll-gutter": "true"
|
|
141
|
-
})
|
|
142
|
-
id: "editor-scroll-gutter",
|
|
143
|
-
style: {
|
|
144
|
-
paddingBottom: "".concat((_allowScrollGutter$gu2 = allowScrollGutter.gutterSize) !== null && _allowScrollGutter$gu2 !== void 0 ? _allowScrollGutter$gu2 : '120', "px")
|
|
145
|
-
},
|
|
146
|
-
"data-vc": "scroll-gutter"
|
|
147
|
-
}))))));
|
|
141
|
+
})))));
|
|
148
142
|
return /*#__PURE__*/React.createElement("div", {
|
|
149
143
|
"data-testid": CONTENT_AREA_TEST_ID,
|
|
150
144
|
ref: containerRef,
|
|
@@ -1,17 +1,36 @@
|
|
|
1
|
-
import
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import React, { useCallback, useEffect, useMemo } from 'react';
|
|
2
5
|
import { QuickInsertMenuItem } from '@atlaskit/editor-common/quick-insert/menu-item';
|
|
3
6
|
import { useQuickInsertContext } from '@atlaskit/editor-common/quick-insert/use-quick-insert-context';
|
|
7
|
+
import { getAppVendorLookup } from './app-vendor/getAppVendorLookup';
|
|
8
|
+
import { useAppVendorName } from './app-vendor/useAppVendorName';
|
|
4
9
|
import { executeExtensionQuickInsertItem } from './executeExtensionQuickInsertItem';
|
|
5
10
|
import { ExtensionQuickInsertIcon } from './ExtensionQuickInsertIcon';
|
|
6
11
|
export var ExtensionQuickInsertMenuItem = function ExtensionQuickInsertMenuItem(_ref) {
|
|
12
|
+
var _getAppVendorLookup;
|
|
7
13
|
var apiRef = _ref.apiRef,
|
|
8
14
|
createAnalyticsEvent = _ref.createAnalyticsEvent,
|
|
9
15
|
editorActions = _ref.editorActions,
|
|
10
16
|
item = _ref.item,
|
|
11
|
-
onInsert = _ref.onInsert
|
|
17
|
+
onInsert = _ref.onInsert,
|
|
18
|
+
prefetchVendors = _ref.prefetchVendors;
|
|
12
19
|
var _useQuickInsertContex = useQuickInsertContext(),
|
|
13
20
|
editorView = _useQuickInsertContex.editorView,
|
|
14
21
|
isOffline = _useQuickInsertContex.isOffline;
|
|
22
|
+
var vendorName = useAppVendorName((_getAppVendorLookup = getAppVendorLookup(item)) === null || _getAppVendorLookup === void 0 ? void 0 : _getAppVendorLookup.id);
|
|
23
|
+
useEffect(function () {
|
|
24
|
+
prefetchVendors === null || prefetchVendors === void 0 || prefetchVendors();
|
|
25
|
+
}, [prefetchVendors]);
|
|
26
|
+
var preview = useMemo(function () {
|
|
27
|
+
var _item$preview;
|
|
28
|
+
return vendorName && !((_item$preview = item.preview) !== null && _item$preview !== void 0 && _item$preview.attribution) ? _objectSpread(_objectSpread({}, item.preview), {}, {
|
|
29
|
+
attribution: {
|
|
30
|
+
name: vendorName
|
|
31
|
+
}
|
|
32
|
+
}) : item.preview;
|
|
33
|
+
}, [item.preview, vendorName]);
|
|
15
34
|
var onSelect = useCallback(function (_ref2) {
|
|
16
35
|
var insert = _ref2.insert,
|
|
17
36
|
source = _ref2.source;
|
|
@@ -38,7 +57,7 @@ export var ExtensionQuickInsertMenuItem = function ExtensionQuickInsertMenuItem(
|
|
|
38
57
|
isDisabled: isOffline,
|
|
39
58
|
lozenge: item.lozenge,
|
|
40
59
|
onSelect: onSelect,
|
|
41
|
-
preview:
|
|
60
|
+
preview: preview,
|
|
42
61
|
description: item.description,
|
|
43
62
|
title: item.title
|
|
44
63
|
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
2
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
|
+
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
4
|
+
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
5
|
+
import _inherits from "@babel/runtime/helpers/inherits";
|
|
6
|
+
import _wrapNativeSuper from "@babel/runtime/helpers/wrapNativeSuper";
|
|
7
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
8
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
9
|
+
/** Statuses where retrying cannot succeed, or would add load to a throttled gateway. */
|
|
10
|
+
var BLOCKING_STATUSES = new Set([401, 403, 429]);
|
|
11
|
+
export var AppVendorRequestError = /*#__PURE__*/function (_Error) {
|
|
12
|
+
/** Whether every remaining lookup should stop rather than retry. */
|
|
13
|
+
|
|
14
|
+
function AppVendorRequestError(message, status) {
|
|
15
|
+
var _this;
|
|
16
|
+
_classCallCheck(this, AppVendorRequestError);
|
|
17
|
+
_this = _callSuper(this, AppVendorRequestError, [message]);
|
|
18
|
+
_this.name = 'AppVendorRequestError';
|
|
19
|
+
_this.isBlocking = status !== undefined && BLOCKING_STATUSES.has(status);
|
|
20
|
+
return _this;
|
|
21
|
+
}
|
|
22
|
+
_inherits(AppVendorRequestError, _Error);
|
|
23
|
+
return _createClass(AppVendorRequestError);
|
|
24
|
+
}( /*#__PURE__*/_wrapNativeSuper(Error));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendor names keyed by lookup id, plus the subscribers to notify when they change.
|
|
3
|
+
* Module scope so names survive editor and provider rebuilds for the rest of the page load.
|
|
4
|
+
*/
|
|
5
|
+
export var appVendorCache = {
|
|
6
|
+
entries: new Map(),
|
|
7
|
+
listeners: new Set()
|
|
8
|
+
};
|