autosuspense 1.0.0 → 1.0.2
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 +62 -10
- package/dist/components/index.d.ts +3 -3
- package/dist/components/index.js +3 -3
- package/dist/components/prefabs/defaultPrefab.d.ts +2 -2
- package/dist/components/prefabs/defaultPrefab.js +9 -9
- package/dist/components/prefabs/prebuilt/Block.d.ts +9 -9
- package/dist/components/prefabs/prebuilt/Block.js +5 -5
- package/dist/components/prefabs/prebuilt/Card.d.ts +9 -9
- package/dist/components/prefabs/prebuilt/Card.js +5 -5
- package/dist/components/prefabs/prebuilt/List.d.ts +9 -9
- package/dist/components/prefabs/prebuilt/List.js +5 -5
- package/dist/components/suspense/AutoSuspense.d.ts +5 -5
- package/dist/components/suspense/AutoSuspense.js +16 -16
- package/dist/components/suspense/GeneratedFallback.d.ts +4 -4
- package/dist/components/suspense/GeneratedFallback.js +9 -9
- package/dist/functions/Suspend.d.ts +3 -3
- package/dist/functions/Suspend.js +22 -22
- package/dist/functions/index.d.ts +2 -2
- package/dist/functions/index.js +2 -2
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/useSuspenseBoundary.d.ts +2 -2
- package/dist/hooks/useSuspenseBoundary.js +19 -19
- package/dist/hooks/useSuspenseFallback.d.ts +2 -2
- package/dist/hooks/useSuspenseFallback.js +19 -19
- package/dist/hooks/useSuspenseProvider.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/types/FallbackRegistry.d.ts +17 -17
- package/dist/types/FallbackRegistry.js +2 -2
- package/dist/types/PrefabFactory.d.ts +4 -4
- package/dist/types/PrefabFactory.js +1 -1
- package/dist/utils/renderNode.d.ts +3 -3
- package/dist/utils/renderNode.js +15 -15
- package/dist/utils/resolveElement.d.ts +3 -3
- package/dist/utils/resolveElement.js +20 -20
- package/package.json +42 -42
- package/src/components/prefabs/{defaultPrefab.tsx → defaultFallbacks.tsx} +1 -1
- package/src/components/suspense/AutoSuspense.tsx +4 -4
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
# AutoSupense
|
|
1
|
+
# AutoSupense
|
|
2
2
|
AutoSuspense is a lightweight React utility that automatically composes Suspense fallback UI based on your component tree without manually wiring nested ```<Suspense>``` boundaries.
|
|
3
3
|
|
|
4
4
|
It lets you define fallback UI at the component level, while a parent ```<AutoSuspense>``` boundary handles rendering everything correctly.
|
|
5
5
|
|
|
6
|
+
---
|
|
6
7
|
## Why AutoSuspense?:
|
|
7
8
|
|
|
8
9
|
React Suspense solves async rendering, but fallback composition quickly becomes messy:
|
|
@@ -38,6 +39,7 @@ function Page() {
|
|
|
38
39
|
|
|
39
40
|
export default Suspend(Page, <div>Loading page...</div>);
|
|
40
41
|
```
|
|
42
|
+
---
|
|
41
43
|
|
|
42
44
|
## Installation:
|
|
43
45
|
```npm install autosuspense```
|
|
@@ -67,11 +69,11 @@ const UserCard = () => {
|
|
|
67
69
|
export default Suspend(UserCard, <div>Loading user...</div>);
|
|
68
70
|
```
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
- Nested components automatically compose
|
|
71
73
|
```
|
|
72
74
|
const Parent = () => <Child />;
|
|
73
75
|
|
|
74
|
-
export default Suspend(Parent, <div>
|
|
76
|
+
export default Suspend(Parent, <div>Outer Loader...</div>);
|
|
75
77
|
const Child = () => {
|
|
76
78
|
const data = resource.read();
|
|
77
79
|
return <div>{data}</div>;
|
|
@@ -81,26 +83,73 @@ export default Suspend(Child, <div>Inner Loader...</div>);
|
|
|
81
83
|
```
|
|
82
84
|
👉 Resulting fallback:
|
|
83
85
|
```
|
|
84
|
-
|
|
86
|
+
Outer Loader...
|
|
85
87
|
Inner Loader...
|
|
86
88
|
```
|
|
87
|
-
|
|
89
|
+
|
|
90
|
+
## Using fallback maps (Per Suspense Reusable Fallbacks)
|
|
91
|
+
Instead of passing JSX everywhere, define reusable fallbacks once based required design. Use this to compose multiple fallback designs in the same component.
|
|
92
|
+
|
|
93
|
+
- Define prefabs at the root
|
|
94
|
+
```
|
|
95
|
+
import { AutoSuspense } from "autosuspense";
|
|
96
|
+
import PageSkeleton from "./skeletons/PageSkeleton";
|
|
97
|
+
import CardSkeleton from "./skeletons/CardSkeleton";
|
|
98
|
+
|
|
99
|
+
function App() {
|
|
100
|
+
return (
|
|
101
|
+
<AutoSuspense
|
|
102
|
+
fallbacks={{
|
|
103
|
+
page: PageSkeleton,
|
|
104
|
+
card: CardSkeleton,
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
<Page />
|
|
108
|
+
</AutoSuspense>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Use fallback map keys in components:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
import { Suspend } from "autosuspense";
|
|
117
|
+
|
|
118
|
+
function Page() {
|
|
119
|
+
return <Feed />;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export default Suspend(Page, "page");
|
|
123
|
+
function Feed() {
|
|
124
|
+
const data = resource.read();
|
|
125
|
+
return <div>{data}</div>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default Suspend(Feed, "card");
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Resulting fallback UI
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
PageSkeleton
|
|
135
|
+
CardSkeleton
|
|
136
|
+
```
|
|
88
137
|
|
|
89
138
|
## Core Idea:
|
|
90
|
-
- Wrap a subtree with
|
|
139
|
+
- Wrap a subtree with ```<AutoSuspense>```.
|
|
91
140
|
- Wrap components with Suspend().
|
|
92
141
|
- Each component declares its fallback.
|
|
93
142
|
- AutoSuspense automatically composes the fallback UI tree without explicit maintaince and wiring.
|
|
143
|
+
- Fallback maps automatically help compose UI changes without changing the actual Component.
|
|
94
144
|
|
|
145
|
+
---
|
|
95
146
|
## Fallback Options:
|
|
96
147
|
|
|
97
148
|
You can provide fallbacks in multiple ways:
|
|
98
|
-
|
|
99
149
|
1. JSX element:
|
|
150
|
+
|
|
100
151
|
```
|
|
101
152
|
Suspend(Component, <Skeleton />);
|
|
102
|
-
Component
|
|
103
|
-
Suspend(Component, SkeletonComponent);
|
|
104
153
|
```
|
|
105
154
|
|
|
106
155
|
2. Component:
|
|
@@ -109,8 +158,11 @@ Suspend(Component, SkeletonComponent);
|
|
|
109
158
|
```
|
|
110
159
|
|
|
111
160
|
3. String:
|
|
161
|
+
|
|
162
|
+
|
|
112
163
|
```
|
|
113
164
|
Suspend(Component, SkeletonComponent);
|
|
114
165
|
```
|
|
115
166
|
|
|
116
|
-
|
|
167
|
+
---
|
|
168
|
+
AutoSuspense aims to make and enhance fallback creation and make it's maintainence easier.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AutoSuspense } from "./suspense/AutoSuspense";
|
|
2
|
-
import { GeneratedFallback } from "./suspense/GeneratedFallback";
|
|
3
|
-
export { AutoSuspense, GeneratedFallback };
|
|
1
|
+
import { AutoSuspense } from "./suspense/AutoSuspense";
|
|
2
|
+
import { GeneratedFallback } from "./suspense/GeneratedFallback";
|
|
3
|
+
export { AutoSuspense, GeneratedFallback };
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/components/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { AutoSuspense } from "./suspense/AutoSuspense";
|
|
2
|
-
import { GeneratedFallback } from "./suspense/GeneratedFallback";
|
|
3
|
-
export { AutoSuspense, GeneratedFallback };
|
|
1
|
+
import { AutoSuspense } from "./suspense/AutoSuspense";
|
|
2
|
+
import { GeneratedFallback } from "./suspense/GeneratedFallback";
|
|
3
|
+
export { AutoSuspense, GeneratedFallback };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
export declare const defaultPrefab: Record<string, React.ReactElement>;
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export declare const defaultPrefab: Record<string, React.ReactElement>;
|
|
3
3
|
//# sourceMappingURL=defaultPrefab.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Block } from "./prebuilt/Block";
|
|
3
|
-
import { Card } from "./prebuilt/Card";
|
|
4
|
-
import { List } from "./prebuilt/List";
|
|
5
|
-
export const defaultPrefab = {
|
|
6
|
-
block: _jsx(Block, {}),
|
|
7
|
-
card: _jsx(Card, {}),
|
|
8
|
-
list: _jsx(List, {}),
|
|
9
|
-
};
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Block } from "./prebuilt/Block";
|
|
3
|
+
import { Card } from "./prebuilt/Card";
|
|
4
|
+
import { List } from "./prebuilt/List";
|
|
5
|
+
export const defaultPrefab = {
|
|
6
|
+
block: _jsx(Block, {}),
|
|
7
|
+
card: _jsx(Card, {}),
|
|
8
|
+
list: _jsx(List, {}),
|
|
9
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import "./Block.css";
|
|
3
|
-
type BlockProps = {
|
|
4
|
-
children?: React.ReactNode;
|
|
5
|
-
className?: string;
|
|
6
|
-
style?: React.CSSProperties;
|
|
7
|
-
};
|
|
8
|
-
export declare const Block: React.FC<BlockProps>;
|
|
9
|
-
export {};
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import "./Block.css";
|
|
3
|
+
type BlockProps = {
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
};
|
|
8
|
+
export declare const Block: React.FC<BlockProps>;
|
|
9
|
+
export {};
|
|
10
10
|
//# sourceMappingURL=Block.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import "./Block.css";
|
|
3
|
-
export const Block = ({ children, className, style }) => {
|
|
4
|
-
return (_jsx("div", { className: `as-block ${className ?? ""}`, style: style, "data-as-block": true, children: children }));
|
|
5
|
-
};
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import "./Block.css";
|
|
3
|
+
export const Block = ({ children, className, style }) => {
|
|
4
|
+
return (_jsx("div", { className: `as-block ${className ?? ""}`, style: style, "data-as-block": true, children: children }));
|
|
5
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import "./Card.css";
|
|
3
|
-
type CardProps = {
|
|
4
|
-
children?: React.ReactNode;
|
|
5
|
-
className?: string;
|
|
6
|
-
style?: React.CSSProperties;
|
|
7
|
-
};
|
|
8
|
-
export declare const Card: React.FC<CardProps>;
|
|
9
|
-
export {};
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import "./Card.css";
|
|
3
|
+
type CardProps = {
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
};
|
|
8
|
+
export declare const Card: React.FC<CardProps>;
|
|
9
|
+
export {};
|
|
10
10
|
//# sourceMappingURL=Card.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import "./Card.css";
|
|
3
|
-
export const Card = ({ children, className, style }) => {
|
|
4
|
-
return (_jsx("div", { className: `as-card ${className ?? ""}`, style: style, "data-as-card": true, children: children }));
|
|
5
|
-
};
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import "./Card.css";
|
|
3
|
+
export const Card = ({ children, className, style }) => {
|
|
4
|
+
return (_jsx("div", { className: `as-card ${className ?? ""}`, style: style, "data-as-card": true, children: children }));
|
|
5
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import "./List.css";
|
|
3
|
-
type ListProps = {
|
|
4
|
-
children?: React.ReactNode;
|
|
5
|
-
className?: string;
|
|
6
|
-
style?: React.CSSProperties;
|
|
7
|
-
};
|
|
8
|
-
export declare const List: React.FC<ListProps>;
|
|
9
|
-
export {};
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import "./List.css";
|
|
3
|
+
type ListProps = {
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
};
|
|
8
|
+
export declare const List: React.FC<ListProps>;
|
|
9
|
+
export {};
|
|
10
10
|
//# sourceMappingURL=List.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import "./List.css";
|
|
3
|
-
export const List = ({ children, className, style }) => {
|
|
4
|
-
return (_jsx("div", { className: `as-list ${className ?? ""}`, style: style, "data-as-list": true, children: children }));
|
|
5
|
-
};
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import "./List.css";
|
|
3
|
+
export const List = ({ children, className, style }) => {
|
|
4
|
+
return (_jsx("div", { className: `as-list ${className ?? ""}`, style: style, "data-as-list": true, children: children }));
|
|
5
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
export declare const AutoSuspense: ({ children, prefab, }: {
|
|
3
|
-
children: React.ReactNode;
|
|
4
|
-
prefab?: Record<string, React.ReactElement | React.ComponentType<any>>;
|
|
5
|
-
}) => JSX.Element;
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export declare const AutoSuspense: ({ children, prefab, }: {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
prefab?: Record<string, React.ReactElement | React.ComponentType<any>>;
|
|
5
|
+
}) => JSX.Element;
|
|
6
6
|
//# sourceMappingURL=AutoSuspense.d.ts.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { GeneratedFallback } from "./GeneratedFallback";
|
|
4
|
-
import { FallbackContext, } from "../../types/FallbackRegistry";
|
|
5
|
-
import { defaultPrefab } from "../prefabs/defaultPrefab";
|
|
6
|
-
export const AutoSuspense = ({ children, prefab = defaultPrefab, }) => {
|
|
7
|
-
const registryRef = React.useRef({
|
|
8
|
-
nodes: new Map(),
|
|
9
|
-
prebuild: new Map(Object.entries(prefab)),
|
|
10
|
-
});
|
|
11
|
-
const fallback = _jsx(GeneratedFallback, { registry: registryRef.current });
|
|
12
|
-
return (_jsx(FallbackContext.Provider, { value: {
|
|
13
|
-
registry: registryRef.current,
|
|
14
|
-
parentId: null,
|
|
15
|
-
}, children: _jsx(React.Suspense, { fallback: fallback, children: children }) }));
|
|
16
|
-
};
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { GeneratedFallback } from "./GeneratedFallback";
|
|
4
|
+
import { FallbackContext, } from "../../types/FallbackRegistry";
|
|
5
|
+
import { defaultPrefab } from "../prefabs/defaultPrefab";
|
|
6
|
+
export const AutoSuspense = ({ children, prefab = defaultPrefab, }) => {
|
|
7
|
+
const registryRef = React.useRef({
|
|
8
|
+
nodes: new Map(),
|
|
9
|
+
prebuild: new Map(Object.entries(prefab)),
|
|
10
|
+
});
|
|
11
|
+
const fallback = _jsx(GeneratedFallback, { registry: registryRef.current });
|
|
12
|
+
return (_jsx(FallbackContext.Provider, { value: {
|
|
13
|
+
registry: registryRef.current,
|
|
14
|
+
parentId: null,
|
|
15
|
+
}, children: _jsx(React.Suspense, { fallback: fallback, children: children }) }));
|
|
16
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FallbackRegistry } from "../../types/FallbackRegistry";
|
|
2
|
-
export declare function GeneratedFallback({ registry, }: {
|
|
3
|
-
registry: FallbackRegistry;
|
|
4
|
-
}): JSX.Element;
|
|
1
|
+
import { FallbackRegistry } from "../../types/FallbackRegistry";
|
|
2
|
+
export declare function GeneratedFallback({ registry, }: {
|
|
3
|
+
registry: FallbackRegistry;
|
|
4
|
+
}): JSX.Element;
|
|
5
5
|
//# sourceMappingURL=GeneratedFallback.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { buildTree } from "../../utils/buildTree";
|
|
4
|
-
import { renderNode } from "../../utils/renderNode";
|
|
5
|
-
export function GeneratedFallback({ registry, }) {
|
|
6
|
-
const tree = buildTree(registry.nodes);
|
|
7
|
-
const roots = tree.get(null) ?? [];
|
|
8
|
-
return (_jsx(React.Fragment, { children: roots.map((node) => renderNode(node, tree, registry)) }));
|
|
9
|
-
}
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { buildTree } from "../../utils/buildTree";
|
|
4
|
+
import { renderNode } from "../../utils/renderNode";
|
|
5
|
+
export function GeneratedFallback({ registry, }) {
|
|
6
|
+
const tree = buildTree(registry.nodes);
|
|
7
|
+
const roots = tree.get(null) ?? [];
|
|
8
|
+
return (_jsx(React.Fragment, { children: roots.map((node) => renderNode(node, tree, registry)) }));
|
|
9
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { FallbackDescriptor } from "../types/FallbackRegistry";
|
|
3
|
-
export declare function Suspend<T extends object>(Component: React.ComponentType<T>, fallback?: FallbackDescriptor): (props: T) => JSX.Element;
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { FallbackDescriptor } from "../types/FallbackRegistry";
|
|
3
|
+
export declare function Suspend<T extends object>(Component: React.ComponentType<T>, fallback?: FallbackDescriptor): (props: T) => JSX.Element;
|
|
4
4
|
//# sourceMappingURL=Suspend.d.ts.map
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { FallbackContext } from "../types/FallbackRegistry";
|
|
4
|
-
import { useCompatId } from "../hooks/useCompatId";
|
|
5
|
-
export function Suspend(Component, fallback) {
|
|
6
|
-
return function Wrapped(props) {
|
|
7
|
-
const ctx = React.useContext(FallbackContext);
|
|
8
|
-
const id = useCompatId();
|
|
9
|
-
if (!ctx) {
|
|
10
|
-
return _jsx(Component, { ...props });
|
|
11
|
-
}
|
|
12
|
-
const { registry, parentId } = ctx;
|
|
13
|
-
if (!registry.nodes.has(id)) {
|
|
14
|
-
registry.nodes.set(id, {
|
|
15
|
-
id,
|
|
16
|
-
element: fallback ?? Component,
|
|
17
|
-
parent: parentId,
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
return (_jsx(FallbackContext.Provider, { value: { registry, parentId: id }, children: _jsx(Component, { ...props }) }));
|
|
21
|
-
};
|
|
22
|
-
}
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { FallbackContext } from "../types/FallbackRegistry";
|
|
4
|
+
import { useCompatId } from "../hooks/useCompatId";
|
|
5
|
+
export function Suspend(Component, fallback) {
|
|
6
|
+
return function Wrapped(props) {
|
|
7
|
+
const ctx = React.useContext(FallbackContext);
|
|
8
|
+
const id = useCompatId();
|
|
9
|
+
if (!ctx) {
|
|
10
|
+
return _jsx(Component, { ...props });
|
|
11
|
+
}
|
|
12
|
+
const { registry, parentId } = ctx;
|
|
13
|
+
if (!registry.nodes.has(id)) {
|
|
14
|
+
registry.nodes.set(id, {
|
|
15
|
+
id,
|
|
16
|
+
element: fallback ?? Component,
|
|
17
|
+
parent: parentId,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return (_jsx(FallbackContext.Provider, { value: { registry, parentId: id }, children: _jsx(Component, { ...props }) }));
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Suspend } from "./Suspend";
|
|
2
|
-
export { Suspend };
|
|
1
|
+
import { Suspend } from "./Suspend";
|
|
2
|
+
export { Suspend };
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/functions/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Suspend } from "./Suspend";
|
|
2
|
-
export { Suspend };
|
|
1
|
+
import { Suspend } from "./Suspend";
|
|
2
|
+
export { Suspend };
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/hooks/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { FallbackDescriptor } from "../types/FallbackRegistry";
|
|
2
|
-
export declare function useSuspenseBoundary(element: FallbackDescriptor): void;
|
|
1
|
+
import { FallbackDescriptor } from "../types/FallbackRegistry";
|
|
2
|
+
export declare function useSuspenseBoundary(element: FallbackDescriptor): void;
|
|
3
3
|
//# sourceMappingURL=useSuspenseBoundary.d.ts.map
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { useContext } from "react";
|
|
2
|
-
import { FallbackContext } from "../types/FallbackRegistry";
|
|
3
|
-
import { useCompatId } from "./useCompatId";
|
|
4
|
-
export function useSuspenseBoundary(element) {
|
|
5
|
-
const registry = useContext(FallbackContext);
|
|
6
|
-
const id = useCompatId();
|
|
7
|
-
if (!registry)
|
|
8
|
-
return;
|
|
9
|
-
if (registry.registry.nodes.has(id))
|
|
10
|
-
return;
|
|
11
|
-
const parentId = registry.parentId;
|
|
12
|
-
registry.registry.nodes.set(id, {
|
|
13
|
-
id,
|
|
14
|
-
element,
|
|
15
|
-
parent: parentId,
|
|
16
|
-
isBoundary: true,
|
|
17
|
-
});
|
|
18
|
-
registry.parentId = id;
|
|
19
|
-
}
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { FallbackContext } from "../types/FallbackRegistry";
|
|
3
|
+
import { useCompatId } from "./useCompatId";
|
|
4
|
+
export function useSuspenseBoundary(element) {
|
|
5
|
+
const registry = useContext(FallbackContext);
|
|
6
|
+
const id = useCompatId();
|
|
7
|
+
if (!registry)
|
|
8
|
+
return;
|
|
9
|
+
if (registry.registry.nodes.has(id))
|
|
10
|
+
return;
|
|
11
|
+
const parentId = registry.parentId;
|
|
12
|
+
registry.registry.nodes.set(id, {
|
|
13
|
+
id,
|
|
14
|
+
element,
|
|
15
|
+
parent: parentId,
|
|
16
|
+
isBoundary: true,
|
|
17
|
+
});
|
|
18
|
+
registry.parentId = id;
|
|
19
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { FallbackDescriptor } from "../types/FallbackRegistry";
|
|
2
|
-
export declare function useSuspenseFallback(element: FallbackDescriptor): void;
|
|
1
|
+
import { FallbackDescriptor } from "../types/FallbackRegistry";
|
|
2
|
+
export declare function useSuspenseFallback(element: FallbackDescriptor): void;
|
|
3
3
|
//# sourceMappingURL=useSuspenseFallback.d.ts.map
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { useContext } from "react";
|
|
2
|
-
import { FallbackContext } from "../types/FallbackRegistry";
|
|
3
|
-
import { useCompatId } from "./useCompatId";
|
|
4
|
-
// Depricated hook, core logic changed
|
|
5
|
-
export function useSuspenseFallback(element) {
|
|
6
|
-
const registry = useContext(FallbackContext);
|
|
7
|
-
const id = useCompatId();
|
|
8
|
-
if (!registry)
|
|
9
|
-
return;
|
|
10
|
-
if (registry.registry.nodes.has(id))
|
|
11
|
-
return;
|
|
12
|
-
const parentId = registry.parentId;
|
|
13
|
-
registry.registry.nodes.set(id, {
|
|
14
|
-
id,
|
|
15
|
-
element,
|
|
16
|
-
parent: parentId,
|
|
17
|
-
});
|
|
18
|
-
registry.parentId = id;
|
|
19
|
-
}
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { FallbackContext } from "../types/FallbackRegistry";
|
|
3
|
+
import { useCompatId } from "./useCompatId";
|
|
4
|
+
// Depricated hook, core logic changed
|
|
5
|
+
export function useSuspenseFallback(element) {
|
|
6
|
+
const registry = useContext(FallbackContext);
|
|
7
|
+
const id = useCompatId();
|
|
8
|
+
if (!registry)
|
|
9
|
+
return;
|
|
10
|
+
if (registry.registry.nodes.has(id))
|
|
11
|
+
return;
|
|
12
|
+
const parentId = registry.parentId;
|
|
13
|
+
registry.registry.nodes.set(id, {
|
|
14
|
+
id,
|
|
15
|
+
element,
|
|
16
|
+
parent: parentId,
|
|
17
|
+
});
|
|
18
|
+
registry.parentId = id;
|
|
19
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AutoSuspense } from "./components";
|
|
2
|
-
export * from "./hooks";
|
|
3
|
-
export * from "./functions";
|
|
1
|
+
export { AutoSuspense } from "./components";
|
|
2
|
+
export * from "./hooks";
|
|
3
|
+
export * from "./functions";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AutoSuspense } from "./components";
|
|
2
|
-
export * from "./hooks";
|
|
3
|
-
export * from "./functions";
|
|
1
|
+
export { AutoSuspense } from "./components";
|
|
2
|
+
export * from "./hooks";
|
|
3
|
+
export * from "./functions";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
export type Node = {
|
|
3
|
-
id: string;
|
|
4
|
-
element: FallbackDescriptor;
|
|
5
|
-
parent: string | null;
|
|
6
|
-
isBoundary?: boolean;
|
|
7
|
-
};
|
|
8
|
-
export type FallbackRegistry = {
|
|
9
|
-
nodes: Map<string, Node>;
|
|
10
|
-
prebuild: Map<string, React.ReactElement | React.ComponentType<any>>;
|
|
11
|
-
};
|
|
12
|
-
export type FallbackDescriptor = string | React.ReactElement | React.ComponentType;
|
|
13
|
-
export type FallbackContextValue = {
|
|
14
|
-
registry: FallbackRegistry;
|
|
15
|
-
parentId: string | null;
|
|
16
|
-
};
|
|
17
|
-
export declare const FallbackContext: React.Context<FallbackContextValue | null>;
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type Node = {
|
|
3
|
+
id: string;
|
|
4
|
+
element: FallbackDescriptor;
|
|
5
|
+
parent: string | null;
|
|
6
|
+
isBoundary?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type FallbackRegistry = {
|
|
9
|
+
nodes: Map<string, Node>;
|
|
10
|
+
prebuild: Map<string, React.ReactElement | React.ComponentType<any>>;
|
|
11
|
+
};
|
|
12
|
+
export type FallbackDescriptor = string | React.ReactElement | React.ComponentType;
|
|
13
|
+
export type FallbackContextValue = {
|
|
14
|
+
registry: FallbackRegistry;
|
|
15
|
+
parentId: string | null;
|
|
16
|
+
};
|
|
17
|
+
export declare const FallbackContext: React.Context<FallbackContextValue | null>;
|
|
18
18
|
//# sourceMappingURL=FallbackRegistry.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
export const FallbackContext = React.createContext(null);
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export const FallbackContext = React.createContext(null);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
export type PrefabFactory = (props: {
|
|
3
|
-
children?: React.ReactNode;
|
|
4
|
-
}) => React.ReactElement;
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type PrefabFactory = (props: {
|
|
3
|
+
children?: React.ReactNode;
|
|
4
|
+
}) => React.ReactElement;
|
|
5
5
|
//# sourceMappingURL=PrefabFactory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { FallbackRegistry, Node } from "../types/FallbackRegistry";
|
|
3
|
-
export declare function renderNode(node: Node, childMap: Map<string | null, Node[]>, registry: FallbackRegistry): React.ReactElement | null;
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { FallbackRegistry, Node } from "../types/FallbackRegistry";
|
|
3
|
+
export declare function renderNode(node: Node, childMap: Map<string | null, Node[]>, registry: FallbackRegistry): React.ReactElement | null;
|
|
4
4
|
//# sourceMappingURL=renderNode.d.ts.map
|
package/dist/utils/renderNode.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import React, { Suspense } from "react";
|
|
3
|
-
import { resolveElement } from "./resolveElement";
|
|
4
|
-
import { Block } from "../components/prefabs/prebuilt/Block";
|
|
5
|
-
export function renderNode(node, childMap, registry) {
|
|
6
|
-
const children = childMap.get(node.id) ?? [];
|
|
7
|
-
const resolvedEle = resolveElement(node.element, registry);
|
|
8
|
-
if (!resolvedEle)
|
|
9
|
-
return null;
|
|
10
|
-
const renderedChildren = children.map((child) => renderNode(child, childMap, registry));
|
|
11
|
-
if (node.isBoundary) {
|
|
12
|
-
return (_jsx(Suspense, { fallback: _jsx(Block, {}), children: React.cloneElement(resolvedEle, {}, renderedChildren) }, node.id));
|
|
13
|
-
}
|
|
14
|
-
return React.cloneElement(resolvedEle, { key: node.id }, renderedChildren);
|
|
15
|
-
}
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { Suspense } from "react";
|
|
3
|
+
import { resolveElement } from "./resolveElement";
|
|
4
|
+
import { Block } from "../components/prefabs/prebuilt/Block";
|
|
5
|
+
export function renderNode(node, childMap, registry) {
|
|
6
|
+
const children = childMap.get(node.id) ?? [];
|
|
7
|
+
const resolvedEle = resolveElement(node.element, registry);
|
|
8
|
+
if (!resolvedEle)
|
|
9
|
+
return null;
|
|
10
|
+
const renderedChildren = children.map((child) => renderNode(child, childMap, registry));
|
|
11
|
+
if (node.isBoundary) {
|
|
12
|
+
return (_jsx(Suspense, { fallback: _jsx(Block, {}), children: React.cloneElement(resolvedEle, {}, renderedChildren) }, node.id));
|
|
13
|
+
}
|
|
14
|
+
return React.cloneElement(resolvedEle, { key: node.id }, renderedChildren);
|
|
15
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { FallbackDescriptor, FallbackRegistry } from "../types/FallbackRegistry";
|
|
3
|
-
export declare function resolveElement(descriptor: FallbackDescriptor, registry: FallbackRegistry): React.ReactElement | null;
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { FallbackDescriptor, FallbackRegistry } from "../types/FallbackRegistry";
|
|
3
|
+
export declare function resolveElement(descriptor: FallbackDescriptor, registry: FallbackRegistry): React.ReactElement | null;
|
|
4
4
|
//# sourceMappingURL=resolveElement.d.ts.map
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
export function resolveElement(descriptor, registry) {
|
|
3
|
-
if (React.isValidElement(descriptor)) {
|
|
4
|
-
return descriptor;
|
|
5
|
-
}
|
|
6
|
-
if (typeof descriptor === "function") {
|
|
7
|
-
return React.createElement(descriptor);
|
|
8
|
-
}
|
|
9
|
-
if (typeof descriptor === "string") {
|
|
10
|
-
const value = registry.prebuild.get(descriptor);
|
|
11
|
-
if (!value)
|
|
12
|
-
return null;
|
|
13
|
-
if (React.isValidElement(value)) {
|
|
14
|
-
return value;
|
|
15
|
-
}
|
|
16
|
-
const Component = value;
|
|
17
|
-
return React.createElement(Component);
|
|
18
|
-
}
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export function resolveElement(descriptor, registry) {
|
|
3
|
+
if (React.isValidElement(descriptor)) {
|
|
4
|
+
return descriptor;
|
|
5
|
+
}
|
|
6
|
+
if (typeof descriptor === "function") {
|
|
7
|
+
return React.createElement(descriptor);
|
|
8
|
+
}
|
|
9
|
+
if (typeof descriptor === "string") {
|
|
10
|
+
const value = registry.prebuild.get(descriptor);
|
|
11
|
+
if (!value)
|
|
12
|
+
return null;
|
|
13
|
+
if (React.isValidElement(value)) {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
const Component = value;
|
|
17
|
+
return React.createElement(Component);
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "autosuspense",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Automatic suspense wiring block for React.",
|
|
5
|
-
"license": "ISC",
|
|
6
|
-
"type": "commonjs",
|
|
7
|
-
"main": "dist/index.js",
|
|
8
|
-
"types": "dist/index.d.ts",
|
|
9
|
-
"author": {
|
|
10
|
-
"name": "Paper-Bag-dev",
|
|
11
|
-
"email": "vikalpsh1234@gmail.com",
|
|
12
|
-
"url": "https://github.com/Paper-Bag-dev"
|
|
13
|
-
},
|
|
14
|
-
"keywords": [
|
|
15
|
-
"react",
|
|
16
|
-
"react-suspense",
|
|
17
|
-
"suspense",
|
|
18
|
-
"react-hooks",
|
|
19
|
-
"fallback",
|
|
20
|
-
"react-library",
|
|
21
|
-
"ui",
|
|
22
|
-
"async",
|
|
23
|
-
"concurrent",
|
|
24
|
-
"typescript"
|
|
25
|
-
],
|
|
26
|
-
"scripts": {
|
|
27
|
-
"build": "tsc && copyfiles -u 1 \"src/**/*.css\" dist",
|
|
28
|
-
"test:build": "node dist/index.js"
|
|
29
|
-
},
|
|
30
|
-
"peerDependencies": {
|
|
31
|
-
"react": ">=16.8",
|
|
32
|
-
"react-dom": ">=16.8"
|
|
33
|
-
},
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"@types/react": "^16.14.68",
|
|
36
|
-
"@types/react-dom": "^16.9.25",
|
|
37
|
-
"copyfiles": "^2.4.1",
|
|
38
|
-
"react": "^16.8.0",
|
|
39
|
-
"react-dom": "^16.8.0",
|
|
40
|
-
"typescript": "^5.3.0"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "autosuspense",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Automatic suspense wiring block for React.",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"author": {
|
|
10
|
+
"name": "Paper-Bag-dev",
|
|
11
|
+
"email": "vikalpsh1234@gmail.com",
|
|
12
|
+
"url": "https://github.com/Paper-Bag-dev"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"react",
|
|
16
|
+
"react-suspense",
|
|
17
|
+
"suspense",
|
|
18
|
+
"react-hooks",
|
|
19
|
+
"fallback",
|
|
20
|
+
"react-library",
|
|
21
|
+
"ui",
|
|
22
|
+
"async",
|
|
23
|
+
"concurrent",
|
|
24
|
+
"typescript"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc && copyfiles -u 1 \"src/**/*.css\" dist",
|
|
28
|
+
"test:build": "node dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": ">=16.8",
|
|
32
|
+
"react-dom": ">=16.8"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/react": "^16.14.68",
|
|
36
|
+
"@types/react-dom": "^16.9.25",
|
|
37
|
+
"copyfiles": "^2.4.1",
|
|
38
|
+
"react": "^16.8.0",
|
|
39
|
+
"react-dom": "^16.8.0",
|
|
40
|
+
"typescript": "^5.3.0"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -3,7 +3,7 @@ import { Block } from "./prebuilt/Block";
|
|
|
3
3
|
import { Card } from "./prebuilt/Card";
|
|
4
4
|
import { List } from "./prebuilt/List";
|
|
5
5
|
|
|
6
|
-
export const
|
|
6
|
+
export const defaultFallbacks: Record<string, React.ReactElement> = {
|
|
7
7
|
block: <Block />,
|
|
8
8
|
card: <Card />,
|
|
9
9
|
list: <List />,
|
|
@@ -5,18 +5,18 @@ import {
|
|
|
5
5
|
FallbackContext,
|
|
6
6
|
FallbackRegistry,
|
|
7
7
|
} from "../../types/FallbackRegistry";
|
|
8
|
-
import {
|
|
8
|
+
import { defaultFallbacks } from "../prefabs/defaultFallbacks";
|
|
9
9
|
|
|
10
10
|
export const AutoSuspense = ({
|
|
11
11
|
children,
|
|
12
|
-
|
|
12
|
+
fallbacks = defaultFallbacks,
|
|
13
13
|
}: {
|
|
14
14
|
children: React.ReactNode;
|
|
15
|
-
|
|
15
|
+
fallbacks?: Record<string, React.ReactElement | React.ComponentType<any>>;
|
|
16
16
|
}) => {
|
|
17
17
|
const registryRef = React.useRef<FallbackRegistry>({
|
|
18
18
|
nodes: new Map(),
|
|
19
|
-
prebuild: new Map(Object.entries(
|
|
19
|
+
prebuild: new Map(Object.entries(fallbacks)),
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
const fallback = <GeneratedFallback registry={registryRef.current} />;
|