Skip to content

Commit 5f16979

Browse files
feat: Update use deferred registration to not depend on fetch hooks (#567)
1 parent fd44eea commit 5f16979

7 files changed

Lines changed: 249 additions & 363 deletions

.changeset/tricky-laws-battle.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@squide/firefly-module-federation": patch
3+
"@squide/firefly": patch
4+
---
5+
6+
useDeferredRegistrations will now trigger a deferred registration update whenever the data object reference changes, even if no global data has been fetch or no feature flags changed.

packages/firefly-module-federation/tests/useDeferredRegistrations.test.tsx

Lines changed: 117 additions & 103 deletions
Large diffs are not rendered by default.

packages/firefly/src/useCanUpdateDeferredRegistrations.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,26 @@ import { useAppRouterState } from "./AppRouterContext.ts";
22

33
export function useCanUpdateDeferredRegistrations() {
44
const {
5-
areModulesReady,
6-
publicDataUpdatedAt,
7-
protectedDataUpdatedAt,
8-
featureFlagsUpdatedAt,
9-
deferredRegistrationsUpdatedAt
5+
areModulesReady
6+
// publicDataUpdatedAt,
7+
// protectedDataUpdatedAt,
8+
// featureFlagsUpdatedAt,
9+
// deferredRegistrationsUpdatedAt
1010
} = useAppRouterState();
1111

12-
return (
13-
// Do not trigger an update if the deferred registrations has not been registered yet (if there are deferred registrations, once they are
14-
// registered, the modules will be marked as ready).
15-
areModulesReady
16-
// Make sure the apps is actually having deferred registrations.
17-
&& deferredRegistrationsUpdatedAt
18-
// If either the public data or the protected data has been updated, update the deferred registrations.
19-
&& (
20-
(publicDataUpdatedAt && publicDataUpdatedAt > deferredRegistrationsUpdatedAt) ||
21-
(protectedDataUpdatedAt && protectedDataUpdatedAt > deferredRegistrationsUpdatedAt) ||
22-
(featureFlagsUpdatedAt && featureFlagsUpdatedAt > deferredRegistrationsUpdatedAt)
23-
)
24-
);
12+
return areModulesReady;
13+
14+
// return !!(
15+
// // Do not trigger an update if the deferred registrations has not been registered yet (if there are deferred registrations, once they are
16+
// // registered, the modules will be marked as ready).
17+
// areModulesReady
18+
// // Make sure the apps is actually having deferred registrations.
19+
// // && deferredRegistrationsUpdatedAt
20+
// // // If either the public data or the protected data has been updated, update the deferred registrations.
21+
// // && (
22+
// // (publicDataUpdatedAt && publicDataUpdatedAt > deferredRegistrationsUpdatedAt) ||
23+
// // (protectedDataUpdatedAt && protectedDataUpdatedAt > deferredRegistrationsUpdatedAt) ||
24+
// // (featureFlagsUpdatedAt && featureFlagsUpdatedAt > deferredRegistrationsUpdatedAt)
25+
// // )
26+
// );
2527
}

packages/firefly/src/useDeferredRegistrations.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useRuntime, type ModuleRegistrationError } from "@squide/core";
2-
import { useEffect } from "react";
2+
import { useEffect, useRef } from "react";
33
import { FireflyRuntime } from "./FireflyRuntime.tsx";
44
import { useCanRegisterDeferredRegistrations } from "./useCanRegisterDeferredRegistrations.ts";
55
import { useCanUpdateDeferredRegistrations } from "./useCanUpdateDeferredRegistrations.ts";
@@ -14,6 +14,7 @@ export interface UseDeferredRegistrationsOptions {
1414

1515
export function useDeferredRegistrations(data?: unknown, { onError }: UseDeferredRegistrationsOptions = {}) {
1616
const runtime = useRuntime() as FireflyRuntime;
17+
// const isExecutedBecauseModulesAreNowReadyRef = useRef(true);
1718

1819
const canRegisterDeferredRegistrations = useCanRegisterDeferredRegistrations();
1920
const canUpdateDeferredRegistrations = useCanUpdateDeferredRegistrations();
@@ -35,8 +36,20 @@ export function useDeferredRegistrations(data?: unknown, { onError }: UseDeferre
3536
}
3637
}, [canRegisterDeferredRegistrations, registerDeferredRegistrations, data, onError]);
3738

