-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhook.ts
More file actions
72 lines (56 loc) · 1.67 KB
/
Copy pathhook.ts
File metadata and controls
72 lines (56 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import * as React from 'react';
import { fetchBundle } from './fetch';
import { BundleError } from '../error';
import { getComponent, getScope } from './utils';
interface IBundle {
path: string
name: string
error: boolean
data: any
}
interface IProps {
path: string
name: string
component?: string | string[]
}
interface IStatus {
isLoading: boolean
error: null | Error
data: any
}
export const bundles = new Map<string, IBundle>();
export function useBundle({ path, name, component }:IProps) {
const bundleExists = bundles.get(name);
const [status, setStatus] = React.useState<IStatus>({ isLoading: !bundleExists, error: null, data: null });
const scope = getScope();
const getBundle = React.useCallback(async () => {
let error = null;
let data = null;
let bundle = bundles.get(name);
try {
if (bundle && bundle.error)
throw bundle.error;
if (!bundle) {
setStatus({ ...status, isLoading: true });
await fetchBundle(path);
if (!(name in scope))
throw new BundleError({
message: `Component ${name} not found in global scope when fetching ${path}`
});
bundle = { path, name, data: scope[name], error };
bundles.set(name, bundle);
}
data = getComponent(bundle.data, component);
} catch (e) {
error = e instanceof BundleError ? e : new BundleError(e);
} finally {
if (!bundle)
bundles.set(name, { path, name, data, error });
setStatus({ isLoading: false, error, data });
}
}, [path, name, component]);
React.useEffect(() => {
getBundle();
}, [path, name, component, getBundle]);
return status;
}