UNPKG

react-on-rails

Version:

react-on-rails JavaScript for react_on_rails Ruby gem

267 lines (264 loc) 10.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); const ClientStartup = require("./clientStartup"); const ComponentRegistry_1 = require("./ComponentRegistry"); const StoreRegistry_1 = require("./StoreRegistry"); const buildConsoleReplay_1 = require("./buildConsoleReplay"); const createReactOutput_1 = require("./createReactOutput"); const Authenticity_1 = require("./Authenticity"); const context_1 = require("./context"); const reactHydrateOrRender_1 = require("./reactHydrateOrRender"); const ctx = (0, context_1.default)(); if (ctx === undefined) { throw new Error("The context (usually Window or NodeJS's Global) is undefined."); } if (ctx.ReactOnRails !== undefined) { throw new Error(` The ReactOnRails value exists in the ${ctx} scope, it may not be safe to overwrite it. This could be caused by setting Webpack's optimization.runtimeChunk to "true" or "multiple," rather than "single." Check your Webpack configuration. Read more at https://github.com/shakacode/react_on_rails/issues/1558. `); } const DEFAULT_OPTIONS = { traceTurbolinks: false, turbo: false, }; ctx.ReactOnRails = { options: {}, /** * Main entry point to using the react-on-rails npm package. This is how Rails will be able to * find you components for rendering. * @param components (key is component name, value is component) */ register(components) { ComponentRegistry_1.default.register(components); }, registerStore(stores) { this.registerStoreGenerators(stores); }, /** * 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 storeGenerators (keys are store names, values are the store generators) */ registerStoreGenerators(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(storeGenerators); }, /** * Allows retrieval of the store by name. This store will be hydrated by any Rails form props. * Pass optional param throwIfMissing = false if you want to use this call to get back null if the * store with name is not registered. * @param name * @param throwIfMissing Defaults to true. Set to false to have this call return undefined if * there is no store with the given name. * @returns Redux Store, possibly hydrated */ getStore(name, throwIfMissing = true) { return StoreRegistry_1.default.getStore(name, throwIfMissing); }, /** * Renders or hydrates the react element passed. In case react version is >=18 will use the new api. * @param domNode * @param reactElement * @param hydrate if true will perform hydration, if false will render * @returns {Root|ReactComponent|ReactElement|null} */ reactHydrateOrRender(domNode, reactElement, hydrate) { return (0, reactHydrateOrRender_1.default)(domNode, reactElement, hydrate); }, /** * Set options for ReactOnRails, typically before you call ReactOnRails.register * Available Options: * `traceTurbolinks: true|false Gives you debugging messages on Turbolinks events * `turbo: true|false Turbo (the follower of Turbolinks) events will be registered, if set to true. */ setOptions(newOptions) { if (typeof newOptions.traceTurbolinks !== 'undefined') { this.options.traceTurbolinks = newOptions.traceTurbolinks; // eslint-disable-next-line no-param-reassign delete newOptions.traceTurbolinks; } if (typeof newOptions.turbo !== 'undefined') { this.options.turbo = newOptions.turbo; // eslint-disable-next-line no-param-reassign delete newOptions.turbo; } if (Object.keys(newOptions).length > 0) { throw new Error(`Invalid options passed to ReactOnRails.options: ${JSON.stringify(newOptions)}`); } }, /** * Allow directly calling the page loaded script in case the default events that trigger react * rendering are not sufficient, such as when loading JavaScript asynchronously with TurboLinks: * More details can be found here: * https://github.com/shakacode/react_on_rails/blob/master/docs/additional-reading/turbolinks.md */ reactOnRailsPageLoaded() { ClientStartup.reactOnRailsPageLoaded(); }, reactOnRailsComponentLoaded(domId) { ClientStartup.reactOnRailsComponentLoaded(domId); }, /** * Returns CSRF authenticity token inserted by Rails csrf_meta_tags * @returns String or null */ authenticityToken() { return Authenticity_1.default.authenticityToken(); }, /** * Returns header with csrf authenticity token and XMLHttpRequest * @param otherHeaders Other headers * @returns {*} header */ authenticityHeaders(otherHeaders = {}) { return Authenticity_1.default.authenticityHeaders(otherHeaders); }, // ///////////////////////////////////////////////////////////////////////////// // INTERNALLY USED APIs // ///////////////////////////////////////////////////////////////////////////// /** * Retrieve an option by key. * @param key * @returns option value */ option(key) { return this.options[key]; }, /** * Allows retrieval of the store generator by name. This is used internally by ReactOnRails after * a Rails form loads to prepare stores. * @param name * @returns Redux Store generator function */ getStoreGenerator(name) { return StoreRegistry_1.default.getStoreGenerator(name); }, /** * Allows saving the store populated by Rails form props. Used internally by ReactOnRails. * @param name * @returns Redux Store, possibly hydrated */ setStore(name, store) { return StoreRegistry_1.default.setStore(name, store); }, /** * Clears hydratedStores to avoid accidental usage of wrong store hydrated in previous/parallel * request. */ clearHydratedStores() { StoreRegistry_1.default.clearHydratedStores(); }, /** * @example * ReactOnRails.render("HelloWorldApp", {name: "Stranger"}, 'app'); * * Does this: * ```js * ReactDOM.render(React.createElement(HelloWorldApp, {name: "Stranger"}), * document.getElementById('app')) * ``` * under React 16/17 and * ```js * const root = ReactDOMClient.createRoot(document.getElementById('app')) * root.render(React.createElement(HelloWorldApp, {name: "Stranger"})) * return root * ``` * under React 18+. * * @param name Name of your registered component * @param props Props to pass to your component * @param domNodeId * @param hydrate Pass truthy to update server rendered html. Default is falsy * @returns {Root|ReactComponent|ReactElement} Under React 18+: the created React root * (see "What is a root?" in https://github.com/reactwg/react-18/discussions/5). * Under React 16/17: Reference to your component's backing instance or `null` for stateless components. */ render(name, props, domNodeId, hydrate) { const componentObj = ComponentRegistry_1.default.get(name); const reactElement = (0, createReactOutput_1.default)({ componentObj, props, domNodeId }); return (0, reactHydrateOrRender_1.default)(document.getElementById(domNodeId), reactElement, hydrate); }, /** * Get the component that you registered * @param name * @returns {name, component, renderFunction, isRenderer} */ getComponent(name) { return ComponentRegistry_1.default.get(name); }, /** * Used by server rendering by Rails * @param options */ serverRenderReactComponent() { throw new Error('serverRenderReactComponent is not available in "react-on-rails/client". Import "react-on-rails" server-side.'); }, /** * Used by server rendering by Rails * @param options */ streamServerRenderedReactComponent() { throw new Error('streamServerRenderedReactComponent is only supported when using a bundle built for Node.js environments'); }, /** * Used by Rails to catch errors in rendering * @param options */ handleError() { throw new Error('handleError is not available in "react-on-rails/client". Import "react-on-rails" server-side.'); }, /** * Used by Rails server rendering to replay console messages. */ buildConsoleReplay() { return (0, buildConsoleReplay_1.default)(); }, /** * Get an Object containing all registered components. Useful for debugging. * @returns {*} */ registeredComponents() { return ComponentRegistry_1.default.components(); }, /** * Get an Object containing all registered store generators. Useful for debugging. * @returns {*} */ storeGenerators() { return StoreRegistry_1.default.storeGenerators(); }, /** * Get an Object containing all hydrated stores. Useful for debugging. * @returns {*} */ stores() { return StoreRegistry_1.default.stores(); }, resetOptions() { this.options = Object.assign({}, DEFAULT_OPTIONS); }, }; ctx.ReactOnRails.resetOptions(); ClientStartup.clientStartup(ctx); __exportStar(require("./types"), exports); exports.default = ctx.ReactOnRails;