piral-core 0.15.0-alpha.4036 → 0.15.0-alpha.4122
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/esm/Piral.d.ts +2 -2
- package/esm/Piral.js +14 -12
- package/esm/Piral.js.map +1 -1
- package/esm/PiralContext.d.ts +21 -0
- package/esm/PiralContext.js +34 -0
- package/esm/PiralContext.js.map +1 -0
- package/esm/actions/app.d.ts +1 -2
- package/esm/actions/app.js +0 -3
- package/esm/actions/app.js.map +1 -1
- package/esm/actions/state.js +5 -1
- package/esm/actions/state.js.map +1 -1
- package/esm/components/ErrorBoundary.d.ts +4 -0
- package/esm/components/ErrorBoundary.js +3 -3
- package/esm/components/ErrorBoundary.js.map +1 -1
- package/esm/components/ForeignComponentContainer.d.ts +1 -1
- package/esm/components/ForeignComponentContainer.js.map +1 -1
- package/esm/components/PiralGlobals.d.ts +6 -0
- package/esm/components/PiralGlobals.js +13 -0
- package/esm/components/PiralGlobals.js.map +1 -0
- package/esm/components/PiralSuspense.d.ts +5 -0
- package/esm/components/PiralSuspense.js +8 -0
- package/esm/components/PiralSuspense.js.map +1 -0
- package/esm/components/PiralView.d.ts +10 -1
- package/esm/components/PiralView.js +12 -24
- package/esm/components/PiralView.js.map +1 -1
- package/esm/components/ResponsiveLayout.d.ts +9 -1
- package/esm/components/ResponsiveLayout.js +5 -12
- package/esm/components/ResponsiveLayout.js.map +1 -1
- package/esm/components/components.d.ts +13 -6
- package/esm/components/components.js +13 -6
- package/esm/components/components.js.map +1 -1
- package/esm/components/index.d.ts +2 -12
- package/esm/components/index.js +2 -12
- package/esm/components/index.js.map +1 -1
- package/esm/components/wrapComponent.d.ts +1 -1
- package/esm/{components → defaults}/DefaultErrorInfo.d.ts +0 -0
- package/esm/{components → defaults}/DefaultErrorInfo.js +1 -2
- package/esm/defaults/DefaultErrorInfo.js.map +1 -0
- package/esm/{components → defaults}/DefaultLayout.d.ts +0 -0
- package/esm/{components → defaults}/DefaultLayout.js +0 -0
- package/esm/defaults/DefaultLayout.js.map +1 -0
- package/esm/{components/DefaultLoader.d.ts → defaults/DefaultLoadingIndicator.d.ts} +0 -0
- package/esm/{components/DefaultLoader.js → defaults/DefaultLoadingIndicator.js} +1 -1
- package/esm/defaults/DefaultLoadingIndicator.js.map +1 -0
- package/esm/{components → defaults}/DefaultRouteSwitch.d.ts +0 -0
- package/esm/{components → defaults}/DefaultRouteSwitch.js +0 -0
- package/esm/defaults/DefaultRouteSwitch.js.map +1 -0
- package/esm/defaults/DefaultRouter.d.ts +3 -0
- package/esm/{components → defaults}/DefaultRouter.js +0 -0
- package/esm/defaults/DefaultRouter.js.map +1 -0
- package/esm/defaults/index.d.ts +5 -0
- package/esm/defaults/index.js +6 -0
- package/esm/defaults/index.js.map +1 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/{components → setters}/SetComponent.d.ts +0 -0
- package/esm/{components → setters}/SetComponent.js +0 -0
- package/esm/setters/SetComponent.js.map +1 -0
- package/esm/{components → setters}/SetError.d.ts +0 -0
- package/esm/{components → setters}/SetError.js +0 -0
- package/esm/setters/SetError.js.map +1 -0
- package/esm/{components → setters}/SetErrors.d.ts +0 -0
- package/esm/{components → setters}/SetErrors.js +0 -0
- package/esm/setters/SetErrors.js.map +1 -0
- package/esm/{components → setters}/SetLayout.d.ts +0 -0
- package/esm/{components → setters}/SetLayout.js +0 -0
- package/esm/setters/SetLayout.js.map +1 -0
- package/esm/{components → setters}/SetProvider.d.ts +0 -0
- package/esm/{components → setters}/SetProvider.js +0 -0
- package/esm/setters/SetProvider.js.map +1 -0
- package/esm/{components → setters}/SetRedirect.d.ts +0 -0
- package/esm/{components → setters}/SetRedirect.js +0 -0
- package/esm/setters/SetRedirect.js.map +1 -0
- package/esm/{components → setters}/SetRoute.d.ts +0 -0
- package/esm/{components → setters}/SetRoute.js +0 -0
- package/esm/setters/SetRoute.js.map +1 -0
- package/esm/setters/index.d.ts +7 -0
- package/esm/setters/index.js +8 -0
- package/esm/setters/index.js.map +1 -0
- package/esm/state/createGlobalState.js +1 -2
- package/esm/state/createGlobalState.js.map +1 -1
- package/esm/state/withApi.js.map +1 -1
- package/esm/types/components.d.ts +9 -1
- package/esm/types/instance.d.ts +10 -3
- package/esm/types/state.d.ts +2 -12
- package/esm/utils/compare.d.ts +1 -1
- package/esm/utils/compare.js +20 -3
- package/esm/utils/compare.js.map +1 -1
- package/esm/utils/media.js +1 -1
- package/esm/utils/media.js.map +1 -1
- package/lib/Piral.d.ts +2 -2
- package/lib/Piral.js +13 -11
- package/lib/Piral.js.map +1 -1
- package/lib/PiralContext.d.ts +21 -0
- package/lib/PiralContext.js +38 -0
- package/lib/PiralContext.js.map +1 -0
- package/lib/actions/app.d.ts +1 -2
- package/lib/actions/app.js +1 -5
- package/lib/actions/app.js.map +1 -1
- package/lib/actions/index.js +6 -6
- package/lib/actions/index.js.map +1 -1
- package/lib/actions/state.js +5 -1
- package/lib/actions/state.js.map +1 -1
- package/lib/components/ErrorBoundary.d.ts +4 -0
- package/lib/components/ErrorBoundary.js +3 -3
- package/lib/components/ErrorBoundary.js.map +1 -1
- package/lib/components/ForeignComponentContainer.d.ts +1 -1
- package/lib/components/ForeignComponentContainer.js.map +1 -1
- package/lib/components/PiralGlobals.d.ts +6 -0
- package/lib/components/PiralGlobals.js +17 -0
- package/lib/components/PiralGlobals.js.map +1 -0
- package/lib/components/PiralRoutes.js +1 -1
- package/lib/components/PiralRoutes.js.map +1 -1
- package/lib/components/PiralSuspense.d.ts +5 -0
- package/lib/components/PiralSuspense.js +12 -0
- package/lib/components/PiralSuspense.js.map +1 -0
- package/lib/components/PiralView.d.ts +10 -1
- package/lib/components/PiralView.js +11 -23
- package/lib/components/PiralView.js.map +1 -1
- package/lib/components/ResponsiveLayout.d.ts +9 -1
- package/lib/components/ResponsiveLayout.js +3 -10
- package/lib/components/ResponsiveLayout.js.map +1 -1
- package/lib/components/components.d.ts +13 -6
- package/lib/components/components.js +14 -7
- package/lib/components/components.js.map +1 -1
- package/lib/components/index.d.ts +2 -12
- package/lib/components/index.js +12 -22
- package/lib/components/index.js.map +1 -1
- package/lib/components/wrapComponent.d.ts +1 -1
- package/lib/{components → defaults}/DefaultErrorInfo.d.ts +0 -0
- package/lib/{components → defaults}/DefaultErrorInfo.js +2 -3
- package/lib/defaults/DefaultErrorInfo.js.map +1 -0
- package/lib/{components → defaults}/DefaultLayout.d.ts +0 -0
- package/lib/{components → defaults}/DefaultLayout.js +0 -0
- package/lib/defaults/DefaultLayout.js.map +1 -0
- package/lib/{components/DefaultLoader.d.ts → defaults/DefaultLoadingIndicator.d.ts} +0 -0
- package/lib/{components/DefaultLoader.js → defaults/DefaultLoadingIndicator.js} +1 -1
- package/lib/defaults/DefaultLoadingIndicator.js.map +1 -0
- package/lib/{components → defaults}/DefaultRouteSwitch.d.ts +0 -0
- package/lib/{components → defaults}/DefaultRouteSwitch.js +1 -1
- package/lib/defaults/DefaultRouteSwitch.js.map +1 -0
- package/lib/defaults/DefaultRouter.d.ts +3 -0
- package/lib/{components → defaults}/DefaultRouter.js +0 -0
- package/lib/defaults/DefaultRouter.js.map +1 -0
- package/lib/defaults/index.d.ts +5 -0
- package/lib/defaults/index.js +9 -0
- package/lib/defaults/index.js.map +1 -0
- package/lib/hooks/actions.js +1 -1
- package/lib/hooks/actions.js.map +1 -1
- package/lib/hooks/index.js +6 -6
- package/lib/hooks/index.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +9 -8
- package/lib/index.js.map +1 -1
- package/lib/modules/index.js +3 -3
- package/lib/modules/index.js.map +1 -1
- package/lib/{components → setters}/SetComponent.d.ts +0 -0
- package/lib/{components → setters}/SetComponent.js +0 -0
- package/lib/setters/SetComponent.js.map +1 -0
- package/lib/{components → setters}/SetError.d.ts +0 -0
- package/lib/{components → setters}/SetError.js +0 -0
- package/lib/setters/SetError.js.map +1 -0
- package/lib/{components → setters}/SetErrors.d.ts +0 -0
- package/lib/{components → setters}/SetErrors.js +0 -0
- package/lib/setters/SetErrors.js.map +1 -0
- package/lib/{components → setters}/SetLayout.d.ts +0 -0
- package/lib/{components → setters}/SetLayout.js +0 -0
- package/lib/setters/SetLayout.js.map +1 -0
- package/lib/{components → setters}/SetProvider.d.ts +0 -0
- package/lib/{components → setters}/SetProvider.js +0 -0
- package/lib/setters/SetProvider.js.map +1 -0
- package/lib/{components → setters}/SetRedirect.d.ts +0 -0
- package/lib/{components → setters}/SetRedirect.js +0 -0
- package/lib/setters/SetRedirect.js.map +1 -0
- package/lib/{components → setters}/SetRoute.d.ts +0 -0
- package/lib/{components → setters}/SetRoute.js +0 -0
- package/lib/setters/SetRoute.js.map +1 -0
- package/lib/setters/index.d.ts +7 -0
- package/lib/setters/index.js +11 -0
- package/lib/setters/index.js.map +1 -0
- package/lib/state/createGlobalState.js +6 -7
- package/lib/state/createGlobalState.js.map +1 -1
- package/lib/state/index.js +4 -4
- package/lib/state/index.js.map +1 -1
- package/lib/state/withApi.js.map +1 -1
- package/lib/types/components.d.ts +9 -1
- package/lib/types/index.js +12 -12
- package/lib/types/index.js.map +1 -1
- package/lib/types/instance.d.ts +10 -3
- package/lib/types/state.d.ts +2 -12
- package/lib/utils/compare.d.ts +1 -1
- package/lib/utils/compare.js +22 -5
- package/lib/utils/compare.js.map +1 -1
- package/lib/utils/helpers.js +1 -1
- package/lib/utils/helpers.js.map +1 -1
- package/lib/utils/index.js +10 -10
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/media.js +1 -1
- package/lib/utils/media.js.map +1 -1
- package/package.json +33 -8
- package/src/Piral.test.tsx +3 -3
- package/src/Piral.tsx +18 -14
- package/src/PiralContext.tsx +43 -0
- package/src/RootListener.test.tsx +7 -5
- package/src/actions/app.test.ts +1 -19
- package/src/actions/app.ts +0 -8
- package/src/actions/state.ts +6 -1
- package/src/components/ErrorBoundary.tsx +7 -3
- package/src/components/ForeignComponentContainer.test.tsx +25 -16
- package/src/components/ForeignComponentContainer.tsx +1 -2
- package/src/components/PiralGlobals.tsx +16 -0
- package/src/components/PiralRoutes.test.tsx +1 -1
- package/src/components/PiralSuspense.tsx +19 -0
- package/src/components/PiralView-server.test.tsx +27 -26
- package/src/components/PiralView.test.tsx +1 -0
- package/src/components/PiralView.tsx +28 -47
- package/src/components/ResponsiveLayout.test.tsx +14 -43
- package/src/components/ResponsiveLayout.tsx +18 -15
- package/src/components/components.tsx +13 -6
- package/src/components/index.ts +2 -12
- package/src/components/wrapComponent.tsx +1 -1
- package/src/{components → defaults}/DefaultErrorInfo.test.tsx +0 -0
- package/src/{components → defaults}/DefaultErrorInfo.tsx +1 -2
- package/src/{components → defaults}/DefaultLayout.test.tsx +0 -0
- package/src/{components → defaults}/DefaultLayout.tsx +1 -1
- package/src/{components/DefaultLoader.test.tsx → defaults/DefaultLoadingIndicator.test.tsx} +2 -2
- package/src/{components/DefaultLoader.tsx → defaults/DefaultLoadingIndicator.tsx} +0 -0
- package/src/{components → defaults}/DefaultRouteSwitch.tsx +0 -0
- package/src/{components → defaults}/DefaultRouter.tsx +2 -1
- package/src/defaults/index.ts +5 -0
- package/src/hooks/setter.test.ts +3 -2
- package/src/index.tsx +1 -0
- package/src/{components → setters}/SetComponent.test.tsx +0 -0
- package/src/{components → setters}/SetComponent.tsx +0 -0
- package/src/{components → setters}/SetError.test.tsx +0 -0
- package/src/{components → setters}/SetError.tsx +0 -0
- package/src/{components → setters}/SetErrors.test.tsx +0 -0
- package/src/{components → setters}/SetErrors.tsx +0 -0
- package/src/{components → setters}/SetLayout.test.tsx +0 -0
- package/src/{components → setters}/SetLayout.tsx +0 -0
- package/src/{components → setters}/SetProvider.test.tsx +0 -0
- package/src/{components → setters}/SetProvider.tsx +0 -0
- package/src/{components → setters}/SetRedirect.test.tsx +0 -0
- package/src/{components → setters}/SetRedirect.tsx +0 -0
- package/src/{components → setters}/SetRoute.test.tsx +0 -0
- package/src/{components → setters}/SetRoute.tsx +0 -0
- package/src/setters/index.ts +7 -0
- package/src/state/createGlobalState.test.ts +1 -10
- package/src/state/createGlobalState.ts +2 -3
- package/src/state/withApi.tsx +2 -3
- package/src/types/components.ts +11 -2
- package/src/types/instance.ts +11 -3
- package/src/types/state.ts +2 -12
- package/src/utils/compare.test.ts +15 -15
- package/src/utils/compare.ts +23 -3
- package/src/utils/foreign.test.ts +1 -1
- package/src/utils/media.ts +1 -1
- package/esm/components/DefaultErrorInfo.js.map +0 -1
- package/esm/components/DefaultLayout.js.map +0 -1
- package/esm/components/DefaultLoader.js.map +0 -1
- package/esm/components/DefaultRouteSwitch.js.map +0 -1
- package/esm/components/DefaultRouter.d.ts +0 -2
- package/esm/components/DefaultRouter.js.map +0 -1
- package/esm/components/SetComponent.js.map +0 -1
- package/esm/components/SetError.js.map +0 -1
- package/esm/components/SetErrors.js.map +0 -1
- package/esm/components/SetLayout.js.map +0 -1
- package/esm/components/SetProvider.js.map +0 -1
- package/esm/components/SetRedirect.js.map +0 -1
- package/esm/components/SetRoute.js.map +0 -1
- package/lib/components/DefaultErrorInfo.js.map +0 -1
- package/lib/components/DefaultLayout.js.map +0 -1
- package/lib/components/DefaultLoader.js.map +0 -1
- package/lib/components/DefaultRouteSwitch.js.map +0 -1
- package/lib/components/DefaultRouter.d.ts +0 -2
- package/lib/components/DefaultRouter.js.map +0 -1
- package/lib/components/SetComponent.js.map +0 -1
- package/lib/components/SetError.js.map +0 -1
- package/lib/components/SetErrors.js.map +0 -1
- package/lib/components/SetLayout.js.map +0 -1
- package/lib/components/SetProvider.js.map +0 -1
- package/lib/components/SetRedirect.js.map +0 -1
- package/lib/components/SetRoute.js.map +0 -1
package/src/Piral.tsx
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { StaticRouter } from 'react-router';
|
|
3
3
|
import { createInstance } from './createInstance';
|
|
4
|
-
import { PiralView,
|
|
5
|
-
import {
|
|
4
|
+
import { PiralView, RegisteredRouter } from './components';
|
|
5
|
+
import { useGlobalState } from './hooks';
|
|
6
|
+
import { PiralContext } from './PiralContext';
|
|
6
7
|
import type { PiralProps } from './types';
|
|
7
8
|
|
|
9
|
+
const FallbackRouter: React.FC = (props) => {
|
|
10
|
+
const publicPath = useGlobalState((s) => s.app.publicPath);
|
|
11
|
+
return <StaticRouter location="/" {...props} basename={publicPath} />;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const Router = typeof window === 'undefined' ? FallbackRouter : RegisteredRouter;
|
|
15
|
+
|
|
8
16
|
/**
|
|
9
17
|
* Represents the Piral app shell frame. Use this component together
|
|
10
18
|
* with an existing instance to render the app shell.
|
|
11
|
-
* Includes layout and routing handling.
|
|
12
|
-
* to the generated views.
|
|
19
|
+
* Includes layout and routing handling. Connects the Piral context
|
|
20
|
+
* and the React router to the generated views.
|
|
13
21
|
*
|
|
14
22
|
* @example
|
|
15
23
|
```jsx
|
|
@@ -21,14 +29,10 @@ const app = (
|
|
|
21
29
|
```
|
|
22
30
|
*/
|
|
23
31
|
export const Piral: React.FC<PiralProps> = ({ instance = createInstance(), breakpoints, children }) => (
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<PortalRenderer id="root" />
|
|
30
|
-
{children}
|
|
31
|
-
</PiralView>
|
|
32
|
-
</StateContext.Provider>
|
|
32
|
+
<PiralContext instance={instance}>
|
|
33
|
+
<Router>
|
|
34
|
+
<PiralView breakpoints={breakpoints}>{children}</PiralView>
|
|
35
|
+
</Router>
|
|
36
|
+
</PiralContext>
|
|
33
37
|
);
|
|
34
38
|
Piral.displayName = 'Piral';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { StateContext } from './state';
|
|
3
|
+
import { createInstance } from './createInstance';
|
|
4
|
+
import { Mediator } from './components';
|
|
5
|
+
import { useGlobalState } from './hooks';
|
|
6
|
+
import { RootListener } from './RootListener';
|
|
7
|
+
import type { PiralContextProps } from './types';
|
|
8
|
+
|
|
9
|
+
interface PiralProviderProps {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const PiralProvider: React.FC<PiralProviderProps> = ({ children }) => {
|
|
14
|
+
const Provider = useGlobalState((m) => m.provider || React.Fragment);
|
|
15
|
+
return <Provider>{children}</Provider>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Represents the Piral app shell frame. Use this component together
|
|
20
|
+
* with an existing instance to render components from micro frontends
|
|
21
|
+
* in your app.
|
|
22
|
+
* Wires the state container together with the global providers.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
```jsx
|
|
26
|
+
const app = (
|
|
27
|
+
<MyRouter>
|
|
28
|
+
<PiralContext instance={yourPiralInstance}>
|
|
29
|
+
<PiralGlobals />
|
|
30
|
+
<MyAppContent />
|
|
31
|
+
</PiralContext>
|
|
32
|
+
</MyRouter>
|
|
33
|
+
);
|
|
34
|
+
```
|
|
35
|
+
*/
|
|
36
|
+
export const PiralContext: React.FC<PiralContextProps> = ({ instance = createInstance(), children }) => (
|
|
37
|
+
<StateContext.Provider value={instance.context}>
|
|
38
|
+
<Mediator options={instance.options} key={instance.id} />
|
|
39
|
+
<RootListener />
|
|
40
|
+
<PiralProvider>{children}</PiralProvider>
|
|
41
|
+
</StateContext.Provider>
|
|
42
|
+
);
|
|
43
|
+
PiralContext.displayName = 'PiralContext';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
3
|
import { act } from 'react-dom/test-utils';
|
|
4
4
|
import { RootListener } from './RootListener';
|
|
5
5
|
|
|
@@ -15,7 +15,8 @@ describe('RootListener Component', () => {
|
|
|
15
15
|
const removed = jest.fn();
|
|
16
16
|
document.body.appendChild(element);
|
|
17
17
|
const container = document.body.appendChild(document.createElement('div'));
|
|
18
|
-
|
|
18
|
+
const root = createRoot(container);
|
|
19
|
+
root.render(<RootListener />);
|
|
19
20
|
document.body.removeEventListener = removed;
|
|
20
21
|
await act(() => {
|
|
21
22
|
const event = new CustomEvent('render-html', {
|
|
@@ -23,7 +24,7 @@ describe('RootListener Component', () => {
|
|
|
23
24
|
detail: {
|
|
24
25
|
target: element,
|
|
25
26
|
props: {},
|
|
26
|
-
}
|
|
27
|
+
},
|
|
27
28
|
});
|
|
28
29
|
element.dispatchEvent(event);
|
|
29
30
|
return Promise.resolve();
|
|
@@ -35,10 +36,11 @@ describe('RootListener Component', () => {
|
|
|
35
36
|
it('removes the RootListener successfully', async () => {
|
|
36
37
|
const container = document.body.appendChild(document.createElement('div'));
|
|
37
38
|
const removed = jest.fn();
|
|
38
|
-
|
|
39
|
+
const root = createRoot(container);
|
|
40
|
+
root.render(<RootListener />);
|
|
39
41
|
document.body.removeEventListener = removed;
|
|
40
42
|
await act(() => Promise.resolve());
|
|
41
|
-
|
|
43
|
+
root.unmount();
|
|
42
44
|
await act(() => Promise.resolve());
|
|
43
45
|
expect(removed).toHaveBeenCalled();
|
|
44
46
|
});
|
package/src/actions/app.test.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { mount } from 'enzyme';
|
|
1
2
|
import { createElement } from 'react';
|
|
2
3
|
import { Atom, deref } from '@dbeining/react-atom';
|
|
3
4
|
import { createListener, Pilet } from 'piral-base';
|
|
4
5
|
import {
|
|
5
|
-
changeLayout,
|
|
6
6
|
includeProvider,
|
|
7
7
|
initialize,
|
|
8
8
|
injectPilet,
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
setRoute,
|
|
13
13
|
} from './app';
|
|
14
14
|
import { createActions } from '../state';
|
|
15
|
-
import { mount } from 'enzyme';
|
|
16
15
|
import { RootListener } from '../RootListener';
|
|
17
16
|
|
|
18
17
|
const pilet: Pilet = {
|
|
@@ -23,23 +22,6 @@ const pilet: Pilet = {
|
|
|
23
22
|
};
|
|
24
23
|
|
|
25
24
|
describe('App Actions Module', () => {
|
|
26
|
-
it('changeLayout changes the current layout', () => {
|
|
27
|
-
const state = Atom.of({
|
|
28
|
-
foo: 5,
|
|
29
|
-
app: {
|
|
30
|
-
layout: 'tablet',
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
const ctx = createActions(state, createListener({}));
|
|
34
|
-
changeLayout(ctx, 'mobile');
|
|
35
|
-
expect(deref(state)).toEqual({
|
|
36
|
-
foo: 5,
|
|
37
|
-
app: {
|
|
38
|
-
layout: 'mobile',
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
25
|
it('initialize initializes state data', () => {
|
|
44
26
|
const state = Atom.of({
|
|
45
27
|
app: {},
|
package/src/actions/app.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { RouteComponentProps } from 'react-router';
|
|
|
3
3
|
import { runPilet } from 'piral-base';
|
|
4
4
|
import { withKey, replaceOrAddItem, removeNested, withProvider, withRoute, noop } from '../utils';
|
|
5
5
|
import {
|
|
6
|
-
LayoutType,
|
|
7
6
|
ComponentsState,
|
|
8
7
|
ErrorComponentsState,
|
|
9
8
|
BaseRegistration,
|
|
@@ -13,13 +12,6 @@ import {
|
|
|
13
12
|
PiletEntry,
|
|
14
13
|
} from '../types';
|
|
15
14
|
|
|
16
|
-
export function changeLayout(ctx: GlobalStateContext, current: LayoutType) {
|
|
17
|
-
ctx.dispatch((state) => ({
|
|
18
|
-
...state,
|
|
19
|
-
app: withKey(state.app, 'layout', current),
|
|
20
|
-
}));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
15
|
export function initialize(ctx: GlobalStateContext, loading: boolean, error: Error | undefined, modules: Array<Pilet>) {
|
|
24
16
|
ctx.dispatch((state) => ({
|
|
25
17
|
...state,
|
package/src/actions/state.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { swap, deref } from '@dbeining/react-atom';
|
|
2
|
+
import { isSame } from '../utils';
|
|
2
3
|
import { GlobalState, GlobalStateContext } from '../types';
|
|
3
4
|
|
|
5
|
+
function onlyChangedState(oldState: GlobalState, newState: GlobalState) {
|
|
6
|
+
return isSame(oldState, newState) ? oldState : newState;
|
|
7
|
+
}
|
|
8
|
+
|
|
4
9
|
export function dispatch(ctx: GlobalStateContext, update: (state: GlobalState) => GlobalState) {
|
|
5
|
-
swap(ctx.state, update);
|
|
10
|
+
swap(ctx.state, oldState => onlyChangedState(oldState, update(oldState)));
|
|
6
11
|
}
|
|
7
12
|
|
|
8
13
|
export function readState<S>(ctx: GlobalStateContext, read: (state: GlobalState) => S) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { RegisteredErrorInfo, RegisteredLoadingIndicator } from './components';
|
|
3
3
|
import { Errors, PiletApi } from '../types';
|
|
4
4
|
|
|
5
5
|
export interface ErrorBoundaryProps {
|
|
@@ -11,6 +11,10 @@ export interface ErrorBoundaryProps {
|
|
|
11
11
|
* The associated pilet api for the metadata.
|
|
12
12
|
*/
|
|
13
13
|
piral: PiletApi;
|
|
14
|
+
/**
|
|
15
|
+
* The content to render (i.e., where to apply the boundary to).
|
|
16
|
+
*/
|
|
17
|
+
children: React.ReactNode;
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
export interface ErrorBoundaryState {
|
|
@@ -45,9 +49,9 @@ export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoun
|
|
|
45
49
|
|
|
46
50
|
if (error) {
|
|
47
51
|
const pilet = piral.meta.name;
|
|
48
|
-
return <
|
|
52
|
+
return <RegisteredErrorInfo type={errorType} error={error} pilet={pilet} {...rest} />;
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
return <React.Suspense fallback={<
|
|
55
|
+
return <React.Suspense fallback={<RegisteredLoadingIndicator />}>{children}</React.Suspense>;
|
|
52
56
|
}
|
|
53
57
|
}
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import { act } from 'react-dom/test-utils';
|
|
3
4
|
import { ForeignComponentContainer } from './ForeignComponentContainer';
|
|
4
5
|
|
|
6
|
+
async function render(element: any, container: Element) {
|
|
7
|
+
const root = createRoot(container);
|
|
8
|
+
root.render(element);
|
|
9
|
+
await act(() => Promise.resolve());
|
|
10
|
+
return root;
|
|
11
|
+
}
|
|
12
|
+
|
|
5
13
|
describe('ForeignComponentContainer component', () => {
|
|
6
|
-
it('mounts an HTML component', () => {
|
|
14
|
+
it('mounts an HTML component', async () => {
|
|
7
15
|
const container = document.body.appendChild(document.createElement('div'));
|
|
8
16
|
const mount = jest.fn();
|
|
9
17
|
const component = { mount };
|
|
10
|
-
render(
|
|
18
|
+
await render(
|
|
11
19
|
<ForeignComponentContainer $component={component} $context={undefined} $portalId="foo" innerProps={{}} />,
|
|
12
20
|
container,
|
|
13
21
|
);
|
|
@@ -15,28 +23,28 @@ describe('ForeignComponentContainer component', () => {
|
|
|
15
23
|
container.remove();
|
|
16
24
|
});
|
|
17
25
|
|
|
18
|
-
it('unmounts an HTML component', () => {
|
|
26
|
+
it('unmounts an HTML component', async () => {
|
|
19
27
|
const container = document.body.appendChild(document.createElement('div'));
|
|
20
28
|
const mount = jest.fn();
|
|
21
29
|
const unmount = jest.fn();
|
|
22
30
|
const component = { mount, unmount };
|
|
23
|
-
render(
|
|
31
|
+
const root = await render(
|
|
24
32
|
<ForeignComponentContainer $component={component} $context={undefined} $portalId="foo" innerProps={{}} />,
|
|
25
33
|
container,
|
|
26
34
|
);
|
|
27
35
|
expect(mount).toHaveBeenCalled();
|
|
28
36
|
expect(unmount).not.toHaveBeenCalled();
|
|
29
|
-
|
|
37
|
+
root.unmount();
|
|
30
38
|
expect(unmount).toHaveBeenCalled();
|
|
31
39
|
container.remove();
|
|
32
40
|
});
|
|
33
41
|
|
|
34
|
-
it('updates an HTML component', () => {
|
|
42
|
+
it('updates an HTML component', async () => {
|
|
35
43
|
const container = document.body.appendChild(document.createElement('div'));
|
|
36
44
|
const mount = jest.fn();
|
|
37
45
|
const update = jest.fn();
|
|
38
46
|
const component = { mount, update };
|
|
39
|
-
render(
|
|
47
|
+
const root = await render(
|
|
40
48
|
<ForeignComponentContainer
|
|
41
49
|
$component={component}
|
|
42
50
|
$context={undefined}
|
|
@@ -47,20 +55,20 @@ describe('ForeignComponentContainer component', () => {
|
|
|
47
55
|
);
|
|
48
56
|
expect(mount).toHaveBeenCalled();
|
|
49
57
|
expect(update).not.toHaveBeenCalled();
|
|
50
|
-
render(
|
|
58
|
+
root.render(
|
|
51
59
|
<ForeignComponentContainer
|
|
52
60
|
$component={component}
|
|
53
61
|
$context={undefined}
|
|
54
62
|
$portalId="foo"
|
|
55
63
|
innerProps={{ a: 'foo' }}
|
|
56
64
|
/>,
|
|
57
|
-
container,
|
|
58
65
|
);
|
|
66
|
+
await act(() => Promise.resolve());
|
|
59
67
|
expect(update).toHaveBeenCalled();
|
|
60
68
|
container.remove();
|
|
61
69
|
});
|
|
62
70
|
|
|
63
|
-
it('forces re-rendering of an HTML component', () => {
|
|
71
|
+
it('forces re-rendering of an HTML component', async () => {
|
|
64
72
|
const container = document.body.appendChild(document.createElement('div'));
|
|
65
73
|
const componentDidMount = ForeignComponentContainer.prototype.componentDidMount;
|
|
66
74
|
ForeignComponentContainer.prototype.componentDidMount = function () {
|
|
@@ -73,7 +81,7 @@ describe('ForeignComponentContainer component', () => {
|
|
|
73
81
|
const update = jest.fn();
|
|
74
82
|
const unmount = jest.fn();
|
|
75
83
|
const component = { mount, update, unmount };
|
|
76
|
-
render(
|
|
84
|
+
const root = await render(
|
|
77
85
|
<ForeignComponentContainer
|
|
78
86
|
$component={component}
|
|
79
87
|
$context={undefined}
|
|
@@ -85,27 +93,27 @@ describe('ForeignComponentContainer component', () => {
|
|
|
85
93
|
expect(mount).toHaveBeenCalled();
|
|
86
94
|
expect(unmount).not.toHaveBeenCalled();
|
|
87
95
|
expect(update).not.toHaveBeenCalled();
|
|
88
|
-
render(
|
|
96
|
+
root.render(
|
|
89
97
|
<ForeignComponentContainer
|
|
90
98
|
$component={component}
|
|
91
99
|
$context={undefined}
|
|
92
100
|
$portalId="foo"
|
|
93
101
|
innerProps={{ a: 'foo' }}
|
|
94
102
|
/>,
|
|
95
|
-
container,
|
|
96
103
|
);
|
|
104
|
+
await act(() => Promise.resolve());
|
|
97
105
|
expect(update).not.toHaveBeenCalled();
|
|
98
106
|
expect(unmount).toHaveBeenCalled();
|
|
99
107
|
container.remove();
|
|
100
108
|
});
|
|
101
109
|
|
|
102
|
-
it('listens to render-html', () => {
|
|
110
|
+
it('listens to render-html', async () => {
|
|
103
111
|
const container = document.body.appendChild(document.createElement('div'));
|
|
104
112
|
const mount = jest.fn();
|
|
105
113
|
const renderHtmlExtension = jest.fn();
|
|
106
114
|
const component = { mount };
|
|
107
115
|
const props = { piral: { renderHtmlExtension }, meta: {} };
|
|
108
|
-
render(
|
|
116
|
+
await render(
|
|
109
117
|
<ForeignComponentContainer $component={component} $context={undefined} $portalId="foo" innerProps={props} />,
|
|
110
118
|
container,
|
|
111
119
|
);
|
|
@@ -113,6 +121,7 @@ describe('ForeignComponentContainer component', () => {
|
|
|
113
121
|
const node = document.querySelector('[data-portal-id=foo]');
|
|
114
122
|
expect(renderHtmlExtension).not.toHaveBeenCalled();
|
|
115
123
|
node.dispatchEvent(new CustomEvent('render-html', { detail: {} }));
|
|
124
|
+
await act(() => Promise.resolve());
|
|
116
125
|
expect(renderHtmlExtension).toHaveBeenCalled();
|
|
117
126
|
container.remove();
|
|
118
127
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { isfunc } from 'piral-base';
|
|
3
|
-
import {
|
|
4
|
-
import { ForeignComponent, BaseComponentProps, ComponentContext } from '../types';
|
|
3
|
+
import type { ForeignComponent, BaseComponentProps, ComponentContext } from '../types';
|
|
5
4
|
|
|
6
5
|
interface ForeignComponentContainerProps<T> {
|
|
7
6
|
$portalId: string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { PortalRenderer } from './PortalRenderer';
|
|
3
|
+
import { RegisteredDebug } from './components';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Integrates the global portal renderer and the debug utilities
|
|
7
|
+
* (if registered).
|
|
8
|
+
*/
|
|
9
|
+
export const PiralGlobals: React.FC = () => {
|
|
10
|
+
return (
|
|
11
|
+
<>
|
|
12
|
+
<PortalRenderer id="root" />
|
|
13
|
+
<RegisteredDebug />
|
|
14
|
+
</>
|
|
15
|
+
);
|
|
16
|
+
};
|
|
@@ -2,8 +2,8 @@ import * as React from 'react';
|
|
|
2
2
|
import * as hooks from '../hooks';
|
|
3
3
|
import { MemoryRouter } from 'react-router';
|
|
4
4
|
import { mount } from 'enzyme';
|
|
5
|
-
import { DefaultRouteSwitch } from './DefaultRouteSwitch';
|
|
6
5
|
import { PiralRoutes } from './PiralRoutes';
|
|
6
|
+
import { DefaultRouteSwitch } from '../defaults';
|
|
7
7
|
|
|
8
8
|
const mountWithRouter = (node, url = '/') =>
|
|
9
9
|
mount(
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { RegisteredErrorInfo, RegisteredLoadingIndicator } from './components';
|
|
3
|
+
import { useGlobalState } from '../hooks';
|
|
4
|
+
|
|
5
|
+
export interface PiralSuspenseProps {
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const PiralSuspense: React.FC<PiralSuspenseProps> = ({ children }) => {
|
|
10
|
+
const { error, loading } = useGlobalState((m) => m.app);
|
|
11
|
+
|
|
12
|
+
return error ? (
|
|
13
|
+
<RegisteredErrorInfo type="loading" error={error} />
|
|
14
|
+
) : loading ? (
|
|
15
|
+
<RegisteredLoadingIndicator />
|
|
16
|
+
) : (
|
|
17
|
+
<>{children}</>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
@@ -17,44 +17,45 @@ StubErrorInfo.displayName = 'StubErrorInfo';
|
|
|
17
17
|
const StubLoader: React.FC = () => <div />;
|
|
18
18
|
StubLoader.displayName = 'StubLoader';
|
|
19
19
|
|
|
20
|
-
const StubRouter: React.FC = ({ children }) => <div>{children}</div>;
|
|
20
|
+
const StubRouter: React.FC<React.PropsWithChildren<{}>> = ({ children }) => <div>{children}</div>;
|
|
21
21
|
StubRouter.displayName = 'StubRouter';
|
|
22
22
|
|
|
23
|
-
const StubLayout: React.FC = ({ children }) => <div>{children}</div>;
|
|
23
|
+
const StubLayout: React.FC<React.PropsWithChildren<{}>> = ({ children }) => <div>{children}</div>;
|
|
24
24
|
StubLayout.displayName = 'StubLayout';
|
|
25
25
|
|
|
26
26
|
jest.mock('../hooks');
|
|
27
27
|
jest.mock('./PiralRoutes');
|
|
28
28
|
|
|
29
29
|
const state = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
30
|
+
app: {
|
|
31
|
+
error: undefined,
|
|
32
|
+
loading: true,
|
|
33
|
+
},
|
|
34
|
+
components: {
|
|
35
|
+
ErrorInfo: StubErrorInfo,
|
|
36
|
+
LoadingIndicator: StubLoader,
|
|
37
|
+
Router: StubRouter,
|
|
38
|
+
Layout: StubLayout,
|
|
39
|
+
},
|
|
40
|
+
registry: {
|
|
41
|
+
pages: {},
|
|
42
|
+
extensions: {},
|
|
43
|
+
},
|
|
44
|
+
portals: {},
|
|
45
|
+
routes: {},
|
|
46
|
+
provider: undefined,
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
(hooks as any).useGlobalState = (select: any) => select(state);
|
|
49
50
|
|
|
50
|
-
(routes as any).PiralRoutes = ({
|
|
51
|
+
(routes as any).PiralRoutes = ({}) => <StubDashboard />;
|
|
51
52
|
|
|
52
53
|
describe('Portal Module', () => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
it('In this test window should be undefined', () => {
|
|
55
|
+
state.app.loading = false;
|
|
56
|
+
state.app.error = undefined;
|
|
57
|
+
const node = render(<PiralView children={undefined} />);
|
|
58
|
+
expect(typeof window).toBe('undefined');
|
|
59
|
+
expect(node.length).toBe(1);
|
|
60
|
+
});
|
|
60
61
|
});
|
|
@@ -1,60 +1,41 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { RouteComponentProps
|
|
2
|
+
import { RouteComponentProps } from 'react-router';
|
|
3
|
+
import { PiralGlobals } from './PiralGlobals';
|
|
3
4
|
import { PiralRoutes } from './PiralRoutes';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
PiralRouteSwitch,
|
|
9
|
-
PiralLayout,
|
|
10
|
-
PiralDebug,
|
|
11
|
-
} from './components';
|
|
12
|
-
import { useGlobalState } from '../hooks';
|
|
5
|
+
import { PiralSuspense } from './PiralSuspense';
|
|
6
|
+
import { ResponsiveLayout } from './ResponsiveLayout';
|
|
7
|
+
import { RegisteredErrorInfo, RegisteredRouteSwitch, RegisteredLayout } from './components';
|
|
8
|
+
import { LayoutBreakpoints } from '../types';
|
|
13
9
|
|
|
14
|
-
const NotFound: React.FC<RouteComponentProps> = (props) => <
|
|
15
|
-
|
|
16
|
-
const PiralContent: React.FC = () => {
|
|
17
|
-
const { error, loading, layout } = useGlobalState((m) => m.app);
|
|
18
|
-
|
|
19
|
-
return error ? (
|
|
20
|
-
<PiralError type="loading" error={error} />
|
|
21
|
-
) : loading ? (
|
|
22
|
-
<PiralLoadingIndicator />
|
|
23
|
-
) : (
|
|
24
|
-
<PiralLayout currentLayout={layout}>
|
|
25
|
-
<PiralRoutes NotFound={NotFound} RouteSwitch={PiralRouteSwitch} />
|
|
26
|
-
</PiralLayout>
|
|
27
|
-
);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const FallbackRouter: React.FC = (props) => {
|
|
31
|
-
const publicPath = useGlobalState((s) => s.app.publicPath);
|
|
32
|
-
return <StaticRouter location="/" {...props} basename={publicPath} />;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const Router = typeof window === 'undefined' ? FallbackRouter : PiralRouter;
|
|
36
|
-
|
|
37
|
-
const PiralProvider: React.FC = ({ children }) => {
|
|
38
|
-
const provider = useGlobalState((m) => m.provider) || React.Fragment;
|
|
39
|
-
return React.createElement(provider, undefined, children);
|
|
40
|
-
};
|
|
10
|
+
const NotFound: React.FC<RouteComponentProps> = (props) => <RegisteredErrorInfo type="not_found" {...props} />;
|
|
41
11
|
|
|
42
12
|
/**
|
|
43
13
|
* The props for the PiralView component.
|
|
44
14
|
*/
|
|
45
|
-
export interface PiralViewProps {
|
|
15
|
+
export interface PiralViewProps {
|
|
16
|
+
/**
|
|
17
|
+
* The custom breakpoints for the different layout modi.
|
|
18
|
+
*/
|
|
19
|
+
breakpoints?: LayoutBreakpoints;
|
|
20
|
+
/**
|
|
21
|
+
* The extra content.
|
|
22
|
+
*/
|
|
23
|
+
children: React.ReactNode;
|
|
24
|
+
}
|
|
46
25
|
|
|
47
26
|
/**
|
|
48
27
|
* The component responsible for the generic view of the application.
|
|
49
|
-
* This includes the
|
|
28
|
+
* This includes the used the current content and some convenience.
|
|
50
29
|
*/
|
|
51
|
-
export const PiralView: React.FC<PiralViewProps> = ({ children }) => (
|
|
52
|
-
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
30
|
+
export const PiralView: React.FC<PiralViewProps> = ({ breakpoints, children }) => (
|
|
31
|
+
<>
|
|
32
|
+
<PiralGlobals />
|
|
33
|
+
<PiralSuspense>
|
|
34
|
+
<ResponsiveLayout breakpoints={breakpoints} Layout={RegisteredLayout}>
|
|
35
|
+
<PiralRoutes NotFound={NotFound} RouteSwitch={RegisteredRouteSwitch} />
|
|
36
|
+
</ResponsiveLayout>
|
|
37
|
+
</PiralSuspense>
|
|
38
|
+
{children}
|
|
39
|
+
</>
|
|
59
40
|
);
|
|
60
41
|
PiralView.displayName = 'PiralView';
|