@squide/firefly 15.0.5 → 16.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/AppRouter.js.map +1 -1
  3. package/dist/AppRouterContext.js.map +1 -1
  4. package/dist/AppRouterReducer.d.ts +3 -4
  5. package/dist/AppRouterReducer.js +51 -82
  6. package/dist/AppRouterReducer.js.map +1 -1
  7. package/dist/AppRouterStore.js.map +1 -1
  8. package/dist/FireflyPlugin.d.ts +6 -0
  9. package/dist/FireflyPlugin.js +6 -0
  10. package/dist/FireflyPlugin.js.map +1 -0
  11. package/dist/FireflyProvider.js.map +1 -1
  12. package/dist/FireflyRuntime.d.ts +9 -7
  13. package/dist/FireflyRuntime.js +20 -28
  14. package/dist/FireflyRuntime.js.map +1 -1
  15. package/dist/GlobalDataQueriesError.js.map +1 -1
  16. package/dist/RootRoute.js.map +1 -1
  17. package/dist/honeycomb/activeSpan.js.map +1 -1
  18. package/dist/honeycomb/createTraceContextId.js.map +1 -1
  19. package/dist/honeycomb/initializeHoneycomb.js.map +1 -1
  20. package/dist/honeycomb/registerHoneycombInstrumentation.d.ts +8 -0
  21. package/dist/honeycomb/registerHoneycombInstrumentation.js +19 -136
  22. package/dist/honeycomb/registerHoneycombInstrumentation.js.map +1 -1
  23. package/dist/honeycomb/tracer.js.map +1 -1
  24. package/dist/honeycomb/utils.js.map +1 -1
  25. package/dist/index.d.ts +2 -3
  26. package/dist/index.js +4 -5
  27. package/dist/index.js.map +1 -1
  28. package/dist/initializeFirefly.d.ts +6 -6
  29. package/dist/initializeFirefly.js +26 -35
  30. package/dist/initializeFirefly.js.map +1 -1
  31. package/dist/internal.d.ts +6 -0
  32. package/dist/internal.js +26 -0
  33. package/dist/internal.js.map +1 -0
  34. package/dist/useAppRouterStore.js.map +1 -1
  35. package/dist/useCanFetchProtectedData.js.map +1 -1
  36. package/dist/useCanFetchPublicData.js.map +1 -1
  37. package/dist/useCanRegisterDeferredRegistrations.js.map +1 -1
  38. package/dist/useCanUpdateDeferredRegistrations.js.map +1 -1
  39. package/dist/useDeferredRegistrations.d.ts +1 -5
  40. package/dist/useDeferredRegistrations.js +2 -5
  41. package/dist/useDeferredRegistrations.js.map +1 -1
  42. package/dist/useExecuteOnce.js.map +1 -1
  43. package/dist/useIsActiveRouteProtected.js.map +1 -1
  44. package/dist/useIsBootstrapping.js.map +1 -1
  45. package/dist/useNavigationItems.js.map +1 -1
  46. package/dist/useProtectedDataHandler.js.map +1 -1
  47. package/dist/useProtectedDataQueries.js.map +1 -1
  48. package/dist/usePublicDataHandler.js.map +1 -1
  49. package/dist/usePublicDataQueries.js.map +1 -1
  50. package/dist/useRegisterDeferredRegistrations.d.ts +1 -4
  51. package/dist/useRegisterDeferredRegistrations.js +1 -5
  52. package/dist/useRegisterDeferredRegistrations.js.map +1 -1
  53. package/dist/useStrictRegistrationMode.js +10 -17
  54. package/dist/useStrictRegistrationMode.js.map +1 -1
  55. package/dist/useUpdateDeferredRegistrations.d.ts +3 -4
  56. package/dist/useUpdateDeferredRegistrations.js +6 -6
  57. package/dist/useUpdateDeferredRegistrations.js.map +1 -1
  58. package/package.json +27 -23
  59. package/src/AppRouterReducer.ts +51 -89
  60. package/src/FireflyPlugin.ts +11 -0
  61. package/src/FireflyRuntime.tsx +31 -34
  62. package/src/honeycomb/registerHoneycombInstrumentation.ts +30 -169
  63. package/src/index.ts +14 -3
  64. package/src/initializeFirefly.ts +51 -48
  65. package/src/internal.ts +22 -0
  66. package/src/useDeferredRegistrations.ts +3 -12
  67. package/src/useRegisterDeferredRegistrations.ts +1 -2
  68. package/src/useStrictRegistrationMode.ts +10 -15
  69. package/src/useUpdateDeferredRegistrations.ts +8 -2
