Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

plume-ssr-browser

Package Overview
Dependencies
Maintainers
0
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

plume-ssr-browser - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

3

build/cjs/index.d.ts

@@ -9,4 +9,3 @@ export { SsrObservableManager } from './lib/observable/SsrObservableManager';

export { Navigate, useNavigate } from './lib/locationcontext/navigate/Navigate';
export type { BrowserRenderOption } from './lib/renderer/BrowserApplicationRenderer';
export { renderBrowserApplication, extractMonitorContextData } from './lib/renderer/BrowserApplicationRenderer';
export { renderBrowserApplication } from './lib/renderer/BrowserApplicationRenderer';
export { installRectPlumeSsrFrontendModule } from './lib/module/reactPlumeSsrFrontend-module';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.installRectPlumeSsrFrontendModule = exports.extractMonitorContextData = exports.renderBrowserApplication = exports.useNavigate = exports.Navigate = exports.redirect = exports.SsrLocationContextHolder = exports.useObservable = exports.SsrWritableObservable = exports.SsrObservableManager = void 0;
exports.installRectPlumeSsrFrontendModule = exports.renderBrowserApplication = exports.useNavigate = exports.Navigate = exports.redirect = exports.SsrLocationContextHolder = exports.useObservable = exports.SsrWritableObservable = exports.SsrObservableManager = void 0;
// observable

@@ -20,5 +20,4 @@ var SsrObservableManager_1 = require("./lib/observable/SsrObservableManager");

