New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-on-rails

Package Overview
Dependencies
Maintainers
4
Versions
207
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-on-rails - npm Package Compare versions

Comparing version 14.0.5 to 15.0.0-alpha.0

node_package/lib/tsconfig.tsbuildinfo

2

node_package/lib/Authenticity.js

@@ -6,3 +6,3 @@ "use strict";

var token = document.querySelector('meta[name="csrf-token"]');
if (token && (token instanceof window.HTMLMetaElement)) {
if (token instanceof HTMLMetaElement) {
return token.content;

@@ -9,0 +9,0 @@ }

@@ -9,3 +9,3 @@ declare global {

}
export declare function consoleReplay(): string;
export default function buildConsoleReplay(): string;
export declare function consoleReplay(customConsoleHistory?: typeof console['history'] | undefined, numberOfMessagesToSkip?: number): string;
export default function buildConsoleReplay(customConsoleHistory?: typeof console['history'] | undefined, numberOfMessagesToSkip?: number): string;

@@ -6,16 +6,27 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.consoleReplay = void 0;
exports.consoleReplay = consoleReplay;
exports.default = buildConsoleReplay;
var RenderUtils_1 = __importDefault(require("./RenderUtils"));
var scriptSanitizedVal_1 = __importDefault(require("./scriptSanitizedVal"));
function consoleReplay() {
function consoleReplay(customConsoleHistory, numberOfMessagesToSkip) {
if (customConsoleHistory === void 0) { customConsoleHistory = undefined; }
if (numberOfMessagesToSkip === void 0) { numberOfMessagesToSkip = 0; }
// console.history is a global polyfill used in server rendering.
// $FlowFixMe
if (!(console.history instanceof Array)) {
var consoleHistory = customConsoleHistory !== null && customConsoleHistory !== void 0 ? customConsoleHistory : console.history;
if (!(Array.isArray(consoleHistory))) {
return '';
}
var lines = console.history.map(function (msg) {
var lines = consoleHistory.slice(numberOfMessagesToSkip).map(function (msg) {
var stringifiedList = msg.arguments.map(function (arg) {
var val;
try {
val = (typeof arg === 'string' || arg instanceof String) ? arg : JSON.stringify(arg);
if (typeof arg === 'string') {
val = arg;
}
else if (arg instanceof String) {
val = String(arg);
}
else {
val = JSON.stringify(arg);
}
if (val === undefined) {

@@ -34,6 +45,6 @@ val = 'undefined';

}
exports.consoleReplay = consoleReplay;
function buildConsoleReplay() {
return RenderUtils_1.default.wrapInScriptTags('consoleReplayLog', consoleReplay());
function buildConsoleReplay(customConsoleHistory, numberOfMessagesToSkip) {
if (customConsoleHistory === void 0) { customConsoleHistory = undefined; }
if (numberOfMessagesToSkip === void 0) { numberOfMessagesToSkip = 0; }
return RenderUtils_1.default.wrapInScriptTags('consoleReplayLog', consoleReplay(customConsoleHistory, numberOfMessagesToSkip));
}
exports.default = buildConsoleReplay;

@@ -15,3 +15,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.clientStartup = exports.reactOnRailsComponentLoaded = exports.reactOnRailsPageLoaded = void 0;
exports.reactOnRailsPageLoaded = reactOnRailsPageLoaded;
exports.reactOnRailsComponentLoaded = reactOnRailsComponentLoaded;
exports.clientStartup = clientStartup;
var react_dom_1 = __importDefault(require("react-dom"));

@@ -167,3 +169,2 @@ var createReactOutput_1 = __importDefault(require("./createReactOutput"));

}
exports.reactOnRailsPageLoaded = reactOnRailsPageLoaded;
function reactOnRailsComponentLoaded(domId) {

@@ -184,3 +185,2 @@ debugTurbolinks("reactOnRailsComponentLoaded ".concat(domId));

}
exports.reactOnRailsComponentLoaded = reactOnRailsComponentLoaded;
function unmount(el) {

@@ -276,2 +276,1 @@ var domNodeId = domNodeIdForEl(el);

}
exports.clientStartup = clientStartup;

@@ -36,4 +36,5 @@ "use strict";

get: function (name) {
if (registeredComponents.has(name)) {
return registeredComponents.get(name);
var registeredComponent = registeredComponents.get(name);
if (registeredComponent !== undefined) {
return registeredComponent;
}

@@ -40,0 +41,0 @@ var keys = Array.from(registeredComponents.keys()).join(', ');

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = context;
/**

@@ -12,2 +13,1 @@ * Get the context, be it window or global

}
exports.default = context;

@@ -7,2 +7,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.default = createReactOutput;
var react_1 = __importDefault(require("react"));

@@ -63,2 +64,1 @@ var isServerRenderResult_1 = require("./isServerRenderResult");

}
exports.default = createReactOutput;

@@ -1,2 +0,2 @@

import { ReactComponentOrRenderFunction } from "./types/index";
import { ReactComponentOrRenderFunction, RenderFunction } from "./types/index";
/**

@@ -8,2 +8,2 @@ * Used to determine we'll call be calling React.createElement on the component of if this is a

*/
export default function isRenderFunction(component: ReactComponentOrRenderFunction): boolean;
export default function isRenderFunction(component: ReactComponentOrRenderFunction): component is RenderFunction;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = isRenderFunction;
/**

@@ -10,5 +11,5 @@ * Used to determine we'll call be calling React.createElement on the component of if this is a

function isRenderFunction(component) {
var _a;
// No for es5 or es6 React Component
if (component.prototype &&
component.prototype.isReactComponent) {
if ((_a = component.prototype) === null || _a === void 0 ? void 0 : _a.isReactComponent) {
return false;

@@ -26,2 +27,1 @@ }

}
exports.default = isRenderFunction;
import type { CreateReactOutputResult, ServerRenderResult } from './types/index';
export declare function isServerRenderHash(testValue: CreateReactOutputResult): testValue is ServerRenderResult;
export declare function isPromise(testValue: CreateReactOutputResult): testValue is Promise<string>;
export declare function isPromise<T>(testValue: CreateReactOutputResult | Promise<T> | string | null): testValue is Promise<T>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isPromise = exports.isServerRenderHash = void 0;
exports.isServerRenderHash = isServerRenderHash;
exports.isPromise = isPromise;
function isServerRenderHash(testValue) {

@@ -10,6 +11,4 @@ return !!(testValue.renderedHtml ||

}
exports.isServerRenderHash = isServerRenderHash;
function isPromise(testValue) {
return !!(testValue.then);
return !!(testValue === null || testValue === void 0 ? void 0 : testValue.then);
}
exports.isPromise = isPromise;

@@ -6,3 +6,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.reactRender = exports.reactHydrate = void 0;
exports.reactHydrate = void 0;
exports.reactRender = reactRender;
exports.default = reactHydrateOrRender;
var react_dom_1 = __importDefault(require("react-dom"));

@@ -40,6 +42,4 @@ var reactApis_1 = require("./reactApis");

}
exports.reactRender = reactRender;
function reactHydrateOrRender(domNode, reactElement, hydrate) {
return hydrate ? (0, exports.reactHydrate)(domNode, reactElement) : reactRender(domNode, reactElement);
}
exports.default = reactHydrateOrRender;

@@ -36,3 +36,3 @@ "use strict";

var StoreRegistry_1 = __importDefault(require("./StoreRegistry"));
var serverRenderReactComponent_1 = __importDefault(require("./serverRenderReactComponent"));
var serverRenderReactComponent_1 = __importStar(require("./serverRenderReactComponent"));
var buildConsoleReplay_1 = __importDefault(require("./buildConsoleReplay"));

@@ -64,14 +64,17 @@ var createReactOutput_1 = __importDefault(require("./createReactOutput"));

},
registerStore: function (stores) {
this.registerStoreGenerators(stores);
},
/**
* Allows registration of store generators to be used by multiple react components on one Rails
* Allows registration of store generators to be used by multiple React components on one Rails
* view. store generators are functions that take one arg, props, and return a store. Note that
* the setStore API is different in that it's the actual store hydrated with props.
* @param stores (keys are store names, values are the store generators)
* @param storeGenerators (keys are store names, values are the store generators)
*/
registerStore: function (stores) {
if (!stores) {
throw new Error('Called ReactOnRails.registerStores with a null or undefined, rather than ' +
registerStoreGenerators: function (storeGenerators) {
if (!storeGenerators) {
throw new Error('Called ReactOnRails.registerStoreGenerators with a null or undefined, rather than ' +
'an Object with keys being the store names and the values are the store generators.');
}
StoreRegistry_1.default.register(stores);
StoreRegistry_1.default.register(storeGenerators);
},

@@ -143,3 +146,3 @@ /**

* Returns header with csrf authenticity token and XMLHttpRequest
* @param {*} other headers
* @param otherHeaders Other headers
* @returns {*} header

@@ -164,3 +167,3 @@ */

* Allows retrieval of the store generator by name. This is used internally by ReactOnRails after
* a rails form loads to prepare stores.
* a Rails form loads to prepare stores.
* @param name

@@ -233,2 +236,9 @@ * @returns Redux Store generator function

/**
* Used by server rendering by Rails
* @param options
*/
streamServerRenderedReactComponent: function (options) {
return (0, serverRenderReactComponent_1.streamServerRenderedReactComponent)(options);
},
/**
* Used by Rails to catch errors in rendering

@@ -235,0 +245,0 @@ * @param options

@@ -1,4 +0,6 @@

import type { RenderParams, RenderResult } from './types/index';
import { Readable } from 'stream';
import type { RenderParams, RenderResult } from './types';
declare function serverRenderReactComponentInternal(options: RenderParams): null | string | Promise<RenderResult>;
declare const serverRenderReactComponent: typeof serverRenderReactComponentInternal;
export declare const streamServerRenderedReactComponent: (options: RenderParams) => Readable;
export default serverRenderReactComponent;
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

@@ -12,4 +23,4 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }

var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }

@@ -43,3 +54,5 @@ function step(op) {

Object.defineProperty(exports, "__esModule", { value: true });
exports.streamServerRenderedReactComponent = void 0;
var server_1 = __importDefault(require("react-dom/server"));
var stream_1 = require("stream");
var ComponentRegistry_1 = __importDefault(require("./ComponentRegistry"));

@@ -50,135 +63,147 @@ var createReactOutput_1 = __importDefault(require("./createReactOutput"));

var handleError_1 = __importDefault(require("./handleError"));
/* eslint-disable @typescript-eslint/no-explicit-any */
function serverRenderReactComponentInternal(options) {
var _this = this;
var name = options.name, domNodeId = options.domNodeId, trace = options.trace, props = options.props, railsContext = options.railsContext, renderingReturnsPromises = options.renderingReturnsPromises, throwJsErrors = options.throwJsErrors;
var renderResult = null;
var hasErrors = false;
var renderingError = null;
function convertToError(e) {
return e instanceof Error ? e : new Error(String(e));
}
function validateComponent(componentObj, componentName) {
if (componentObj.isRenderer) {
throw new Error("Detected a renderer while server rendering component '".concat(componentName, "'. See https://github.com/shakacode/react_on_rails#renderer-functions"));
}
}
function processServerRenderHash(result, options) {
var redirectLocation = result.redirectLocation, routeError = result.routeError;
var hasErrors = !!routeError;
if (hasErrors) {
console.error("React Router ERROR: ".concat(JSON.stringify(routeError)));
}
var htmlResult;
if (redirectLocation) {
if (options.trace) {
var redirectPath = redirectLocation.pathname + redirectLocation.search;
console.log("ROUTER REDIRECT: ".concat(options.componentName, " to dom node with id: ").concat(options.domNodeId, ", redirect to ").concat(redirectPath));
}
// For redirects on server rendering, we can't stop Rails from returning the same result.
// Possibly, someday, we could have the Rails server redirect.
htmlResult = '';
}
else {
htmlResult = result.renderedHtml;
}
return { result: htmlResult, hasErrors: hasErrors };
}
function processPromise(result, renderingReturnsPromises) {
if (!renderingReturnsPromises) {
console.error('Your render function returned a Promise, which is only supported by a node renderer, not ExecJS.');
// If the app is using server rendering with ExecJS, then the promise will not be awaited.
// And when a promise is passed to JSON.stringify, it will be converted to '{}'.
return '{}';
}
return result;
}
function processReactElement(result) {
try {
var componentObj = ComponentRegistry_1.default.get(name);
if (componentObj.isRenderer) {
throw new Error("Detected a renderer while server rendering component '".concat(name, "'. See https://github.com/shakacode/react_on_rails#renderer-functions"));
}
var reactRenderingResult_1 = (0, createReactOutput_1.default)({
componentObj: componentObj,
domNodeId: domNodeId,
trace: trace,
props: props,
railsContext: railsContext,
});
var processServerRenderHash = function () {
// We let the client side handle any redirect
// Set hasErrors in case we want to throw a Rails exception
hasErrors = !!reactRenderingResult_1.routeError;
if (hasErrors) {
console.error("React Router ERROR: ".concat(JSON.stringify(reactRenderingResult_1.routeError)));
return server_1.default.renderToString(result);
}
catch (error) {
console.error("Invalid call to renderToString. Possibly you have a renderFunction, a function that already\ncalls renderToString, that takes one parameter. You need to add an extra unused parameter to identify this function\nas a renderFunction and not a simple React Function Component.");
throw error;
}
}
function processRenderingResult(result, options) {
if ((0, isServerRenderResult_1.isServerRenderHash)(result)) {
return processServerRenderHash(result, options);
}
if ((0, isServerRenderResult_1.isPromise)(result)) {
return { result: processPromise(result, options.renderingReturnsPromises), hasErrors: false };
}
return { result: processReactElement(result), hasErrors: false };
}
function handleRenderingError(e, options) {
if (options.throwJsErrors) {
throw e;
}
var error = convertToError(e);
return {
hasErrors: true,
result: (0, handleError_1.default)({ e: error, name: options.componentName, serverSide: true }),
error: error,
};
}
function createResultObject(html, consoleReplayScript, renderState) {
return {
html: html,
consoleReplayScript: consoleReplayScript,
hasErrors: renderState.hasErrors,
renderingError: renderState.error && { message: renderState.error.message, stack: renderState.error.stack },
isShellReady: 'isShellReady' in renderState ? renderState.isShellReady : undefined,
};
}
function createPromiseResult(renderState, componentName, throwJsErrors) {
return __awaiter(this, void 0, void 0, function () {
var consoleHistory, html, consoleReplayScript, e_1, errorRenderState, consoleReplayScript;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
consoleHistory = console.history;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, renderState.result];
case 2:
html = _a.sent();
consoleReplayScript = (0, buildConsoleReplay_1.default)(consoleHistory);
return [2 /*return*/, createResultObject(html, consoleReplayScript, renderState)];
case 3:
e_1 = _a.sent();
errorRenderState = handleRenderingError(e_1, { componentName: componentName, throwJsErrors: throwJsErrors });
consoleReplayScript = (0, buildConsoleReplay_1.default)(consoleHistory);
return [2 /*return*/, createResultObject(errorRenderState.result, consoleReplayScript, renderState)];
case 4: return [2 /*return*/];
}
if (reactRenderingResult_1.redirectLocation) {
if (trace) {
var redirectLocation = reactRenderingResult_1.redirectLocation;
var redirectPath = redirectLocation.pathname + redirectLocation.search;
console.log(" ROUTER REDIRECT: ".concat(name, " to dom node with id: ").concat(domNodeId, ", redirect to ").concat(redirectPath));
}
// For redirects on server rendering, we can't stop Rails from returning the same result.
// Possibly, someday, we could have the rails server redirect.
return '';
}
return reactRenderingResult_1.renderedHtml;
};
var processPromise = function () {
if (!renderingReturnsPromises) {
console.error('Your render function returned a Promise, which is only supported by a node renderer, not ExecJS.');
}
return reactRenderingResult_1;
};
var processReactElement = function () {
try {
return server_1.default.renderToString(reactRenderingResult_1);
}
catch (error) {
console.error("Invalid call to renderToString. Possibly you have a renderFunction, a function that already\ncalls renderToString, that takes one parameter. You need to add an extra unused parameter to identify this function\nas a renderFunction and not a simple React Function Component.");
throw error;
}
};
if ((0, isServerRenderResult_1.isServerRenderHash)(reactRenderingResult_1)) {
renderResult = processServerRenderHash();
}
else if ((0, isServerRenderResult_1.isPromise)(reactRenderingResult_1)) {
renderResult = processPromise();
}
else {
renderResult = processReactElement();
}
}
catch (e) {
if (throwJsErrors) {
throw e;
}
hasErrors = true;
renderResult = (0, handleError_1.default)({
e: e,
name: name,
serverSide: true,
});
renderingError = e;
});
}
function createFinalResult(renderState, componentName, throwJsErrors) {
var result = renderState.result;
if ((0, isServerRenderResult_1.isPromise)(result)) {
return createPromiseResult(__assign(__assign({}, renderState), { result: result }), componentName, throwJsErrors);
}
var consoleReplayScript = (0, buildConsoleReplay_1.default)();
var addRenderingErrors = function (resultObject, renderError) {
resultObject.renderingError = {
message: renderError.message,
stack: renderError.stack,
};
return JSON.stringify(createResultObject(result, consoleReplayScript, renderState));
}
function serverRenderReactComponentInternal(options) {
var componentName = options.name, domNodeId = options.domNodeId, trace = options.trace, props = options.props, railsContext = options.railsContext, renderingReturnsPromises = options.renderingReturnsPromises, throwJsErrors = options.throwJsErrors;
var renderState = {
result: null,
hasErrors: false,
};
if (renderingReturnsPromises) {
var resolveRenderResult = function () { return __awaiter(_this, void 0, void 0, function () {
var promiseResult, e_1;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
_a = {};
return [4 /*yield*/, renderResult];
case 1:
promiseResult = (_a.html = _b.sent(),
_a.consoleReplayScript = consoleReplayScript,
_a.hasErrors = hasErrors,
_a);
return [3 /*break*/, 3];
case 2:
e_1 = _b.sent();
if (throwJsErrors) {
throw e_1;
}
promiseResult = {
html: (0, handleError_1.default)({
e: e_1,
name: name,
serverSide: true,
}),
consoleReplayScript: consoleReplayScript,
hasErrors: true,
};
renderingError = e_1;
return [3 /*break*/, 3];
case 3:
if (renderingError !== null) {
addRenderingErrors(promiseResult, renderingError);
}
return [2 /*return*/, promiseResult];
}
});
}); };
return resolveRenderResult();
try {
var componentObj = ComponentRegistry_1.default.get(componentName);
validateComponent(componentObj, componentName);
// Renders the component or executes the render function
// - If the registered component is a React element or component, it renders it
// - If it's a render function, it executes the function and processes the result:
// - For React elements or components, it renders them
// - For promises, it returns them without awaiting (for async rendering)
// - For other values (e.g., strings), it returns them directly
// Note: Only synchronous operations are performed at this stage
var reactRenderingResult = (0, createReactOutput_1.default)({ componentObj: componentObj, domNodeId: domNodeId, trace: trace, props: props, railsContext: railsContext });
// Processes the result from createReactOutput:
// 1. Converts React elements to HTML strings
// 2. Returns rendered HTML from serverRenderHash
// 3. Handles promises for async rendering
renderState = processRenderingResult(reactRenderingResult, { componentName: componentName, domNodeId: domNodeId, trace: trace, renderingReturnsPromises: renderingReturnsPromises });
}
var result = {
html: renderResult,
consoleReplayScript: consoleReplayScript,
hasErrors: hasErrors,
};
if (renderingError) {
addRenderingErrors(result, renderingError);
catch (e) {
renderState = handleRenderingError(e, { componentName: componentName, throwJsErrors: throwJsErrors });
}
return JSON.stringify(result);
// Finalize the rendering result and prepare it for server response
// 1. Builds the consoleReplayScript for client-side console replay
// 2. Extract the result from promise (if needed) by awaiting it
// 3. Constructs a JSON object with the following properties:
// - html: string | null (The rendered component HTML)
// - consoleReplayScript: string (Script to replay console outputs on the client)
// - hasErrors: boolean (Indicates if any errors occurred during rendering)
// - renderingError: Error | null (The error object if an error occurred, null otherwise)
// 4. For Promise results, it awaits resolution before creating the final JSON
return createFinalResult(renderState, componentName, throwJsErrors);
}

@@ -192,5 +217,111 @@ var serverRenderReactComponent = function (options) {

// See `RubyEmbeddedJavaScript.console_polyfill` for initialization.
// This is necessary when ExecJS and old versions of node renderer are used.
// New versions of node renderer reset the console history automatically.
console.history = [];
}
};
var stringToStream = function (str) {
var stream = new stream_1.PassThrough();
stream.write(str);
stream.end();
return stream;
};
var transformRenderStreamChunksToResultObject = function (renderState) {
var consoleHistory = console.history;
var previouslyReplayedConsoleMessages = 0;
var transformStream = new stream_1.PassThrough({
transform: function (chunk, _, callback) {
var htmlChunk = chunk.toString();
var consoleReplayScript = (0, buildConsoleReplay_1.default)(consoleHistory, previouslyReplayedConsoleMessages);
previouslyReplayedConsoleMessages = (consoleHistory === null || consoleHistory === void 0 ? void 0 : consoleHistory.length) || 0;
var jsonChunk = JSON.stringify(createResultObject(htmlChunk, consoleReplayScript, renderState));
this.push("".concat(jsonChunk, "\n"));
callback();
}
});
var pipedStream = null;
var pipeToTransform = function (pipeableStream) {
pipeableStream.pipe(transformStream);
pipedStream = pipeableStream;
};
// We need to wrap the transformStream in a Readable stream to properly handle errors:
// 1. If we returned transformStream directly, we couldn't emit errors into it externally
// 2. If an error is emitted into the transformStream, it would cause the render to fail
// 3. By wrapping in Readable.from(), we can explicitly emit errors into the readableStream without affecting the transformStream
// Note: Readable.from can merge multiple chunks into a single chunk, so we need to ensure that we can separate them later
var readableStream = stream_1.Readable.from(transformStream);
var writeChunk = function (chunk) { return transformStream.write(chunk); };
var emitError = function (error) { return readableStream.emit('error', error); };
var endStream = function () {
transformStream.end();
pipedStream === null || pipedStream === void 0 ? void 0 : pipedStream.abort();
};
return { readableStream: readableStream, pipeToTransform: pipeToTransform, writeChunk: writeChunk, emitError: emitError, endStream: endStream };
};
var streamRenderReactComponent = function (reactRenderingResult, options) {
var componentName = options.name, throwJsErrors = options.throwJsErrors;
var renderState = {
result: null,
hasErrors: false,
isShellReady: false
};
var _a = transformRenderStreamChunksToResultObject(renderState), readableStream = _a.readableStream, pipeToTransform = _a.pipeToTransform, writeChunk = _a.writeChunk, emitError = _a.emitError, endStream = _a.endStream;
var renderingStream = server_1.default.renderToPipeableStream(reactRenderingResult, {
onShellError: function (e) {
var error = convertToError(e);
renderState.hasErrors = true;
renderState.error = error;
if (throwJsErrors) {
emitError(error);
}
var errorHtml = (0, handleError_1.default)({ e: error, name: componentName, serverSide: true });
writeChunk(errorHtml);
endStream();
},
onShellReady: function () {
renderState.isShellReady = true;
pipeToTransform(renderingStream);
},
onError: function (e) {
if (!renderState.isShellReady) {
return;
}
var error = convertToError(e);
if (throwJsErrors) {
emitError(error);
}
renderState.hasErrors = true;
renderState.error = error;
},
});
return readableStream;
};
var streamServerRenderedReactComponent = function (options) {
var componentName = options.name, domNodeId = options.domNodeId, trace = options.trace, props = options.props, railsContext = options.railsContext, throwJsErrors = options.throwJsErrors;
try {
var componentObj = ComponentRegistry_1.default.get(componentName);
validateComponent(componentObj, componentName);
var reactRenderingResult = (0, createReactOutput_1.default)({
componentObj: componentObj,
domNodeId: domNodeId,
trace: trace,
props: props,
railsContext: railsContext,
});
if ((0, isServerRenderResult_1.isServerRenderHash)(reactRenderingResult) || (0, isServerRenderResult_1.isPromise)(reactRenderingResult)) {
throw new Error('Server rendering of streams is not supported for server render hashes or promises.');
}
return streamRenderReactComponent(reactRenderingResult, options);
}
catch (e) {
if (throwJsErrors) {
throw e;
}
var error = convertToError(e);
var htmlResult = (0, handleError_1.default)({ e: error, name: componentName, serverSide: true });
var jsonResult = JSON.stringify(createResultObject(htmlResult, (0, buildConsoleReplay_1.default)(), { hasErrors: true, error: error, result: null }));
return stringToStream(jsonResult);
}
};
exports.streamServerRenderedReactComponent = streamServerRenderedReactComponent;
exports.default = serverRenderReactComponent;

@@ -1,3 +0,2 @@

import type { StoreGenerator } from './types';
type Store = any;
import type { Store, StoreGenerator } from './types';
declare const _default: {

@@ -9,3 +8,3 @@ /**

register(storeGenerators: {
[id: string]: any;
[id: string]: StoreGenerator;
}): void;

@@ -12,0 +11,0 @@ /**

@@ -53,4 +53,5 @@ "use strict";

getStoreGenerator: function (name) {
if (registeredStoreGenerators.has(name)) {
return registeredStoreGenerators.get(name);
var registeredStoreGenerator = registeredStoreGenerators.get(name);
if (registeredStoreGenerator) {
return registeredStoreGenerator;
}

@@ -57,0 +58,0 @@ var storeKeys = Array.from(registeredStoreGenerators.keys()).join(', ');

import type { ReactElement, ReactNode, Component, ComponentType } from 'react';
type Store = any;
import type { Readable } from 'stream';
type Store = unknown;
type ReactComponent = ComponentType<any> | string;

@@ -43,12 +44,40 @@ export interface RailsContext {

type RenderFunctionResult = ReactComponent | ServerRenderResult | Promise<string>;
/**
* Render functions are used to create dynamic React components or server-rendered HTML with side effects.
* They receive two arguments: props and railsContext.
*
* @param props - The component props passed to the render function
* @param railsContext - The Rails context object containing environment information
* @returns A string, React component, React element, or a Promise resolving to a string
*
* @remarks
* To distinguish a render function from a React Function Component:
* 1. Ensure it accepts two parameters (props and railsContext), even if railsContext is unused, or
* 2. Set the `renderFunction` property to `true` on the function object.
*
* If neither condition is met, it will be treated as a React Function Component,
* and ReactDOMServer will attempt to render it.
*
* @example
* // Option 1: Two-parameter function
* const renderFunction = (props, railsContext) => { ... };
*
* // Option 2: Using renderFunction property
* const anotherRenderFunction = (props) => { ... };
* anotherRenderFunction.renderFunction = true;
*/
interface RenderFunction {
(props?: any, railsContext?: RailsContext, domNodeId?: string): RenderFunctionResult;
renderFunction?: boolean;
renderFunction?: true;
}
type ReactComponentOrRenderFunction = ReactComponent | RenderFunction;
export type { // eslint-disable-line import/prefer-default-export
ReactComponentOrRenderFunction, ReactComponent, AuthenticityHeaders, RenderFunction, RenderFunctionResult, StoreGenerator, CreateReactOutputResult, ServerRenderResult, };
ReactComponentOrRenderFunction, ReactComponent, AuthenticityHeaders, RenderFunction, RenderFunctionResult, Store, StoreGenerator, CreateReactOutputResult, ServerRenderResult, };
export interface RegisteredComponent {
name: string;
component: ReactComponentOrRenderFunction;
/**
* Indicates if the registered component is a RenderFunction
* @see RenderFunction for more details on its behavior and usage.
*/
renderFunction: boolean;

@@ -72,8 +101,7 @@ isRenderer: boolean;

}
interface FileError extends Error {
fileName: string;
lineNumber: string;
}
export interface ErrorOptions {
e: FileError;
e: Error & {
fileName?: string;
lineNumber?: string;
};
name?: string;

@@ -83,6 +111,3 @@ jsCode?: string;

}
export interface RenderingError {
message: string;
stack: string;
}
export type RenderingError = Pick<Error, 'message' | 'stack'>;
export interface RenderResult {

@@ -93,2 +118,3 @@ html: string | null;

renderingError?: RenderingError;
isShellReady?: boolean;
}

@@ -104,5 +130,9 @@ export interface Root {

}): void;
/** @deprecated Use registerStoreGenerators instead */
registerStore(stores: {
[id: string]: Store;
[id: string]: StoreGenerator;
}): void;
registerStoreGenerators(storeGenerators: {
[id: string]: StoreGenerator;
}): void;
getStore(name: string, throwIfMissing?: boolean): Store | undefined;

@@ -126,2 +156,3 @@ setOptions(newOptions: {

serverRenderReactComponent(options: RenderParams): null | string | Promise<RenderResult>;
streamServerRenderedReactComponent(options: RenderParams): Readable;
handleError(options: ErrorOptions): string | undefined;

@@ -128,0 +159,0 @@ buildConsoleReplay(): string;

{
"name": "react-on-rails",
"version": "14.0.5",
"version": "15.0.0-alpha.0",
"description": "react-on-rails JavaScript for react_on_rails Ruby gem",

@@ -18,4 +18,4 @@ "main": "node_package/lib/ReactOnRails.js",

"@types/jest": "^29.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@types/turbolinks": "^5.2.2",

@@ -43,8 +43,8 @@ "@types/webpack-env": "^1.18.4",

"prop-types": "^15.8.1",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react": "18.3.0-canary-670811593-20240322",
"react-dom": "18.3.0-canary-670811593-20240322",
"react-transform-hmr": "^1.0.4",
"redux": "^4.2.1",
"ts-jest": "^29.1.0",
"typescript": "^5.3.3"
"typescript": "^5.6.2"
},

@@ -51,0 +51,0 @@ "dependencies": {

@@ -20,2 +20,3 @@ ![reactrails](https://user-images.githubusercontent.com/10421828/79436261-52159b80-7fd9-11ea-994e-2a98dd43e540.png)

# News
* [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/) supports the latest features of React 18, including [React Server Components](https://react.dev/reference/rsc/server-components) and [streaming](https://react.dev/reference/react-dom/server/renderToPipeableStream). Contact [Justin Gordon](mailto:justin@shakacode.com) for more information.
* ShakaCode now maintains the official successor to `rails/webpacker`, [`shakapacker`](https://github.com/shakacode/shakapacker).

@@ -22,0 +23,0 @@ * Project is updated to support Rails 7 and Shakapacker v6+!

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