@dr.pogodin/react-utils 1.35.2 → 1.35.3

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.
@@ -1,3 +1,9 @@
1
1
  import 'node-forge/lib/aes';
2
2
  import type { InjT } from '../shared/utils/globalState';
3
3
  export default function getInj(): InjT;
4
+ /**
5
+ * Allows to set a custom injection object instance,
6
+ * for server-less scenarios, for example, where it is not auto-injected
7
+ * into generated pages from the server side.
8
+ */
9
+ export declare function setInj(value: InjT): void;
@@ -1,12 +1,13 @@
1
1
  import { type ComponentType } from 'react';
2
+ import { setInj } from './getInj';
2
3
  type OptionsT = {
3
4
  dontHydrate?: boolean;
4
5
  initialState?: any;
5
6
  };
7
+ export { setInj };
6
8
  /**
7
9
  * Prepares and launches the app at client side.
8
10
  * @param Application Root application component
9
11
  * @param [options={}] Optional. Additional settings.
10
12
  */
11
13
  export default function Launch(Application: ComponentType, options?: OptionsT): void;
12
- export {};
@@ -1,7 +1,7 @@
1
1
  import 'styles/global.scss';
2
2
  import type ServerT from './server';
3
3
  declare const server: typeof ServerT | null;
4
- declare const client: any;
4
+ declare let client: any;
5
5
  export { default as api } from 'axios';
6
6
  export * as PT from 'prop-types';
7
7
  export { type AsyncCollectionLoaderT, type AsyncDataEnvelopeT, type AsyncDataLoaderT, type ForceT, type UseAsyncDataOptionsT, type UseAsyncDataResT, type UseGlobalStateResT, type ValueOrInitializerT, getGlobalState, GlobalStateProvider, newAsyncDataEnvelope, useAsyncCollection, useAsyncData, useGlobalState, withGlobalStateType, } from '@dr.pogodin/react-global-state';
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.35.2",
2
+ "version": "1.35.3",
3
3
  "bin": {
4
4
  "react-utils-build": "bin/build.js",
5
5
  "react-utils-setup": "bin/setup.js"
@@ -41,3 +41,12 @@ if (metaElement) {
41
41
  export default function getInj(): InjT {
42
42
  return inj;
43
43
  }
44
+
45
+ /**
46
+ * Allows to set a custom injection object instance,
47
+ * for server-less scenarios, for example, where it is not auto-injected
48
+ * into generated pages from the server side.
49
+ */
50
+ export function setInj(value: InjT) {
51
+ inj = value;
52
+ }
@@ -8,13 +8,15 @@ import { GlobalStateProvider } from '@dr.pogodin/react-global-state';
8
8
  import { createRoot, hydrateRoot } from 'react-dom/client';
9
9
  import { BrowserRouter } from 'react-router-dom';
10
10
 
11
- import getInj from './getInj';
11
+ import getInj, { setInj } from './getInj';
12
12
 
13
13
  type OptionsT = {
14
14
  dontHydrate?: boolean;
15
15
  initialState?: any;
16
16
  };
17
17
 
18
+ export { setInj };
19
+
18
20
  /**
19
21
  * Prepares and launches the app at client side.
20
22
  * @param Application Root application component
package/src/index.ts CHANGED
@@ -6,7 +6,15 @@ import type ServerT from './server';
6
6
 
7
7
  const server = webpack.requireWeak('./server', __dirname) as (typeof ServerT) | null;
8
8
 
9
- const client = server ? undefined : require('./client').default;
9
+ // TODO: Should be done in a cleaner way, but technically it is fine
10
+ // for this scenario.
11
+ // eslint-disable-next-line import/no-mutable-exports
12
+ let client = server ? undefined : require('./client');
13
+
14
+ if (client) {
15
+ client.default.setInj = client.setInj;
16
+ client = client.default;
17
+ }
10
18
 
11
19
  export { default as api } from 'axios';
12
20
  export * as PT from 'prop-types';
@@ -22,15 +22,23 @@ import {
22
22
  getBuildInfo,
23
23
  } from './isomorphy';
24
24
 
25
- // Note: At the client side we can get chunk groups immediately when loading
26
- // the module; at the server-side we only can get them within React render flow.
25
+ // NOTE: At the client-side we get chunk groups the first time they are needed
26
+ // (we used to get them eagerly when this module loaded, but it did not work well
27
+ // alongside custom chunk info injection in server-less scenario);
28
+ // at the server-side we only can get them within React render flow.
27
29
  // Thus, we set and use the following variable at the client-side, and then when
28
30
  // needed on the server side, we'll fetch it differently.
29
- let clientChunkGroups: ChunkGroupsT;
31
+ let cachedClientChunkGroups: ChunkGroupsT | undefined;
30
32
 
31
- if (IS_CLIENT_SIDE) {
32
- // eslint-disable-next-line global-require
33
- clientChunkGroups = require('client/getInj').default().CHUNK_GROUPS || {};
33
+ function getClientChunkGroups(): ChunkGroupsT {
34
+ if (IS_CLIENT_SIDE && !cachedClientChunkGroups) {
35
+ // eslint-disable-next-line global-require
36
+ cachedClientChunkGroups = require('client/getInj').default().CHUNK_GROUPS || {};
37
+ }
38
+
39
+ if (!cachedClientChunkGroups) throw Error('Internal error');
40
+
41
+ return cachedClientChunkGroups;
34
42
  }
35
43
 
36
44
  const refCounts: { [path: string]: number } = {};
@@ -185,7 +193,7 @@ export default function splitComponent<
185
193
  placeholder?: ReactNode,
186
194
  }) {
187
195
  // On the client side we can check right away if the chunk name is known.
188
- if (IS_CLIENT_SIDE) assertChunkName(chunkName, clientChunkGroups);
196
+ if (IS_CLIENT_SIDE) assertChunkName(chunkName, getClientChunkGroups());
189
197
 
190
198
  // The correct usage of splitComponent() assumes a single call per chunk.
191
199
  if (usedChunkNames.has(chunkName)) {
@@ -200,7 +208,7 @@ export default function splitComponent<
200
208
  // the component (the lazy load function is executed by React one at
201
209
  // the frist mount).
202
210
  if (IS_CLIENT_SIDE) {
203
- await bookStyleSheets(chunkName, clientChunkGroups, false);
211
+ await bookStyleSheets(chunkName, getClientChunkGroups(), false);
204
212
  }
205
213
 
206
214
  const Wrapper = forwardRef((
@@ -218,8 +226,8 @@ export default function splitComponent<
218
226
  // This takes care about stylesheets management every time an instance of
219
227
  // this component is mounted / unmounted.
220
228
  useInsertionEffect(() => {
221
- bookStyleSheets(chunkName, clientChunkGroups, true);
222
- return () => freeStyleSheets(chunkName, clientChunkGroups);
229
+ bookStyleSheets(chunkName, getClientChunkGroups(), true);
230
+ return () => freeStyleSheets(chunkName, getClientChunkGroups());
223
231
  }, []);
224
232
 
225
233
  return (