Object.defineProperty(exports, "renderBrowserApplication", { enumerable: true, get: function () { return BrowserApplicationRenderer_1.renderBrowserApplication; } });
Object.defineProperty(exports, "extractMonitorContextData", { enumerable: true, get: function () { return BrowserApplicationRenderer_1.extractMonitorContextData; } });
var reactPlumeSsrFrontend_module_1 = require("./lib/module/reactPlumeSsrFrontend-module");
Object.defineProperty(exports, "installRectPlumeSsrFrontendModule", { enumerable: true, get: function () { return reactPlumeSsrFrontend_module_1.installRectPlumeSsrFrontendModule; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsYUFBYTtBQUNiLDhFQUE2RTtBQUFwRSw0SEFBQSxvQkFBb0IsT0FBQTtBQUM3QixnRkFBK0U7QUFBdEUsOEhBQUEscUJBQXFCLE9BQUE7QUFFOUIsZ0VBQStEO0FBQXRELDhHQUFBLGFBQWEsT0FBQTtBQUd0QiwrRUFBb0Y7QUFBM0UsOEhBQUEsd0JBQXdCLE9BQUE7QUFDakMsb0VBQW1FO0FBQTFELG9HQUFBLFFBQVEsT0FBQTtBQUNqQixvRUFBZ0Y7QUFBdkUsb0dBQUEsUUFBUSxPQUFBO0FBQUUsdUdBQUEsV0FBVyxPQUFBO0FBRzlCLHdGQUFnSDtBQUF2RyxzSUFBQSx3QkFBd0IsT0FBQTtBQUFFLHVJQUFBLHlCQUF5QixPQUFBO0FBRTVELDBGQUE4RjtBQUFyRixpSkFBQSxpQ0FBaUMsT0FBQSJ9
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsYUFBYTtBQUNiLDhFQUE2RTtBQUFwRSw0SEFBQSxvQkFBb0IsT0FBQTtBQUM3QixnRkFBK0U7QUFBdEUsOEhBQUEscUJBQXFCLE9BQUE7QUFFOUIsZ0VBQStEO0FBQXRELDhHQUFBLGFBQWEsT0FBQTtBQUd0QiwrRUFBb0Y7QUFBM0UsOEhBQUEsd0JBQXdCLE9BQUE7QUFDakMsb0VBQW1FO0FBQTFELG9HQUFBLFFBQVEsT0FBQTtBQUNqQixvRUFBZ0Y7QUFBdkUsb0dBQUEsUUFBUSxPQUFBO0FBQUUsdUdBQUEsV0FBVyxPQUFBO0FBRTlCLHdGQUFxRjtBQUE1RSxzSUFBQSx3QkFBd0IsT0FBQTtBQUVqQywwRkFBOEY7QUFBckYsaUpBQUEsaUNBQWlDLE9BQUEifQ==
/// <reference types="react" />
import { PromiseMonitor } from 'simple-http-rest-client';
/**
* Options passed to the renderApplication function to configure the application hydration.
*
* Warning: The options used should be exactly the same used to render the SsrApplication,
* otherwise the hydration may fail.
*
* @property {number} maxRender Maximum number of renderings to perform
* before replacing the Html retrieved from the SSR Server with the application
* if the promises are still not resolved.
*/
export interface BrowserRenderOption {
maxRender: number;
}
/**
* Render the application by hydrating the html received from the SSR Server.

@@ -32,12 +18,3 @@ *

* @param rootElementId Id of the HTML element in which the application will be mounted.
* @param promiseMonitors Array of promise monitors that maintains a state of all the application promises
* that are being executed and that have an impact on the rendering of the application
* @param [option={maxRender:10}] - used to configure the application rendering
*/
export declare function renderBrowserApplication(reactApp: JSX.Element, rootElementId?: string, promiseMonitors?: PromiseMonitor[], option?: BrowserRenderOption): Promise<void>;
/**
* Extract context data from an array promiseMonitors.
* It is useful especially for logging reasons.
* @param promiseMonitors The promise monitors array
*/
export declare const extractMonitorContextData: (promiseMonitors: PromiseMonitor[]) => (object | undefined)[];
export declare function renderBrowserApplication(reactApp: JSX.Element, rootElementId?: string): Promise<void>;

@@ -26,8 +26,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.extractMonitorContextData = exports.renderBrowserApplication = void 0;
exports.renderBrowserApplication = void 0;
const client_1 = require("react-dom/client");
const ReactDOM = __importStar(require("react-dom/client"));
const simple_logging_system_1 = require("simple-logging-system");
const HydrationWrapper_1 = require("./HydrationWrapper");
const logger = new simple_logging_system_1.Logger('RenderBrowserApplication');
/**

@@ -49,10 +46,4 @@ * Render the application by hydrating the html received from the SSR Server.

* @param rootElementId Id of the HTML element in which the application will be mounted.
* @param promiseMonitors Array of promise monitors that maintains a state of all the application promises
* that are being executed and that have an impact on the rendering of the application
* @param [option={maxRender:10}] - used to configure the application rendering
*/
async function renderBrowserApplication(reactApp, rootElementId = 'root', promiseMonitors = [], option = {
maxRender: 10,
}) {
const currentMillis = Date.now();
async function renderBrowserApplication(reactApp, rootElementId = 'root') {
const rootDomElement = document.getElementById(rootElementId);

@@ -63,69 +54,9 @@ if (rootDomElement === null) {

if (rootDomElement.children.length > 0) {
try {
const unMountDummyApp = await renderDummyApp(reactApp);
await prepareApplicationForHydration(promiseMonitors, option);
unMountDummyApp();
logger.info('All pending promises has been resolved, hydrating the received Html with the app...');
(0, client_1.hydrateRoot)(rootDomElement, reactApp);
logger.info(`DOM hydrated in ${Date.now() - currentMillis}ms`);
return;
}
catch {
logger.error('DOM hydration failed, rendering app instead');
}
(0, client_1.hydrateRoot)(rootDomElement, reactApp);
}
ReactDOM.createRoot(rootDomElement).render(reactApp);
logger.info(`DOM rendered in ${Date.now() - currentMillis}ms`);
else {
ReactDOM.createRoot(rootDomElement).render(reactApp);
}
}
exports.renderBrowserApplication = renderBrowserApplication;
function renderDummyApp(reactApp) {
// Try to re-render the application while there are pending Promises
const dummyDiv = document.createElement('div');
const dummyRoot = ReactDOM.createRoot(dummyDiv);
return new Promise((resolve) => {
const onAppMounted = () => resolve(() => dummyRoot.unmount());
dummyRoot.render((0, HydrationWrapper_1.hydrationWrapper)(onAppMounted, reactApp));
});
}
/**
* Extract context data from an array promiseMonitors.
* It is useful especially for logging reasons.
* @param promiseMonitors The promise monitors array
*/
const extractMonitorContextData = (promiseMonitors) => promiseMonitors
.flatMap((promiseMonitor) => promiseMonitor
.getRunningPromisesWithInfo()
.map((runningPromise) => runningPromise[1].promiseInfo));
exports.extractMonitorContextData = extractMonitorContextData;
/**
* Render the application in a dummy Html element until all the data promises are resolved,
*
* @param promiseMonitors
* @param hydrationOption
* @returns Promise resolved if all promises have been resolved,
* Promise rejected if some promises are still pending after the maximum number of returns is reached.
*/
async function prepareApplicationForHydration(promiseMonitors, hydrationOption) {
const { maxRender } = hydrationOption;
for (let i = 0; i < maxRender; i += 1) {
// attend un cycle supplémentaire pour vérifier que React n'est pas en train de monter des modules dynamiques
// eslint-disable-next-line no-await-in-loop
await new Promise(
// eslint-disable-next-line no-promise-executor-return
(resolve) => setTimeout(resolve, 0));
if (promiseMonitors.every((promiseMonitor) => promiseMonitor.getRunningPromisesCount() === 0)) {
return Promise.resolve();
}
logger.info('There are Promises whose resolution is necessary to the hydration, waiting for their resolution...', {
promiseMonitors: (0, exports.extractMonitorContextData)(promiseMonitors),
});
// eslint-disable-next-line no-await-in-loop
await Promise.allSettled(promiseMonitors.flatMap((promiseMonitor) => promiseMonitor.getRunningPromises()));
logger.info('Re-render the React application now that the Promises have been resolved');
}
logger.warn(`There are still unresolved promises after ${maxRender} iterations`, {
promiseMonitors: (0, exports.extractMonitorContextData)(promiseMonitors),
});
return Promise.reject();
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQnJvd3NlckFwcGxpY2F0aW9uUmVuZGVyZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlbmRlcmVyL0Jyb3dzZXJBcHBsaWNhdGlvblJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQStDO0FBQy9DLDJEQUE2QztBQUU3QyxpRUFBK0M7QUFDL0MseURBQXNEO0FBZ0J0RCxNQUFNLE1BQU0sR0FBRyxJQUFJLDhCQUFNLENBQUMsMEJBQTBCLENBQUMsQ0FBQztBQUV0RDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNJLEtBQUssVUFBVSx3QkFBd0IsQ0FDNUMsUUFBcUIsRUFDckIsZ0JBQXdCLE1BQU0sRUFDOUIsa0JBQW9DLEVBQUUsRUFDdEMsU0FBOEI7SUFDNUIsU0FBUyxFQUFFLEVBQUU7Q0FDZDtJQUVELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNqQyxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzlELElBQUksY0FBYyxLQUFLLElBQUksRUFBRTtRQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLDRDQUE0QyxhQUFhLEdBQUcsQ0FBQyxDQUFDO0tBQy9FO0lBRUQsSUFBSSxjQUFjLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDdEMsSUFBSTtZQUNGLE1BQU0sZUFBZSxHQUFHLE1BQU0sY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sOEJBQThCLENBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzlELGVBQWUsRUFBRSxDQUFDO1lBQ2xCLE1BQU0sQ0FBQyxJQUFJLENBQUMscUZBQXFGLENBQUMsQ0FBQztZQUNuRyxJQUFBLG9CQUFXLEVBQUMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3RD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
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQnJvd3NlckFwcGxpY2F0aW9uUmVuZGVyZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlbmRlcmVyL0Jyb3dzZXJBcHBsaWNhdGlvblJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQStDO0FBQy9DLDJEQUE2QztBQUU3Qzs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNJLEtBQUssVUFBVSx3QkFBd0IsQ0FDNUMsUUFBcUIsRUFDckIsZ0JBQXdCLE1BQU07SUFFOUIsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM5RCxJQUFJLGNBQWMsS0FBSyxJQUFJLEVBQUU7UUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsYUFBYSxHQUFHLENBQUMsQ0FBQztLQUMvRTtJQUVELElBQUksY0FBYyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3RDLElBQUEsb0JBQVcsRUFBQyxjQUFjLEVBQUUsUUFBUSxDQUFDLENBQUM7S0FDdkM7U0FBTTtRQUNMLFFBQVEsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQ3REO0FBQ0gsQ0FBQztBQWRELDREQWNDIn0=

@@ -9,4 +9,3 @@ export { SsrObservableManager } from './lib/observable/SsrObservableManager';

export { Navigate, useNavigate } from './lib/locationcontext/navigate/Navigate';
export type { BrowserRenderOption } from './lib/renderer/BrowserApplicationRenderer';
export { renderBrowserApplication, extractMonitorContextData } from './lib/renderer/BrowserApplicationRenderer';
export { renderBrowserApplication } from './lib/renderer/BrowserApplicationRenderer';
export { installRectPlumeSsrFrontendModule } from './lib/module/reactPlumeSsrFrontend-module';

@@ -8,4 +8,4 @@ // observable

export { Navigate, useNavigate } from './lib/locationcontext/navigate/Navigate';
export { renderBrowserApplication, extractMonitorContextData } from './lib/renderer/BrowserApplicationRenderer';
export { renderBrowserApplication } from './lib/renderer/BrowserApplicationRenderer';
export { installRectPlumeSsrFrontendModule } from './lib/module/reactPlumeSsrFrontend-module';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsYUFBYTtBQUNiLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBRS9FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUcvRCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNwRixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDbkUsT0FBTyxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUdoRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUseUJBQXlCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUVoSCxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQyJ9
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsYUFBYTtBQUNiLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBRS9FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUcvRCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNwRixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDbkUsT0FBTyxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUVoRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUVyRixPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQyJ9
/// <reference types="react" />
import { PromiseMonitor } from 'simple-http-rest-client';
/**
* Options passed to the renderApplication function to configure the application hydration.
*
* Warning: The options used should be exactly the same used to render the SsrApplication,
* otherwise the hydration may fail.
*
* @property {number} maxRender Maximum number of renderings to perform
* before replacing the Html retrieved from the SSR Server with the application
* if the promises are still not resolved.
*/
export interface BrowserRenderOption {
maxRender: number;
}
/**
* Render the application by hydrating the html received from the SSR Server.

@@ -32,12 +18,3 @@ *

* @param rootElementId Id of the HTML element in which the application will be mounted.
* @param promiseMonitors Array of promise monitors that maintains a state of all the application promises
* that are being executed and that have an impact on the rendering of the application
* @param [option={maxRender:10}] - used to configure the application rendering
*/
export declare function renderBrowserApplication(reactApp: JSX.Element, rootElementId?: string, promiseMonitors?: PromiseMonitor[], option?: BrowserRenderOption): Promise<void>;
/**
* Extract context data from an array promiseMonitors.
* It is useful especially for logging reasons.
* @param promiseMonitors The promise monitors array
*/
export declare const extractMonitorContextData: (promiseMonitors: PromiseMonitor[]) => (object | undefined)[];
export declare function renderBrowserApplication(reactApp: JSX.Element, rootElementId?: string): Promise<void>;
import { hydrateRoot } from 'react-dom/client';
import * as ReactDOM from 'react-dom/client';
import { Logger } from 'simple-logging-system';
import { hydrationWrapper } from './HydrationWrapper';
const logger = new Logger('RenderBrowserApplication');
/**

@@ -22,10 +19,4 @@ * Render the application by hydrating the html received from the SSR Server.

* @param rootElementId Id of the HTML element in which the application will be mounted.
* @param promiseMonitors Array of promise monitors that maintains a state of all the application promises
* that are being executed and that have an impact on the rendering of the application
* @param [option={maxRender:10}] - used to configure the application rendering
*/
export async function renderBrowserApplication(reactApp, rootElementId = 'root', promiseMonitors = [], option = {
maxRender: 10,
}) {
const currentMillis = Date.now();
export async function renderBrowserApplication(reactApp, rootElementId = 'root') {
const rootDomElement = document.getElementById(rootElementId);

@@ -36,67 +27,8 @@ if (rootDomElement === null) {

if (rootDomElement.children.length > 0) {
try {
const unMountDummyApp = await renderDummyApp(reactApp);
await prepareApplicationForHydration(promiseMonitors, option);
unMountDummyApp();
logger.info('All pending promises has been resolved, hydrating the received Html with the app...');
hydrateRoot(rootDomElement, reactApp);
logger.info(`DOM hydrated in ${Date.now() - currentMillis}ms`);
return;
}
catch {
logger.error('DOM hydration failed, rendering app instead');
}
hydrateRoot(rootDomElement, reactApp);
}
ReactDOM.createRoot(rootDomElement).render(reactApp);
logger.info(`DOM rendered in ${Date.now() - currentMillis}ms`);
}
function renderDummyApp(reactApp) {
// Try to re-render the application while there are pending Promises
const dummyDiv = document.createElement('div');
const dummyRoot = ReactDOM.createRoot(dummyDiv);
return new Promise((resolve) => {
const onAppMounted = () => resolve(() => dummyRoot.unmount());
dummyRoot.render(hydrationWrapper(onAppMounted, reactApp));
});
}
/**
* Extract context data from an array promiseMonitors.
* It is useful especially for logging reasons.
* @param promiseMonitors The promise monitors array
*/
export const extractMonitorContextData = (promiseMonitors) => promiseMonitors
.flatMap((promiseMonitor) => promiseMonitor
.getRunningPromisesWithInfo()
.map((runningPromise) => runningPromise[1].promiseInfo));
/**
* Render the application in a dummy Html element until all the data promises are resolved,
*
* @param promiseMonitors
* @param hydrationOption
* @returns Promise resolved if all promises have been resolved,
* Promise rejected if some promises are still pending after the maximum number of returns is reached.
*/
async function prepareApplicationForHydration(promiseMonitors, hydrationOption) {
const { maxRender } = hydrationOption;
for (let i = 0; i < maxRender; i += 1) {
// attend un cycle supplémentaire pour vérifier que React n'est pas en train de monter des modules dynamiques
// eslint-disable-next-line no-await-in-loop
await new Promise(
// eslint-disable-next-line no-promise-executor-return
(resolve) => setTimeout(resolve, 0));
if (promiseMonitors.every((promiseMonitor) => promiseMonitor.getRunningPromisesCount() === 0)) {
return Promise.resolve();
}
logger.info('There are Promises whose resolution is necessary to the hydration, waiting for their resolution...', {
promiseMonitors: extractMonitorContextData(promiseMonitors),
});
// eslint-disable-next-line no-await-in-loop
await Promise.allSettled(promiseMonitors.flatMap((promiseMonitor) => promiseMonitor.getRunningPromises()));
logger.info('Re-render the React application now that the Promises have been resolved');
else {
ReactDOM.createRoot(rootDomElement).render(reactApp);
}
logger.warn(`There are still unresolved promises after ${maxRender} iterations`, {
promiseMonitors: extractMonitorContextData(promiseMonitors),
});
return Promise.reject();
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQnJvd3NlckFwcGxpY2F0aW9uUmVuZGVyZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlbmRlcmVyL0Jyb3dzZXJBcHBsaWNhdGlvblJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvQyxPQUFPLEtBQUssUUFBUSxNQUFNLGtCQUFrQixDQUFDO0FBRTdDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQWdCdEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsMEJBQTBCLENBQUMsQ0FBQztBQUV0RDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsd0JBQXdCLENBQzVDLFFBQXFCLEVBQ3JCLGdCQUF3QixNQUFNLEVBQzlCLGtCQUFvQyxFQUFFLEVBQ3RDLFNBQThCO0lBQzVCLFNBQVMsRUFBRSxFQUFFO0NBQ2Q7SUFFRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDakMsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM5RCxJQUFJLGNBQWMsS0FBSyxJQUFJLEVBQUU7UUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsYUFBYSxHQUFHLENBQUMsQ0FBQztLQUMvRTtJQUVELElBQUksY0FBYyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3RDLElBQUk7WUFDRixNQUFNLGVBQWUsR0FBRyxNQUFNLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2RCxNQUFNLDhCQUE4QixDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM5RCxlQUFlLEVBQUUsQ0FBQztZQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLHFGQUFxRixDQUFDLENBQUM7WUFDbkcsV0FBVyxDQUFDLGNBQWMsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN0QyxNQUFNLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsYUFBYSxJQUFJLENBQUMsQ0FBQztZQUMvRCxPQUFPO1NBQ1I7UUFBQyxNQUFNO1lBQ04sTUFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1NBQzdEO0tBQ0Y7SUFFRCxRQUFRLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNyRCxNQUFNLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsYUFBYSxJQUFJLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsUUFBcUI7SUFDM0Msb0VBQW9FO0lBQ3BFLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0MsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVoRCxPQUFPLElBQUksT0FBTyxDQUFhLENBQUMsT0FBTyxFQUFFLEVBQUU7UUFDekMsTUFBTSxZQUFZLEdBQUcsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzlELFNBQVMsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLENBQUMsZUFBaUMsRUFBRSxFQUFFLENBQUMsZUFBZTtLQUM1RixPQUFPLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLGNBQWM7S0FDeEMsMEJBQTBCLEVBQUU7S0FDNUIsR0FBRyxDQUFDLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQ3hELENBQUM7QUFFSjs7Ozs7OztHQU9HO0FBQ0gsS0FBSyxVQUFVLDhCQUE4QixDQUMzQyxlQUFpQyxFQUNqQyxlQUFvQztJQUVwQyxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsZUFBZSxDQUFDO0lBRXRDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUNyQyw2R0FBNkc7UUFDN0csNENBQTRDO1FBQzVDLE1BQU0sSUFBSSxPQUFPO1FBQ2Ysc0RBQXNEO1FBQ3RELENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUNwQyxDQUFDO1FBRUYsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxjQUFjLENBQUMsdUJBQXVCLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRTtZQUM3RixPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUMxQjtRQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsb0dBQW9HLEVBQUU7WUFDaEgsZUFBZSxFQUFFLHlCQUF5QixDQUFDLGVBQWUsQ0FBQztTQUM1RCxDQUFDLENBQUM7UUFFSCw0Q0FBNEM7UUFDNUMsTUFBTSxPQUFPLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUUzRyxNQUFNLENBQUMsSUFBSSxDQUFDLDBFQUEwRSxDQUFDLENBQUM7S0FDekY7SUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLDZDQUE2QyxTQUFTLGFBQWEsRUFBRTtRQUMvRSxlQUFlLEVBQUUseUJBQXlCLENBQUMsZUFBZSxDQUFDO0tBQzVELENBQUMsQ0FBQztJQUNILE9BQU8sT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQzFCLENBQUMifQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQnJvd3NlckFwcGxpY2F0aW9uUmVuZGVyZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlbmRlcmVyL0Jyb3dzZXJBcHBsaWNhdGlvblJlbmRlcmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvQyxPQUFPLEtBQUssUUFBUSxNQUFNLGtCQUFrQixDQUFDO0FBRTdDOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSx3QkFBd0IsQ0FDNUMsUUFBcUIsRUFDckIsZ0JBQXdCLE1BQU07SUFFOUIsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM5RCxJQUFJLGNBQWMsS0FBSyxJQUFJLEVBQUU7UUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsYUFBYSxHQUFHLENBQUMsQ0FBQztLQUMvRTtJQUVELElBQUksY0FBYyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3RDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsUUFBUSxDQUFDLENBQUM7S0FDdkM7U0FBTTtRQUNMLFFBQVEsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQ3REO0FBQ0gsQ0FBQyJ9
{
"name": "plume-ssr-browser",
"version": "1.2.0",
"version": "1.3.0",
"description": "A framework to create an SSR server for a React Plume project",

@@ -5,0 +5,0 @@ "author": "Aurélien Manteaux <amanteaux@coreoz.com> (https://coreoz.com)",

Plume SSR - Browser
===================
The frontend part of [Plume SSR](https://github.com/Coreoz/plume-ssr).

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc