piral-lazy
Version:
Plugin for lazy loading third-party framework components in Piral.
55 lines (48 loc) • 1.55 kB
text/typescript
import { lazy, createElement, ComponentType } from 'react';
import { PiralPlugin, withApi } from 'piral-core';
import { PiletLazyApi, LazyDependencyLoader } from './types';
interface DependencyCache {
[name: string]: {
result: Promise<any>;
loader: LazyDependencyLoader;
};
}
export function createLazyApi(): PiralPlugin<PiletLazyApi> {
return (context) => {
return (api) => {
const cache: DependencyCache = {};
const getDependency = (name: string) => {
const dep = cache[name];
if (!dep) {
throw new Error(
`The given dependency "${name}" cannot be found. Please add it first using "defineDependency"`,
);
}
return dep.result ?? (dep.result = dep.loader());
};
return {
defineDependency(name, loader) {
cache[name] = {
loader,
result: undefined,
};
},
fromLazy(load, deps = []) {
return lazy(() =>
Promise.all(deps.map(getDependency)).then((values) => {
const depMap = deps.reduce((obj, name, index) => {
obj[name] = values[index];
return obj;
}, {});
return load()
.then((comp) => withApi(context, comp, api, 'unknown'))
.then((compWithApi) => ({
default: (props) => createElement(compWithApi as ComponentType, { deps: depMap, ...props }),
}));
}),
);
},
};
};
};
}