39+
const isInitialUpdateDeferredRegistrationsExecution = useRef(true);
40+
3841
useEffect(() => {
3942
if (canUpdateDeferredRegistrations) {
43+
// HACK: Skipping the first execution successfully passing the gate because this is due to
44+
// the modules being ready, and it's most certainly the same data that has been forwarded earlier to the deferred registration.
45+
// Ideally, instead of this hacky ref, it would be a ref tracking the previous data object, and the deferred registration would
46+
// only be updated if the current data object != than the previous data object. Sadly, it is not possible because
47+
// of the feature flags.
48+
if (isInitialUpdateDeferredRegistrationsExecution.current) {
49+
isInitialUpdateDeferredRegistrationsExecution.current = false;
50+
return;
51+
}
52+
4053
const update = async () => {
4154
const errors = await updateDeferredRegistrations(data);
4255

packages/firefly/tests/useCanUpdateDeferredRegistrations.test.tsx

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,9 @@ function renderUseCanUpdateDeferredRegistrationsHook<TProps>(state: AppRouterSta
1717
});
1818
}
1919

20-
test.concurrent("when modules are ready, the deferred registrations has been registered once, and the public data has been updated, return true", ({ expect }) => {
20+
test.concurrent("when modules are ready, return true", ({ expect }) => {
2121
const state = createDefaultAppRouterState();
2222
state.areModulesReady = true;
23-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
24-
state.publicDataUpdatedAt = Date.parse("2020-03-14");
25-
26-
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
27-
28-
expect(result.current).toBeTruthy();
29-
});
30-
31-
test.concurrent("when modules are ready, the deferred registrations has been registered once, and the protected data has been updated, return true", ({ expect }) => {
32-
const state = createDefaultAppRouterState();
33-
state.areModulesReady = true;
34-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
35-
state.protectedDataUpdatedAt = Date.parse("2020-03-14");
36-
37-
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
38-
39-
expect(result.current).toBeTruthy();
40-
});
41-
42-
test.concurrent("when modules are ready, the deferred registrations has been registered once, the public data has been updated, and the protected data has been updated, return true", ({ expect }) => {
43-
const state = createDefaultAppRouterState();
44-
state.areModulesReady = true;
45-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
46-
state.publicDataUpdatedAt = Date.parse("2020-03-14");
47-
state.protectedDataUpdatedAt = Date.parse("2020-03-14");
48-
49-
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
50-
51-
expect(result.current).toBeTruthy();
52-
});
53-
54-
test.concurrent("when modules are ready, the deferred registrations has been registered once, and the feature flags has been updated, return true", ({ expect }) => {
55-
const state = createDefaultAppRouterState();
56-
state.areModulesReady = true;
57-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
58-
state.featureFlagsUpdatedAt = Date.parse("2020-03-14");
5923

6024
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
6125

@@ -65,69 +29,6 @@ test.concurrent("when modules are ready, the deferred registrations has been reg
6529
test.concurrent("when modules are not ready, return false", ({ expect }) => {
6630
const state = createDefaultAppRouterState();
6731
state.areModulesReady = false;
68-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
69-
state.publicDataUpdatedAt = Date.parse("2020-03-14");
70-
state.protectedDataUpdatedAt = Date.parse("2020-04-14");
71-
state.featureFlagsUpdatedAt = Date.parse("2020-05-14");
72-
73-
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
74-
75-
expect(result.current).toBeFalsy();
76-
});
77-
78-
test.concurrent("when there's no deferred registrations, return false", ({ expect }) => {
79-
const state = createDefaultAppRouterState();
80-
state.areModulesReady = true;
81-
state.deferredRegistrationsUpdatedAt = undefined;
82-
state.publicDataUpdatedAt = Date.parse("2020-02-14");
83-
state.protectedDataUpdatedAt = Date.parse("2020-03-14");
84-
state.featureFlagsUpdatedAt = Date.parse("2020-04-14");
85-
86-
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
87-
88-
expect(result.current).toBeFalsy();
89-
});
90-
91-
test.concurrent("when the public and protected data has never been updated, return false", ({ expect }) => {
92-
const state = createDefaultAppRouterState();
93-
state.areModulesReady = true;
94-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
95-
state.publicDataUpdatedAt = undefined;
96-
state.protectedDataUpdatedAt = undefined;
97-
98-
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
99-
100-
expect(result.current).toBeFalsy();
101-
});
102-
103-
test.concurrent("when the public and protected data has never not updated since the last deferred registration update, return false", ({ expect }) => {
104-
const state = createDefaultAppRouterState();
105-
state.areModulesReady = true;
106-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
107-
state.publicDataUpdatedAt = Date.parse("2020-01-16");
108-
state.protectedDataUpdatedAt = Date.parse("2020-01-18");
109-
110-
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
111-
112-
expect(result.current).toBeFalsy();
113-
});
114-
115-
test.concurrent("when the feature flags has never been updated, return false", ({ expect }) => {
116-
const state = createDefaultAppRouterState();
117-
state.areModulesReady = true;
118-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
119-
state.featureFlagsUpdatedAt = undefined;
120-
121-
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
122-
123-
expect(result.current).toBeFalsy();
124-
});
125-
126-
test.concurrent("when the feature flags has never not updated since the last deferred registration update, return false", ({ expect }) => {
127-
const state = createDefaultAppRouterState();
128-
state.areModulesReady = true;
129-
state.deferredRegistrationsUpdatedAt = Date.parse("2020-02-14");
130-
state.featureFlagsUpdatedAt = Date.parse("2020-01-16");
13132

13233
const { result } = renderUseCanUpdateDeferredRegistrationsHook(state);
13334

0 commit comments

Comments
 (0)