@squide/firefly 8.0.0 → 9.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.
- package/CHANGELOG.md +66 -2
- package/dist/AppRouter.d.ts +13 -26
- package/dist/AppRouter.js +6 -1
- package/dist/AppRouterContext.d.ts +9 -0
- package/dist/AppRouterContext.js +1 -0
- package/dist/AppRouterReducer.d.ts +31 -0
- package/dist/AppRouterReducer.js +1 -0
- package/dist/{fireflyRuntime.d.ts → FireflyRuntime.d.ts} +3 -2
- package/dist/FireflyRuntime.js +2 -0
- package/dist/GlobalDataQueriesError.d.ts +8 -0
- package/dist/GlobalDataQueriesError.js +1 -0
- package/dist/RootRoute.d.ts +5 -0
- package/dist/RootRoute.js +3 -0
- package/dist/chunk-2E76JVV7.js +41 -0
- package/dist/chunk-36U4TTNR.js +34 -0
- package/dist/chunk-ENUCXEMN.js +180 -0
- package/dist/chunk-FKQ7XQEU.js +54 -0
- package/dist/chunk-G32YX2KR.js +22 -0
- package/dist/chunk-H6F7HDB3.js +9 -0
- package/dist/chunk-HE5HKFL3.js +16 -0
- package/dist/chunk-I6L3AYOB.js +24 -0
- package/dist/chunk-IOMSOUAL.js +20 -0
- package/dist/chunk-L5BP3WP3.js +21 -0
- package/dist/chunk-MZG2PJJG.js +19 -0
- package/dist/chunk-N2GOIQ5E.js +14 -0
- package/dist/chunk-PP3MRMJJ.js +11 -0
- package/dist/chunk-PU7MASPN.js +18 -0
- package/dist/chunk-RG5N56BQ.js +55 -0
- package/dist/chunk-VUMBZ5BP.js +46 -0
- package/dist/chunk-WOPD33CM.js +25 -0
- package/dist/chunk-WVRMJZV6.js +18 -0
- package/dist/chunk-YRWFYWK4.js +11 -0
- package/dist/index.d.ts +21 -4
- package/dist/index.js +19 -2
- package/dist/useCanFetchProtectedData.d.ts +3 -0
- package/dist/useCanFetchProtectedData.js +2 -0
- package/dist/useCanFetchPublicData.d.ts +3 -0
- package/dist/useCanFetchPublicData.js +2 -0
- package/dist/useCanRegisterDeferredRegistrations.d.ts +3 -0
- package/dist/useCanRegisterDeferredRegistrations.js +2 -0
- package/dist/useCanUpdateDeferredRegistrations.d.ts +3 -0
- package/dist/useCanUpdateDeferredRegistrations.js +2 -0
- package/dist/useDeferredRegistrations.d.ts +13 -0
- package/dist/useDeferredRegistrations.js +6 -0
- package/dist/useIsActiveRouteProtected.d.ts +3 -0
- package/dist/useIsActiveRouteProtected.js +1 -0
- package/dist/useIsBootstrapping.d.ts +3 -0
- package/dist/useIsBootstrapping.js +2 -0
- package/dist/useNavigationItems.d.ts +5 -0
- package/dist/useNavigationItems.js +2 -0
- package/dist/useProtectedDataQueries.d.ts +9 -0
- package/dist/useProtectedDataQueries.js +4 -0
- package/dist/usePublicDataQueries.d.ts +8 -0
- package/dist/usePublicDataQueries.js +4 -0
- package/dist/useRegisterDeferredRegistrations.d.ts +9 -0
- package/dist/useRegisterDeferredRegistrations.js +1 -0
- package/dist/useStrictRegistrationMode.d.ts +3 -0
- package/dist/useStrictRegistrationMode.js +1 -0
- package/dist/useUpdateDeferredRegistrations.d.ts +9 -0
- package/dist/useUpdateDeferredRegistrations.js +2 -0
- package/package.json +16 -17
- package/dist/chunk-URNAUMUG.js +0 -160
- package/dist/chunk-YXMNS6U3.js +0 -45
- package/dist/fireflyRuntime.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
# @squide/firefly
|
|
2
2
|
|
|
3
|
+
## 9.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#182](https://github.com/gsoft-inc/wl-squide/pull/182) [`58cf066`](https://github.com/gsoft-inc/wl-squide/commit/58cf066e87e23611510c254cca96016bd2bad08a) Thanks [@patricklafrance](https://github.com/patricklafrance)! - ## Firefly v9
|
|
8
|
+
|
|
9
|
+
This major version of @squide/firefly introduces TanStack Query as the official library for fetching the global data of a Squide's application and features a complete rewrite of the AppRouter component, which now uses a state machine to manage the application's bootstrapping flow.
|
|
10
|
+
|
|
11
|
+
Prior to v9, Squide applications couldn't use TanStack Query to fetch global data, making it challenging for Workleap's applications to keep their global data in sync with the server state. With v9, applications can now leverage custom wrappers of the useQueries hook to fetch and keep their global data up-to-date with the server state. Additionally, the new deferred registrations update feature allows applications to even keep their conditional navigation items in sync with the server state.
|
|
12
|
+
|
|
13
|
+
Finally, with v9, Squide's philosophy has evolved. We used to describe Squide as a shell for federated applications. Now, we refer to Squide as a shell for modular applications. After playing with Squide's local module feature for a while, we discovered that Squide offers significant value even for non-federated applications, which triggered this shift in philosophy.
|
|
14
|
+
|
|
15
|
+
> For a full breakdown of the changres and a migration procedure, read the following [documentation](https://gsoft-inc.github.io/wl-squide/guides/migrate-to-firefly-v9/).
|
|
16
|
+
|
|
17
|
+
## Breaking changes
|
|
18
|
+
|
|
19
|
+
- The `useAreModulesRegistered` hook has been removed, use the `useIsBootstrapping` hook instead.
|
|
20
|
+
- The `useAreModulesReady` hook has been removed, use the `useIsBootstrapping` hook instead.
|
|
21
|
+
- The `useIsMswStarted` hook has been removed, use the `useIsBootstrapping` hook instead.
|
|
22
|
+
- The `completeModuleRegistrations` function as been removed use the `useDeferredRegistrations` hook instead.
|
|
23
|
+
- The `completeLocalModulesRegistrations` function has been removed use the `useDeferredRegistrations` hook instead.
|
|
24
|
+
- The `completeRemoteModuleRegistrations` function has been removed use the `useDeferredRegistrations` hook instead.
|
|
25
|
+
- The `useSession` hook has been removed, define your own React context instead.
|
|
26
|
+
- The `useIsAuthenticated` hook has been removed, define your own React context instead.
|
|
27
|
+
- The `sessionAccessor` option has been removed from the `FireflyRuntime` options, define your own React context instead.
|
|
28
|
+
- Removed supports for deferred routes.
|
|
29
|
+
- Plugin's constructor now requires a runtime instance argument.
|
|
30
|
+
- Plugins now registers with a factory function.
|
|
31
|
+
- Full rewrite of the `AppRouter` component.
|
|
32
|
+
|
|
33
|
+
## Renamed
|
|
34
|
+
|
|
35
|
+
- The `setMswAsStarted` function has been renamed to `setMswIsReady`.
|
|
36
|
+
|
|
37
|
+
## Others
|
|
38
|
+
|
|
39
|
+
- The `@squide/firefly` package now takes a peerDependency on `@tanstack/react-query`.
|
|
40
|
+
- The `@squide/firefly` package doesn't takes a peerDependency on `react-error-boundary` anymore.
|
|
41
|
+
|
|
42
|
+
## New hooks and functions
|
|
43
|
+
|
|
44
|
+
- A new `useIsBoostrapping` hook is now available.
|
|
45
|
+
- A new `useDeferredRegistrations` hook is now available.
|
|
46
|
+
- A new `usePublicDataQueries` hook is now available.
|
|
47
|
+
- A new `useProtectedDataQueries` hook is now available.
|
|
48
|
+
- A new `isGlobalDataQueriesError` function is now available.
|
|
49
|
+
|
|
50
|
+
## Improvements
|
|
51
|
+
|
|
52
|
+
- Deferred registration functions now always receive a `data` argument.
|
|
53
|
+
- Deferred registration functions now receives a new `operation` argument.
|
|
54
|
+
- Navigation items now include a `$canRender` option, enabling modules to control whether a navigation item should be rendered.
|
|
55
|
+
- New `$key` option for navigation items.
|
|
56
|
+
|
|
57
|
+
For more details about the changes and a migration procedure, read the following [documentation](https://gsoft-inc.github.io/wl-squide/guides/migrate-to-firefly-v9/).
|
|
58
|
+
|
|
59
|
+
### Patch Changes
|
|
60
|
+
|
|
61
|
+
- Updated dependencies [[`58cf066`](https://github.com/gsoft-inc/wl-squide/commit/58cf066e87e23611510c254cca96016bd2bad08a)]:
|
|
62
|
+
- @squide/core@5.0.0
|
|
63
|
+
- @squide/module-federation@6.0.0
|
|
64
|
+
- @squide/msw@3.0.0
|
|
65
|
+
- @squide/react-router@6.0.0
|
|
66
|
+
|
|
3
67
|
## 8.0.0
|
|
4
68
|
|
|
5
69
|
### Major Changes
|
|
@@ -58,7 +122,7 @@
|
|
|
58
122
|
import { defineDevHostConfig } from "@squide/firefly-webpack-configs";
|
|
59
123
|
import { swcConfig } from "./swc.dev.js";
|
|
60
124
|
|
|
61
|
-
export default defineDevHostConfig(swcConfig,
|
|
125
|
+
export default defineDevHostConfig(swcConfig, 8080, {
|
|
62
126
|
overlay: false,
|
|
63
127
|
});
|
|
64
128
|
```
|
|
@@ -98,7 +162,7 @@
|
|
|
98
162
|
},
|
|
99
163
|
];
|
|
100
164
|
|
|
101
|
-
export default defineDevHostConfig(swcConfig,
|
|
165
|
+
export default defineDevHostConfig(swcConfig, 8080, Remotes, {
|
|
102
166
|
overlay: false,
|
|
103
167
|
});
|
|
104
168
|
```
|
package/dist/AppRouter.d.ts
CHANGED
|
@@ -1,36 +1,23 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { ReactElement } from 'react';
|
|
3
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
2
|
import { Route } from '@squide/react-router';
|
|
3
|
+
import { ReactElement } from 'react';
|
|
5
4
|
import { RouterProviderProps } from 'react-router-dom';
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
interface
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
isPublicDataLoaded: boolean;
|
|
15
|
-
isProtectedDataLoaded: boolean;
|
|
16
|
-
onCompleteRegistrations?: OnCompleteRegistrationsFunction;
|
|
17
|
-
waitForMsw: boolean;
|
|
18
|
-
areModulesRegistered: boolean;
|
|
19
|
-
areModulesReady: boolean;
|
|
6
|
+
interface AppRouterRenderFunctionArgs {
|
|
7
|
+
routes: Route[];
|
|
8
|
+
}
|
|
9
|
+
interface RenderRouterProviderFunctionArgs {
|
|
10
|
+
rootRoute: ReactElement;
|
|
11
|
+
registeredRoutes: Route[];
|
|
12
|
+
routerProviderProps: Omit<RouterProviderProps, "router">;
|
|
20
13
|
}
|
|
21
|
-
|
|
22
|
-
type RenderRouterProviderFunction = (routes: Route[], providerProps: Omit<RouterProviderProps, "router">) => ReactElement;
|
|
14
|
+
type RenderRouterProviderFunction = (args: RenderRouterProviderFunctionArgs) => ReactElement;
|
|
23
15
|
interface AppRouterProps {
|
|
24
|
-
fallbackElement: ReactElement;
|
|
25
|
-
errorElement: ReactElement;
|
|
26
|
-
onLoadPublicData?: OnLoadPublicDataFunction;
|
|
27
|
-
onLoadProtectedData?: OnLoadProtectedDataFunction;
|
|
28
|
-
isPublicDataLoaded?: boolean;
|
|
29
|
-
isProtectedDataLoaded?: boolean;
|
|
30
|
-
onCompleteRegistrations?: OnCompleteRegistrationsFunction;
|
|
31
16
|
waitForMsw: boolean;
|
|
17
|
+
waitForPublicData?: boolean;
|
|
18
|
+
waitForProtectedData?: boolean;
|
|
32
19
|
children: RenderRouterProviderFunction;
|
|
33
20
|
}
|
|
34
|
-
declare function AppRouter(props: AppRouterProps):
|
|
21
|
+
declare function AppRouter(props: AppRouterProps): react_jsx_runtime.JSX.Element;
|
|
35
22
|
|
|
36
|
-
export { AppRouter, type AppRouterProps,
|
|
23
|
+
export { AppRouter, type AppRouterProps, type AppRouterRenderFunctionArgs, type RenderRouterProviderFunction, type RenderRouterProviderFunctionArgs };
|
package/dist/AppRouter.js
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
export { AppRouter
|
|
1
|
+
export { AppRouter } from './chunk-36U4TTNR.js';
|
|
2
|
+
import './chunk-WOPD33CM.js';
|
|
3
|
+
import './chunk-ENUCXEMN.js';
|
|
4
|
+
import './chunk-MZG2PJJG.js';
|
|
5
|
+
import './chunk-PP3MRMJJ.js';
|
|
6
|
+
import './chunk-G32YX2KR.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { AppRouterState, AppRouterDispatch } from './AppRouterReducer.js';
|
|
3
|
+
|
|
4
|
+
declare const AppRouterStateContext: react.Context<AppRouterState | undefined>;
|
|
5
|
+
declare function useAppRouterState(): AppRouterState;
|
|
6
|
+
declare const AppRouterDispatcherContext: react.Context<AppRouterDispatch | undefined>;
|
|
7
|
+
declare function useAppRouterDispatcher(): AppRouterDispatch;
|
|
8
|
+
|
|
9
|
+
export { AppRouterDispatcherContext, AppRouterStateContext, useAppRouterDispatcher, useAppRouterState };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AppRouterDispatcherContext, AppRouterStateContext, useAppRouterDispatcher, useAppRouterState } from './chunk-G32YX2KR.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Dispatch } from 'react';
|
|
2
|
+
|
|
3
|
+
interface AppRouterState {
|
|
4
|
+
waitForMsw: boolean;
|
|
5
|
+
waitForPublicData: boolean;
|
|
6
|
+
waitForProtectedData: boolean;
|
|
7
|
+
areModulesRegistered: boolean;
|
|
8
|
+
areModulesReady: boolean;
|
|
9
|
+
isMswReady: boolean;
|
|
10
|
+
isPublicDataReady: boolean;
|
|
11
|
+
isProtectedDataReady: boolean;
|
|
12
|
+
publicDataUpdatedAt?: number;
|
|
13
|
+
protectedDataUpdatedAt?: number;
|
|
14
|
+
deferredRegistrationsUpdatedAt?: number;
|
|
15
|
+
isActiveRouteProtected: boolean;
|
|
16
|
+
isUnauthorized: boolean;
|
|
17
|
+
}
|
|
18
|
+
type AppRouterActionType = "modules-registered" | "modules-ready" | "msw-ready" | "public-data-ready" | "protected-data-ready" | "public-data-updated" | "protected-data-updated" | "deferred-registrations-updated" | "active-route-is-protected" | "is-unauthorized";
|
|
19
|
+
interface AppRouterAction {
|
|
20
|
+
type: AppRouterActionType;
|
|
21
|
+
}
|
|
22
|
+
type AppRouterDispatch = Dispatch<AppRouterAction>;
|
|
23
|
+
declare function getAreModulesRegistered(): boolean;
|
|
24
|
+
declare function getAreModulesReady(): boolean;
|
|
25
|
+
declare function useModuleRegistrationStatusDispatcher(areModulesRegisteredValue: boolean, areModulesReadyValue: boolean, dispatch: AppRouterDispatch): void;
|
|
26
|
+
declare function useMswStatusDispatcher(isMswReadyValue: boolean, dispatch: AppRouterDispatch): void;
|
|
27
|
+
declare function __setAppReducerDispatchProxyFactory(factory: (reactDispatch: AppRouterDispatch) => AppRouterDispatch): void;
|
|
28
|
+
declare function __clearAppReducerDispatchProxy(): void;
|
|
29
|
+
declare function useAppRouterReducer(waitForMsw: boolean, waitForPublicData: boolean, waitForProtectedData: boolean): [AppRouterState, AppRouterDispatch];
|
|
30
|
+
|
|
31
|
+
export { type AppRouterAction, type AppRouterActionType, type AppRouterDispatch, type AppRouterState, __clearAppReducerDispatchProxy, __setAppReducerDispatchProxyFactory, getAreModulesReady, getAreModulesRegistered, useAppRouterReducer, useModuleRegistrationStatusDispatcher, useMswStatusDispatcher };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { __clearAppReducerDispatchProxy, __setAppReducerDispatchProxyFactory, getAreModulesReady, getAreModulesRegistered, useAppRouterReducer, useModuleRegistrationStatusDispatcher, useMswStatusDispatcher } from './chunk-ENUCXEMN.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RuntimeOptions } from '@squide/core';
|
|
2
|
-
import { ReactRouterRuntime } from '@squide/react-router';
|
|
1
|
+
import { RuntimeOptions, RegisterRouteOptions } from '@squide/core';
|
|
2
|
+
import { ReactRouterRuntime, Route } from '@squide/react-router';
|
|
3
3
|
import { RequestHandler } from 'msw';
|
|
4
4
|
|
|
5
5
|
interface FireflyRuntimeOptions extends RuntimeOptions {
|
|
@@ -10,6 +10,7 @@ declare class FireflyRuntime extends ReactRouterRuntime {
|
|
|
10
10
|
constructor({ plugins, useMsw, ...options }?: FireflyRuntimeOptions);
|
|
11
11
|
registerRequestHandlers(handlers: RequestHandler[]): void;
|
|
12
12
|
get requestHandlers(): RequestHandler[];
|
|
13
|
+
registerRoute(route: Route, options?: RegisterRouteOptions): void;
|
|
13
14
|
get isMswEnabled(): boolean;
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare class GlobalDataQueriesError extends Error {
|
|
2
|
+
#private;
|
|
3
|
+
constructor(message: string, errors: Error[]);
|
|
4
|
+
get errors(): Error[];
|
|
5
|
+
}
|
|
6
|
+
declare function isGlobalDataQueriesError(error?: unknown): error is GlobalDataQueriesError;
|
|
7
|
+
|
|
8
|
+
export { GlobalDataQueriesError, isGlobalDataQueriesError };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GlobalDataQueriesError, isGlobalDataQueriesError } from './chunk-HE5HKFL3.js';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useRegisterDeferredRegistrations } from './chunk-YRWFYWK4.js';
|
|
2
|
+
import { useUpdateDeferredRegistrations } from './chunk-N2GOIQ5E.js';
|
|
3
|
+
import { useCanRegisterDeferredRegistrations } from './chunk-PU7MASPN.js';
|
|
4
|
+
import { useCanUpdateDeferredRegistrations } from './chunk-WVRMJZV6.js';
|
|
5
|
+
import { useRuntime } from '@squide/core';
|
|
6
|
+
import { useEffect } from 'react';
|
|
7
|
+
|
|
8
|
+
function hasError({ localModuleErrors, remoteModuleErrors }) {
|
|
9
|
+
return localModuleErrors.length > 0 || remoteModuleErrors.length > 0;
|
|
10
|
+
}
|
|
11
|
+
function useDeferredRegistrations(data, { onError } = {}) {
|
|
12
|
+
const runtime = useRuntime();
|
|
13
|
+
const canRegisterDeferredRegistrations = useCanRegisterDeferredRegistrations();
|
|
14
|
+
const canUpdateDeferredRegistrations = useCanUpdateDeferredRegistrations();
|
|
15
|
+
const registerDeferredRegistrations = useRegisterDeferredRegistrations();
|
|
16
|
+
const updateDeferredRegistrations = useUpdateDeferredRegistrations();
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (canRegisterDeferredRegistrations) {
|
|
19
|
+
const register = async () => {
|
|
20
|
+
const errors = await registerDeferredRegistrations(data, runtime);
|
|
21
|
+
if (hasError(errors) && onError) {
|
|
22
|
+
onError(errors);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
register();
|
|
26
|
+
}
|
|
27
|
+
}, [canRegisterDeferredRegistrations, registerDeferredRegistrations, data, onError, runtime]);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (canUpdateDeferredRegistrations) {
|
|
30
|
+
const update = async () => {
|
|
31
|
+
const errors = await updateDeferredRegistrations(data, runtime);
|
|
32
|
+
if (hasError(errors) && onError) {
|
|
33
|
+
onError(errors);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
update();
|
|
37
|
+
}
|
|
38
|
+
}, [canUpdateDeferredRegistrations, updateDeferredRegistrations, data, onError, runtime]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { useDeferredRegistrations };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useStrictRegistrationMode } from './chunk-WOPD33CM.js';
|
|
2
|
+
import { useAppRouterReducer } from './chunk-ENUCXEMN.js';
|
|
3
|
+
import { RootRoute } from './chunk-MZG2PJJG.js';
|
|
4
|
+
import { AppRouterDispatcherContext, AppRouterStateContext } from './chunk-G32YX2KR.js';
|
|
5
|
+
import { useLogger } from '@squide/core';
|
|
6
|
+
import { useRoutes } from '@squide/react-router';
|
|
7
|
+
import { useEffect, useMemo } from 'react';
|
|
8
|
+
import { jsx } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
function AppRouter(props) {
|
|
11
|
+
const {
|
|
12
|
+
waitForMsw,
|
|
13
|
+
waitForPublicData = false,
|
|
14
|
+
waitForProtectedData = false,
|
|
15
|
+
children: renderRouterProvider
|
|
16
|
+
} = props;
|
|
17
|
+
const [state, dispatch] = useAppRouterReducer(waitForMsw, waitForPublicData, waitForProtectedData);
|
|
18
|
+
const logger = useLogger();
|
|
19
|
+
const routes = useRoutes();
|
|
20
|
+
useStrictRegistrationMode();
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
logger.debug("[squide] AppRouter state updated:", state);
|
|
23
|
+
}, [state, logger]);
|
|
24
|
+
const routerProvider = useMemo(() => {
|
|
25
|
+
return renderRouterProvider({
|
|
26
|
+
rootRoute: /* @__PURE__ */ jsx(RootRoute, {}),
|
|
27
|
+
registeredRoutes: routes,
|
|
28
|
+
routerProviderProps: {}
|
|
29
|
+
});
|
|
30
|
+
}, [routes, renderRouterProvider]);
|
|
31
|
+
return /* @__PURE__ */ jsx(AppRouterDispatcherContext.Provider, { value: dispatch, children: /* @__PURE__ */ jsx(AppRouterStateContext.Provider, { value: state, children: routerProvider }) });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { AppRouter };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { getLocalModuleRegistrationStatus, useLogger, addLocalModuleRegistrationStatusChangedListener, removeLocalModuleRegistrationStatusChangedListener } from '@squide/core';
|
|
2
|
+
import { getRemoteModuleRegistrationStatus, areModulesRegistered, areModulesReady, addRemoteModuleRegistrationStatusChangedListener, removeRemoteModuleRegistrationStatusChangedListener } from '@squide/module-federation';
|
|
3
|
+
import { addMswStateChangedListener, removeMswStateChangedListener, isMswReady } from '@squide/msw';
|
|
4
|
+
import { useEffect, useReducer, useCallback, useMemo } from 'react';
|
|
5
|
+
|
|
6
|
+
// src/AppRouterReducer.ts
|
|
7
|
+
function useVerboseDispatch(dispatch) {
|
|
8
|
+
const logger = useLogger();
|
|
9
|
+
return useCallback((action) => {
|
|
10
|
+
logger.debug("[squide] The following action has been dispatched to the AppRouter reducer:", action);
|
|
11
|
+
dispatch(action);
|
|
12
|
+
}, [dispatch, logger]);
|
|
13
|
+
}
|
|
14
|
+
function reducer(state, action) {
|
|
15
|
+
let newState = state;
|
|
16
|
+
switch (action.type) {
|
|
17
|
+
case "modules-registered": {
|
|
18
|
+
newState = {
|
|
19
|
+
...newState,
|
|
20
|
+
areModulesRegistered: true
|
|
21
|
+
};
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
case "modules-ready": {
|
|
25
|
+
newState = {
|
|
26
|
+
...newState,
|
|
27
|
+
areModulesReady: true,
|
|
28
|
+
// Will be set even if the app is not using deferred registrations.
|
|
29
|
+
deferredRegistrationsUpdatedAt: Date.now()
|
|
30
|
+
};
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
case "msw-ready": {
|
|
34
|
+
newState = {
|
|
35
|
+
...newState,
|
|
36
|
+
isMswReady: true
|
|
37
|
+
};
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case "public-data-ready": {
|
|
41
|
+
newState = {
|
|
42
|
+
...newState,
|
|
43
|
+
isPublicDataReady: true,
|
|
44
|
+
publicDataUpdatedAt: Date.now()
|
|
45
|
+
};
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case "protected-data-ready": {
|
|
49
|
+
newState = {
|
|
50
|
+
...newState,
|
|
51
|
+
isProtectedDataReady: true,
|
|
52
|
+
protectedDataUpdatedAt: Date.now()
|
|
53
|
+
};
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case "public-data-updated": {
|
|
57
|
+
newState = {
|
|
58
|
+
...newState,
|
|
59
|
+
publicDataUpdatedAt: Date.now()
|
|
60
|
+
};
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case "protected-data-updated": {
|
|
64
|
+
newState = {
|
|
65
|
+
...newState,
|
|
66
|
+
protectedDataUpdatedAt: Date.now()
|
|
67
|
+
};
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case "deferred-registrations-updated": {
|
|
71
|
+
newState = {
|
|
72
|
+
...newState,
|
|
73
|
+
deferredRegistrationsUpdatedAt: Date.now()
|
|
74
|
+
};
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case "active-route-is-protected": {
|
|
78
|
+
newState = {
|
|
79
|
+
...newState,
|
|
80
|
+
isActiveRouteProtected: true
|
|
81
|
+
};
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case "is-unauthorized": {
|
|
85
|
+
newState = {
|
|
86
|
+
...newState,
|
|
87
|
+
isUnauthorized: true
|
|
88
|
+
};
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
default: {
|
|
92
|
+
throw new Error(`[squide] The AppRouter component state reducer doesn't support action type "${action.type}".`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return newState;
|
|
96
|
+
}
|
|
97
|
+
function getAreModulesRegistered() {
|
|
98
|
+
const localModuleStatus = getLocalModuleRegistrationStatus();
|
|
99
|
+
const remoteModuleStatus = getRemoteModuleRegistrationStatus();
|
|
100
|
+
return areModulesRegistered(localModuleStatus, remoteModuleStatus);
|
|
101
|
+
}
|
|
102
|
+
function getAreModulesReady() {
|
|
103
|
+
const localModuleStatus = getLocalModuleRegistrationStatus();
|
|
104
|
+
const remoteModuleStatus = getRemoteModuleRegistrationStatus();
|
|
105
|
+
return areModulesReady(localModuleStatus, remoteModuleStatus);
|
|
106
|
+
}
|
|
107
|
+
function useModuleRegistrationStatusDispatcher(areModulesRegisteredValue, areModulesReadyValue, dispatch) {
|
|
108
|
+
const logger = useLogger();
|
|
109
|
+
return useEffect(() => {
|
|
110
|
+
const handleModulesRegistrationStatusChange = () => {
|
|
111
|
+
if (!areModulesRegisteredValue && getAreModulesRegistered()) {
|
|
112
|
+
dispatch({ type: "modules-registered" });
|
|
113
|
+
}
|
|
114
|
+
if (!areModulesReadyValue && getAreModulesReady()) {
|
|
115
|
+
dispatch({ type: "modules-ready" });
|
|
116
|
+
logger.debug("[squide] %cModules are ready%c.", "color: white; background-color: green;", "");
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
addLocalModuleRegistrationStatusChangedListener(handleModulesRegistrationStatusChange);
|
|
120
|
+
addRemoteModuleRegistrationStatusChangedListener(handleModulesRegistrationStatusChange);
|
|
121
|
+
return () => {
|
|
122
|
+
removeLocalModuleRegistrationStatusChangedListener(handleModulesRegistrationStatusChange);
|
|
123
|
+
removeRemoteModuleRegistrationStatusChangedListener(handleModulesRegistrationStatusChange);
|
|
124
|
+
};
|
|
125
|
+
}, [areModulesRegisteredValue, areModulesReadyValue, dispatch, logger]);
|
|
126
|
+
}
|
|
127
|
+
function useMswStatusDispatcher(isMswReadyValue, dispatch) {
|
|
128
|
+
const logger = useLogger();
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
const handleMswStateChange = () => {
|
|
131
|
+
if (!isMswReadyValue && isMswReady()) {
|
|
132
|
+
dispatch({ type: "msw-ready" });
|
|
133
|
+
logger.debug("[squide] %cMSW is ready%c.", "color: white; background-color: green;", "");
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
addMswStateChangedListener(handleMswStateChange);
|
|
137
|
+
return () => {
|
|
138
|
+
removeMswStateChangedListener(handleMswStateChange);
|
|
139
|
+
};
|
|
140
|
+
}, [isMswReadyValue, dispatch, logger]);
|
|
141
|
+
}
|
|
142
|
+
var dispatchProxyFactory;
|
|
143
|
+
function __setAppReducerDispatchProxyFactory(factory) {
|
|
144
|
+
dispatchProxyFactory = factory;
|
|
145
|
+
}
|
|
146
|
+
function __clearAppReducerDispatchProxy() {
|
|
147
|
+
dispatchProxyFactory = void 0;
|
|
148
|
+
}
|
|
149
|
+
function useDispatchProxy(reactDispatch) {
|
|
150
|
+
return useMemo(() => {
|
|
151
|
+
return dispatchProxyFactory ? dispatchProxyFactory(reactDispatch) : reactDispatch;
|
|
152
|
+
}, [reactDispatch]);
|
|
153
|
+
}
|
|
154
|
+
function useAppRouterReducer(waitForMsw, waitForPublicData, waitForProtectedData) {
|
|
155
|
+
const [state, reactDispatch] = useReducer(reducer, {
|
|
156
|
+
waitForMsw,
|
|
157
|
+
waitForPublicData,
|
|
158
|
+
waitForProtectedData,
|
|
159
|
+
// When the modules registration functions are awaited, the event listeners are registered after the modules are registered.
|
|
160
|
+
areModulesRegistered: getAreModulesRegistered(),
|
|
161
|
+
areModulesReady: getAreModulesReady(),
|
|
162
|
+
isMswReady: isMswReady(),
|
|
163
|
+
isPublicDataReady: false,
|
|
164
|
+
isProtectedDataReady: false,
|
|
165
|
+
isActiveRouteProtected: false,
|
|
166
|
+
isUnauthorized: false
|
|
167
|
+
});
|
|
168
|
+
const {
|
|
169
|
+
areModulesRegistered: areModulesRegisteredValue,
|
|
170
|
+
areModulesReady: areModulesReadyValue,
|
|
171
|
+
isMswReady: isMswReadyValue
|
|
172
|
+
} = state;
|
|
173
|
+
const dispatchProxy = useDispatchProxy(reactDispatch);
|
|
174
|
+
const dispatch = useVerboseDispatch(dispatchProxy);
|
|
175
|
+
useModuleRegistrationStatusDispatcher(areModulesRegisteredValue, areModulesReadyValue, dispatch);
|
|
176
|
+
useMswStatusDispatcher(isMswReadyValue, dispatch);
|
|
177
|
+
return [state, dispatch];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export { __clearAppReducerDispatchProxy, __setAppReducerDispatchProxyFactory, getAreModulesReady, getAreModulesRegistered, useAppRouterReducer, useModuleRegistrationStatusDispatcher, useMswStatusDispatcher };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getAreModulesRegistered } from './chunk-ENUCXEMN.js';
|
|
2
|
+
import { MswPlugin } from '@squide/msw';
|
|
3
|
+
import { ReactRouterRuntime } from '@squide/react-router';
|
|
4
|
+
|
|
5
|
+
var FireflyRuntime = class extends ReactRouterRuntime {
|
|
6
|
+
#useMsw;
|
|
7
|
+
constructor({ plugins, useMsw, ...options } = {}) {
|
|
8
|
+
if (useMsw) {
|
|
9
|
+
super({
|
|
10
|
+
plugins: [
|
|
11
|
+
...plugins ?? [],
|
|
12
|
+
(runtime) => new MswPlugin(runtime)
|
|
13
|
+
],
|
|
14
|
+
...options
|
|
15
|
+
});
|
|
16
|
+
this.#useMsw = true;
|
|
17
|
+
} else {
|
|
18
|
+
super({
|
|
19
|
+
plugins,
|
|
20
|
+
...options
|
|
21
|
+
});
|
|
22
|
+
this.#useMsw = false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
registerRequestHandlers(handlers) {
|
|
26
|
+
const mswPlugin = this.getPlugin(MswPlugin.name);
|
|
27
|
+
if (!mswPlugin) {
|
|
28
|
+
throw new Error(`[squide] Cannot register the provided MSW request handlers because the runtime hasn't been initialized with MSW. Did you instanciate the FireflyRuntime with the "useMsw" option?`);
|
|
29
|
+
}
|
|
30
|
+
if (getAreModulesRegistered()) {
|
|
31
|
+
throw new Error("[squide] Cannot register an MSW request handlers once the modules are registered. Are you trying to register an MSW request handler in a deferred registration function? Only navigation items can be registered in a deferred registration function.");
|
|
32
|
+
}
|
|
33
|
+
mswPlugin.registerRequestHandlers(handlers);
|
|
34
|
+
}
|
|
35
|
+
// Must define a return type otherwise we get an "error TS2742: The inferred type of 'requestHandlers' cannot be named" error.
|
|
36
|
+
get requestHandlers() {
|
|
37
|
+
const mswPlugin = this.getPlugin(MswPlugin.name);
|
|
38
|
+
if (!mswPlugin) {
|
|
39
|
+
throw new Error(`[squide] Cannot retrieve MSW request handlers because the runtime hasn't been initialized with MSW. Did you instanciate the FireflyRuntime with the "useMsw" option?`);
|
|
40
|
+
}
|
|
41
|
+
return mswPlugin.requestHandlers;
|
|
42
|
+
}
|
|
43
|
+
registerRoute(route, options = {}) {
|
|
44
|
+
if (getAreModulesRegistered()) {
|
|
45
|
+
throw new Error("[squide] Cannot register a route once the modules are registered. Are you trying to register a route in a deferred registration function? Only navigation items can be registered in a deferred registration function.");
|
|
46
|
+
}
|
|
47
|
+
super.registerRoute(route, options);
|
|
48
|
+
}
|
|
49
|
+
get isMswEnabled() {
|
|
50
|
+
return this.#useMsw;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export { FireflyRuntime };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isNil } from '@squide/core';
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
|
|
4
|
+
// src/AppRouterContext.ts
|
|
5
|
+
var AppRouterStateContext = createContext(void 0);
|
|
6
|
+
function useAppRouterState() {
|
|
7
|
+
const state = useContext(AppRouterStateContext);
|
|
8
|
+
if (isNil(state)) {
|
|
9
|
+
throw new Error("[squide] The useAppRouterState hook must be called by a children of the AppRouter component.");
|
|
10
|
+
}
|
|
11
|
+
return state;
|
|
12
|
+
}
|
|
13
|
+
var AppRouterDispatcherContext = createContext(void 0);
|
|
14
|
+
function useAppRouterDispatcher() {
|
|
15
|
+
const dispatch = useContext(AppRouterDispatcherContext);
|
|
16
|
+
if (isNil(dispatch)) {
|
|
17
|
+
throw new Error("[squide] The useAppRouterDispatcher hook must be called by a children of the AppRouter component.");
|
|
18
|
+
}
|
|
19
|
+
return dispatch;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { AppRouterDispatcherContext, AppRouterStateContext, useAppRouterDispatcher, useAppRouterState };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/GlobalDataQueriesError.ts
|
|
2
|
+
var GlobalDataQueriesError = class extends Error {
|
|
3
|
+
#errors;
|
|
4
|
+
constructor(message, errors) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.#errors = errors;
|
|
7
|
+
}
|
|
8
|
+
get errors() {
|
|
9
|
+
return this.#errors;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
function isGlobalDataQueriesError(error) {
|
|
13
|
+
return error !== void 0 && error !== null && error instanceof GlobalDataQueriesError;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { GlobalDataQueriesError, isGlobalDataQueriesError };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useAppRouterState } from './chunk-G32YX2KR.js';
|
|
2
|
+
|
|
3
|
+
// src/useIsBootstrapping.ts
|
|
4
|
+
function useIsBootstrapping() {
|
|
5
|
+
const {
|
|
6
|
+
waitForMsw,
|
|
7
|
+
waitForPublicData,
|
|
8
|
+
waitForProtectedData,
|
|
9
|
+
areModulesReady,
|
|
10
|
+
isMswReady,
|
|
11
|
+
isPublicDataReady,
|
|
12
|
+
isProtectedDataReady,
|
|
13
|
+
isActiveRouteProtected,
|
|
14
|
+
isUnauthorized
|
|
15
|
+
} = useAppRouterState();
|
|
16
|
+
const isAppReady = !isUnauthorized && areModulesReady && (!waitForMsw || isMswReady) && (!waitForPublicData || isPublicDataReady) && (!waitForProtectedData || !isActiveRouteProtected || isProtectedDataReady);
|
|
17
|
+
const flush = (
|
|
18
|
+
// Only applicable when there's a unauthorized request while fetching the initial data.
|
|
19
|
+
isUnauthorized && (!waitForMsw || isMswReady) && (!waitForPublicData || isPublicDataReady)
|
|
20
|
+
);
|
|
21
|
+
return !isAppReady && !flush;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { useIsBootstrapping };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useAppRouterState } from './chunk-G32YX2KR.js';
|
|
2
|
+
|
|
3
|
+
// src/useCanFetchPublicData.ts
|
|
4
|
+
function useCanFetchPublicData() {
|
|
5
|
+
const {
|
|
6
|
+
waitForMsw,
|
|
7
|
+
areModulesRegistered,
|
|
8
|
+
areModulesReady,
|
|
9
|
+
isMswReady,
|
|
10
|
+
isPublicDataReady
|
|
11
|
+
} = useAppRouterState();
|
|
12
|
+
return (
|
|
13
|
+
// Always return true when the public data has already been fetched sucessfully so TanStack Query can update the data in the background.
|
|
14
|
+
isPublicDataReady || // Wait until the modules has been registered, but do not wait for the deferred registrations to be registered has they will probably
|
|
15
|
+
// depends on the protected data.
|
|
16
|
+
(areModulesRegistered || areModulesReady) && (!waitForMsw || isMswReady)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { useCanFetchPublicData };
|