react-simple-loadable 1.0.0 → 2.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # React Simple Loadable HOC
2
2
 
3
- This is simple ErrorBoundary component
3
+ This is simple loadable component based on Class React Component
4
4
 
5
5
  ## Usage
6
6
 
@@ -12,4 +12,15 @@ loadable(async () => {
12
12
  },
13
13
  SkeletonComponent
14
14
  )
15
+ ```
16
+
17
+ ```tsx
18
+ import { loadable } from "react-simple-loadable";
19
+
20
+ loadable(async () => {
21
+ return (await import('./your-component')).YourNamedComponent
22
+ },{
23
+ loader: SkeletonComponent,
24
+ extra: () => <div>renders with the lazy component</div>
25
+ })
15
26
  ```
package/loadable.d.ts CHANGED
@@ -1,5 +1,12 @@
1
1
  import { ComponentType } from 'react';
2
- import { Maybe } from 'yammies/utils/types';
3
2
  export type LoadableComponentFunction<P = Record<string, any>> = () => Promise<ComponentType<P>>;
4
- export declare function loadable<P = any>(loadFunction: LoadableComponentFunction<P>, Fallback?: Maybe<ComponentType>, ExtraComponent?: ComponentType<any>): ComponentType<P>;
3
+ interface LoadableConfig {
4
+ loader?: ComponentType<any>;
5
+ /**
6
+ * Component which renders with the lazy component
7
+ */
8
+ extra?: ComponentType<any>;
9
+ }
10
+ export declare function loadable<P = any>(loadFn: LoadableComponentFunction<P>, loaderOrConfig?: null | undefined | LoadableConfig['loader'] | LoadableConfig): ComponentType<P>;
11
+ export {};
5
12
  //# sourceMappingURL=loadable.d.ts.map
package/loadable.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"loadable.d.ts","sourceRoot":"","sources":["../src/loadable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,OAAO,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG5C,MAAM,MAAM,yBAAyB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,MAAM,OAAO,CAC5E,aAAa,CAAC,CAAC,CAAC,CACjB,CAAC;AAKF,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAC9B,YAAY,EAAE,yBAAyB,CAAC,CAAC,CAAC,EAC1C,QAAQ,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,EAE/B,cAAc,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,GAClC,aAAa,CAAC,CAAC,CAAC,CAclB"}
1
+ {"version":3,"file":"loadable.d.ts","sourceRoot":"","sources":["../src/loadable.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,aAAa,EAAE,MAAM,OAAO,CAAC;AAGjD,MAAM,MAAM,yBAAyB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,MAAM,OAAO,CAC5E,aAAa,CAAC,CAAC,CAAC,CACjB,CAAC;AAIF,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;IAC5B;;OAEG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC;CAC5B;AAyID,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAC9B,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC,EACpC,cAAc,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,cAAc,GAC5E,aAAa,CAAC,CAAC,CAAC,CAsBlB"}
package/loadable.js CHANGED
@@ -1,13 +1,115 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { lazy, Suspense } from 'react';
3
- const DefaultFallback = () => null;
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /* eslint-disable sonarjs/sonar-no-unused-class-component-methods */
3
+ /* eslint-disable sonarjs/no-unsafe */
4
+ /* eslint-disable sonarjs/public-static-readonly */
5
+ /* eslint-disable @typescript-eslint/ban-types */
6
+ import { Component } from 'react';
7
+ const DefaultLoader = () => null;
8
+ const loadingStates = new WeakMap();
9
+ const getOrCreateLoadingState = (loadFn) => {
10
+ if (!loadingStates.has(loadFn)) {
11
+ loadingStates.set(loadFn, {
12
+ error: null,
13
+ loading: true,
14
+ });
15
+ }
16
+ return loadingStates.get(loadFn);
17
+ };
18
+ const updateLoadingState = (loadFn, update) => {
19
+ const loadingState = getOrCreateLoadingState(loadFn);
20
+ const updatedState = { ...loadingState, ...update };
21
+ loadingStates.set(loadFn, updatedState);
22
+ return updatedState;
23
+ };
24
+ const load = (loadFn) => {
25
+ const state = getOrCreateLoadingState(loadFn);
26
+ if (state.result) {
27
+ return state;
28
+ }
29
+ updateLoadingState(loadFn, { loading: true, error: null });
30
+ state.loading = true;
31
+ state.error = null;
32
+ state.promise = loadFn()
33
+ .then((result) => {
34
+ state.loading = false;
35
+ state.result = result;
36
+ updateLoadingState(loadFn, state);
37
+ return result;
38
+ })
39
+ .catch((error) => {
40
+ state.loading = false;
41
+ state.error = error;
42
+ updateLoadingState(loadFn, state);
43
+ throw error;
44
+ });
45
+ updateLoadingState(loadFn, state);
46
+ return state;
47
+ };
48
+ class LoadableComponentBase extends Component {
49
+ config;
50
+ constructor(config, initialState, props) {
51
+ super(props);
52
+ this.config = config;
53
+ this.state = initialState;
54
+ }
55
+ static loadFn = undefined;
56
+ static preload() {
57
+ load(this.loadFn);
58
+ }
59
+ UNSAFE_componentWillMount() {
60
+ this.loadModule();
61
+ }
62
+ loadModule() {
63
+ if (!this.state.loading) {
64
+ return;
65
+ }
66
+ const { promise } = load(this.config.loadFn);
67
+ this.syncLoadingState();
68
+ promise
69
+ .then(() => {
70
+ this.syncLoadingState();
71
+ return null;
72
+ })
73
+ .catch(() => {
74
+ this.syncLoadingState();
75
+ return null;
76
+ });
77
+ }
78
+ syncLoadingState() {
79
+ this.setState(getOrCreateLoadingState(this.config.loadFn));
80
+ }
81
+ updateLoadingState(update) {
82
+ this.setState(updateLoadingState(this.config.loadFn, update));
83
+ }
84
+ render() {
85
+ const { loader } = this.config;
86
+ const Loader = loader || DefaultLoader;
87
+ if (this.state.loading || this.state.error) {
88
+ return _jsx(Loader, {});
89
+ }
90
+ else if (this.state.result) {
91
+ const Component = this.state.result;
92
+ const Extra = this.config.extra;
93
+ return (_jsxs(_Fragment, { children: [_jsx(Component, { ...this.props }), Extra && _jsx(Extra, {})] }));
94
+ }
95
+ else {
96
+ return null;
97
+ }
98
+ }
99
+ }
4
100
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
5
- export function loadable(loadFunction, Fallback,
6
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
- ExtraComponent) {
8
- const LazyComponent = lazy(async () => ({
9
- default: await loadFunction(),
10
- }));
11
- const UsageFallback = Fallback ?? DefaultFallback;
12
- return (props) => (_jsxs(Suspense, { fallback: _jsx(UsageFallback, { ...props }), children: [_jsx(LazyComponent, { ...props }), ExtraComponent && _jsx(ExtraComponent, {})] }));
101
+ export function loadable(loadFn, loaderOrConfig) {
102
+ const config = typeof loaderOrConfig === 'object'
103
+ ? loaderOrConfig
104
+ : { loader: loaderOrConfig };
105
+ class LoadableComponent extends LoadableComponentBase {
106
+ loadFn = loadFn;
107
+ constructor(props) {
108
+ super({
109
+ loadFn,
110
+ ...config,
111
+ }, getOrCreateLoadingState(loadFn), props);
112
+ }
113
+ }
114
+ return LoadableComponent;
13
115
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-simple-loadable",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "Really simple React Loadable component",
5
5
  "repository": {
6
6
  "type": "git",