@servicetitan/web-components 28.1.0 → 28.2.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.
Files changed (63) hide show
  1. package/dist/common.d.ts +10 -0
  2. package/dist/common.d.ts.map +1 -1
  3. package/dist/common.js +1 -0
  4. package/dist/common.js.map +1 -1
  5. package/dist/get-value-for-environment.d.ts +4 -0
  6. package/dist/get-value-for-environment.d.ts.map +1 -0
  7. package/dist/get-value-for-environment.js +26 -0
  8. package/dist/get-value-for-environment.js.map +1 -0
  9. package/dist/globals.d.ts +4 -3
  10. package/dist/globals.d.ts.map +1 -1
  11. package/dist/globals.js +4 -2
  12. package/dist/globals.js.map +1 -1
  13. package/dist/index.d.ts +3 -2
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -2
  16. package/dist/index.js.map +1 -1
  17. package/dist/loader.d.ts.map +1 -1
  18. package/dist/loader.js +40 -9
  19. package/dist/loader.js.map +1 -1
  20. package/dist/register.d.ts.map +1 -1
  21. package/dist/register.js +21 -4
  22. package/dist/register.js.map +1 -1
  23. package/dist/utils/get-bundle-info.d.ts +13 -2
  24. package/dist/utils/get-bundle-info.d.ts.map +1 -1
  25. package/dist/utils/get-bundle-info.js +3 -1
  26. package/dist/utils/get-bundle-info.js.map +1 -1
  27. package/dist/utils/get-ld-service-token.d.ts +4 -0
  28. package/dist/utils/get-ld-service-token.d.ts.map +1 -0
  29. package/dist/utils/get-ld-service-token.js +11 -0
  30. package/dist/utils/get-ld-service-token.js.map +1 -0
  31. package/dist/utils/get-mfe-has-compatible-launchdarkly-version.d.ts +11 -0
  32. package/dist/utils/get-mfe-has-compatible-launchdarkly-version.d.ts.map +1 -0
  33. package/dist/utils/get-mfe-has-compatible-launchdarkly-version.js +16 -0
  34. package/dist/utils/get-mfe-has-compatible-launchdarkly-version.js.map +1 -0
  35. package/dist/utils/index.d.ts +1 -0
  36. package/dist/utils/index.d.ts.map +1 -1
  37. package/dist/utils/index.js +1 -0
  38. package/dist/utils/index.js.map +1 -1
  39. package/dist/utils/validate-bundle-info.d.ts +7 -4
  40. package/dist/utils/validate-bundle-info.d.ts.map +1 -1
  41. package/dist/utils/validate-bundle-info.js +30 -12
  42. package/dist/utils/validate-bundle-info.js.map +1 -1
  43. package/dist/utils/web-component.d.ts +4 -1
  44. package/dist/utils/web-component.d.ts.map +1 -1
  45. package/dist/utils/web-component.js +3 -1
  46. package/dist/utils/web-component.js.map +1 -1
  47. package/package.json +14 -9
  48. package/src/__tests__/get-value-for-environment.test.ts +77 -0
  49. package/src/__tests__/globals.test.ts +4 -8
  50. package/src/__tests__/loader.test.tsx +112 -13
  51. package/src/common.ts +10 -0
  52. package/src/get-value-for-environment.ts +42 -0
  53. package/src/globals.ts +12 -3
  54. package/src/index.ts +3 -2
  55. package/src/loader.tsx +56 -11
  56. package/src/register.tsx +20 -7
  57. package/src/utils/__tests__/get-mfe-has-compatible-launchdarkly-version.test.ts +54 -0
  58. package/src/utils/get-bundle-info.ts +25 -9
  59. package/src/utils/get-ld-service-token.ts +13 -0
  60. package/src/utils/get-mfe-has-compatible-launchdarkly-version.ts +20 -0
  61. package/src/utils/index.ts +1 -0
  62. package/src/utils/validate-bundle-info.ts +40 -19
  63. package/src/utils/web-component.tsx +15 -2
