@j2inn/app-react
Version:
React implementation of the j2inn-app framework
77 lines (76 loc) • 2.99 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
/*
* Copyright (c) 2021, J2 Innovations. All Rights Reserved
*/
import { getPodName, getRemoteEntry, isRemoteApp, loadDefault, } from '@j2inn/app';
import { useMemo } from 'react';
import { AppStoreContext } from '../../hooks';
import { Loading } from '../Loading';
import { Suspense } from '../Suspense';
import { RemoteResources } from './RemoteResources';
var LoadingStatus;
(function (LoadingStatus) {
LoadingStatus[LoadingStatus["pending"] = 0] = "pending";
LoadingStatus[LoadingStatus["success"] = 1] = "success";
LoadingStatus[LoadingStatus["error"] = 2] = "error";
})(LoadingStatus || (LoadingStatus = {}));
/**
* Loads a remote app store resource using the asynchronous data fetching design
* pattern as outlined in the React concurrent documentation.
*
* @param remoteApp The remote app to load the store for.
* @returns A resource that will asynchronously load an wait for resources
* to be created.
*/
function loadAppStoreResource(remoteApp) {
let status = remoteApp.store ? LoadingStatus.success : LoadingStatus.pending;
let error;
const promise = remoteApp.store
? Promise.resolve()
: loadDefault(getPodName(remoteApp.app), remoteApp.remoteStoreUri)().then((module) => {
if (!remoteApp.store) {
remoteApp.store = new module.default();
}
status = LoadingStatus.success;
}, (err) => {
error = err;
status = LoadingStatus.error;
});
return {
read() {
if (status === LoadingStatus.pending) {
throw promise;
}
else if (status === LoadingStatus.success) {
return remoteApp.store;
}
else {
throw error ?? new Error('Unknown error');
}
},
};
}
/**
* Loads a remote app store asynchronously.
*/
const RemoteLoader = ({ remoteApp, children, }) => {
const resource = useMemo(() => loadAppStoreResource(remoteApp), [remoteApp.id]);
return (_jsx(Suspense, { fallback: _jsx(Loading, {}), children: _jsx(AppStoreContext.Provider, { value: resource.read(), children: children }) }));
};
/**
* Loads the store for a remote application.
*
* This will load any store asynchronously.
*/
export const RemoteAppStoreLoader = ({ app, children, }) => {
if (app && !app.store && isRemoteApp(app) && app.remoteStoreUri) {
return (_jsx(RemoteResources, { urls: [getRemoteEntry(app.app)], children: _jsx(RemoteLoader, { remoteApp: app, children: children }) }));
}
else if (app?.store) {
return (_jsx(AppStoreContext.Provider, { value: app.store, children: children }));
}
else {
// If we're here then no store is defined or used so just do nothing.
return _jsx(_Fragment, { children: children });
}
};