autosuspense 0.1.1

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.
Files changed (45) hide show
  1. package/README.md +6 -0
  2. package/autosuspense-lib-1.0.0.tgz +0 -0
  3. package/dist/components/AutoSuspense.d.ts +5 -0
  4. package/dist/components/AutoSuspense.d.ts.map +1 -0
  5. package/dist/components/AutoSuspense.js +18 -0
  6. package/dist/components/GeneratedFallback.d.ts +6 -0
  7. package/dist/components/GeneratedFallback.d.ts.map +1 -0
  8. package/dist/components/GeneratedFallback.js +8 -0
  9. package/dist/components/index.d.ts +4 -0
  10. package/dist/components/index.d.ts.map +1 -0
  11. package/dist/components/index.js +3 -0
  12. package/dist/hooks/index.d.ts +3 -0
  13. package/dist/hooks/index.d.ts.map +1 -0
  14. package/dist/hooks/index.js +2 -0
  15. package/dist/hooks/useCompatId.d.ts +2 -0
  16. package/dist/hooks/useCompatId.d.ts.map +1 -0
  17. package/dist/hooks/useCompatId.js +18 -0
  18. package/dist/hooks/useSuspenseFallback.d.ts +3 -0
  19. package/dist/hooks/useSuspenseFallback.d.ts.map +1 -0
  20. package/dist/hooks/useSuspenseFallback.js +18 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +2 -0
  24. package/dist/types/FallbackRegistry.d.ts +12 -0
  25. package/dist/types/FallbackRegistry.d.ts.map +1 -0
  26. package/dist/types/FallbackRegistry.js +2 -0
  27. package/dist/utils/buildTree.d.ts +3 -0
  28. package/dist/utils/buildTree.d.ts.map +1 -0
  29. package/dist/utils/buildTree.js +9 -0
  30. package/dist/utils/renderNode.d.ts +4 -0
  31. package/dist/utils/renderNode.d.ts.map +1 -0
  32. package/dist/utils/renderNode.js +5 -0
  33. package/package.json +41 -0
  34. package/src/components/AutoSuspense.tsx +27 -0
  35. package/src/components/GeneratedFallback.tsx +19 -0
  36. package/src/components/index.ts +3 -0
  37. package/src/hooks/index.ts +2 -0
  38. package/src/hooks/useCompatId.ts +24 -0
  39. package/src/hooks/useSuspenseFallback.ts +21 -0
  40. package/src/index.ts +2 -0
  41. package/src/types/FallbackRegistry.ts +14 -0
  42. package/src/utils/buildTree.ts +12 -0
  43. package/src/utils/renderNode.ts +15 -0
  44. package/tsconfig.json +23 -0
  45. package/tsconfig.tsbuildinfo +1 -0