package/src/loader.tsx CHANGED
@@ -9,23 +9,27 @@ import {
9
9
  useMemo,
10
10
  } from 'react';
11
11
  import { ErrorBoundary } from '@servicetitan/error-boundary';
12
+ import { type LDService } from '@servicetitan/launchdarkly-service';
12
13
  import { Log } from '@servicetitan/log-service';
13
14
  import { useOptionalDependencies } from '@servicetitan/react-ioc';
14
15
 
15
16
  import {
16
17
  EXPOSED_DEPENDENCIES_TOKEN,
18
+ EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,
17
19
  ExposedDependencies,
20
+ ExposedInstanceDependencies,
18
21
  GetJsonError,
19
22
  useCancelation,
20
23
  } from './common';
21
24
  import { MFEContextData } from './contexts/mfe-data-context';
22
25
  import { Delayed } from './delayed';
23
26
  import { EventBus, EVENT_BUS_TOKEN, useEventBus } from './event-bus';
24
- import { EXPOSED_DEPENDENCIES } from './globals';
27
+ import { EXPOSED_DEPENDENCIES, EXPOSED_INSTANCE_DEPENDENCIES } from './globals';
25
28
  import {
26
29
  BundleInfo,
27
30
  TtlCache,
28
31
  getBundleInfo,
32
+ getLDServiceToken,
29
33
  validateBundleInfo,
30
34
  loadScripts,
31
35
  webComponent,
@@ -59,8 +63,18 @@ export const Loader = forwardRef<LoaderRef, LoaderProps<{}>>((props, ref) => {
59
63
  const { loadingFallback, loadingFallbackDelayed = true } = props;
60
64
 
61
65
  const bus = useEventBus();
62
- const [logService, exposedDependencies = EXPOSED_DEPENDENCIES, eventBus = bus] =
63
- useOptionalDependencies(Log, EXPOSED_DEPENDENCIES_TOKEN, EVENT_BUS_TOKEN);
66
+ const [
67
+ logService,
68
+ exposedDependencies = EXPOSED_DEPENDENCIES,
69
+ exposedInstanceDependencies = EXPOSED_INSTANCE_DEPENDENCIES,
70
+ eventBus = bus,
71
+ ] = useOptionalDependencies(
72
+ Log,
73
+ EXPOSED_DEPENDENCIES_TOKEN,
74
+ EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,
75
+ EVENT_BUS_TOKEN
76
+ );
77
+ const [ldService] = useOptionalDependencies(getLDServiceToken() ?? Symbol());
64
78
  const cancelation = useCancelation();
65
79
 
66
80
  const LoadingFallback = useMemo(() => {
@@ -73,6 +87,8 @@ export const Loader = forwardRef<LoaderRef, LoaderProps<{}>>((props, ref) => {
73
87
  return getFallback(props.errorFallback, message);
74
88
  }, [props.errorFallback, src]);
75
89
 
90
+ ensureLDService(exposedInstanceDependencies, ldService);
91
+
76
92
  const Loader = useMemo(
77
93
  () =>
78
94
  lazyLoader({
@@ -80,6 +96,7 @@ export const Loader = forwardRef<LoaderRef, LoaderProps<{}>>((props, ref) => {
80
96
  cache,
81
97
  cancelation,
82
98
  exposedDependencies,
99
+ exposedInstanceDependencies,
83
100
  eventBus,
84
101
  fallbackSrc,
85
102
  logService,
@@ -92,6 +109,7 @@ export const Loader = forwardRef<LoaderRef, LoaderProps<{}>>((props, ref) => {
92
109
  cache,
93
110
  cancelation,
94
111
  exposedDependencies,
112
+ exposedInstanceDependencies,
95
113
  eventBus,
96
114
  logService,
97
115
  onRequestError,
@@ -119,6 +137,7 @@ export const Loader = forwardRef<LoaderRef, LoaderProps<{}>>((props, ref) => {
119
137
  type LazyLoaderProps = LoaderProps<any> & {
120
138
  cancelation: AbortController;
121
139
  exposedDependencies?: ExposedDependencies;
140
+ exposedInstanceDependencies?: ExposedInstanceDependencies;
122
141
  eventBus: EventBus;
123
142
  logService?: Log;
124
143
  };
@@ -150,6 +169,7 @@ function lazyWebComponent(props: LazyLoaderProps) {
150
169
  basename,
151
170
  cancelation,
152
171
  exposedDependencies,
172
+ exposedInstanceDependencies,
153
173
  eventBus,
154
174
  fallbackSrc,
155
175
  logService,
@@ -160,18 +180,19 @@ function lazyWebComponent(props: LazyLoaderProps) {
160
180
 
161
181
  let { cache } = props;
162
182
 
163
- return lazy<(props: LoaderDataProps) => JSX.Element | null>(async () => {
183
+ return lazy<(_: LoaderDataProps) => JSX.Element | null>(async () => {
164
184
  let bundleInfo: BundleInfo | undefined = cache ? bundleCache.get(src) : undefined;
165
185
  if (!bundleInfo) {
166
186
  try {
167
- bundleInfo = await getBundleInfo(
168
- src,
169
- fallbackSrc,
187
+ bundleInfo = await getBundleInfo({
188
+ mainPackageUrl: src,
189
+ fallbackPackageUrl: fallbackSrc,
170
190
  exposedDependencies,
171
- cancelation.signal,
191
+ exposedInstanceDependencies,
192
+ signal: cancelation.signal,
172
193
  retries,
173
- onRequestError
174
- );
194
+ onRequestError,
195
+ });
175
196
  } catch (e) {
176
197
  if (cancelation.signal.aborted) {
177
198
  return {
@@ -190,17 +211,28 @@ function lazyWebComponent(props: LazyLoaderProps) {
190
211
  bundleCache.set(src, bundleInfo, typeof cache === 'number' ? cache : undefined);
191
212
  }
192
213
 
193
- validateBundleInfo(bundleInfo, { exposedDependencies, logService, packageName: src });
214
+ validateBundleInfo(bundleInfo, {
215
+ exposedDependencies,
216
+ exposedInstanceDependencies,
217
+ logService,
218
+ packageUrl: src,
219
+ });
194
220
  }
195
221
 
196
222
  await loadScripts(bundleInfo);
197
223
 
224
+ const ldService = bundleInfo.mfeHasCompatibleLaunchDarklyVersion
225
+ ? exposedInstanceDependencies?.launchDarkly?.ldService
226
+ : undefined;
227
+
198
228
  return {
199
229
  default: webComponent({
200
230
  basename,
201
231
  bundleInfo,
202
232
  eventBus,
203
233
  exposedDependencies,
234
+ exposedInstanceDependencies,
235
+ ldService,
204
236
  logService,
205
237
  }),
206
238
  };
@@ -220,5 +252,18 @@ function isLocalHost(source: string) {
220
252
  return ['localhost', '127.0.0.1'].some(host => source.indexOf(host) >= 0);
221
253
  }
222
254
 
255
+ function ensureLDService(
256
+ exposedInstanceDependencies?: ExposedInstanceDependencies,
257
+ ldService?: LDService
258
+ ) {
259
+ if (
260
+ exposedInstanceDependencies?.launchDarkly?.version &&
261
+ !exposedInstanceDependencies.launchDarkly.ldService &&
262
+ ldService
263
+ ) {
264
+ exposedInstanceDependencies.launchDarkly.ldService = ldService;
265
+ }
266
+ }
267
+
223
268
  const MINUTE = 1000 * 60;
224
269
  const bundleCache = new TtlCache<BundleInfo>({ ttlMs: 15 * MINUTE });
package/src/register.tsx CHANGED
@@ -1,15 +1,18 @@
1
1
  import { FC, ComponentType, ReactElement, useEffect } from 'react';
2
+ import { type LDService } from '@servicetitan/launchdarkly-service';
2
3
  import { Log } from '@servicetitan/log-service';
3
4
  import { Provider } from '@servicetitan/react-ioc';
4
5
 
5
6
  import {
6
- ExposedDependencies,
7
- EXPOSED_DEPENDENCIES_TOKEN,
8
- Entries,
9
- IWebComponent,
10
7
  BASENAME_TOKEN,
8
+ EXPOSED_DEPENDENCIES_TOKEN,
9
+ EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,
11
10
  IS_WEB_COMPONENT_TOKEN,
12
11
  RENDER_ROOT_TOKEN,
12
+ Entries,
13
+ ExposedDependencies,
14
+ ExposedInstanceDependencies,
15
+ IWebComponent,
13
16
  } from './common';
14
17
  import { MFEDataContext } from './contexts/mfe-data-context';
15
18
  import { MFEMetadataContext } from './contexts/mfe-metadata-context';
@@ -17,7 +20,7 @@ import { EventBus, EVENT_BUS_TOKEN } from './event-bus';
17
20
  import { WEB_COMPONENT_NAME } from './globals';
18
21
  import { HistoryManager } from './history-manager';
19
22
  import { render } from './render';
20
- import { getElementName } from './utils';
23
+ import { getElementName, getLDServiceToken } from './utils';
21
24
 
22
25
  function createLink(url: string, onLoad: () => void) {
23
26
  const element = document.createElement('link');
@@ -50,9 +53,11 @@ export function register(Component: ComponentType, light: boolean, options?: Reg
50
53
  elements: HTMLElement[];
51
54
  } = { total: 0, loaded: 0, elements: [] };
52
55
 
56
+ private ldService?: LDService;
53
57
  private logService?: Log;
54
58
  private historyManager?: HistoryManager;
55
59
  private exposedDependencies?: ExposedDependencies;
60
+ private exposedInstanceDependencies?: ExposedInstanceDependencies;
56
61
  private eventBus?: EventBus;
57
62
  private basename?: string;
58
63
  private onReady?: () => void;
@@ -246,9 +251,17 @@ export function register(Component: ComponentType, light: boolean, options?: Reg
246
251
  provide: EXPOSED_DEPENDENCIES_TOKEN,
247
252
  useValue: this.exposedDependencies,
248
253
  },
249
- { provide: EVENT_BUS_TOKEN, useValue: this.eventBus },
254
+ {
255
+ provide: EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,
256
+ useValue: this.exposedInstanceDependencies,
257
+ },
250
258
  { provide: BASENAME_TOKEN, useValue: this.basename },
251
- ].filter(({ useValue }) => useValue !== undefined)}
259
+ { provide: EVENT_BUS_TOKEN, useValue: this.eventBus },
260
+ { provide: getLDServiceToken(), useValue: this.ldService },
261
+ ].filter(
262
+ ({ provide, useValue }) =>
263
+ useValue !== undefined && provide !== undefined
264
+ )}
252
265
  >
253
266
  <MFEDataContext.Provider value={{ ...mfeData }}>
254
267
  <MFEMetadataContext.Provider value={metadata}>
@@ -0,0 +1,54 @@
1
+ import { ExposedInstanceDependencies } from '../../common';
2
+ import { Metadata } from '../get-bundle-info';
3
+ import { getMFEHasCompatibleLaunchDarklyVersion } from '../get-mfe-has-compatible-launchdarkly-version';
4
+
5
+ describe(`[web-components] ${getMFEHasCompatibleLaunchDarklyVersion.name}`, () => {
6
+ const version = '1.0.0';
7
+ let metadata: Pick<Metadata, 'bundledWith'>;
8
+ let exposedInstanceDependencies: ExposedInstanceDependencies;
9
+
10
+ beforeEach(() => {
11
+ metadata = {
12
+ bundledWith: { 'launchdarkly-js-client-sdk': version },
13
+ };
14
+ });
15
+
16
+ function itReturns(value: boolean | undefined) {
17
+ test(`return ${value}`, () => {
18
+ expect(subject()).toBe(value);
19
+ });
20
+ }
21
+
22
+ const subject = () =>
23
+ getMFEHasCompatibleLaunchDarklyVersion(metadata.bundledWith, exposedInstanceDependencies);
24
+
25
+ describe('when host and MFE use same LaunchDarkly version', () => {
26
+ beforeEach(() => (exposedInstanceDependencies = { launchDarkly: { version } }));
27
+
28
+ itReturns(true);
29
+ });
30
+
31
+ describe('when host uses different LaunchDarkly version', () => {
32
+ beforeEach(() => (exposedInstanceDependencies = { launchDarkly: { version: '1.0.1' } }));
33
+
34
+ itReturns(false);
35
+ });
36
+
37
+ describe('when host does not use LaunchDarkly', () => {
38
+ beforeEach(() => (exposedInstanceDependencies = {}));
39
+
40
+ itReturns(undefined);
41
+ });
42
+
43
+ describe('when MFE does not use LaunchDarkly', () => {
44
+ beforeEach(() => (metadata.bundledWith = {}));
45
+
46
+ itReturns(undefined);
47
+ });
48
+
49
+ describe('when metadata omits "bundledWith"', () => {
50
+ beforeEach(() => delete metadata.bundledWith);
51
+
52
+ itReturns(undefined);
53
+ });
54
+ });
@@ -1,11 +1,12 @@
1
1
  import semver from 'semver';
2
2
  import get from 'lodash.get';
3
3
 
4
- import { ExposedDependencies, getJson, GetJsonError } from '../common';
4
+ import { ExposedDependencies, ExposedInstanceDependencies, getJson, GetJsonError } from '../common';
5
5
  import { EntryPoints, getEntrypoints } from './get-entry-points';
6
6
  import { getMFESupportsRerendering } from './get-mfe-supports-rerendering';
7
7
  import { getVersionMismatches } from './get-version-mismatches';
8
8
  import { isVersionedUrl } from './is-versioned-url';
9
+ import { getMFEHasCompatibleLaunchDarklyVersion } from './get-mfe-has-compatible-launchdarkly-version';
9
10
  import { getMFEHasUniqueChunkNamespace } from './get-mfe-has-unique-chunk-namespace';
10
11
 
11
12
  export interface Metadata {
@@ -18,14 +19,25 @@ export interface Metadata {
18
19
 
19
20
  export type BundleInfo = Awaited<ReturnType<typeof getBundleInfo>>;
20
21
 
21
- export async function getBundleInfo(
22
- mainPackageUrl: string,
23
- fallbackPackageUrl: string | undefined,
24
- exposedDependencies: ExposedDependencies = {},
25
- signal?: AbortSignal,
26
- retries?: number,
27
- onRequestError?: (error: GetJsonError) => void
28
- ) {
22
+ interface GetBundleInfoProps {
23
+ exposedDependencies?: ExposedDependencies;
24
+ exposedInstanceDependencies?: ExposedInstanceDependencies;
25
+ fallbackPackageUrl?: string;
26
+ mainPackageUrl: string;
27
+ onRequestError?: (error: GetJsonError) => void;
28
+ retries?: number;
29
+ signal?: AbortSignal;
30
+ }
31
+
32
+ export async function getBundleInfo({
33
+ mainPackageUrl,
34
+ fallbackPackageUrl,
35
+ exposedDependencies = {},
36
+ exposedInstanceDependencies = {},
37
+ signal,
38
+ retries,
39
+ onRequestError,
40
+ }: GetBundleInfoProps) {
29
41
  const { data: metadata, url: packageUrl } = await getMetadata({
30
42
  fallbackPackageUrl,
31
43
  mainPackageUrl,
@@ -84,6 +96,10 @@ export async function getBundleInfo(
84
96
  disposer,
85
97
  mfeSupportsRerendering: getMFESupportsRerendering(bundledWith, dependencies),
86
98
  mfeHasUniqueChunkNamespace: getMFEHasUniqueChunkNamespace(bundledWith),
99
+ mfeHasCompatibleLaunchDarklyVersion: getMFEHasCompatibleLaunchDarklyVersion(
100
+ bundledWith,
101
+ exposedInstanceDependencies
102
+ ),
87
103
  mismatch: hasMismatch ? mismatch : undefined,
88
104
  urls,
89
105
  WebComponent: name,
@@ -0,0 +1,13 @@
1
+ import { type LDService } from '@servicetitan/launchdarkly-service';
2
+ import { SymbolToken } from '@servicetitan/react-ioc';
3
+
4
+ let token: SymbolToken<LDService>;
5
+ try {
6
+ token = require('@servicetitan/launchdarkly-service').LD_SERVICE_TOKEN;
7
+ } catch (e) {
8
+ // ignore
9
+ }
10
+
11
+ export function getLDServiceToken() {
12
+ return token;
13
+ }
@@ -0,0 +1,20 @@
1
+ import { ExposedInstanceDependencies } from '../common';
2
+ import { Metadata } from './get-bundle-info';
3
+
4
+ /**
5
+ * @param bundledWith THe MFE's metadata.bundledWith.
6
+ * @param exposedInstanceDependencies The hosts's EXPOSED_INSTANCE_DEPENDENCIES, if any.
7
+ * @returns Returns true when host and MFE use compatible version of LaunchDarkly
8
+ * and returns false when host and MGE use incompatible version.
9
+ * Returns undefined when either the host or MFE doesn't expose LaunchDarkly.
10
+ */
11
+ export function getMFEHasCompatibleLaunchDarklyVersion(
12
+ bundledWith: Metadata['bundledWith'],
13
+ exposedInstanceDependencies: ExposedInstanceDependencies
14
+ ) {
15
+ const mfeVersion = bundledWith?.['launchdarkly-js-client-sdk'];
16
+ const hostVersion = exposedInstanceDependencies.launchDarkly?.version;
17
+ if (hostVersion && mfeVersion) {
18
+ return hostVersion === mfeVersion;
19
+ }
20
+ }
@@ -1,6 +1,7 @@
1
1
  export * from './get-bundle-info';
2
2
  export * from './get-element-name';
3
3
  export * from './get-entry-points';
4
+ export * from './get-ld-service-token';
4
5
  export * from './get-mfe-supports-rerendering';
5
6
  export * from './get-version-mismatches';
6
7
  export * from './is-versioned-url';
@@ -1,31 +1,52 @@
1
1
  import { Log } from '@servicetitan/log-service';
2
- import { ExposedDependencies } from '../common';
2
+ import { ExposedDependencies, ExposedInstanceDependencies } from '../common';
3
3
  import { BundleInfo } from './get-bundle-info';
4
4
 
5
+ interface Context {
6
+ exposedDependencies?: ExposedDependencies;
7
+ exposedInstanceDependencies?: ExposedInstanceDependencies;
8
+ logService?: Log;
9
+ packageUrl: string;
10
+ }
5
11
  export function validateBundleInfo(
6
- { mismatch }: BundleInfo,
7
- {
8
- exposedDependencies = {},
9
- logService,
10
- packageName,
11
- }: { exposedDependencies?: ExposedDependencies; logService?: Log; packageName: string }
12
+ { mismatch, mfeHasCompatibleLaunchDarklyVersion }: BundleInfo,
13
+ { exposedDependencies = {}, exposedInstanceDependencies, logService, packageUrl }: Context
12
14
  ) {
13
- if (!mismatch || !logService) {
15
+ if (!logService) {
14
16
  return;
15
17
  }
16
18
 
17
- const data = { package: packageName, dependencies: JSON.stringify(mismatch) };
18
- if (Object.keys(exposedDependencies).length === 0) {
19
- logService.warning({
20
- category: 'MicroFrontends.NoExposedDependencies',
21
- message:
22
- 'Cannot use light bundle because the host is not exposing dependencies or the list of shared dependencies is empty.',
23
- data,
24
- });
25
- } else {
19
+ if (mismatch) {
20
+ const data = { package: packageUrl, dependencies: JSON.stringify(mismatch) };
21
+ if (Object.keys(exposedDependencies).length === 0) {
22
+ logService.warning({
23
+ category: 'MicroFrontends.NoExposedDependencies',
24
+ message:
25
+ 'Cannot use light bundle because the host is not exposing dependencies or the list of shared dependencies is empty.',
26
+ data,
27
+ });
28
+ } else {
29
+ logService.warning({
30
+ category: 'MicroFrontends.DependenciesMismatch',
31
+ message: 'Some of the package dependencies have incompatible versions.',
32
+ data,
33
+ });
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Note, only checking false here because the value is undefined when the host
39
+ * or the MFE isn't using LaunchDarkly at all.
40
+ */
41
+
42
+ if (mfeHasCompatibleLaunchDarklyVersion === false) {
43
+ const data = {
44
+ package: packageUrl,
45
+ hostVersion: exposedInstanceDependencies?.launchDarkly?.version ?? '',
46
+ };
26
47
  logService.warning({
27
- category: 'MicroFrontends.DependenciesMismatch',
28
- message: 'Some of the package dependencies have incompatible versions.',
48
+ category: 'MicroFrontends.LaunchDarklyMismatch',
49
+ message: 'LaunchDarkly versions are incompatible',
29
50
  data,
30
51
  });
31
52
  }
@@ -1,8 +1,9 @@
1
1
  import { Fragment, useMemo, useState } from 'react';
2
2
  import { Log } from '@servicetitan/log-service';
3
+ import { type LDService } from '@servicetitan/launchdarkly-service';
3
4
  import { useOptionalDependencies } from '@servicetitan/react-ioc';
4
5
 
5
- import { ExposedDependencies, IWebComponent } from '../common';
6
+ import { ExposedDependencies, ExposedInstanceDependencies, IWebComponent } from '../common';
6
7
  import { MFEContextData } from '../contexts/mfe-data-context';
7
8
  import { EventBus } from '../event-bus';
8
9
  import { BundleInfo } from './get-bundle-info';
@@ -15,11 +16,21 @@ interface WebComponentProps {
15
16
  bundleInfo: BundleInfo;
16
17
  eventBus: EventBus;
17
18
  exposedDependencies?: ExposedDependencies;
19
+ exposedInstanceDependencies?: ExposedInstanceDependencies;
20
+ ldService?: LDService;
18
21
  logService?: Log;
19
22
  }
20
23
 
21
24
  export function webComponent(props: WebComponentProps) {
22
- const { basename, bundleInfo, eventBus, exposedDependencies, logService } = props;
25
+ const {
26
+ basename,
27
+ bundleInfo,
28
+ eventBus,
29
+ exposedDependencies,
30
+ exposedInstanceDependencies,
31
+ ldService,
32
+ logService,
33
+ } = props;
23
34
  const { WebComponent, disposer, mfeSupportsRerendering } = bundleInfo;
24
35
  const elementName = getElementName(bundleInfo);
25
36
 
@@ -29,9 +40,11 @@ export function webComponent(props: WebComponentProps) {
29
40
 
30
41
  const handleRef = (webComponent: IWebComponent | null) => {
31
42
  webComponent?.provide({
43
+ ldService,
32
44
  logService,
33
45
  historyManager,
34
46
  exposedDependencies,
47
+ exposedInstanceDependencies,
35
48
  eventBus,
36
49
  basename,
37
50
  onReady: () => {