@1fe/shell
Version:
Frontend shell and runtime for 1FE micro-frontend applications
1,520 lines (1,481 loc) • 90.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('systemjs/dist/extras/dynamic-import-maps.min.js');
require('systemjs/dist/extras/global.min.js');
require('systemjs/dist/extras/module-types.min.js');
require('systemjs/dist/extras/named-register.min.js');
require('systemjs/dist/extras/use-default.min.js');
var React = require('react');
var ReactDOMClient = require('react-dom/client');
var reactRouterDom = require('react-router-dom');
var lodash = require('lodash');
var jsxRuntime = require('react/jsx-runtime');
var deepFreeze = require('deep-freeze');
var styled = require('@emotion/styled');
var bowser = require('bowser');
var Emittery = require('emittery');
var store = require('store2');
var Cookies = require('js-cookie');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespace(React);
var ReactDOMClient__default = /*#__PURE__*/_interopDefault(ReactDOMClient);
var deepFreeze__default = /*#__PURE__*/_interopDefault(deepFreeze);
var styled__default = /*#__PURE__*/_interopDefault(styled);
var bowser__default = /*#__PURE__*/_interopDefault(bowser);
var Emittery__default = /*#__PURE__*/_interopDefault(Emittery);
var store__default = /*#__PURE__*/_interopDefault(store);
var Cookies__default = /*#__PURE__*/_interopDefault(Cookies);
// src/shell/index.tsx
var oneFEConfigs = null;
var readOneFEShellConfigs = () => {
if (lodash.isEmpty(oneFEConfigs)) {
throw new Error("OneFE Shell configs have not been initialized.");
}
return oneFEConfigs;
};
var setOneFEShellConfigs = (newConfigs) => {
oneFEConfigs = newConfigs;
};
// src/shell/configs/config-helpers.ts
var generateWidgetConfigMap = (parsedWidgetConfigData) => new Map(
parsedWidgetConfigData.map((widgetConfig) => [
widgetConfig.widgetId,
widgetConfig
])
);
var getConfigArrFromGlobal = (configName) => {
const defaultValue = configName === "dynamic-config" ? {} : [];
try {
const oneDsConfig = JSON.parse(
document?.querySelector(`script[data-1fe-config-id="${configName}"]`)?.innerHTML || JSON.stringify(defaultValue)
) ?? defaultValue;
return oneDsConfig;
} catch (e) {
return defaultValue;
}
};
var getConfigObjFromGlobal = (configName, overrideSelector = `script[data-1fe-config-id="${configName}"]`) => {
try {
const oneDsConfig = JSON.parse(
document?.querySelector(overrideSelector)?.innerHTML ?? "{}"
) ?? {};
if (Object.keys(oneDsConfig).length === 0) {
return {};
}
return oneDsConfig;
} catch (e) {
return {};
}
};
var PLUGIN_CONFIGS = generateWidgetConfigMap(
getConfigArrFromGlobal("plugin-config")
);
var WIDGET_CONFIGS = generateWidgetConfigMap(
getConfigArrFromGlobal("widget-config")
);
var ENVIRONMENT_CONFIG = getConfigObjFromGlobal("env-config");
var DYNAMIC_CONFIGS = getConfigArrFromGlobal(
"dynamic-config"
);
var LAZY_LOADED_LIB_CONFIGS = getConfigObjFromGlobal("lazy-loaded-libs-config");
var getWidgetConfigValues = (widgetConfigs) => Array.from(widgetConfigs.values());
// src/shell/constants/event-names.ts
var SHELL_NAVIGATED_EVENT = "[shell] navigated";
// src/shell/utils/telemetry.ts
var getShellLogger = () => {
return readOneFEShellConfigs()?.shellLogger || {
log: (logObject) => {
console.log(logObject);
},
error: (logObject) => {
console.error(logObject);
},
logPlatformUtilUsage: true,
redactSensitiveData: true
};
};
// ../../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js
function _setPrototypeOf(t, e) {
return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(t2, e2) {
return t2.__proto__ = e2, t2;
}, _setPrototypeOf(t, e);
}
// ../../node_modules/@babel/runtime/helpers/esm/inheritsLoose.js
function _inheritsLoose(t, o) {
t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o);
}
var changedArray = function changedArray2(a, b) {
if (a === void 0) {
a = [];
}
if (b === void 0) {
b = [];
}
return a.length !== b.length || a.some(function(item, index) {
return !Object.is(item, b[index]);
});
};
var initialState = {
error: null
};
var ErrorBoundary = /* @__PURE__ */ function(_React$Component) {
_inheritsLoose(ErrorBoundary2, _React$Component);
function ErrorBoundary2() {
var _this;
for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
_args[_key] = arguments[_key];
}
_this = _React$Component.call.apply(_React$Component, [this].concat(_args)) || this;
_this.state = initialState;
_this.resetErrorBoundary = function() {
var _this$props;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
_this.props.onReset == null ? void 0 : (_this$props = _this.props).onReset.apply(_this$props, args);
_this.reset();
};
return _this;
}
ErrorBoundary2.getDerivedStateFromError = function getDerivedStateFromError(error) {
return {
error
};
};
var _proto = ErrorBoundary2.prototype;
_proto.reset = function reset() {
this.setState(initialState);
};
_proto.componentDidCatch = function componentDidCatch(error, info) {
var _this$props$onError, _this$props2;
(_this$props$onError = (_this$props2 = this.props).onError) == null ? void 0 : _this$props$onError.call(_this$props2, error, info);
};
_proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
var error = this.state.error;
var resetKeys = this.props.resetKeys;
if (error !== null && prevState.error !== null && changedArray(prevProps.resetKeys, resetKeys)) {
var _this$props$onResetKe, _this$props3;
(_this$props$onResetKe = (_this$props3 = this.props).onResetKeysChange) == null ? void 0 : _this$props$onResetKe.call(_this$props3, prevProps.resetKeys, resetKeys);
this.reset();
}
};
_proto.render = function render() {
var error = this.state.error;
var _this$props4 = this.props, fallbackRender = _this$props4.fallbackRender, FallbackComponent = _this$props4.FallbackComponent, fallback = _this$props4.fallback;
if (error !== null) {
var _props = {
error,
resetErrorBoundary: this.resetErrorBoundary
};
if (/* @__PURE__ */ React__namespace.isValidElement(fallback)) {
return fallback;
} else if (typeof fallbackRender === "function") {
return fallbackRender(_props);
} else if (FallbackComponent) {
return /* @__PURE__ */ React__namespace.createElement(FallbackComponent, _props);
} else {
throw new Error("react-error-boundary requires either a fallback, fallbackRender, or FallbackComponent prop");
}
}
return this.props.children;
};
return ErrorBoundary2;
}(React__namespace.Component);
var OneDsErrorBoundary = ({
children,
widget,
fallbackComponent,
onError,
onRender
}) => {
const logger = getShellLogger();
React.useEffect(() => {
if (onRender) {
onRender();
}
}, [onRender]);
React.useEffect(() => {
logger.log({
message: `[1FE Shell] Rendering widget `,
widget
});
}, [widget]);
const handleError = (error, info) => {
if (onError) {
onError(error, info);
} else {
logger.error({
message: widget ? `[1FE-Shell] Failure with the following:
${widget?.plugin?.route}
${widget.widgetId}
${widget.version}` : `[1FE-Shell] An error has occured.`,
error,
info,
widget
});
}
};
return (
// DRAGON! ErrorBoundaries need a fallback.
// On a widget level we don't want to show a fallback
// unless the parent Widget renders the fallback. This is because we want the error to bubble up
// to the parent Widget so that it can decide what to do with the error.
//
// We have to find a better approach for this.
/* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { onError: handleError, fallback: fallbackComponent, children })
);
};
var GenericError = (errorProps) => {
const { type = "error", plugin, message } = errorProps || {};
React.useEffect(() => {
const shellLogger = getShellLogger();
shellLogger.log({
message: "[1FE-Shell] error page rendered",
errorComponent: {
type,
plugin,
message
}
});
}, []);
const ErrorPageData = {
error: {
titleText: "An error has occurred",
subText: "Make sure your connection is stable and try again",
buttonText: "Try Again"
},
notFound: {
titleText: "Looks like this page is not here",
subText: "Check your URL, or go back",
buttonText: "Go Back"
}
};
const mainText = message ?? ErrorPageData[type].titleText;
const subText = ErrorPageData[type].subText;
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx("h1", { children: mainText }),
/* @__PURE__ */ jsxRuntime.jsx("p", { children: subText })
] });
};
var getGenericError = (genericErrorProps) => {
return /* @__PURE__ */ jsxRuntime.jsx(GenericError, { ...genericErrorProps });
};
var RouteWrapper = ({
children,
plugin
}) => {
const location = reactRouterDom.useLocation();
const logger = getShellLogger();
const previousPathRef = React.useRef(location?.pathname);
React.useEffect(() => {
window.dispatchEvent(
new CustomEvent(SHELL_NAVIGATED_EVENT, {
detail: location
})
);
logger.log({
message: `[1FE-Shell] Route changed`,
path: location?.pathname,
from: previousPathRef.current,
widgetId: plugin?.widgetId
});
previousPathRef.current = location?.pathname;
}, [location]);
const handleError = (error, info) => {
logger.error({
message: `[1FE-Shell] Unhandled Route Failure`,
error,
info,
location
});
};
const IS_PROD = ENVIRONMENT_CONFIG.isProduction;
const getError = readOneFEShellConfigs()?.components?.getError || getGenericError;
if (!IS_PROD) {
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
}
return /* @__PURE__ */ jsxRuntime.jsx(
OneDsErrorBoundary,
{
fallbackComponent: getError({
plugin
}),
onError: handleError,
children
}
);
};
// src/shell/utils/url.ts
var templatizeCDNUrl = ({
widgetId,
widgetVersion,
templateFilePath = "js/1fe-bundle.js"
}) => {
return new URL(
`${DYNAMIC_CONFIGS.widgets.basePrefix}${widgetId}/${widgetVersion}/${templateFilePath}`
);
};
var generateCDNUrl = (widget) => {
return templatizeCDNUrl({
widgetId: widget.widgetId,
widgetVersion: widget.version
});
};
var getBaseHrefUrl = (doc = document) => {
const baseHref = doc?.querySelector("base")?.getAttribute("href");
if (!baseHref) {
const error = "missing href attribute on base html element";
throw new Error(error);
}
return baseHref;
};
var basePathname = () => new URL(getBaseHrefUrl()).pathname;
var getWidgetBundleCdnUrl = ({
widgetId,
version
}) => {
const widgetBundlePath = "/js/1fe-bundle.js";
const baseUrl = `${DYNAMIC_CONFIGS.widgets.basePrefix}/${widgetId}/${version}`;
return new URL(`${baseUrl}${widgetBundlePath}`);
};
// src/shell/constants/shell.ts
var getShellWidgetId = () => "@1fe/shell";
// ../1fe-server/src/server/constants/index.ts
var PINNED_WIDGET_TYPE = "pinned";
// ../1fe-server/src/server/utils/widget-config-helpers.ts
var isWidgetTypePinned = (widgetType) => widgetType === PINNED_WIDGET_TYPE;
var getPinnedWidgets = (widgetConfig) => {
return widgetConfig?.runtime?.dependsOn?.pinnedWidgets || [];
};
var getRequestedWidgetConfigWithoutRuntimeConfig = ({
hostWidgetId,
requestedWidgetId,
widgetConfigs
}) => {
const hostWidgetConfig = widgetConfigs.get(hostWidgetId);
const requestedWidgetConfig = widgetConfigs.get(requestedWidgetId);
if (!requestedWidgetConfig) {
console.error(
"[1FE][platformProps.utils.widgets.get] Unable to find requested widget config in the global WIDGET_CONFIGS map. Returning empty object.",
{
hostWidgetId,
requestedWidgetId
}
);
return { requestedWidgetConfig: {} };
}
const requestedWidgetPinnedConfig = getPinnedWidgets(hostWidgetConfig).find(
(pinnedWidget) => pinnedWidget.widgetId === requestedWidgetId
);
if (requestedWidgetPinnedConfig) {
if (!isWidgetTypePinned(requestedWidgetConfig.type)) {
console.warn(
"[platformProps.utils.widgets.get][PINNED_WIDGETS] Requested pinned widget is not a pinned widget. The 1fe shell will request the current version instead."
);
return { requestedWidgetConfig };
}
return {
requestedWidgetConfig: {
...requestedWidgetConfig,
version: requestedWidgetPinnedConfig.version
},
type: PINNED_WIDGET_TYPE
};
}
return { requestedWidgetConfig };
};
// src/shell/constants/widgets.ts
var PINNED_WIDGET_TYPE2 = "pinned";
var SYSTEM_WIDGET_TYPE = "system";
var WIDGET_MODULE_KEYS = {
/**
* this key indicates that the widget has variants. It is always going to be `true` for now.
*/
hasVariants: "__hasVariants",
/**
* The key that holds the function that returns the widget.
*/
getWidget: "__getWidget",
/**
* The key that holds the function that returns the variant.
*/
getVariant: "__getVariant"
};
// src/shell/utils/widget-type.ts
var isWidgetTypeSystem = (widgetType) => widgetType === SYSTEM_WIDGET_TYPE;
var isWidgetTypePinned2 = (widgetType) => widgetType === PINNED_WIDGET_TYPE2;
var isShellWidget = (widgetId) => widgetId === getShellWidgetId();
// src/shell/utils/dom-helpers.ts
var injectPreloadTags = (preloadUrls = [], as = "script") => {
return preloadUrls.forEach((url) => {
const link = document.createElement("link");
link.href = url;
link.setAttribute("as", as);
link.setAttribute("rel", "preload");
link.setAttribute("crossorigin", "");
document.body.appendChild(link);
});
};
// src/shell/platformProps/utils/widgets/internal/utils/widgetConfigUtils.ts
var queueWidgetPreloadsIfFound = (hostWidget, requestedWidgetConfig) => {
if (isShellWidget(hostWidget.widgetId)) {
return;
}
const preloadArr = requestedWidgetConfig.runtime?.preload || [];
const preloadWidgetArr = preloadArr.map((preload) => preload.widget).filter((e) => e);
const preloadAPIGetArr = preloadArr.map((preload) => preload.apiGet).filter((e) => e);
const widgetURLsToPreload = preloadWidgetArr?.reduce(
(itr, preloadedWidgetId) => {
const preloadedWidgetConfig = WIDGET_CONFIGS.get(preloadedWidgetId);
if (!preloadedWidgetConfig) {
return itr;
}
const { requestedWidgetConfig: widgetConfigPreloadedByRequestedWidget } = getRequestedWidgetConfigWithoutRuntimeConfig({
hostWidgetId: requestedWidgetConfig.widgetId,
requestedWidgetId: preloadedWidgetConfig.widgetId,
widgetConfigs: WIDGET_CONFIGS
});
const requestedWidgetConfigBundleCdnUrl = getWidgetBundleCdnUrl({
widgetId: widgetConfigPreloadedByRequestedWidget.widgetId,
version: widgetConfigPreloadedByRequestedWidget.version
});
return [...itr, requestedWidgetConfigBundleCdnUrl];
},
[]
);
if (widgetURLsToPreload.length) {
injectPreloadTags(
widgetURLsToPreload.map((url) => url.toString()),
"script"
);
}
if (preloadAPIGetArr.length) {
injectPreloadTags(preloadAPIGetArr, "fetch");
}
};
var getRequestedWidgetVersionForConsole = (hostWidgetId, widgetRequest) => {
if (!widgetRequest) {
return "widgetRequest undefined";
}
if (!("version" in widgetRequest)) {
return widgetRequest;
}
const { type } = getRequestedWidgetConfigWithoutRuntimeConfig({
hostWidgetId,
requestedWidgetId: widgetRequest.widgetId,
widgetConfigs: WIDGET_CONFIGS
});
const version = isWidgetTypePinned2(type) ? `${widgetRequest.version} (pinned)` : widgetRequest.version;
const importMapOverrides = window.importMapOverrides?.getOverrideMap()?.imports || {};
return importMapOverrides[widgetRequest.widgetId] ? "overridden" : version;
};
var getGenericLoader = () => /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Loading..." });
// src/shell/platformProps/utils/widgets/internal/utils/constants.tsx
var getDefaultWidgetOptions = () => {
const getLoader = readOneFEShellConfigs()?.components?.getLoader || getGenericLoader;
return {
variantId: "default",
Loader: getLoader()
};
};
// src/shell/platformProps/utils/logPlatformUtilUsage.ts
var logPlatformUtilUsage = ({
widgetId,
utilNamespace,
functionName,
success,
args,
attributes,
topLevelAttributes
}) => {
const shouldLogPlatformUtilUsage = readOneFEShellConfigs()?.shellLogger?.logPlatformUtilUsage || false;
if (shouldLogPlatformUtilUsage) {
getShellLogger().log({
message: `utils.${utilNamespace}.${functionName} called`,
category: `utils.${utilNamespace}.${functionName}`,
widgetId,
metaData: {
success,
arguments: { ...args },
...attributes
},
...topLevelAttributes
});
}
};
// src/shell/constants/event-bus.ts
var ONE_FE_SHELL_ID = "1FE_SHELL";
// src/shell/utils/tree.ts
var getNodeId = () => {
const random = crypto.getRandomValues(new Uint32Array(1))[0];
return `node-${random}`;
};
var TreeNode = class {
constructor(key, type, data) {
this.key = key;
this.id = getNodeId();
this.type = type;
this.parents = /* @__PURE__ */ new Set();
this.children = /* @__PURE__ */ new Set();
this._data = data;
}
_data;
id;
type;
parents;
children;
get data() {
return this._data;
}
update(data) {
this._data = data;
}
addChild(child) {
this.children.add(child.id);
child.parents.add(this.id);
}
addParent(parent) {
this.parents.add(parent.id);
parent.children.add(this.id);
}
removeChild(child) {
this.children.delete(child.id);
child.parents.delete(this.id);
}
removeParent(parent) {
this.parents.delete(parent.id);
parent.children.delete(this.id);
}
};
var Tree = class {
/**
* Tracks all memory references to {@link TreeNode}s.
*/
_refs;
/**
* Tracks all {@link TreeNode}s by their key.
*/
keyMap;
/**
* An empty node that serves as the root of the tree.
*/
root;
constructor() {
this._refs = /* @__PURE__ */ new Map();
this.keyMap = /* @__PURE__ */ new Map();
this.root = new TreeNode("#", "1FE_SHELL", {});
}
get refs() {
return this._refs;
}
/**
* Given a key, returns the {@link TreeNode} associated with it.
* NOTE: There's no getById since the id is opaque.
*/
getByKey(key) {
if (!key) {
return;
}
const id = this.keyMap.get(key);
if (id) {
return this.refs.get(id);
}
}
getById(id) {
return this.refs.get(id);
}
/**
* Adds a new node to the tree.
*/
add(key, data, nodeType, parent = this.root) {
let node = this.getByKey(key);
if (!node) {
node = new TreeNode(key, nodeType, data);
this.refs.set(node.id, node);
this.keyMap.set(key, node.id);
} else {
node.update(data);
}
if (parent) {
parent.addChild(node);
}
return node;
}
/**
* Removes a node from the tree.
*/
remove(key) {
const node = this.getByKey(key);
if (!node) {
return;
}
for (const child of node.children) {
this.refs.get(child)?.removeParent(node);
}
for (const parent of node.parents) {
this.refs.get(parent)?.removeChild(node);
}
this.refs.delete(node.id);
this.keyMap.delete(key);
}
/**
* Returns an iterator over all nodes in the tree. The iterator
* will yield the nodes in depth-first order.
*/
*[Symbol.iterator]() {
yield* this.dfs();
}
/**
* Returns an iterator over all nodes in the tree. The iterator
* will yield the nodes in depth-first order. The iterator can be started
* at any node in the tree by passing in the key of the node to start at.
*/
*dfs(key = "") {
const node = this.getByKey(key) ?? this.root;
const visited = /* @__PURE__ */ new Set();
const stack = [node];
while (stack.length) {
const top = stack.pop();
if (!top) {
return;
}
if (visited.has(top.id)) {
continue;
}
visited.add(top.id);
if (top !== this.root) {
yield [top.key, top.data];
}
top.children.forEach((id) => {
const child = this.refs.get(id);
if (child) {
stack.push(child);
}
});
}
}
};
var widgetDependencyTree = new Tree();
var widgetContextDependencyTree = new Tree();
// src/shell/platformProps/context/getWidgetPath/index.ts
var getWidgetPath = (widgetId) => {
const path = [];
let current = widgetDependencyTree.getByKey(widgetId);
while (current != null) {
path.push(current.data.widgetId);
const parentNodeId = current.parents.keys().next().value;
current = widgetDependencyTree.getById(parentNodeId);
}
return [...path, ONE_FE_SHELL_ID];
};
// src/shell/platformProps/utils/widgets/internal/utils/getComponentFromModule.ts
async function getComponentFromModule({
options: {
variantId = getDefaultWidgetOptions().variantId
} = getDefaultWidgetOptions(),
module,
log
}) {
const isVariantWidget = module.default?.[WIDGET_MODULE_KEYS.hasVariants];
const isRequestingDefaultVariant = variantId === getDefaultWidgetOptions().variantId;
const logSuccessfulGet = ({
isVariantWidget: isVariantWidget2,
variantId: variantId2,
isRequestingDefaultVariant: isRequestingDefaultVariant2
} = {}) => log("[UTILS_API][WIDGETS] successful widgets.get call", {
...isVariantWidget2 && { isVariantWidget: isVariantWidget2 },
...variantId2 && { variantId: variantId2 },
...isRequestingDefaultVariant2 && { isRequestingDefaultVariant: isRequestingDefaultVariant2 }
});
if (isVariantWidget) {
if (isRequestingDefaultVariant) {
logSuccessfulGet({
isVariantWidget,
isRequestingDefaultVariant,
variantId
});
return module.default[WIDGET_MODULE_KEYS.getWidget]();
} else {
logSuccessfulGet({ isVariantWidget, variantId });
return module.default[WIDGET_MODULE_KEYS.getVariant](variantId);
}
}
logSuccessfulGet();
return module;
}
// src/shell/platformProps/utils/widgets/internal/utils/isSystem.ts
var isSystemEnv = () => typeof window !== "undefined" && typeof System !== "undefined";
// src/shell/constants/search-params.ts
var STATE = "state";
var WIDGET_URL_OVERRIDES = "widget_url_overrides";
var RUNTIME_CONFIG_OVERRIDES = "runtime_config_overrides";
var parseRuntimeConfig = ({
runtimeConfig,
widgetConfig
}) => {
const parsedRuntimeConfig = { ...runtimeConfig };
if (parsedRuntimeConfig?.preload) {
const parsedPreloads = parsedRuntimeConfig.preload.map((preloadObj) => {
if ("apiGet" in preloadObj) {
const templatizedApiGetUrl = lodash.template(preloadObj.apiGet);
return {
apiGet: templatizedApiGetUrl({
WIDGET_VERSION: widgetConfig.version,
WIDGET_ID: widgetConfig.widgetId,
// If 1fe-app is running locally, the environment is development.
// There is no cdn for development, so we use integration instead.
// TODO[post-mvp][1fe]: How do we consume this back in 1fe if development has it's own cdn?
ENVIRONMENT: ENVIRONMENT_CONFIG.environment
})
};
}
return preloadObj;
});
parsedRuntimeConfig.preload = parsedPreloads;
}
return parsedRuntimeConfig;
};
// src/shell/utils/runtime-configs.ts
var clearRuntimeConfigOverrides = () => {
const url = new URL(window.location.href);
url.searchParams.delete(RUNTIME_CONFIG_OVERRIDES);
window.location.href = url.toString();
};
var getParsedRuntimeConfigOverrides = () => {
try {
const param = new URL(window.location.href).searchParams.get(
RUNTIME_CONFIG_OVERRIDES
);
return param ? JSON.parse(param) : {};
} catch (e) {
console.error(
`[1FE][RUNTIME_CONFIG_OVERRIDES] Unable to parse JSON in ${RUNTIME_CONFIG_OVERRIDES} param`
);
return {};
}
};
var overrideWidgetConfigRuntime = (widgetId, runtimeConfig) => {
const widgetConfig = WIDGET_CONFIGS.get(widgetId);
if (!widgetConfig) {
console.warn(
"[1FE][overrideWidgetConfigRuntime] The key for you import map override does not exist in the global WIDGET_CONFIGS map. This could be because of a typo in a widgetId or because you are overriding a library."
);
return;
}
WIDGET_CONFIGS.set(widgetId, {
...widgetConfig,
runtime: parseRuntimeConfig({
runtimeConfig,
widgetConfig
})
});
};
var widgetRuntimeConfigUrlFilename = "widget-runtime-config.json";
var getRuntimeConfigUrlFromBundleUrl = (bundleUrl) => bundleUrl.replace("js/1fe-bundle.js", widgetRuntimeConfigUrlFilename);
// src/shell/init/import-map-ui.ts
var isOverrideActive = (element) => {
const isActiveImportMapOverride = element.classList?.value.includes(
"imo-current-override"
);
return isActiveImportMapOverride || !lodash.isEmpty(getParsedRuntimeConfigOverrides());
};
var selectImportMapOverrideUi = () => document.querySelector("import-map-overrides-full")?.shadowRoot;
var getImportMapOverridesButton = () => document?.getElementsByTagName("import-map-overrides-full")[0]?.shadowRoot?.querySelector("button");
var isOverrideElementActive = () => {
const element = getImportMapOverridesButton();
if (!element) {
return false;
}
return isOverrideActive(element);
};
var animateImportMapButtonIfOverrides = () => {
const colors = ["red", "salmon"];
let colorIndex = 0;
let animationInterval = null;
let scale = 1;
setInterval(() => {
const element = document?.getElementsByTagName("import-map-overrides-full")[0]?.shadowRoot?.querySelector("button");
if (!element) {
return;
}
const isActiveOverride = isOverrideActive(element);
if (isActiveOverride && !animationInterval) {
const animationSpeed = "0.75s";
element.style.transition = `background-color ${animationSpeed}, transform ${animationSpeed}`;
const tooltip = document.createElement("span");
tooltip.id = "activeImportMapTooltip";
tooltip.textContent = "You have active overrides";
Object.assign(tooltip.style, {
display: "none",
position: "absolute",
bottom: "75px",
right: "10px",
padding: "10px",
width: "auto",
fontSize: "16",
backgroundColor: "#F0EAD6",
color: "black",
borderRadius: "5px"
});
document.body.appendChild(tooltip);
element.addEventListener("mouseover", () => {
tooltip.style.display = "block";
});
element.addEventListener("mouseout", () => {
tooltip.style.display = "none";
});
animationInterval = window.setInterval(() => {
element.style.backgroundColor = colors[colorIndex];
colorIndex = (colorIndex + 1) % colors.length;
scale = scale == 1 ? 1.25 : 1;
element.style.transform = `scale(${scale})`;
}, 750);
} else if (!isActiveOverride && animationInterval) {
clearInterval(animationInterval);
animationInterval = null;
element.style.transition = "";
element.style.backgroundColor = "navajowhite";
element.style.transform = "scale(1)";
const tooltip = document.getElementById("activeImportMapTooltip");
if (tooltip) {
document.body.removeChild(tooltip);
}
}
}, 100);
};
var copyImportMapOverridesButton = (textContent, onClick, applyCustomStyling = (button) => button) => {
const importMapOverrides = document?.getElementsByTagName("import-map-overrides-full")[0]?.shadowRoot?.querySelector(".imo-table-header-actions");
if (!importMapOverrides) {
return;
}
const divElement = document.createElement("div");
divElement.className = "imo-add-new";
const copyButton = document.createElement("button");
copyButton.textContent = textContent;
copyButton.addEventListener("click", onClick);
applyCustomStyling(copyButton);
divElement.appendChild(copyButton);
importMapOverrides?.appendChild(divElement);
};
var deleteImportMapOverridesButton = () => {
const element = getImportMapOverridesButton();
if (element) {
element.remove();
}
};
var initializeImportMapOverridesReskin = () => {
const IS_PROD = ENVIRONMENT_CONFIG.isProduction;
const enableUI = DYNAMIC_CONFIGS?.devtools?.importMapOverrides?.enableUI || true;
if (IS_PROD || enableUI === false) {
deleteImportMapOverridesButton();
return;
}
animateImportMapButtonIfOverrides();
const overrideShadowRoot = selectImportMapOverrideUi();
if (!overrideShadowRoot) {
return;
}
const shadowRootCss = new CSSStyleSheet();
shadowRootCss.replaceSync(`
.imo-popup { color: #343434; background: rgb(255, 255, 255); font-family: "DS Indigo", DSIndigo, Helvetica, Arial, sans-serif; border-top: 4px solid rgb(38, 70, 83); }
.imo-header a {color: rgb(42, 157, 143);}
.imo-table-header-actions { padding: 2rem; border: 2px dashed rgb(42, 157, 143); display: flex; }
.imo-list-search { flex-grow: 1; height: 35px;
box-sizing: border-box;
font-family: inherit;
font-size: 14px;
letter-spacing: .16px;
border-radius: 0;
outline: 2px solid transparent;
outline-offset: -2px;
border: none;
border-bottom: 1px solid #8d8d8d;
background-color: #f4f4f4;
padding: 0 16px;
color: #161616;
}
.imo-list-container button { height: 35px; }
.imo-add-new button { cursor: pointer; border-radius: 8px; border: 1px solid #666; background: #f2f2f2; color: #232323; }
.imo-header .imo-unstyled { color: black; }
.imo-overrides-table thead { background: #e9edc9; }
.imo-overrides-table { width: 100%; background: rgb(254, 250, 224); }
.imo-overrides-table td, .imo-overrides-table th { border: 1px solid #7b7b7b; }
.imo-overrides-table tbody tr:hover { background: #dddddd; }
.imo-default-module { background-color: #dddddd; }
.imo-popup a:visited, .imo-popup a { color: rgb(42, 157, 143); }
`);
overrideShadowRoot.adoptedStyleSheets.push(shadowRootCss);
const documentCss = new CSSStyleSheet();
documentCss.replaceSync(`
.imo-module-dialog { border: white; }
.imo-modal-container * { font-family: "DS Indigo", DSIndigo, Helvetica, Arial, sans-serif; }
.imo-module-dialog.imo-overridden { }
.imo-dialog-actions button { cursor: pointer; border-radius: 8px; border: 1px solid #666; background: #f2f2f2; color: #232323; height: 35px; }
.imo-module-dialog table td:first-child { font-weight: bold; }
.imo-module-dialog h3 { padding-bottom: 0.5rem; border-bottom: 1px solid #ddd; }
.imo-dialog-actions { display: flex; align-items: center; justify-content: center; }
`);
document.adoptedStyleSheets.push(documentCss);
overrideShadowRoot?.querySelector("button.imo-trigger")?.addEventListener("click", () => {
if (overrideShadowRoot?.querySelector(".imo-header h1")) {
overrideShadowRoot.querySelector(".imo-header h1").innerHTML = "1FE Widget Overrides";
overrideShadowRoot.querySelector(".imo-header p a").href = "https://github.docusignhq.com/pages/Core/1fe-docs/widgets/development/overrides/";
}
copyImportMapOverridesButton("Copy overrides", () => {
const copyLink = new URL(window.location.href);
copyLink.searchParams.set(
WIDGET_URL_OVERRIDES,
JSON.stringify(window.importMapOverrides.getOverrideMap().imports)
);
const textArea = document.createElement("textarea");
textArea.value = copyLink.toString();
document.body.appendChild(textArea);
textArea.select();
document.execCommand("copy");
document.body.removeChild(textArea);
});
if (!lodash.isEmpty(getParsedRuntimeConfigOverrides())) {
copyImportMapOverridesButton(
"Clear runtime config overrides",
clearRuntimeConfigOverrides,
// animate the button to glow on an interval
(button) => {
let colorIndex = 0;
let animationInterval = null;
if (!animationInterval) {
const colors = ["red", "salmon"];
const animationSpeed = "0.75s";
button.style.transition = `background-color ${animationSpeed}`;
animationInterval = window.setInterval(() => {
button.style.backgroundColor = colors[colorIndex];
colorIndex = (colorIndex + 1) % colors.length;
}, 750);
} else if (animationInterval) {
clearInterval(animationInterval);
animationInterval = null;
button.style.backgroundColor = "navajowhite";
}
}
);
}
});
};
// src/shell/platformProps/utils/widgets/internal/system/get.ts
var get = (_System, hostWidgetId) => async (requestedWidgetId, {
variantId = getDefaultWidgetOptions().variantId
} = getDefaultWidgetOptions()) => {
const logger = getShellLogger();
const options = { variantId };
const widgetLogInfo = {
hostWidget: {
widgetId: hostWidgetId
},
requestedWidget: {
widgetId: requestedWidgetId,
widgetPath: getWidgetPath(requestedWidgetId)
}
};
const getComponentFromModule2 = async (widgetId) => getComponentFromModule({
options,
module: await _System.import(widgetId),
log(message, otherData = {}) {
logger.log({
...otherData,
message,
category: "utils.widgets.get",
widgetId: requestedWidgetId,
isOverrideActive: isOverrideElementActive(),
...widgetLogInfo
});
}
});
if (!requestedWidgetId) {
const errorMessage = "[platformProps.utils.widgets.get] No widget ID provided, please refer to API documentation: https://github.docusignhq.com/pages/Core/1fe-docs/widgets/utils/widgets/#get";
console.error(errorMessage);
throw new Error(errorMessage);
}
if (!isSystemEnv()) {
const errorMessage = "[platformProps.utils.widgets.get] Systemjs not detected. Something is critically wrong. Please reach out to 1FE team.";
console.error(errorMessage);
throw new Error(errorMessage);
}
try {
const { requestedWidgetConfig, type } = getRequestedWidgetConfigWithoutRuntimeConfig({
hostWidgetId,
requestedWidgetId,
widgetConfigs: WIDGET_CONFIGS
});
const isPinnedWidget = isWidgetTypePinned2(type);
logPlatformUtilUsage({
utilNamespace: "widgets",
functionName: "get",
widgetId: hostWidgetId,
args: { requestedWidgetId, isPinnedWidget, options },
attributes: { isSystemEnv }
});
const importMapOverrides = window.importMapOverrides?.getOverrideMap() || {};
const doesPinnedWidgetOverrideExist = !!importMapOverrides.imports?.[requestedWidgetId];
if (!!requestedWidgetConfig && isPinnedWidget && !doesPinnedWidgetOverrideExist) {
const requestedPinnedWidgetConfigBundleCdnUrl = getWidgetBundleCdnUrl({
widgetId: requestedWidgetId,
version: requestedWidgetConfig.version
});
return getComponentFromModule2(
requestedPinnedWidgetConfigBundleCdnUrl.toString()
);
}
return getComponentFromModule2(requestedWidgetId);
} catch (error) {
const message = `[platformProps.utils.widgets.get] Getting widget by ID failed.`;
console.error(message, error, widgetLogInfo);
logger.error({
error,
message,
...widgetLogInfo,
category: "utils.widgets.get",
isOverrideActive: isOverrideElementActive(),
widgetId: requestedWidgetId
});
throw new Error(message);
}
};
var getByUrl = (_System, hostWidgetId) => async (url, {
variantId = getDefaultWidgetOptions().variantId
} = getDefaultWidgetOptions()) => {
const logger = getShellLogger();
const options = { variantId };
logPlatformUtilUsage({
utilNamespace: "widgets",
functionName: "getByUrl",
widgetId: hostWidgetId,
args: { url, options },
attributes: { isSystemEnv }
});
if (url && isSystemEnv()) {
const urlAsAString = url.toString();
try {
const module = await _System.import(urlAsAString);
return getComponentFromModule({
options,
module,
log(message) {
logger.log({
message,
url: urlAsAString,
category: "utils.widgets.getByUrl",
widgetId: hostWidgetId
});
}
});
} catch (error) {
const message = "[UTILS_API][WIDGETS] Getting widget by URL failed.";
console.error(message, error, urlAsAString, options);
logger.error({
error,
message,
url: urlAsAString,
category: "utils.widgets.getByUrl",
widgetId: hostWidgetId
});
throw new Error(message);
}
}
console.warn(
"[UTILS_API] (widgets.getByUrl) Incorrect usage of API, please refer to API documentation."
);
throw new Error("Improper usage of widgets.getByUrl() or bad environment.");
};
var getAsset = (_System, hostWidgetId) => async (widgetId, path) => {
const logger = getShellLogger();
logPlatformUtilUsage({
utilNamespace: "widgets",
functionName: "getAsset",
widgetId: hostWidgetId,
args: { widgetId, path },
attributes: { isSystemEnv }
});
if (widgetId && isSystemEnv()) {
try {
const oneDsBundleUrl = await (window.importMapOverrides ? window.importMapOverrides.getCurrentPageMap().then(
(importMap) => importMap.imports[widgetId]
) : _System.resolve(widgetId));
const cdnBaseUrl = oneDsBundleUrl.replace(/js\/1fe-bundle\.js$/, "");
return await _System.import(`${cdnBaseUrl}${path}`);
} catch (error) {
const message = `[UTILS_API][WIDGETS] Getting widget asset by ID failed.`;
console.error(message, error, widgetId, path);
logger.error({
error,
message,
path,
category: "utils.widgets.getAsset",
widgetId
});
throw new Error(message);
}
}
console.warn(
"[UTILS_API] (widgets.get) Incorrect usage of API, please refer to API documentation."
);
throw new Error("Improper usage of widgets.getAsset() or bad environment.");
};
// src/shell/platformProps/utils/widgets/internal/system/index.ts
var widgets = ({ system, hostWidgetId }) => ({
get: get(system, hostWidgetId),
getByUrl: getByUrl(system, hostWidgetId),
getAsset: getAsset(system, hostWidgetId)
});
// src/shell/platformProps/utils/widgets/internal/WidgetFrame/is-url.ts
function isUrl(widgetRequest) {
return widgetRequest instanceof URL;
}
// src/shell/platformProps/utils/widgets/internal/WidgetFrame/downloadWidget.ts
async function downloadWidget(widgetId, setWidgetRenderStatus, options) {
const {
requestedWidgetConfigOrUrl,
hostWidgetId,
// hostProps,
widgetOptions,
widgetFrameId
} = options;
const widgetsInstance = widgets({
hostWidgetId,
system: System
});
const logger = getShellLogger();
const isWidgetOverriden = isOverrideElementActive();
const IS_PROD = ENVIRONMENT_CONFIG.isProduction;
const widgetLoadTime = getShellPlatformUtils().appLoadTime;
const logDownloadWidgetError = (message, error) => {
logger.error({
message,
parsedWidget: widgetId,
error,
widget: isUrl(widgetId) ? { widgetId: widgetId.toString(), version: "0.0.0" } : requestedWidgetConfigOrUrl,
url: isUrl(widgetId) ? widgetId.toString() : void 0,
isOverrideActive: isWidgetOverriden,
widgetId: widgetId || widgetFrameId
});
};
try {
widgetLoadTime.markStart(widgetId.toString());
widgetLoadTime.markStart(`${widgetId}-download`);
const getModule = isUrl(widgetId) ? () => widgetsInstance.getByUrl(widgetId, widgetOptions) : () => widgetsInstance.get(widgetId, widgetOptions);
const module = await getModule();
widgetLoadTime.markEnd(`${widgetId}-download`, {
detail: {
status: "success"
}
});
logger.log({
message: `[1FE-Shell] Widget loaded`,
widget: isUrl(widgetId) ? { widgetId: widgetId.toString(), version: "0.0.0" } : requestedWidgetConfigOrUrl,
url: isUrl(widgetId) ? widgetId.toString() : void 0,
isOverrideActive: isWidgetOverriden,
widgetId: widgetId || widgetFrameId
});
if (!isWidgetOverriden) {
}
if (module.default == null || typeof module.default !== "function") {
throw new Error(`Widget ${widgetId} has no default export`);
}
setWidgetRenderStatus("rendered");
return module;
} catch (error) {
widgetLoadTime.markEnd(`${widgetId}-download`, {
detail: {
status: "failure"
}
});
widgetLoadTime.markEnd(widgetId.toString(), {
detail: { status: "failure" }
});
logDownloadWidgetError(`[1FE-Shell] Widget download failed`, error);
setWidgetRenderStatus("error");
let errorMessage = `Failed to load widget: ${widgetId}`;
if (!IS_PROD) {
if (error instanceof Error) {
errorMessage += ` ErrorMessage: ${error.message}, ErrorStack: ${error.stack}`;
} else {
errorMessage += ` ErrorMessage: ${String(error)}`;
}
}
throw new Error(errorMessage);
}
}
// src/shell/constants/platform-props.ts
var ONEDS_SHELL_IMPORT_MAP_ID = "app:@1fe/shell";
// src/shell/platformProps/context/getHostWidget/index.ts
var getHostWidget = (widget) => {
const immediateHostWidgetNodeId = widgetDependencyTree.getByKey(widget.widgetId)?.parents.keys().next().value;
if (!immediateHostWidgetNodeId) {
return null;
}
const node = widgetDependencyTree.getById(immediateHostWidgetNodeId);
if (!node) {
return null;
}
return {
id: node.key,
data: node.data
};
};
// src/shell/platformProps/context/index.ts
var getContext = (widget, options = getDefaultWidgetOptions()) => {
return {
self: {
widgetId: widget.widgetId,
version: widget.version,
variantId: options.variantId
},
getHost: () => getHostWidget(widget)
// The following methods are intentionally disabled for now
// context: https://docusign.slack.com/archives/C04CZ0F69CJ/p1709672412983809
// getTree,
// yggdrasil: getTree,
// getPlugin,
};
};
// src/shell/platformProps/index.ts
var getPlatformProps = (widget, options = getDefaultWidgetOptions()) => {
const platformProps2 = {
environment: ENVIRONMENT_CONFIG.environment,
context: getContext(widget, options),
utils: getPlatformUtils(widget)
};
return deepFreeze__default.default(platformProps2);
};
// src/shell/utils/widget-url-overrides.ts
var getParsedWidgetUrlOverrides = () => {
try {
const param = new URL(window.location.href).searchParams.get(
WIDGET_URL_OVERRIDES
);
return param ? JSON.parse(param) : {};
} catch (e) {
console.error(
`[1FE][RUNTIME_CONFIG_OVERRIDES] Unable to parse JSON in ${WIDGET_URL_OVERRIDES} param`
);
return {};
}
};
var isAllowedSource = (source, allowedSources) => {
try {
const sourceUrl = new URL(source);
return allowedSources.includes(sourceUrl.hostname);
} catch {
}
return false;
};
// src/shell/utils/system-helpers.ts
var CONTEXT_IMPORT_NAME = "1feContext";
var INTERNAL_CONTEXT_REF = Symbol("1feContext");
var hackyWidgetIdDetermination = (url) => {
if (!isAllowedSource(
url,
DYNAMIC_CONFIGS?.devtools?.importMapOverrides.allowedSources
)) {
return;
}
const template2 = /1ds\/widgets\/(.*?)\/js\/1ds-bundle.js/i;
const match = url.match(template2);
if (!match || match.length < 2) {
return;
}
const mayBeWidgetName = match[1];
const parts = mayBeWidgetName.split("/");
if (parts.length < 3) {
return;
}
const [org, widgetName, version] = parts;
const widgetId = `${org}/${widgetName}`;
const mayBeWidget = WIDGET_CONFIGS.get(widgetId);
if (!mayBeWidget) {
return;
}
console.log(
`[1DS-Context] Best case effort for pinned widget:${widgetId}, version:${version} from url ${url}`
);
return {
...mayBeWidget,
version
};
};
var addScopedImportMapForPlatformProps = (widgetId, platformProps2) => {
const scopedPlatformPropsIdentifier = `${ONEDS_SHELL_IMPORT_MAP_ID}::${widgetId}`;
System.set(scopedPlatformPropsIdentifier, {
__esModule: true,
platformProps: platformProps2
});
};
var injectScopedWidgetContext = (requestedBy) => {
let platformProps2;
const existingContext = Object.getOwnPropertyDescriptor(
requestedBy,
INTERNAL_CONTEXT_REF
);
if (existingContext?.value) {
platformProps2 = existingContext.value;
} else {
platformProps2 = getPlatformProps(requestedBy.data);
Object.defineProperty(requestedBy, INTERNAL_CONTEXT_REF, {
value: platformProps2
});
}
const scopeId = `oneds://${requestedBy.data.widgetId}/${requestedBy.id}`;
System.set(scopeId, {
__esModule: true,
platformProps: platformProps2
});
return scopeId;
};
var tryGetParentTreeNode = (url) => {
if (!url) {
return;
}
const requestedBy = widgetContextDependencyTree.getByKey(url);
if (!requestedBy) {
const logger = getShellLogger();
logger.error({
message: "[1DS-Injection] Couldn't find parent widget for url",
url
});
return;
}
return requestedBy;
};
var patchSystemJSResolve = () => {
const SYSTEMJS_PROTOTYPE = System.constructor.prototype;
const existingHook = SYSTEMJS_PROTOTYPE.resolve;
SYSTEMJS_PROTOTYPE.resolve = function oneDsResolver(importName, requestedByUrl) {
const requestedBy = tryGetParentTreeNode(requestedByUrl);
if (importName === CONTEXT_IMPORT_NAME) {
if (!requestedBy) {
return;
}
const scopeId = injectScopedWidgetContext(requestedBy);
return scopeId;
}
const resolvedUrl = existingHook.call(
this,
importName,
requestedByUrl
);
const mayBeExistingNode = widgetContextDependencyTree.getByKey(resolvedUrl);
if (!mayBeExistingNode) {
let mayBeWidget = WIDGET_CONFIGS.get(importName);
if (!mayBeWidget) {
mayBeWidget = hackyWidgetIdDetermination(importName);
}
if (!mayBeWidget) {
console.log(
`[1DS-Context] Couldn't find configuration for url ${resolvedUrl}. Treating as a library.`
);
mayBeWidget = {
widgetId: importName,
// _url: resolvedUrl,
version: "latest",
// activePhasedDeployment: false,
runtime: {}
};
}
widgetContextDependencyTree.add(
resolvedUrl,
mayBeWidget,
"library",
// This is incorrect since everything is being treated as a library.
requestedBy
);
}
return resolvedUrl;
};
return () => {
SYSTEMJS_PROTOTYPE.resolve = existingHook;
};
};
var platformProps = {};
function WidgetLoader({
widgetFrameId,
requestedWidgetConfigOrUrl,
widgetProps,
setWidgetRenderStatus,
options: { variantId, Loader },
// dragon: always deconstruct options to maintain stability in useMemo calls below
hostWidgetId
}) {
const { widgetId, version } = requestedWidgetConfigOrUrl;
const platformProps2 = React.useMemo(
() => getPlatformProps(requestedWidgetConfigOrUrl, {
variantId}),
[`${widgetId}@${version}`, variantId]
);
const { children, ...hostProps } = widgetProps;
const LazyWidget = React.useMemo(() => {
return React__namespace.default.lazy(
() => downloadWidget(widgetId, setWidgetRenderStatus, {
widgetFrameId,
requestedWidgetConfigOrUrl,
hostWidgetId,
widgetOptions: {
variantId,
Loader
}
})
);
}, [`${widgetId}@${version}`, variantId]);
addScopedImportMapForPlatformProps(widgetId, platformProps2);
const widget = /* @__PURE__ */ jsxRuntime.jsx(LazyWidget, { platform: platformProps2, host: hostProps, children });
return /* @__PURE__ */ jsxRuntime.jsx(
React.Suspense,
{
fallback: Loader,
children: widget
},
`${widgetFrameId}-suspense`
);
}
function WidgetURLLoader({
widgetFrameId,
requestedWidgetConfigOrUrl,
setWidgetRenderStatus,
widgetProps = {},
hostWidgetId,
options: { variantId }
// dragon: always deconstruct options to maintain stability in useMemo calls below
}) {
const Loader = getDefaultWidgetOptions().Loader;
const platformProps2 = React.useMemo(
() => getPlatformProps(
{
widgetId: requestedWidgetConfigOrUrl.toString(),
version: "0.0.0",
runtime: {}
},
{
variantId}
),
[requestedWidgetConfigOrUrl, variantId]
);
addScopedImportMapForPlatformProps("test-widget", platformProps2);
const { children, ...hostProps } = widgetProps;
const LazyWidget = React.useMemo(() => {
return React__namespace.default.lazy(
() => downloadWidget(
requestedWidgetCo