@@ -20,43 +20,27 @@ import {
20
20
  type LocalModulesRegistrationStartedEventPayload,
21
21
  type ModuleRegistrationError
22
22
  } from "@squide/core";
23
- import {
24
- DeferredRegistrationsUpdateCompletedEvent,
25
- DeferredRegistrationsUpdateStartedEvent,
26
- RemoteModuleDeferredRegistrationFailedEvent,
27
- RemoteModuleDeferredRegistrationUpdateFailedEvent,
28
- type RemoteModuleRegistrationError,
29
- RemoteModuleRegistrationFailedEvent,
30
- RemoteModulesDeferredRegistrationCompletedEvent,
31
- type RemoteModulesDeferredRegistrationCompletedEventPayload,
32
- RemoteModulesDeferredRegistrationStartedEvent,
33
- type RemoteModulesDeferredRegistrationStartedEventPayload,
34
- RemoteModulesDeferredRegistrationsUpdateCompletedEvent,
35
- type RemoteModulesDeferredRegistrationsUpdateCompletedEventPayload,
36
- RemoteModulesDeferredRegistrationsUpdateStartedEvent,
37
- type RemoteModulesDeferredRegistrationsUpdateStartedEventPayload,
38
- RemoteModulesRegistrationCompletedEvent,
39
- type RemoteModulesRegistrationCompletedEventPayload,
40
- RemoteModulesRegistrationStartedEvent,
41
- type RemoteModulesRegistrationStartedEventPayload
42
- } from "@squide/module-federation";
43
23
  import { ApplicationBoostrappedEvent, type AppRouterWaitState, ModulesReadyEvent, ModulesRegisteredEvent, MswReadyEvent, ProtectedDataReadyEvent, PublicDataReadyEvent } from "../AppRouterReducer.ts";
24
+ import { FireflyPlugin } from "../FireflyPlugin.ts";
44
25
  import type { FireflyRuntime } from "../FireflyRuntime.tsx";
45
26
  import { ApplicationBootstrappingStartedEvent } from "../initializeFirefly.ts";
46
27
  import { ProtectedDataFetchFailedEvent, ProtectedDataFetchStartedEvent } from "../useProtectedDataQueries.ts";
47
28
  import { PublicDataFetchFailedEvent, PublicDataFetchStartedEvent } from "../usePublicDataQueries.ts";
29
+ import { DeferredRegistrationsUpdateCompletedEvent, DeferredRegistrationsUpdateStartedEvent } from "../useUpdateDeferredRegistrations.ts";
48
30
  import { type ActiveSpan, createOverrideFetchRequestSpanWithActiveSpanContext, registerActiveSpanStack } from "./activeSpan.ts";
49
31
  import { getTracer } from "./tracer.ts";
50
32
  import { endActiveSpan, startActiveChildSpan, startChildSpan, startSpan, traceError } from "./utils.ts";
51
33
 
52
34
  // TIPS:
53
- // To query those traces in Honeycomb, use the following query filter: "root.name = squide-bootstrapping".
35
+ // To query those traces in Honeycomb, use the following query filter:
36
+ // "root.name = squide-bootstrapping" and
37
+ // "root.name = squide-deferred-registrations-update".
54
38
 
55
- interface AddProtectedListenerOptions extends AddListenerOptions {
39
+ export interface AddProtectedListenerOptions extends AddListenerOptions {
56
40
  onError?: (error: unknown) => void;
57
41
  }
58
42
 
59
- function addProtectedListener(runtime: FireflyRuntime, eventName: EventName, callback: EventCallbackFunction, options?: AddProtectedListenerOptions) {
43
+ export function addProtectedListener(runtime: FireflyRuntime, eventName: EventName, callback: EventCallbackFunction, options?: AddProtectedListenerOptions) {
60
44
  const protectedCallback = (...args: unknown[]) => {
61
45
  try {
62
46
  callback(...args);
@@ -71,6 +55,9 @@ function addProtectedListener(runtime: FireflyRuntime, eventName: EventName, cal
71
55
  runtime.eventBus.addListener(eventName, protectedCallback, options);
72
56
  }
73
57
 
58
+ export type GetSpanFunction = () => Span;
59
+ export type HoneycombTrackingUnmanagedErrorHandler = (error: unknown) => void;
60
+
74
61
  type DataFetchState = "none" | "fetching-data" | "public-data-ready" | "protected-data-ready" | "data-ready" | "data-fetch-failed";
75
62
 
76
63
  export function reduceDataFetchEvents(
@@ -172,12 +159,11 @@ function registerTrackingListeners(runtime: FireflyRuntime) {
172
159
  let bootstrappingSpanHasEnded: boolean = false;
173
160
  let localModuleRegistrationSpan: Span;
174
161
  let localModuleDeferredRegistrationSpan: Span;
175
- let remoteModuleRegistrationSpan: Span;
176
- let remoteModuleDeferredRegistrationSpan: Span;
177
162
  let dataFetchSpan: ActiveSpan;
178
163
  let deferredRegistrationsUpdateSpan: Span;
179
164
  let localModuleDeferredRegistrationsUpdateSpan: ActiveSpan;
180
- let remoteModuleDeferredRegistrationsUpdateSpan: ActiveSpan;
165
+
166
+ const pluginsUnmanagedErrorHandlers: HoneycombTrackingUnmanagedErrorHandler[] = [];
181
167
 
182
168
  const handleUnmanagedError = (error: unknown) => {
183
169
  if (bootstrappingSpan && !bootstrappingSpanHasEnded) {
@@ -195,14 +181,6 @@ function registerTrackingListeners(runtime: FireflyRuntime) {
195
181
  localModuleDeferredRegistrationSpan.end();
196
182
  }
197
183
 
198
- if (remoteModuleRegistrationSpan) {
199
- remoteModuleRegistrationSpan.end();
200
- }
201
-
202
- if (remoteModuleDeferredRegistrationSpan) {
203
- remoteModuleDeferredRegistrationSpan.end();
204
- }
205
-
206
184
  if (dataFetchSpan) {
207
185
  dataFetchSpan.instance.end();
208
186
  }
@@ -215,9 +193,9 @@ function registerTrackingListeners(runtime: FireflyRuntime) {
215
193
  localModuleDeferredRegistrationsUpdateSpan.instance.end();
216
194
  }
217
195
 
218
- if (remoteModuleDeferredRegistrationsUpdateSpan) {
219
- remoteModuleDeferredRegistrationsUpdateSpan.instance.end();
220
- }
196
+ pluginsUnmanagedErrorHandlers.forEach(x => {
197
+ x(error);
198
+ });
221
199
  };
222
200
 
223
201
  addProtectedListener(runtime, ApplicationBootstrappingStartedEvent, () => {
@@ -332,92 +310,6 @@ function registerTrackingListeners(runtime: FireflyRuntime) {
332
310
  onError: handleUnmanagedError
333
311
  });
334
312
 
335
- addProtectedListener(runtime, RemoteModulesRegistrationStartedEvent, (payload: unknown) => {
336
- const attributes = {
337
- "app.squide.remote_count": (payload as RemoteModulesRegistrationStartedEventPayload).remoteCount
338
- };
339
-
340
- if (bootstrappingSpan) {
341
- bootstrappingSpan.addEvent("remote-module-registration-started", attributes);
342
- }
343
-
344
- remoteModuleRegistrationSpan = startChildSpan(bootstrappingSpan, (options, context) => {
345
- return getTracer().startSpan("remote-module-registration", { ...options, attributes }, context);
346
- });
347
- }, {
348
- once: true,
349
- onError: handleUnmanagedError
350
- });
351
-
352
- addProtectedListener(runtime, RemoteModulesRegistrationCompletedEvent, (payload: unknown) => {
353
- if (bootstrappingSpan) {
354
- bootstrappingSpan.addEvent("remote-module-registration-completed", {
355
- "app.squide.remote_count": (payload as RemoteModulesRegistrationCompletedEventPayload).remoteCount
356
- });
357
- }
358
-
359
- if (remoteModuleRegistrationSpan) {
360
- remoteModuleRegistrationSpan.end();
361
- }
362
- }, {
363
- once: true,
364
- onError: handleUnmanagedError
365
- });
366
-
367
- // Can occur multiple times.
368
- addProtectedListener(runtime, RemoteModuleRegistrationFailedEvent, (payload: unknown) => {
369
- const registrationError = payload as RemoteModuleRegistrationError;
370
-
371
- if (remoteModuleRegistrationSpan) {
372
- traceError(remoteModuleRegistrationSpan, registrationError);
373
- }
374
- }, {
375
- onError: handleUnmanagedError
376
- });
377
-
378
- addProtectedListener(runtime, RemoteModulesDeferredRegistrationStartedEvent, (payload: unknown) => {
379
- const attributes = {
380
- "app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationStartedEventPayload).registrationCount
381
- };
382
-
383
- if (bootstrappingSpan) {
384
- bootstrappingSpan.addEvent("remote-module-deferred-registration-started", attributes);
385
- }
386
-
387
- remoteModuleDeferredRegistrationSpan = startChildSpan(bootstrappingSpan, (options, context) => {
388
- return getTracer().startSpan("remote-module-deferred-registration", { ...options, attributes }, context);
389
- });
390
- }, {
391
- once: true,
392
- onError: handleUnmanagedError
393
- });
394
-
395
- addProtectedListener(runtime, RemoteModulesDeferredRegistrationCompletedEvent, (payload: unknown) => {
396
- if (bootstrappingSpan) {
397
- bootstrappingSpan.addEvent("remote-module-deferred-registration-completed", {
398
- "app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationCompletedEventPayload).registrationCount
399
- });
400
- }
401
-
402
- if (remoteModuleDeferredRegistrationSpan) {
403
- remoteModuleDeferredRegistrationSpan.end();
404
- }
405
- }, {
406
- once: true,
407
- onError: handleUnmanagedError
408
- });
409
-
410
- // Can occur multiple times.
411
- addProtectedListener(runtime, RemoteModuleDeferredRegistrationFailedEvent, (payload: unknown) => {
412
- const registrationError = payload as RemoteModuleRegistrationError;
413
-
414
- if (remoteModuleDeferredRegistrationSpan) {
415
- traceError(remoteModuleDeferredRegistrationSpan, registrationError);
416
- }
417
- }, {
418
- onError: handleUnmanagedError
419
- });
420
-
421
313
  const handleFetchDataStarted = () => {
422
314
  dataFetchSpan = startActiveChildSpan(bootstrappingSpan, (options, context) => {
423
315
  const name = "data-fetch";
@@ -576,57 +468,26 @@ function registerTrackingListeners(runtime: FireflyRuntime) {
576
468
  onError: handleUnmanagedError
577
469
  });
578
470
 
579
- // Can occur multiple times.
580
- addProtectedListener(runtime, RemoteModulesDeferredRegistrationsUpdateStartedEvent, (payload: unknown) => {
581
- const attributes = {
582
- "app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationsUpdateStartedEventPayload).registrationCount
583
- };
584
-
585
- if (deferredRegistrationsUpdateSpan) {
586
- deferredRegistrationsUpdateSpan.addEvent("remote-module-deferred-registrations-update-started", attributes);
587
- }
588
-
589
- remoteModuleDeferredRegistrationsUpdateSpan = startActiveChildSpan(deferredRegistrationsUpdateSpan, (options, context) => {
590
- const name = "remote-module-deferred-registrations-update";
591
-
592
- const span = getTracer().startSpan(name, {
593
- attributes,
594
- ...options
595
- }, context);
596
-
597
- return {
598
- name,
599
- span
600
- };
601
- });
602
- }, {
603
- onError: handleUnmanagedError
604
- });
471
+ const getBootstrappingSpan: GetSpanFunction = () => bootstrappingSpan;
472
+ const getDeferredRegistrationsUpdateSpan: GetSpanFunction = () => deferredRegistrationsUpdateSpan;
605
473
 
606
- // Can occur multiple times.
607
- addProtectedListener(runtime, RemoteModulesDeferredRegistrationsUpdateCompletedEvent, (payload: unknown) => {
608
- if (deferredRegistrationsUpdateSpan) {
609
- deferredRegistrationsUpdateSpan.addEvent("remote-module-deferred-registrations-update-completed", {
610
- "app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationsUpdateCompletedEventPayload).registrationCount
611
- });
612
- }
474
+ const handlePluginUnmanagedError: HoneycombTrackingUnmanagedErrorHandler = (error: unknown) => {
475
+ handleUnmanagedError(error);
476
+ };
613
477
 
614
- if (remoteModuleDeferredRegistrationsUpdateSpan) {
615
- endActiveSpan(remoteModuleDeferredRegistrationsUpdateSpan);
616
- }
617
- }, {
618
- onError: handleUnmanagedError
619
- });
478
+ // Register plugins specific handlers for Honeycomb telemetry.
479
+ runtime.plugins.forEach(x => {
480
+ const plugin = x as FireflyPlugin;
620
481
 
621
- // Can occur multiple times.
622
- addProtectedListener(runtime, RemoteModuleDeferredRegistrationUpdateFailedEvent, (payload: unknown) => {
623
- const registrationError = payload as RemoteModuleRegistrationError;
482
+ if (plugin.registerHoneycombTrackingListeners) {
483
+ const unmanagedErrorHandler = plugin.registerHoneycombTrackingListeners(
484
+ getBootstrappingSpan,
485
+ getDeferredRegistrationsUpdateSpan,
486
+ handlePluginUnmanagedError
487
+ );
624
488
 
625
- if (remoteModuleDeferredRegistrationsUpdateSpan) {
626
- traceError(remoteModuleDeferredRegistrationsUpdateSpan.instance, registrationError);
489
+ pluginsUnmanagedErrorHandlers.push(unmanagedErrorHandler);
627
490
  }
628
- }, {
629
- onError: handleUnmanagedError
630
491
  });
631
492
  }
632
493
 
package/src/index.ts CHANGED
@@ -1,14 +1,25 @@
1
1
  export * from "@squide/core";
2
- export * from "@squide/module-federation";
3
2
  export * from "@squide/msw";
4
3
  export * from "@squide/react-router";
5
4
 
5
+ export type { FireflyPlugin } from "./FireflyPlugin.ts";
6
6
  export * from "./FireflyProvider.tsx";
7
7
  export * from "./FireflyRuntime.tsx";
8
8
 
9
9
  export * from "./AppRouter.tsx";
10
- export * from "./AppRouterContext.ts";
11
- export * from "./AppRouterReducer.ts";
10
+ export {
11
+ ActiveRouteIsProtectedEvent,
12
+ ActiveRouteIsPublicEvent,
13
+ ApplicationBoostrappedEvent,
14
+ DeferredRegistrationsUpdatedEvent,
15
+ ModulesReadyEvent,
16
+ ModulesRegisteredEvent,
17
+ MswReadyEvent,
18
+ ProtectedDataReadyEvent,
19
+ ProtectedDataUpdatedEvent,
20
+ PublicDataReadyEvent,
21
+ PublicDataUpdatedEvent
22
+ } from "./AppRouterReducer.ts";
12
23
 
13
24
  export * from "./AppRouterStore.ts";
14
25
  export * from "./GlobalDataQueriesError.ts";
@@ -1,6 +1,5 @@
1
- import { isFunction, registerLocalModules, type ModuleRegisterFunction, type RegisterModulesOptions } from "@squide/core";
2
- import { registerRemoteModules, type RemoteDefinition } from "@squide/module-federation";
3
- import { setMswAsReady } from "@squide/msw";
1
+ import { isFunction, ModuleDefinition, toLocalModuleDefinitions, type ModuleRegisterFunction, type RegisterModulesOptions } from "@squide/core";
2
+ import { MswPlugin } from "@squide/msw";
4
3
  import type { HoneycombInstrumentationPartialClient } from "@workleap-telemetry/core";
5
4
  import { FireflyRuntime, type FireflyRuntimeOptions } from "./FireflyRuntime.tsx";
6
5
  import { initializeHoneycomb } from "./honeycomb/initializeHoneycomb.ts";
@@ -13,26 +12,19 @@ export type StartMswFunction<TRuntime = FireflyRuntime> = (runtime: TRuntime) =>
13
12
 
14
13
  export interface InitializeFireflyOptions<TRuntime extends FireflyRuntime, TContext = unknown, TData = unknown> extends RegisterModulesOptions<TContext>, FireflyRuntimeOptions {
15
14
  localModules?: ModuleRegisterFunction<TRuntime, TContext, TData>[];
16
- remotes?: RemoteDefinition[];
15
+ moduleDefinitions?: ModuleDefinition<TRuntime, TContext, TData>[];
16
+ useMsw?: boolean;
17
17
  honeycombInstrumentationClient?: HoneycombInstrumentationPartialClient;
18
18
  startMsw?: StartMswFunction<FireflyRuntime>;
19
19
  onError?: OnInitializationErrorFunction;
20
20
  }
21
21
 
22
- function propagateRegistrationErrors(results: PromiseSettledResult<unknown[]>, onError: OnInitializationErrorFunction) {
23
- if (results) {
24
- if (results.status === "fulfilled") {
25
- results.value.forEach(x => {
26
- onError(x);
27
- });
28
- }
29
- }
30
- }
31
-
32
- export function bootstrap<TRuntime extends FireflyRuntime = FireflyRuntime, TContext = unknown, TData = unknown>(runtime: TRuntime, options: InitializeFireflyOptions<TRuntime, TContext, TData> = {}) {
22
+ export function bootstrap<TRuntime extends FireflyRuntime = FireflyRuntime, TContext = unknown, TData = unknown>(
23
+ runtime: TRuntime,
24
+ modulesDefinitions: ModuleDefinition<TRuntime, TContext, TData>[],
25
+ options: Omit<InitializeFireflyOptions<TRuntime, TContext, TData>, "localModules" | "moduleDefinitions"> = {}
26
+ ) {
33
27
  const {
34
- localModules = [],
35
- remotes = [],
36
28
  startMsw,
37
29
  onError,
38
30
  context
@@ -40,43 +32,51 @@ export function bootstrap<TRuntime extends FireflyRuntime = FireflyRuntime, TCon
40
32
 
41
33
  runtime.eventBus.dispatch(ApplicationBootstrappingStartedEvent);
42
34
 
43
- Promise.allSettled([
44
- registerLocalModules<TRuntime, TContext, TData>(localModules, runtime, { context }),
45
- registerRemoteModules(remotes, runtime, { context })
46
- ]).then(results => {
47
- if (runtime.isMswEnabled) {
48
- if (!isFunction(startMsw)) {
49
- throw new Error("[squide] When MSW is enabled, the \"startMsw\" function must be provided.");
35
+ runtime.moduleManager.registerModules(modulesDefinitions, { context })
36
+ .then(results => {
37
+ if (runtime.isMswEnabled) {
38
+ if (!isFunction(startMsw)) {
39
+ throw new Error("[squide] When MSW is enabled, the \"startMsw\" function must be provided.");
40
+ }
41
+
42
+ startMsw(runtime)
43
+ .then(() => {
44
+ if (runtime.isMswEnabled) {
45
+ runtime.getMswState().setAsReady();
46
+ }
47
+ })
48
+ .catch((error: unknown) => {
49
+ runtime.logger
50
+ .withText("[squide] An error occured while starting MSW.")
51
+ .withError(error as Error)
52
+ .error();
53
+ });
50
54
  }
51
55
 
52
- startMsw(runtime)
53
- .then(() => {
54
- setMswAsReady();
55
- })
56
- .catch((error: unknown) => {
57
- runtime.logger
58
- .withText("[squide] An error occured while starting MSW.")
59
- .withError(error as Error)
60
- .error();
56
+ if (onError) {
57
+ results.forEach(error => {
58
+ onError(error);
61
59
  });
62
- }
63
-
64
- if (onError) {
65
- propagateRegistrationErrors(results[0], onError);
66
- propagateRegistrationErrors(results[1], onError);
67
- }
68
- });
60
+ }
61
+ });
69
62
  }
70
63
 
71
64
  let hasExecuted = false;
72
65
 
66
+ // Should only be used by tests.
67
+ export function __resetHasExecutedGuard() {
68
+ hasExecuted = false;
69
+ }
70
+
73
71
  export function initializeFirefly<TContext = unknown, TData = unknown>(options: InitializeFireflyOptions<FireflyRuntime, TContext, TData> = {}) {
74
72
  const {
75
73
  mode,
74
+ localModules = [],
75
+ moduleDefinitions = [],
76
76
  useMsw,
77
- loggers,
78
- plugins,
77
+ plugins = [],
79
78
  honeycombInstrumentationClient,
79
+ loggers,
80
80
  onError
81
81
  } = options;
82
82
 
@@ -86,9 +86,12 @@ export function initializeFirefly<TContext = unknown, TData = unknown>(options:
86
86
 
87
87
  hasExecuted = true;
88
88
 
89
+ if (useMsw) {
90
+ plugins.push(x => new MswPlugin(x));
91
+ }
92
+
89
93
  const runtime = new FireflyRuntime({
90
94
  mode,
91
- useMsw,
92
95
  honeycombInstrumentationClient,
93
96
  loggers,
94
97
  plugins
@@ -101,12 +104,12 @@ export function initializeFirefly<TContext = unknown, TData = unknown>(options:
101
104
  }
102
105
  })
103
106
  .finally(() => {
104
- bootstrap(runtime, options);
107
+ bootstrap(
108
+ runtime,
109
+ [...moduleDefinitions, ...toLocalModuleDefinitions(localModules)],
110
+ options
111
+ );
105
112
  });
106
113
 
107
114
  return runtime;
108
115
  }
109
-
110
- export function __resetHasExecuteGuard() {
111
- hasExecuted = false;
112
- }
@@ -0,0 +1,22 @@
1
+ export { AppRouterDispatcherContext, AppRouterStateContext } from "./AppRouterContext.ts";
2
+ export { __clearAppReducerDispatchProxy, __setAppReducerDispatchProxyFactory, useAppRouterReducer, type AppRouterDispatch, type AppRouterState } from "./AppRouterReducer.ts";
3
+
4
+ export type { ActiveSpan, ActiveSpanId } from "./honeycomb/activeSpan.ts";
5
+ export { addProtectedListener, type AddProtectedListenerOptions, type GetSpanFunction, type HoneycombTrackingUnmanagedErrorHandler } from "./honeycomb/registerHoneycombInstrumentation.ts";
6
+ export { getTracer } from "./honeycomb/tracer.ts";
7
+ export {
8
+ endActiveSpan,
9
+ startActiveChildSpan,
10
+ startActiveSpan,
11
+ startChildSpan,
12
+ startSpan,
13
+ traceError,
14
+ type StartActiveChildSpanFactory,
15
+ type StartActiveChildSpanFactoryReturn,
16
+ type StartActiveSpanFactory,
17
+ type StartActiveSpanFactoryReturn,
18
+ type StartChildSpanFactory,
19
+ type StartSpanFactory,
20
+ type TraceErrorOptions
21
+ } from "./honeycomb/utils.ts";
22
+
@@ -5,21 +5,12 @@ import { useCanUpdateDeferredRegistrations } from "./useCanUpdateDeferredRegistr
5
5
  import { useRegisterDeferredRegistrations } from "./useRegisterDeferredRegistrations.ts";
6
6
  import { useUpdateDeferredRegistrations } from "./useUpdateDeferredRegistrations.ts";
7
7
 
8
- export interface DeferredRegistrationsErrorsObject {
9
- localModuleErrors: ModuleRegistrationError[];
10
- remoteModuleErrors: ModuleRegistrationError[];
11
- }
12
-
13
- export type DeferredRegistrationsErrorCallback = (errorsObject: DeferredRegistrationsErrorsObject) => void;
8
+ export type DeferredRegistrationsErrorCallback = (errors: ModuleRegistrationError[]) => void;
14
9
 
15
10
  export interface UseDeferredRegistrationsOptions {
16
11
  onError?: DeferredRegistrationsErrorCallback;
17
12
  }
18
13
 
19
- function hasError({ localModuleErrors, remoteModuleErrors }: DeferredRegistrationsErrorsObject) {
20
- return localModuleErrors.length > 0 || remoteModuleErrors.length > 0;
21
- }
22
-
23
14
  export function useDeferredRegistrations(data: unknown, { onError }: UseDeferredRegistrationsOptions = {}) {
24
15
  const runtime = useRuntime();
25
16
 
@@ -34,7 +25,7 @@ export function useDeferredRegistrations(data: unknown, { onError }: UseDeferred
34
25
  const register = async () => {
35
26
  const errors = await registerDeferredRegistrations(data, runtime);
36
27
 
37
- if (hasError(errors) && onError) {
28
+ if (errors.length > 0 && onError) {
38
29
  onError(errors);
39
30
  }
40
31
  };
@@ -48,7 +39,7 @@ export function useDeferredRegistrations(data: unknown, { onError }: UseDeferred
48
39
  const update = async () => {
49
40
  const errors = await updateDeferredRegistrations(data, runtime);
50
41
 
51
- if (hasError(errors) && onError) {
42
+ if (errors.length > 0 && onError) {
52
43
  onError(errors);
53
44
  }
54
45
  };
@@ -1,9 +1,8 @@
1
1
  import type { Runtime } from "@squide/core";
2
- import { registerDeferredRegistrations } from "@squide/module-federation";
3
2
  import { useCallback } from "react";
4
3
 
5
4
  export function useRegisterDeferredRegistrations() {
6
5
  return useCallback(<TData = unknown, TRuntime extends Runtime = Runtime>(data: TData, runtime: TRuntime) => {
7
- return registerDeferredRegistrations(data, runtime);
6
+ return runtime.moduleManager.registerDeferredRegistrations(data);
8
7
  }, []);
9
8
  }
@@ -1,28 +1,23 @@
1
- import { addLocalModuleRegistrationStatusChangedListener, getLocalModuleRegistrationStatus, removeLocalModuleRegistrationStatusChangedListener, useRuntime } from "@squide/core";
2
- import { addRemoteModuleRegistrationStatusChangedListener, areModulesReady, getRemoteModuleRegistrationStatus, removeRemoteModuleRegistrationStatusChangedListener } from "@squide/module-federation";
1
+ import { Runtime, useRuntime } from "@squide/core";
3
2
  import { useEffect, useSyncExternalStore } from "react";
4
3
 
5
- function subscribeToLocalModuleRegistrationStatusChanged(callback: () => void) {
6
- addLocalModuleRegistrationStatusChangedListener(callback);
4
+ function subscribeToModulesReady(runtime: Runtime) {
5
+ return (callback: () => void) => {
6
+ runtime.moduleManager.registerModulesReadyListener(callback);
7
7
 
8
- return () => removeLocalModuleRegistrationStatusChangedListener(callback);
9
- }
10
-
11
- function subscribeToRemoteModuleRegistrationStatusChanged(callback: () => void) {
12
- addRemoteModuleRegistrationStatusChangedListener(callback);
13
-
14
- return () => removeRemoteModuleRegistrationStatusChangedListener(callback);
8
+ return () => runtime.moduleManager.removeModulesReadyListener(callback);
9
+ };
15
10
  }
16
11
 
17
12
  export function useStrictRegistrationMode() {
18
13
  const runtime = useRuntime();
19
14
 
20
- const localModuleStatus = useSyncExternalStore(subscribeToLocalModuleRegistrationStatusChanged, getLocalModuleRegistrationStatus);
21
- const remoteModuleStatus = useSyncExternalStore(subscribeToRemoteModuleRegistrationStatusChanged, getRemoteModuleRegistrationStatus);
15
+ // This listener is only executed if the modules are ready.
16
+ const areModulesReady = useSyncExternalStore(subscribeToModulesReady(runtime), () => runtime.moduleManager.getAreModulesReady());
22
17
 
23
18
  useEffect(() => {
24
- if (areModulesReady(localModuleStatus, remoteModuleStatus)) {
19
+ if (areModulesReady) {
25
20
  runtime._validateRegistrations();
26
21
  }
27
- }, [runtime, localModuleStatus, remoteModuleStatus]);
22
+ }, [runtime, areModulesReady]);
28
23
  }
@@ -1,16 +1,22 @@
1
1
  import type { Runtime } from "@squide/core";
2
- import { updateDeferredRegistrations } from "@squide/module-federation";
3
2
  import { useCallback } from "react";
4
3
  import { useAppRouterDispatcher } from "./AppRouterContext.ts";
5
4
 
5
+ export const DeferredRegistrationsUpdateStartedEvent = "squide-deferred-registrations-update-started";
6
+ export const DeferredRegistrationsUpdateCompletedEvent = "squide-deferred-registrations-update-completed-started";
7
+
6
8
  export function useUpdateDeferredRegistrations() {
7
9
  const dispatch = useAppRouterDispatcher();
8
10
 
9
11
  return useCallback(async <TData = unknown, TRuntime extends Runtime = Runtime>(data: TData, runtime: TRuntime) => {
10
- const errors = await updateDeferredRegistrations(data, runtime);
12
+ runtime.eventBus.dispatch(DeferredRegistrationsUpdateStartedEvent);
13
+
14
+ const errors = await runtime.moduleManager.updateDeferredRegistrations(data);
11
15
 
12
16
  dispatch({ type: "deferred-registrations-updated" });
13
17
 
18
+ runtime.eventBus.dispatch(DeferredRegistrationsUpdateCompletedEvent);
19
+
14
20
  return errors;
15
21
  }, [dispatch]);
16
22
  }