@backstage/core-app-api 1.0.5 → 1.1.0-next.2

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 CHANGED
@@ -1,5 +1,62 @@
1
1
  # @backstage/core-app-api
2
2
 
3
+ ## 1.1.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - f9ec4e46e3: When using React Router v6 stable, it is now possible for components within the `Route` element tree to have `path` props, although they will be ignored.
8
+ - 667d917488: Updated dependency `msw` to `^0.47.0`.
9
+ - 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`.
10
+ - e9d40ebf54: If you'd like to send analytics events to multiple implementations, you may now
11
+ do so using the `MultipleAnalyticsApi` implementation provided by this package.
12
+
13
+ ```tsx
14
+ import { MultipleAnalyticsApi } from '@backstage/core-app-api';
15
+ import {
16
+ analyticsApiRef,
17
+ configApiRef,
18
+ storageApiRef,
19
+ identityApiRef,
20
+ } from '@internal/backstage/core-plugin-api';
21
+ import { CustomAnalyticsApi } from '@internal/analytics';
22
+ import { VendorAnalyticsApi } from '@vendor/analytics';
23
+
24
+ createApiFactory({
25
+ api: analyticsApiRef,
26
+ deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef },
27
+ factory: ({ configApi, identityApi, storageApi }) =>
28
+ MultipleAnalyticsApi.fromApis([
29
+ VendorAnalyticsApi.fromConfig(configApi, { identityApi }),
30
+ CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }),
31
+ ]),
32
+ }),
33
+ ```
34
+
35
+ - Updated dependencies
36
+ - @backstage/core-plugin-api@1.0.6-next.2
37
+
38
+ ## 1.1.0-next.1
39
+
40
+ ### Minor Changes
41
+
42
+ - a448fea691: Updated the routing system to be compatible with React Router v6 stable.
43
+
44
+ ### Patch Changes
45
+
46
+ - 817f3196f6: Updated React Router dependencies to be peer dependencies.
47
+ - 70299c99d5: Updated `FlatRoutes` to be compatible with React Router v6 stable.
48
+ - Updated dependencies
49
+ - @backstage/core-plugin-api@1.0.6-next.1
50
+
51
+ ## 1.0.6-next.0
52
+
53
+ ### Patch Changes
54
+
55
+ - 744fea158b: Added `getSystemIcons()` function to the `AppContext` available through `useApp` that will pull a list of all the icons that have been registered in the App.
56
+ - bf5e9030eb: Updated dependency `msw` to `^0.45.0`.
57
+ - Updated dependencies
58
+ - @backstage/core-plugin-api@1.0.6-next.0
59
+
3
60
  ## 1.0.5
4
61
 
5
62
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -276,6 +276,49 @@ declare class AlertApiForwarder implements AlertApi {
276
276
  alert$(): Observable<AlertMessage>;
277
277
  }
278
278
 
279
+ /**
280
+ * An implementation of the AnalyticsApi that can be used to forward analytics
281
+ * events to multiple concrete implementations.
282
+ *
283
+ * @public
284
+ *
285
+ * @example
286
+ *
287
+ * ```jsx
288
+ * createApiFactory({
289
+ * api: analyticsApiRef,
290
+ * deps: { configApi: configApiRef, identityApi: identityApiRef, storageApi: storageApiRef },
291
+ * factory: ({ configApi, identityApi, storageApi }) =>
292
+ * MultipleAnalyticsApi.fromApis([
293
+ * VendorAnalyticsApi.fromConfig(configApi, { identityApi }),
294
+ * CustomAnalyticsApi.fromConfig(configApi, { identityApi, storageApi }),
295
+ * ]),
296
+ * });
297
+ * ```
298
+ */
299
+ declare class MultipleAnalyticsApi implements AnalyticsApi {
300
+ private readonly actualApis;
301
+ private constructor();
302
+ /**
303
+ * Create an AnalyticsApi implementation from an array of concrete
304
+ * implementations.
305
+ *
306
+ * @example
307
+ *
308
+ * ```jsx
309
+ * MultipleAnalyticsApi.fromApis([
310
+ * SomeAnalyticsApi.fromConfig(configApi),
311
+ * new CustomAnalyticsApi(),
312
+ * ]);
313
+ * ```
314
+ */
315
+ static fromApis(actualApis: AnalyticsApi[]): MultipleAnalyticsApi;
316
+ /**
317
+ * Forward the event to all configured analytics API implementations.
318
+ */
319
+ captureEvent(event: AnalyticsEvent): void;
320
+ }
321
+
279
322
  /**
280
323
  * Base implementation for the AnalyticsApi that does nothing.
281
324
  *
@@ -778,6 +821,10 @@ declare type AppContext = {
778
821
  * Get a common or custom icon for this app.
779
822
  */
780
823
  getSystemIcon(key: string): IconComponent | undefined;
824
+ /**
825
+ * Get a list of common and custom icons for this app.
826
+ */
827
+ getSystemIcons(): Record<string, IconComponent>;
781
828
  /**
782
829
  * Get the components registered for various purposes in the app.
783
830
  */
@@ -855,4 +902,4 @@ declare type FeatureFlaggedProps = {
855
902
  */
856
903
  declare const FeatureFlagged: (props: FeatureFlaggedProps) => JSX.Element;
857
904
 
858
- export { AlertApiForwarder, ApiFactoryHolder, ApiFactoryRegistry, ApiFactoryScope, ApiProvider, ApiProviderProps, ApiResolver, AppComponents, AppConfigLoader, AppContext, AppIcons, AppOptions, AppRouteBinder, AppThemeSelector, AtlassianAuth, AuthApiCreateOptions, BackstageApp, BitbucketAuth, BitbucketSession, BootErrorPageProps, ErrorAlerter, ErrorApiForwarder, ErrorBoundaryFallbackProps, FeatureFlagged, FeatureFlaggedProps, FetchMiddleware, FetchMiddlewares, FlatRoutes, FlatRoutesProps, GithubAuth, GitlabAuth, GoogleAuth, LocalStorageFeatureFlags, MicrosoftAuth, NoOpAnalyticsApi, OAuth2, OAuth2CreateOptions, OAuth2Session, OAuthApiCreateOptions, OAuthRequestManager, OktaAuth, OneLoginAuth, OneLoginAuthCreateOptions, SamlAuth, SignInPageProps, UnhandledErrorForwarder, UrlPatternDiscovery, WebStorage, createFetchApi, createSpecializedApp, defaultConfigLoader };
905
+ export { AlertApiForwarder, ApiFactoryHolder, ApiFactoryRegistry, ApiFactoryScope, ApiProvider, ApiProviderProps, ApiResolver, AppComponents, AppConfigLoader, AppContext, AppIcons, AppOptions, AppRouteBinder, AppThemeSelector, AtlassianAuth, AuthApiCreateOptions, BackstageApp, BitbucketAuth, BitbucketSession, BootErrorPageProps, ErrorAlerter, ErrorApiForwarder, ErrorBoundaryFallbackProps, FeatureFlagged, FeatureFlaggedProps, FetchMiddleware, FetchMiddlewares, FlatRoutes, FlatRoutesProps, GithubAuth, GitlabAuth, GoogleAuth, LocalStorageFeatureFlags, MicrosoftAuth, MultipleAnalyticsApi, NoOpAnalyticsApi, OAuth2, OAuth2CreateOptions, OAuth2Session, OAuthApiCreateOptions, OAuthRequestManager, OktaAuth, OneLoginAuth, OneLoginAuthCreateOptions, SamlAuth, SignInPageProps, UnhandledErrorForwarder, UrlPatternDiscovery, WebStorage, createFetchApi, createSpecializedApp, defaultConfigLoader };
package/dist/index.esm.js CHANGED
@@ -6,7 +6,7 @@ import { SessionState, FeatureFlagState, getComponentData, attachComponentData,
6
6
  import { z } from 'zod';
7
7
  import { ConfigReader } from '@backstage/config';
8
8
  export { ConfigReader } from '@backstage/config';
9
- import { matchRoutes, generatePath, useLocation, Routes, Route, useRoutes } from 'react-router-dom';
9
+ import { matchRoutes, generatePath, useLocation, createRoutesFromChildren, Route, Routes, useRoutes } from 'react-router-dom';
10
10
  import useAsync from 'react-use/lib/useAsync';
11
11
  import useObservable from 'react-use/lib/useObservable';
12
12
 
@@ -1172,6 +1172,23 @@ class AlertApiForwarder {
1172
1172
  }
1173
1173
  }
1174
1174
 
1175
+ class MultipleAnalyticsApi {
1176
+ constructor(actualApis) {
1177
+ this.actualApis = actualApis;
1178
+ }
1179
+ static fromApis(actualApis) {
1180
+ return new MultipleAnalyticsApi(actualApis);
1181
+ }
1182
+ captureEvent(event) {
1183
+ this.actualApis.forEach((analyticsApi) => {
1184
+ try {
1185
+ analyticsApi.captureEvent(event);
1186
+ } catch {
1187
+ }
1188
+ });
1189
+ }
1190
+ }
1191
+
1175
1192
  class NoOpAnalyticsApi {
1176
1193
  captureEvent(_event) {
1177
1194
  }
@@ -1745,10 +1762,137 @@ attachComponentData(FeatureFlagged, "core.featureFlagged", true);
1745
1762
 
1746
1763
  const MATCH_ALL_ROUTE = {
1747
1764
  caseSensitive: false,
1748
- path: "/*",
1765
+ path: "*",
1749
1766
  element: "match-all",
1750
1767
  routeRefs: /* @__PURE__ */ new Set()
1751
1768
  };
1769
+ function stringifyNode(node) {
1770
+ var _a, _b;
1771
+ const anyNode = node;
1772
+ if (anyNode == null ? void 0 : anyNode.type) {
1773
+ return (_b = (_a = anyNode.type.displayName) != null ? _a : anyNode.type.name) != null ? _b : String(anyNode.type);
1774
+ }
1775
+ return String(anyNode);
1776
+ }
1777
+ function collectSubTree(node, entries = new Array()) {
1778
+ Children.forEach(node, (element) => {
1779
+ if (!isValidElement(element)) {
1780
+ return;
1781
+ }
1782
+ const routeRef = getComponentData(element, "core.mountPoint");
1783
+ if (routeRef) {
1784
+ const plugin = getComponentData(element, "core.plugin");
1785
+ entries.push({ routeRef, plugin });
1786
+ }
1787
+ collectSubTree(element.props.children, entries);
1788
+ });
1789
+ return entries;
1790
+ }
1791
+ const routingV2Collector = createCollector(
1792
+ () => ({
1793
+ paths: /* @__PURE__ */ new Map(),
1794
+ parents: /* @__PURE__ */ new Map(),
1795
+ objects: new Array()
1796
+ }),
1797
+ (acc, node, parent, ctx) => {
1798
+ var _a, _b, _c, _d, _e, _f;
1799
+ if (ctx == null ? void 0 : ctx.isElementAncestor) {
1800
+ return ctx;
1801
+ }
1802
+ if ((parent == null ? void 0 : parent.props.element) === node) {
1803
+ return { ...ctx, isElementAncestor: true };
1804
+ }
1805
+ const pathProp = (_a = node.props) == null ? void 0 : _a.path;
1806
+ const mountPoint = getComponentData(node, "core.mountPoint");
1807
+ if (mountPoint && pathProp) {
1808
+ throw new Error(
1809
+ `Path property may not be set directly on a routable extension "${stringifyNode(
1810
+ node
1811
+ )}"`
1812
+ );
1813
+ }
1814
+ const parentChildren = (_c = (_b = ctx == null ? void 0 : ctx.obj) == null ? void 0 : _b.children) != null ? _c : acc.objects;
1815
+ if (pathProp !== void 0) {
1816
+ if (typeof pathProp !== "string") {
1817
+ throw new Error(
1818
+ `Element path must be a string at "${stringifyNode(node)}"`
1819
+ );
1820
+ }
1821
+ const path = pathProp.startsWith("/") ? pathProp.slice(1) : pathProp;
1822
+ const elementProp = node.props.element;
1823
+ if (getComponentData(node, "core.gatherMountPoints")) {
1824
+ if (elementProp) {
1825
+ throw new Error(
1826
+ `Mount point gatherers may not have an element prop "${stringifyNode(
1827
+ node
1828
+ )}"`
1829
+ );
1830
+ }
1831
+ const newObj = {
1832
+ path,
1833
+ element: "gathered",
1834
+ routeRefs: /* @__PURE__ */ new Set(),
1835
+ caseSensitive: Boolean((_d = node.props) == null ? void 0 : _d.caseSensitive),
1836
+ children: [MATCH_ALL_ROUTE],
1837
+ plugin: void 0
1838
+ };
1839
+ parentChildren.push(newObj);
1840
+ return {
1841
+ obj: newObj,
1842
+ gatherPath: path,
1843
+ routeRef: ctx == null ? void 0 : ctx.routeRef,
1844
+ gatherRouteRef: ctx == null ? void 0 : ctx.routeRef
1845
+ };
1846
+ }
1847
+ if (elementProp) {
1848
+ const [extension, ...others] = collectSubTree(elementProp);
1849
+ if (others.length > 0) {
1850
+ throw new Error(
1851
+ `Route element with path "${pathProp}" may not contain multiple routable extensions`
1852
+ );
1853
+ }
1854
+ if (!extension) {
1855
+ return ctx;
1856
+ }
1857
+ const { routeRef, plugin } = extension;
1858
+ const newObj = {
1859
+ path,
1860
+ element: "mounted",
1861
+ routeRefs: /* @__PURE__ */ new Set([routeRef]),
1862
+ caseSensitive: Boolean((_e = node.props) == null ? void 0 : _e.caseSensitive),
1863
+ children: [MATCH_ALL_ROUTE],
1864
+ plugin
1865
+ };
1866
+ parentChildren.push(newObj);
1867
+ acc.paths.set(routeRef, path);
1868
+ acc.parents.set(routeRef, ctx == null ? void 0 : ctx.routeRef);
1869
+ return {
1870
+ obj: newObj,
1871
+ routeRef: routeRef != null ? routeRef : ctx == null ? void 0 : ctx.routeRef,
1872
+ gatherPath: path,
1873
+ gatherRouteRef: ctx == null ? void 0 : ctx.gatherRouteRef
1874
+ };
1875
+ }
1876
+ }
1877
+ if (mountPoint) {
1878
+ if (!(ctx == null ? void 0 : ctx.gatherPath)) {
1879
+ throw new Error(
1880
+ `Routable extension "${stringifyNode(
1881
+ node
1882
+ )}" with mount point "${mountPoint}" must be assigned a path`
1883
+ );
1884
+ }
1885
+ (_f = ctx == null ? void 0 : ctx.obj) == null ? void 0 : _f.routeRefs.add(mountPoint);
1886
+ acc.paths.set(mountPoint, ctx.gatherPath);
1887
+ acc.parents.set(mountPoint, ctx == null ? void 0 : ctx.gatherRouteRef);
1888
+ return {
1889
+ ...ctx,
1890
+ routeRef: mountPoint
1891
+ };
1892
+ }
1893
+ return ctx;
1894
+ }
1895
+ );
1752
1896
  const routingV1Collector = createCollector(
1753
1897
  () => ({
1754
1898
  paths: /* @__PURE__ */ new Map(),
@@ -1880,6 +2024,7 @@ function joinPaths(...paths) {
1880
2024
  }
1881
2025
  return normalized;
1882
2026
  }
2027
+
1883
2028
  function resolveTargetRef(anyRouteRef, routePaths, routeBindings) {
1884
2029
  let targetRef;
1885
2030
  let subRoutePath = "";
@@ -1914,7 +2059,7 @@ function resolveTargetRef(anyRouteRef, routePaths, routeBindings) {
1914
2059
  return [void 0, ""];
1915
2060
  }
1916
2061
  const resolvedPath = routePaths.get(targetRef);
1917
- if (!resolvedPath) {
2062
+ if (resolvedPath === void 0) {
1918
2063
  return [void 0, ""];
1919
2064
  }
1920
2065
  const targetPath = joinPaths(resolvedPath, subRoutePath);
@@ -1938,21 +2083,19 @@ function resolveBasePath(targetRef, sourceLocation, routePaths, routeParents, ro
1938
2083
  matchIndex -= 1;
1939
2084
  }
1940
2085
  const parentPath = matchIndex === -1 ? "" : match[matchIndex].pathname;
1941
- const diffPath = joinPaths(
1942
- ...refDiffList.slice(0, -1).map((ref) => {
1943
- const path = routePaths.get(ref);
1944
- if (!path) {
1945
- throw new Error(`No path for ${ref}`);
1946
- }
1947
- if (path.includes(":")) {
1948
- throw new Error(
1949
- `Cannot route to ${targetRef} with parent ${ref} as it has parameters`
1950
- );
1951
- }
1952
- return path;
1953
- })
1954
- );
1955
- return parentPath + diffPath;
2086
+ const diffPaths = refDiffList.slice(0, -1).map((ref) => {
2087
+ const path = routePaths.get(ref);
2088
+ if (path === void 0) {
2089
+ throw new Error(`No path for ${ref}`);
2090
+ }
2091
+ if (path.includes(":")) {
2092
+ throw new Error(
2093
+ `Cannot route to ${targetRef} with parent ${ref} as it has parameters`
2094
+ );
2095
+ }
2096
+ return path;
2097
+ });
2098
+ return `${joinPaths(parentPath, ...diffPaths)}/`;
1956
2099
  }
1957
2100
  class RouteResolver {
1958
2101
  constructor(routePaths, routeParents, routeObjects, routeBindings, appBasePath) {
@@ -1990,7 +2133,7 @@ class RouteResolver {
1990
2133
  this.routeObjects
1991
2134
  );
1992
2135
  const routeFunc = (...[params]) => {
1993
- return basePath + generatePath(targetPath, params);
2136
+ return joinPaths(basePath, generatePath(targetPath, params));
1994
2137
  };
1995
2138
  return routeFunc;
1996
2139
  }
@@ -2088,10 +2231,10 @@ function validateRouteParameters(routePaths, routeParents) {
2088
2231
  let fullPath = "";
2089
2232
  while (currentRouteRef) {
2090
2233
  const path = routePaths.get(currentRouteRef);
2091
- if (!path) {
2234
+ if (path === void 0) {
2092
2235
  throw new Error(`No path for ${currentRouteRef}`);
2093
2236
  }
2094
- fullPath = `${path}${fullPath}`;
2237
+ fullPath = joinPaths(path, fullPath);
2095
2238
  currentRouteRef = routeParents.get(currentRouteRef);
2096
2239
  }
2097
2240
  const params = fullPath.match(/:(\w+)/g);
@@ -2360,6 +2503,14 @@ function resolveRouteBindings(bindRoutes) {
2360
2503
  return result;
2361
2504
  }
2362
2505
 
2506
+ function isReactRouterBeta() {
2507
+ const [obj] = createRoutesFromChildren(/* @__PURE__ */ React.createElement(Route, {
2508
+ index: true,
2509
+ element: /* @__PURE__ */ React.createElement("div", null)
2510
+ }));
2511
+ return !obj.index;
2512
+ }
2513
+
2363
2514
  const InternalAppContext = createContext({ routeObjects: [] });
2364
2515
  function getBasePath(configApi) {
2365
2516
  var _a;
@@ -2406,6 +2557,9 @@ class AppContextImpl {
2406
2557
  getSystemIcon(key) {
2407
2558
  return this.app.getSystemIcon(key);
2408
2559
  }
2560
+ getSystemIcons() {
2561
+ return this.app.getSystemIcons();
2562
+ }
2409
2563
  getComponents() {
2410
2564
  return this.app.getComponents();
2411
2565
  }
@@ -2430,6 +2584,9 @@ class AppManager {
2430
2584
  getSystemIcon(key) {
2431
2585
  return this.icons[key];
2432
2586
  }
2587
+ getSystemIcons() {
2588
+ return this.icons;
2589
+ }
2433
2590
  getComponents() {
2434
2591
  return this.components;
2435
2592
  }
@@ -2446,7 +2603,7 @@ class AppManager {
2446
2603
  root: children,
2447
2604
  discoverers: [childDiscoverer, routeElementDiscoverer],
2448
2605
  collectors: {
2449
- routing: routingV1Collector,
2606
+ routing: isReactRouterBeta() ? routingV1Collector : routingV2Collector,
2450
2607
  collectedPlugins: pluginCollector,
2451
2608
  featureFlags: featureFlagCollector
2452
2609
  }
@@ -2674,9 +2831,11 @@ function createSpecializedApp(options) {
2674
2831
  return new AppManager(options);
2675
2832
  }
2676
2833
 
2834
+ let warned = false;
2677
2835
  const FlatRoutes = (props) => {
2678
2836
  const app = useApp();
2679
2837
  const { NotFoundErrorPage } = app.getComponents();
2838
+ const isBeta = useMemo(() => isReactRouterBeta(), []);
2680
2839
  const routes = useElementFilter(
2681
2840
  props.children,
2682
2841
  (elements) => elements.getElements().flatMap((child) => {
@@ -2686,29 +2845,39 @@ const FlatRoutes = (props) => {
2686
2845
  return [];
2687
2846
  }
2688
2847
  path = (_a = path == null ? void 0 : path.replace(/\/\*$/, "")) != null ? _a : "/";
2848
+ let element = isBeta ? child : child.props.element;
2849
+ if (!isBeta && !element) {
2850
+ element = child;
2851
+ if (!warned && process.env.NODE_ENV !== "test") {
2852
+ console.warn(
2853
+ "DEPRECATION WARNING: All elements within <FlatRoutes> must be of type <Route> with an element prop. Existing usages of <Navigate key=[path] to=[to] /> should be replaced with <Route path=[path] element={<Navigate to=[to] />} />."
2854
+ );
2855
+ warned = true;
2856
+ }
2857
+ }
2689
2858
  return [
2690
2859
  {
2691
2860
  path,
2692
- element: child,
2861
+ element,
2693
2862
  children: child.props.children ? [
2694
2863
  {
2695
- path: path === "/" ? "/" : "/*",
2864
+ path: path === "/" ? "/" : "*",
2696
2865
  element: child.props.children
2697
2866
  }
2698
2867
  ] : void 0
2699
2868
  }
2700
2869
  ];
2701
- }).sort((a, b) => b.path.localeCompare(a.path)).map((obj) => {
2702
- obj.path = obj.path === "/" ? "/" : `${obj.path}/*`;
2703
- return obj;
2704
- })
2870
+ }).sort((a, b) => b.path.localeCompare(a.path)).map((obj) => ({ ...obj, path: obj.path === "/" ? "/" : `${obj.path}/*` }))
2705
2871
  );
2706
- routes.push({
2707
- element: /* @__PURE__ */ React.createElement(NotFoundErrorPage, null),
2708
- path: "/*"
2709
- });
2710
- return useRoutes(routes);
2872
+ const withNotFound = [
2873
+ ...routes,
2874
+ {
2875
+ path: "*",
2876
+ element: /* @__PURE__ */ React.createElement(NotFoundErrorPage, null)
2877
+ }
2878
+ ];
2879
+ return useRoutes(withNotFound);
2711
2880
  };
2712
2881
 
2713
- export { AlertApiForwarder, ApiFactoryRegistry, ApiProvider, ApiResolver, AppThemeSelector, AtlassianAuth, BitbucketAuth, ErrorAlerter, ErrorApiForwarder, FeatureFlagged, FetchMiddlewares, FlatRoutes, GithubAuth, GitlabAuth, GoogleAuth, LocalStorageFeatureFlags, MicrosoftAuth, NoOpAnalyticsApi, OAuth2, OAuthRequestManager, OktaAuth, OneLoginAuth, SamlAuth, UnhandledErrorForwarder, UrlPatternDiscovery, WebStorage, createFetchApi, createSpecializedApp, defaultConfigLoader };
2882
+ export { AlertApiForwarder, ApiFactoryRegistry, ApiProvider, ApiResolver, AppThemeSelector, AtlassianAuth, BitbucketAuth, ErrorAlerter, ErrorApiForwarder, FeatureFlagged, FetchMiddlewares, FlatRoutes, GithubAuth, GitlabAuth, GoogleAuth, LocalStorageFeatureFlags, MicrosoftAuth, MultipleAnalyticsApi, NoOpAnalyticsApi, OAuth2, OAuthRequestManager, OktaAuth, OneLoginAuth, SamlAuth, UnhandledErrorForwarder, UrlPatternDiscovery, WebStorage, createFetchApi, createSpecializedApp, defaultConfigLoader };
2714
2883
  //# sourceMappingURL=index.esm.js.map