package/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # AutoSupense
2
+ AutoSuspense is a simple react library allowing user's to automatically wire suspense components based on there component structure automatically without building additional fallback UI.
3
+
4
+ ## How to use?:
5
+ 1. Install this library
6
+ ```npm i autosuspense```
Binary file
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ export declare const AutoSuspense: ({ children }: {
3
+ children: React.ReactNode;
4
+ }) => React.JSX.Element;
5
+ //# sourceMappingURL=AutoSuspense.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoSuspense.d.ts","sourceRoot":"","sources":["../../src/components/AutoSuspense.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,eAAO,MAAM,YAAY,GAAI,cAAc;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,sBAmBvE,CAAC"}
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ import { FallbackContext, } from "../types/FallbackRegistry";
3
+ import { GeneratedFallback } from "./GeneratedFallback";
4
+ export const AutoSuspense = ({ children }) => {
5
+ const registryRef = React.useRef({
6
+ nodes: new Map(),
7
+ currentParent: null,
8
+ });
9
+ if (registryRef.current === null) {
10
+ registryRef.current = {
11
+ nodes: new Map(),
12
+ currentParent: null,
13
+ };
14
+ }
15
+ const fallback = React.createElement(GeneratedFallback, { registry: registryRef.current });
16
+ return (React.createElement(FallbackContext.Provider, { value: registryRef.current },
17
+ React.createElement(React.Suspense, { fallback: fallback }, children)));
18
+ };
@@ -0,0 +1,6 @@
1
+ import * as React from "react";
2
+ import type { FallbackRegistry } from "../types/FallbackRegistry";
3
+ export declare function GeneratedFallback({ registry, }: {
4
+ registry: FallbackRegistry;
5
+ }): React.JSX.Element;
6
+ //# sourceMappingURL=GeneratedFallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeneratedFallback.d.ts","sourceRoot":"","sources":["../../src/components/GeneratedFallback.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,qBASA"}
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ import { buildTree } from "../utils/buildTree";
3
+ import { renderNode } from "../utils/renderNode";
4
+ export function GeneratedFallback({ registry, }) {
5
+ const tree = buildTree(registry.nodes);
6
+ const roots = tree.get(null) ?? [];
7
+ return (React.createElement(React.Fragment, null, roots.map((node) => renderNode(node, tree))));
8
+ }
@@ -0,0 +1,4 @@
1
+ import { AutoSuspense } from "./AutoSuspense";
2
+ import { GeneratedFallback } from "./GeneratedFallback";
3
+ export { AutoSuspense, GeneratedFallback };
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { AutoSuspense } from "./AutoSuspense";
2
+ import { GeneratedFallback } from "./GeneratedFallback";
3
+ export { AutoSuspense, GeneratedFallback };
@@ -0,0 +1,3 @@
1
+ import { useSuspenseFallback } from "./useSuspenseFallback";
2
+ export { useSuspenseFallback };
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { useSuspenseFallback } from "./useSuspenseFallback";
2
+ export { useSuspenseFallback };
@@ -0,0 +1,2 @@
1
+ export declare function useCompatId(): string;
2
+ //# sourceMappingURL=useCompatId.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCompatId.d.ts","sourceRoot":"","sources":["../../src/hooks/useCompatId.ts"],"names":[],"mappings":"AASA,wBAAgB,WAAW,IAAI,MAAM,CAcpC"}
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ let globalId = 0;
3
+ function generateFallbackId() {
4
+ globalId += 1;
5
+ return `as-${globalId}`;
6
+ }
7
+ export function useCompatId() {
8
+ // React 18 path
9
+ if (typeof React.useId === "function") {
10
+ return React.useId();
11
+ }
12
+ // React 16/17 fallback
13
+ const idRef = React.useRef(null);
14
+ if (idRef.current === null) {
15
+ idRef.current = generateFallbackId();
16
+ }
17
+ return idRef.current;
18
+ }
@@ -0,0 +1,3 @@
1
+ import { type ReactElement } from "react";
2
+ export declare function useSuspenseFallback(element: ReactElement): void;
3
+ //# sourceMappingURL=useSuspenseFallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSuspenseFallback.d.ts","sourceRoot":"","sources":["../../src/hooks/useSuspenseFallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAItD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAgB/D"}
@@ -0,0 +1,18 @@
1
+ import { useContext } from "react";
2
+ import { FallbackContext } from "../types/FallbackRegistry";
3
+ import { useCompatId } from "./useCompatId";
4
+ export function useSuspenseFallback(element) {
5
+ const registry = useContext(FallbackContext);
6
+ const id = useCompatId();
7
+ if (!registry)
8
+ return;
9
+ if (registry.nodes.has(id))
10
+ return;
11
+ const parentId = registry.currentParent;
12
+ registry.nodes.set(id, {
13
+ id,
14
+ element,
15
+ parent: parentId,
16
+ });
17
+ registry.currentParent = id;
18
+ }
@@ -0,0 +1,3 @@
1
+ export { AutoSuspense } from "./components";
2
+ export { useSuspenseFallback } from "./hooks";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { AutoSuspense } from "./components";
2
+ export { useSuspenseFallback } from "./hooks";
@@ -0,0 +1,12 @@
1
+ import { type ReactElement } from "react";
2
+ export type Node = {
3
+ id: string;
4
+ element: ReactElement;
5
+ parent: string | null;
6
+ };
7
+ export type FallbackRegistry = {
8
+ nodes: Map<string, Node>;
9
+ currentParent: string | null;
10
+ };
11
+ export declare const FallbackContext: import("react").Context<FallbackRegistry | null>;
12
+ //# sourceMappingURL=FallbackRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FallbackRegistry.d.ts","sourceRoot":"","sources":["../../src/types/FallbackRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAEzD,MAAM,MAAM,IAAI,GAAG;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,eAAe,kDAA+C,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { createContext } from "react";
2
+ export const FallbackContext = createContext(null);
@@ -0,0 +1,3 @@
1
+ import type { Node } from "../types/FallbackRegistry";
2
+ export declare function buildTree(nodes: Map<string, Node>): Map<string | null, Node[]>;
3
+ //# sourceMappingURL=buildTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildTree.d.ts","sourceRoot":"","sources":["../../src/utils/buildTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAEtD,wBAAgB,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,8BASjD"}
@@ -0,0 +1,9 @@
1
+ export function buildTree(nodes) {
2
+ const childMap = new Map();
3
+ for (const node of nodes.values()) {
4
+ const list = childMap.get(node.parent) ?? [];
5
+ list.push(node);
6
+ childMap.set(node.parent, list);
7
+ }
8
+ return childMap;
9
+ }
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import type { Node } from "../types/FallbackRegistry";
3
+ export declare function renderNode(node: Node, childMap: Map<string | null, Node[]>): React.ReactElement;
4
+ //# sourceMappingURL=renderNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderNode.d.ts","sourceRoot":"","sources":["../../src/utils/renderNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAEtD,wBAAgB,UAAU,CACxB,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,GACnC,KAAK,CAAC,YAAY,CAQpB"}
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ export function renderNode(node, childMap) {
3
+ const children = childMap.get(node.id) ?? [];
4
+ return React.cloneElement(node.element, undefined, children.map((child) => renderNode(child, childMap)));
5
+ }
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "autosuspense",
3
+ "version": "0.1.1",
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 -b",
28
+ "test:build": "node dist/index.js"
29
+ },
30
+ "peerDependencies": {
31
+ "react": ">=16.8",
32
+ "react-dom": ">=16.8"
33
+ },
34
+ "devDependencies": {
35
+ "react": "^16.8.0",
36
+ "react-dom": "^16.8.0",
37
+ "@types/react": "^16.14.68",
38
+ "@types/react-dom": "^16.9.25",
39
+ "typescript": "^5.3.0"
40
+ }
41
+ }
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ import {
3
+ FallbackContext,
4
+ type FallbackRegistry,
5
+ } from "../types/FallbackRegistry";
6
+ import { GeneratedFallback } from "./GeneratedFallback";
7
+
8
+ export const AutoSuspense = ({ children }: { children: React.ReactNode }) => {
9
+ const registryRef = React.useRef<FallbackRegistry>({
10
+ nodes: new Map(),
11
+ currentParent: null,
12
+ });
13
+
14
+ if (registryRef.current === null) {
15
+ registryRef.current = {
16
+ nodes: new Map(),
17
+ currentParent: null,
18
+ };
19
+ }
20
+ const fallback = <GeneratedFallback registry={registryRef.current} />;
21
+
22
+ return (
23
+ <FallbackContext.Provider value={registryRef.current}>
24
+ <React.Suspense fallback={fallback}>{children}</React.Suspense>
25
+ </FallbackContext.Provider>
26
+ );
27
+ };
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+ import type { FallbackRegistry } from "../types/FallbackRegistry";
3
+ import { buildTree } from "../utils/buildTree";
4
+ import { renderNode } from "../utils/renderNode";
5
+
6
+ export function GeneratedFallback({
7
+ registry,
8
+ }: {
9
+ registry: FallbackRegistry;
10
+ }) {
11
+ const tree = buildTree(registry.nodes);
12
+ const roots = tree.get(null) ?? [];
13
+
14
+ return (
15
+ <React.Fragment>
16
+ {roots.map((node) => renderNode(node, tree))}
17
+ </React.Fragment>
18
+ );
19
+ }
@@ -0,0 +1,3 @@
1
+ import { AutoSuspense } from "./AutoSuspense";
2
+ import { GeneratedFallback } from "./GeneratedFallback";
3
+ export { AutoSuspense, GeneratedFallback };
@@ -0,0 +1,2 @@
1
+ import { useSuspenseFallback } from "./useSuspenseFallback";
2
+ export { useSuspenseFallback };
@@ -0,0 +1,24 @@
1
+ import * as React from "react";
2
+
3
+ let globalId = 0;
4
+
5
+ function generateFallbackId() {
6
+ globalId += 1;
7
+ return `as-${globalId}`;
8
+ }
9
+
10
+ export function useCompatId(): string {
11
+ // React 18 path
12
+ if (typeof (React as any).useId === "function") {
13
+ return (React as any).useId();
14
+ }
15
+
16
+ // React 16/17 fallback
17
+ const idRef = React.useRef<string | null>(null);
18
+
19
+ if (idRef.current === null) {
20
+ idRef.current = generateFallbackId();
21
+ }
22
+
23
+ return idRef.current;
24
+ }
@@ -0,0 +1,21 @@
1
+ import { useContext, type ReactElement } from "react";
2
+ import { FallbackContext } from "../types/FallbackRegistry";
3
+ import { useCompatId } from "./useCompatId";
4
+
5
+ export function useSuspenseFallback(element: ReactElement): void {
6
+ const registry = useContext(FallbackContext);
7
+ const id = useCompatId();
8
+
9
+ if (!registry) return;
10
+ if (registry.nodes.has(id)) return;
11
+
12
+ const parentId = registry.currentParent;
13
+
14
+ registry.nodes.set(id, {
15
+ id,
16
+ element,
17
+ parent: parentId,
18
+ });
19
+
20
+ registry.currentParent = id;
21
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { AutoSuspense } from "./components";
2
+ export { useSuspenseFallback } from "./hooks";
@@ -0,0 +1,14 @@
1
+ import { createContext, type ReactElement } from "react";
2
+
3
+ export type Node = {
4
+ id: string;
5
+ element: ReactElement;
6
+ parent: string | null;
7
+ };
8
+
9
+ export type FallbackRegistry = {
10
+ nodes: Map<string, Node>;
11
+ currentParent: string | null;
12
+ };
13
+
14
+ export const FallbackContext = createContext<FallbackRegistry | null>(null);
@@ -0,0 +1,12 @@
1
+ import type { Node } from "../types/FallbackRegistry";
2
+
3
+ export function buildTree(nodes: Map<string, Node>) {
4
+ const childMap = new Map<string | null, Node[]>();
5
+
6
+ for (const node of nodes.values()) {
7
+ const list = childMap.get(node.parent) ?? [];
8
+ list.push(node);
9
+ childMap.set(node.parent, list);
10
+ }
11
+ return childMap;
12
+ }
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import type { Node } from "../types/FallbackRegistry";
3
+
4
+ export function renderNode(
5
+ node: Node,
6
+ childMap: Map<string | null, Node[]>,
7
+ ): React.ReactElement {
8
+ const children = childMap.get(node.id) ?? [];
9
+
10
+ return React.cloneElement(
11
+ node.element,
12
+ undefined,
13
+ children.map((child) => renderNode(child, childMap)),
14
+ );
15
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "jsx": "react",
6
+ "lib": ["DOM", "ES2019"],
7
+ "types": ["react"],
8
+
9
+ "declaration": true,
10
+ "declarationMap": true,
11
+ "emitDeclarationOnly": false,
12
+
13
+ "outDir": "./dist",
14
+ "rootDir": "./src",
15
+
16
+ "strict": true,
17
+
18
+ "moduleResolution": "Bundler",
19
+ "esModuleInterop": true,
20
+ "skipLibCheck": true
21
+ },
22
+ "include": ["src"]
23
+ }
@@ -0,0 +1 @@
1
+ {"root":["./src/index.ts","./src/components/autosuspense.tsx","./src/components/generatedfallback.tsx","./src/components/index.ts","./src/hooks/index.ts","./src/hooks/usecompatid.ts","./src/hooks/usesuspensefallback.ts","./src/types/fallbackregistry.ts","./src/utils/buildtree.ts","./src/utils/rendernode.ts"],"version":"5.9.3"}