@dr.pogodin/react-utils 1.13.1 → 1.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/development/index.js +1 -11
- package/build/development/index.js.map +1 -1
- package/build/development/server/server.js +14 -0
- package/build/development/server/server.js.map +1 -1
- package/build/development/shared/components/CodeSplit/ClientSide.js +28 -17
- package/build/development/shared/components/CodeSplit/ClientSide.js.map +1 -1
- package/build/development/shared/components/CodeSplit/ServerSide.js +19 -46
- package/build/development/shared/components/CodeSplit/ServerSide.js.map +1 -1
- package/build/development/shared/components/CodeSplit/index.js +6 -10
- package/build/development/shared/components/CodeSplit/index.js.map +1 -1
- package/build/development/shared/components/index.js +0 -8
- package/build/development/shared/components/index.js.map +1 -1
- package/build/development/shared/utils/Semaphore.js +83 -0
- package/build/development/shared/utils/Semaphore.js.map +1 -0
- package/build/development/shared/utils/config.js +1 -3
- package/build/development/shared/utils/config.js.map +1 -1
- package/build/development/shared/utils/index.js +31 -9
- package/build/development/shared/utils/index.js.map +1 -1
- package/build/development/shared/utils/splitComponent.js +43 -0
- package/build/development/shared/utils/splitComponent.js.map +1 -0
- package/build/development/shared/utils/webpack.js +26 -39
- package/build/development/shared/utils/webpack.js.map +1 -1
- package/build/development/web.bundle.js +46 -16
- package/build/production/index.js +1 -2
- package/build/production/index.js.map +1 -1
- package/build/production/server/server.js +6 -2
- package/build/production/server/server.js.map +1 -1
- package/build/production/shared/components/CodeSplit/ClientSide.js +15 -10
- package/build/production/shared/components/CodeSplit/ClientSide.js.map +1 -1
- package/build/production/shared/components/CodeSplit/ServerSide.js +9 -15
- package/build/production/shared/components/CodeSplit/ServerSide.js.map +1 -1
- package/build/production/shared/components/CodeSplit/index.js +5 -2
- package/build/production/shared/components/CodeSplit/index.js.map +1 -1
- package/build/production/shared/components/index.js +1 -1
- package/build/production/shared/components/index.js.map +1 -1
- package/build/production/shared/utils/Semaphore.js +20 -0
- package/build/production/shared/utils/Semaphore.js.map +1 -0
- package/build/production/shared/utils/config.js +1 -1
- package/build/production/shared/utils/config.js.map +1 -1
- package/build/production/shared/utils/index.js +5 -3
- package/build/production/shared/utils/index.js.map +1 -1
- package/build/production/shared/utils/splitComponent.js +14 -0
- package/build/production/shared/utils/splitComponent.js.map +1 -0
- package/build/production/shared/utils/webpack.js +4 -27
- package/build/production/shared/utils/webpack.js.map +1 -1
- package/build/production/web.bundle.js +1 -1
- package/build/production/web.bundle.js.map +1 -1
- package/config/babel/node-ssr.js +2 -4
- package/package.json +20 -22
|
@@ -94,17 +94,7 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
|
|
|
94
94
|
|
|
95
95
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
const server = _utils.webpack.requireWeak("./server", __dirname);
|
|
98
98
|
|
|
99
99
|
exports.server = server;
|
|
100
|
-
|
|
101
|
-
if (_utils.isomorphy.IS_SERVER_SIDE) {
|
|
102
|
-
try {
|
|
103
|
-
const path = _utils.webpack.requireWeak('path');
|
|
104
|
-
|
|
105
|
-
exports.server = server = _utils.webpack.requireWeak(path.resolve(__dirname, './server'));
|
|
106
|
-
} catch (error) {
|
|
107
|
-
exports.server = server = null;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
100
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.js"],"names":["server","
|
|
1
|
+
{"version":3,"sources":["../../src/index.js"],"names":["server","webpack","requireWeak","__dirname"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA;;AAgBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAZA;;;;;;AAGA;;AAQA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;AAbA,MAAMA,MAAM,GAAGC,eAAQC,WAAR,aAAgCC,SAAhC,CAAf","sourcesContent":["import 'styles/global.scss';\n\nimport { webpack } from 'utils';\n\nconst server = webpack.requireWeak('./server', __dirname);\n\nexport { default as api } from 'axios';\nexport * as PT from 'prop-types';\n\nexport {\n getGlobalState,\n GlobalStateProvider,\n useAsyncCollection,\n useAsyncData,\n useGlobalState,\n} from '@dr.pogodin/react-global-state';\n\nexport * from 'components';\nexport * from 'utils';\n\nexport { server };\n"],"file":"index.js"}
|
|
@@ -8,6 +8,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
exports.default = factory;
|
|
9
9
|
exports.getDefaultCspSettings = getDefaultCspSettings;
|
|
10
10
|
|
|
11
|
+
var _path = require("path");
|
|
12
|
+
|
|
13
|
+
var _url = require("url");
|
|
14
|
+
|
|
11
15
|
var _lodash = require("lodash");
|
|
12
16
|
|
|
13
17
|
var _compression = _interopRequireDefault(require("compression"));
|
|
@@ -167,6 +171,16 @@ async function factory(webpackConfig, options) {
|
|
|
167
171
|
/* eslint-disable import/no-unresolved */
|
|
168
172
|
|
|
169
173
|
if (options.devMode) {
|
|
174
|
+
// This is a workaround for SASS bug:
|
|
175
|
+
// https://github.com/dart-lang/sdk/issues/27979
|
|
176
|
+
// which manifests itself sometimes when webpack dev middleware is used
|
|
177
|
+
// (in dev mode), and app modules are imported in some unfortunate ways.
|
|
178
|
+
if (!global.location) {
|
|
179
|
+
global.location = {
|
|
180
|
+
href: `${(0, _url.pathToFileURL)(process.cwd()).href}${_path.sep}`
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
170
184
|
const webpack = require('webpack');
|
|
171
185
|
|
|
172
186
|
const webpackDevMiddleware = require('webpack-dev-middleware');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/server.js"],"names":["defaultCspSettings","directives","helmet","contentSecurityPolicy","getDefaultDirectives","array","filter","item","push","getDefaultCspSettings","factory","webpackConfig","options","rendererOps","renderer","publicPath","output","server","beforeExpressJsSetup","logger","httpsRedirect","use","req","res","next","schema","headers","url","host","originalUrl","redirect","crossOriginEmbedderPolicy","crossOriginOpenerPolicy","crossOriginResourcePolicy","noCsp","nonce","cspNonce","cspSettings","cspSettingsHook","favicon","send","express","json","limit","urlencoded","extended","requestIp","mw","loggerMiddleware","token","clientIp","FORMAT","stream","write","info","bind","header","devMode","webpack","require","webpackDevMiddleware","webpackHotMiddleware","compiler","serverSideRender","static","path","onExpressJsSetup","ERRORS","NOT_FOUND","CODES","dontAttachDefaultErrorHandler","beforeExpressJsError","error","status","INTERNAL_SERVER_ERROR","serverSide","log","message","process","env","NODE_ENV"],"mappings":"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","sourcesContent":["/**\n * Creation of standard ExpressJS server for ReactJS apps.\n */\n\nimport {\n cloneDeep,\n mapValues,\n pick,\n} from 'lodash';\n\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport express from 'express';\nimport favicon from 'serve-favicon';\nimport helmet from 'helmet';\nimport loggerMiddleware from 'morgan';\nimport requestIp from 'request-ip';\nimport { v4 as uuid } from 'uuid';\n\nimport rendererFactory from './renderer';\n\nimport {\n CODES,\n ERRORS,\n fail,\n getErrorForCode,\n} from './utils/errors';\n\n/**\n * Default Content Security Policy settings.\n * @ignore\n */\nconst defaultCspSettings = {\n directives: mapValues(\n helmet.contentSecurityPolicy.getDefaultDirectives(),\n\n // 'https:' options (automatic re-write of insecure URLs to secure ones)\n // is removed to facilitate local development with HTTP server. In cloud\n // deployments we assume Apache or Nginx server in front of out app takes\n // care about such re-writes.\n (array) => array.filter((item) => item !== 'https:'),\n ),\n};\ndefaultCspSettings.directives['frame-src'] = [\n \"'self'\",\n\n // YouTube domain is whitelisted to allow <YouTubeVideo> component to work\n // out of box.\n 'https://*.youtube.com',\n];\ndefaultCspSettings.directives['script-src'].push(\"'unsafe-eval'\");\n\n// No need for automatic re-writes via Content Security Policy settings:\n// the forefront Apache or Nginx server is supposed to take care of this\n// in production cloud deployments.\ndelete defaultCspSettings.directives['upgrade-insecure-requests'];\n\n/**\n * @category Utilities\n * @func server/getDefaultCspSettings\n * @global\n * @desc\n * ```js\n * import { server } from '@dr.pogodin/react-utils';\n * const { getDefaultCspSettings } from '@dr.pogodin/react-utils';\n * ```\n * @return {{\n * directives: object\n * }} A deep copy of default CSP settings object used by `react-utils`,\n * with the exception of `nonce-xxx` clause in `script-src` directive,\n * which is added dynamically for each request.\n */\nexport function getDefaultCspSettings() {\n return cloneDeep(defaultCspSettings);\n}\n\nexport default async function factory(webpackConfig, options) {\n const rendererOps = pick(options, [\n 'Application',\n 'beforeRender',\n 'favicon',\n 'maxSsrRounds',\n 'noCsp',\n 'ssrTimeout',\n 'staticCacheController',\n 'staticCacheSize',\n ]);\n const renderer = rendererFactory(webpackConfig, rendererOps);\n const { publicPath } = webpackConfig.output;\n\n const server = express();\n\n if (options.beforeExpressJsSetup) {\n await options.beforeExpressJsSetup(server);\n }\n\n server.logger = options.logger;\n\n if (options.httpsRedirect) {\n server.use((req, res, next) => {\n const schema = req.headers['x-forwarded-proto'];\n if (schema === 'http') {\n let url = `https://${req.headers.host}`;\n if (req.originalUrl !== '/') url += req.originalUrl;\n return res.redirect(url);\n }\n return next();\n });\n }\n\n server.use(compression());\n server.use(\n helmet({\n contentSecurityPolicy: false,\n crossOriginEmbedderPolicy: false,\n crossOriginOpenerPolicy: false,\n crossOriginResourcePolicy: false,\n }),\n );\n\n if (!options.noCsp) {\n server.use((req, res, next) => {\n req.nonce = uuid();\n\n // TODO: This is deprecated, but it is kept for now for backward\n // compatibility. Should be removed sometime later.\n req.cspNonce = req.nonce;\n\n // The deep clone is necessary here to ensure that default value can't be\n // mutated during request processing.\n let cspSettings = cloneDeep(defaultCspSettings);\n cspSettings.directives['script-src'].push(`'nonce-${req.nonce}'`);\n if (options.cspSettingsHook) {\n cspSettings = options.cspSettingsHook(cspSettings, req);\n }\n helmet.contentSecurityPolicy(cspSettings)(req, res, next);\n });\n }\n\n if (options.favicon) {\n server.use(favicon(options.favicon));\n }\n\n server.use('/robots.txt', (req, res) => res.send('User-agent: *\\nDisallow:'));\n\n server.use(express.json({ limit: '300kb' }));\n server.use(express.urlencoded({ extended: false }));\n server.use(cookieParser());\n server.use(requestIp.mw());\n\n loggerMiddleware.token('ip', (req) => req.clientIp);\n const FORMAT = ':ip > :status :method :url :response-time ms :res[content-length] :referrer :user-agent';\n server.use(loggerMiddleware(FORMAT, {\n stream: {\n write: options.logger.info.bind(options.logger),\n },\n }));\n\n /* Ensures no caching for the service worker script. */\n server.use(`${publicPath}service-worker.js`, (req, res, next) => {\n res.header('Cache-Control', 'no-cache');\n next();\n });\n\n /* Setup of Hot Module Reloading for development environment.\n * These dependencies are not used, nor installed for production use,\n * hence we should violate some import-related lint rules. */\n /* eslint-disable global-require */\n /* eslint-disable import/no-extraneous-dependencies */\n /* eslint-disable import/no-unresolved */\n if (options.devMode) {\n const webpack = require('webpack');\n const webpackDevMiddleware = require('webpack-dev-middleware');\n const webpackHotMiddleware = require('webpack-hot-middleware');\n const compiler = webpack(webpackConfig);\n server.use(webpackDevMiddleware(compiler, {\n publicPath,\n serverSideRender: true,\n }));\n server.use(webpackHotMiddleware(compiler));\n }\n /* eslint-enable global-require */\n /* eslint-enable import/no-extraneous-dependencies */\n /* eslint-enable import/no-unresolved */\n\n server.use(publicPath, express.static(webpackConfig.output.path));\n\n if (options.onExpressJsSetup) {\n await options.onExpressJsSetup(server);\n }\n server.use(renderer);\n\n /* Detects 404 errors, and forwards them to the error handler. */\n server.use(() => fail(ERRORS.NOT_FOUND, CODES.NOT_FOUND));\n\n let dontAttachDefaultErrorHandler;\n if (options.beforeExpressJsError) {\n dontAttachDefaultErrorHandler = await options.beforeExpressJsError(server);\n }\n\n /* Error handler. */\n if (!dontAttachDefaultErrorHandler) {\n // TODO: It is better to move the default error handler definition\n // to a stand-alone function at top-level, but the use of options.logger\n // prevents to do it without some extra refactoring. Should be done sometime\n // though.\n /* eslint-disable no-unused-vars */\n server.use((error, req, res, next) => {\n /* eslint-enable no-unused-vars */\n const status = error.status || CODES.INTERNAL_SERVER_ERROR;\n const serverSide = status >= CODES.INTERNAL_SERVER_ERROR;\n\n // Log server-side errors always, client-side at debug level only.\n options.logger.log(serverSide ? 'error' : 'debug', error);\n\n let message = error.message || getErrorForCode(status);\n if (serverSide && process.env.NODE_ENV === 'production') {\n message = ERRORS.INTERNAL_SERVER_ERROR;\n }\n\n res.status(status).send(message);\n });\n }\n\n return server;\n}\n"],"file":"server.js"}
|
|
1
|
+
{"version":3,"sources":["../../../src/server/server.js"],"names":["defaultCspSettings","directives","helmet","contentSecurityPolicy","getDefaultDirectives","array","filter","item","push","getDefaultCspSettings","factory","webpackConfig","options","rendererOps","renderer","publicPath","output","server","beforeExpressJsSetup","logger","httpsRedirect","use","req","res","next","schema","headers","url","host","originalUrl","redirect","crossOriginEmbedderPolicy","crossOriginOpenerPolicy","crossOriginResourcePolicy","noCsp","nonce","cspNonce","cspSettings","cspSettingsHook","favicon","send","express","json","limit","urlencoded","extended","requestIp","mw","loggerMiddleware","token","clientIp","FORMAT","stream","write","info","bind","header","devMode","global","location","href","process","cwd","sep","webpack","require","webpackDevMiddleware","webpackHotMiddleware","compiler","serverSideRender","static","path","onExpressJsSetup","ERRORS","NOT_FOUND","CODES","dontAttachDefaultErrorHandler","beforeExpressJsError","error","status","INTERNAL_SERVER_ERROR","serverSide","log","message","env","NODE_ENV"],"mappings":"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","sourcesContent":["/**\n * Creation of standard ExpressJS server for ReactJS apps.\n */\n\nimport { sep } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n cloneDeep,\n mapValues,\n pick,\n} from 'lodash';\n\nimport compression from 'compression';\nimport cookieParser from 'cookie-parser';\nimport express from 'express';\nimport favicon from 'serve-favicon';\nimport helmet from 'helmet';\nimport loggerMiddleware from 'morgan';\nimport requestIp from 'request-ip';\nimport { v4 as uuid } from 'uuid';\n\nimport rendererFactory from './renderer';\n\nimport {\n CODES,\n ERRORS,\n fail,\n getErrorForCode,\n} from './utils/errors';\n\n/**\n * Default Content Security Policy settings.\n * @ignore\n */\nconst defaultCspSettings = {\n directives: mapValues(\n helmet.contentSecurityPolicy.getDefaultDirectives(),\n\n // 'https:' options (automatic re-write of insecure URLs to secure ones)\n // is removed to facilitate local development with HTTP server. In cloud\n // deployments we assume Apache or Nginx server in front of out app takes\n // care about such re-writes.\n (array) => array.filter((item) => item !== 'https:'),\n ),\n};\ndefaultCspSettings.directives['frame-src'] = [\n \"'self'\",\n\n // YouTube domain is whitelisted to allow <YouTubeVideo> component to work\n // out of box.\n 'https://*.youtube.com',\n];\ndefaultCspSettings.directives['script-src'].push(\"'unsafe-eval'\");\n\n// No need for automatic re-writes via Content Security Policy settings:\n// the forefront Apache or Nginx server is supposed to take care of this\n// in production cloud deployments.\ndelete defaultCspSettings.directives['upgrade-insecure-requests'];\n\n/**\n * @category Utilities\n * @func server/getDefaultCspSettings\n * @global\n * @desc\n * ```js\n * import { server } from '@dr.pogodin/react-utils';\n * const { getDefaultCspSettings } from '@dr.pogodin/react-utils';\n * ```\n * @return {{\n * directives: object\n * }} A deep copy of default CSP settings object used by `react-utils`,\n * with the exception of `nonce-xxx` clause in `script-src` directive,\n * which is added dynamically for each request.\n */\nexport function getDefaultCspSettings() {\n return cloneDeep(defaultCspSettings);\n}\n\nexport default async function factory(webpackConfig, options) {\n const rendererOps = pick(options, [\n 'Application',\n 'beforeRender',\n 'favicon',\n 'maxSsrRounds',\n 'noCsp',\n 'ssrTimeout',\n 'staticCacheController',\n 'staticCacheSize',\n ]);\n const renderer = rendererFactory(webpackConfig, rendererOps);\n const { publicPath } = webpackConfig.output;\n\n const server = express();\n\n if (options.beforeExpressJsSetup) {\n await options.beforeExpressJsSetup(server);\n }\n\n server.logger = options.logger;\n\n if (options.httpsRedirect) {\n server.use((req, res, next) => {\n const schema = req.headers['x-forwarded-proto'];\n if (schema === 'http') {\n let url = `https://${req.headers.host}`;\n if (req.originalUrl !== '/') url += req.originalUrl;\n return res.redirect(url);\n }\n return next();\n });\n }\n\n server.use(compression());\n server.use(\n helmet({\n contentSecurityPolicy: false,\n crossOriginEmbedderPolicy: false,\n crossOriginOpenerPolicy: false,\n crossOriginResourcePolicy: false,\n }),\n );\n\n if (!options.noCsp) {\n server.use((req, res, next) => {\n req.nonce = uuid();\n\n // TODO: This is deprecated, but it is kept for now for backward\n // compatibility. Should be removed sometime later.\n req.cspNonce = req.nonce;\n\n // The deep clone is necessary here to ensure that default value can't be\n // mutated during request processing.\n let cspSettings = cloneDeep(defaultCspSettings);\n cspSettings.directives['script-src'].push(`'nonce-${req.nonce}'`);\n if (options.cspSettingsHook) {\n cspSettings = options.cspSettingsHook(cspSettings, req);\n }\n helmet.contentSecurityPolicy(cspSettings)(req, res, next);\n });\n }\n\n if (options.favicon) {\n server.use(favicon(options.favicon));\n }\n\n server.use('/robots.txt', (req, res) => res.send('User-agent: *\\nDisallow:'));\n\n server.use(express.json({ limit: '300kb' }));\n server.use(express.urlencoded({ extended: false }));\n server.use(cookieParser());\n server.use(requestIp.mw());\n\n loggerMiddleware.token('ip', (req) => req.clientIp);\n const FORMAT = ':ip > :status :method :url :response-time ms :res[content-length] :referrer :user-agent';\n server.use(loggerMiddleware(FORMAT, {\n stream: {\n write: options.logger.info.bind(options.logger),\n },\n }));\n\n /* Ensures no caching for the service worker script. */\n server.use(`${publicPath}service-worker.js`, (req, res, next) => {\n res.header('Cache-Control', 'no-cache');\n next();\n });\n\n /* Setup of Hot Module Reloading for development environment.\n * These dependencies are not used, nor installed for production use,\n * hence we should violate some import-related lint rules. */\n /* eslint-disable global-require */\n /* eslint-disable import/no-extraneous-dependencies */\n /* eslint-disable import/no-unresolved */\n if (options.devMode) {\n // This is a workaround for SASS bug:\n // https://github.com/dart-lang/sdk/issues/27979\n // which manifests itself sometimes when webpack dev middleware is used\n // (in dev mode), and app modules are imported in some unfortunate ways.\n if (!global.location) {\n global.location = {\n href: `${pathToFileURL(process.cwd()).href}${sep}`,\n };\n }\n\n const webpack = require('webpack');\n const webpackDevMiddleware = require('webpack-dev-middleware');\n const webpackHotMiddleware = require('webpack-hot-middleware');\n const compiler = webpack(webpackConfig);\n server.use(webpackDevMiddleware(compiler, {\n publicPath,\n serverSideRender: true,\n }));\n server.use(webpackHotMiddleware(compiler));\n }\n /* eslint-enable global-require */\n /* eslint-enable import/no-extraneous-dependencies */\n /* eslint-enable import/no-unresolved */\n\n server.use(publicPath, express.static(webpackConfig.output.path));\n\n if (options.onExpressJsSetup) {\n await options.onExpressJsSetup(server);\n }\n server.use(renderer);\n\n /* Detects 404 errors, and forwards them to the error handler. */\n server.use(() => fail(ERRORS.NOT_FOUND, CODES.NOT_FOUND));\n\n let dontAttachDefaultErrorHandler;\n if (options.beforeExpressJsError) {\n dontAttachDefaultErrorHandler = await options.beforeExpressJsError(server);\n }\n\n /* Error handler. */\n if (!dontAttachDefaultErrorHandler) {\n // TODO: It is better to move the default error handler definition\n // to a stand-alone function at top-level, but the use of options.logger\n // prevents to do it without some extra refactoring. Should be done sometime\n // though.\n /* eslint-disable no-unused-vars */\n server.use((error, req, res, next) => {\n /* eslint-enable no-unused-vars */\n const status = error.status || CODES.INTERNAL_SERVER_ERROR;\n const serverSide = status >= CODES.INTERNAL_SERVER_ERROR;\n\n // Log server-side errors always, client-side at debug level only.\n options.logger.log(serverSide ? 'error' : 'debug', error);\n\n let message = error.message || getErrorForCode(status);\n if (serverSide && process.env.NODE_ENV === 'production') {\n message = ERRORS.INTERNAL_SERVER_ERROR;\n }\n\n res.status(status).send(message);\n });\n }\n\n return server;\n}\n"],"file":"server.js"}
|
|
@@ -11,7 +11,7 @@ var _react = require("react");
|
|
|
11
11
|
|
|
12
12
|
var _reactGlobalState = require("@dr.pogodin/react-global-state");
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var _Barrier = require("../../utils/Barrier");
|
|
15
15
|
|
|
16
16
|
var _isomorphy = require("../../utils/isomorphy");
|
|
17
17
|
|
|
@@ -28,26 +28,31 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
28
28
|
/* eslint-disable react/jsx-props-no-spreading */
|
|
29
29
|
function ClientSide({
|
|
30
30
|
chunkName,
|
|
31
|
-
|
|
31
|
+
children,
|
|
32
|
+
getClientSide,
|
|
32
33
|
placeholder,
|
|
34
|
+
// Not used in <ClientSide>, but should not go into "...rest" either.
|
|
35
|
+
serverSide,
|
|
33
36
|
...rest
|
|
34
37
|
}) {
|
|
35
38
|
const {
|
|
36
39
|
current: heap
|
|
37
40
|
} = (0, _react.useRef)({
|
|
41
|
+
mounted: false,
|
|
38
42
|
pendingStyles: [],
|
|
39
|
-
renderInitialized: false
|
|
40
|
-
stylesInitialized: false
|
|
43
|
+
renderInitialized: false
|
|
41
44
|
}); // publicPath from buildInfo does not have a trailing slash at the end.
|
|
42
45
|
|
|
43
46
|
const {
|
|
44
47
|
publicPath
|
|
45
|
-
} = (0, _isomorphy.getBuildInfo)(); // This code block initiates style loading as soon as possible
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
} = (0, _isomorphy.getBuildInfo)(); // This code block initiates style loading as soon as possible, even prior to
|
|
49
|
+
// the component loading, and it collects all style load / failure promises
|
|
50
|
+
// into heap.pendingStyles array, allowing us to wait and thus avoid flash of
|
|
51
|
+
// unstyled content issue (that's why we don't rely on mini-css-extract-plugin
|
|
52
|
+
// to handle CSS chunk mounting and unmounting, which it is able to do).
|
|
53
|
+
|
|
54
|
+
if (!heap.mounted) {
|
|
55
|
+
heap.mounted = true;
|
|
51
56
|
window.CHUNK_GROUPS[chunkName].forEach(asset => {
|
|
52
57
|
if (!asset.endsWith('.css')) return;
|
|
53
58
|
const path = `${publicPath}/${asset}`;
|
|
@@ -57,8 +62,11 @@ function ClientSide({
|
|
|
57
62
|
link = document.createElement('link');
|
|
58
63
|
link.setAttribute('href', path);
|
|
59
64
|
link.setAttribute('rel', 'stylesheet');
|
|
60
|
-
const barrier = (0,
|
|
61
|
-
link.onload = barrier.resolve;
|
|
65
|
+
const barrier = (0, _Barrier.newBarrier)();
|
|
66
|
+
link.onload = barrier.resolve; // Even if the style load failed, still allow to mount the component,
|
|
67
|
+
// abeit with broken styling.
|
|
68
|
+
|
|
69
|
+
link.onerror = barrier.resolve;
|
|
62
70
|
heap.pendingStyles.push(barrier);
|
|
63
71
|
const head = document.querySelector('head');
|
|
64
72
|
head.appendChild(link);
|
|
@@ -71,7 +79,7 @@ function ClientSide({
|
|
|
71
79
|
|
|
72
80
|
const {
|
|
73
81
|
data
|
|
74
|
-
} = (0, _reactGlobalState.useAsyncData)(`dr_pogodin_react_utils___split_components.${chunkName}`,
|
|
82
|
+
} = (0, _reactGlobalState.useAsyncData)(`dr_pogodin_react_utils___split_components.${chunkName}`, getClientSide, {
|
|
75
83
|
maxage: _time.default.YEAR_MS
|
|
76
84
|
});
|
|
77
85
|
|
|
@@ -79,7 +87,8 @@ function ClientSide({
|
|
|
79
87
|
const Scene = data.default || data;
|
|
80
88
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
81
89
|
"data-chunk-name": chunkName,
|
|
82
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Scene, { ...rest
|
|
90
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Scene, { ...rest,
|
|
91
|
+
children: children
|
|
83
92
|
})
|
|
84
93
|
});
|
|
85
94
|
};
|
|
@@ -110,7 +119,9 @@ function ClientSide({
|
|
|
110
119
|
const Scene = placeholder || (() => null);
|
|
111
120
|
|
|
112
121
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
113
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Scene, {
|
|
122
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Scene, { ...rest,
|
|
123
|
+
children: children
|
|
124
|
+
})
|
|
114
125
|
});
|
|
115
126
|
}); // At this point, if we have data, the absense of heap.renderInitialized flag
|
|
116
127
|
// means we have to await styles loading; once it is done, and if we are still
|
|
@@ -119,13 +130,13 @@ function ClientSide({
|
|
|
119
130
|
if (data && !heap.renderInitialized) {
|
|
120
131
|
heap.renderInitialized = true;
|
|
121
132
|
Promise.all(heap.pendingStyles).then(() => {
|
|
122
|
-
if (heap.
|
|
133
|
+
if (heap.mounted) setRender(createRender());
|
|
123
134
|
});
|
|
124
135
|
} // This effectively fires only once, just before the component unmounts.
|
|
125
136
|
|
|
126
137
|
|
|
127
138
|
(0, _react.useEffect)(() => () => {
|
|
128
|
-
heap.
|
|
139
|
+
heap.mounted = false;
|
|
129
140
|
window.CHUNK_GROUPS[chunkName].forEach(item => {
|
|
130
141
|
if (!item.endsWith('.css')) return;
|
|
131
142
|
const path = `${publicPath}/${item}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/shared/components/CodeSplit/ClientSide.jsx"],"names":["ClientSide","chunkName","
|
|
1
|
+
{"version":3,"sources":["../../../../../src/shared/components/CodeSplit/ClientSide.jsx"],"names":["ClientSide","chunkName","children","getClientSide","placeholder","serverSide","rest","current","heap","mounted","pendingStyles","renderInitialized","publicPath","window","CHUNK_GROUPS","forEach","asset","endsWith","path","link","document","querySelector","createElement","setAttribute","barrier","onload","resolve","onerror","push","head","appendChild","dependants","Set","add","data","maxage","time","YEAR_MS","createRender","Scene","default","render","setRender","length","node","__html","innerHTML","Promise","all","then","item","delete","size","removeChild"],"mappings":"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","sourcesContent":["/**\n * Client-side implementation of a split code chunk.\n */\n/* global document, window */\n/* eslint-disable react/jsx-props-no-spreading */\n\nimport { useEffect, useRef, useState } from 'react';\n\nimport { useAsyncData } from '@dr.pogodin/react-global-state';\n\nimport { newBarrier } from 'utils/Barrier';\nimport { getBuildInfo } from 'utils/isomorphy';\nimport time from 'utils/time';\n\nexport default function ClientSide({\n chunkName,\n children,\n getClientSide,\n placeholder,\n\n // Not used in <ClientSide>, but should not go into \"...rest\" either.\n serverSide,\n\n ...rest\n}) {\n const { current: heap } = useRef({\n mounted: false,\n pendingStyles: [],\n renderInitialized: false,\n });\n\n // publicPath from buildInfo does not have a trailing slash at the end.\n const { publicPath } = getBuildInfo();\n\n // This code block initiates style loading as soon as possible, even prior to\n // the component loading, and it collects all style load / failure promises\n // into heap.pendingStyles array, allowing us to wait and thus avoid flash of\n // unstyled content issue (that's why we don't rely on mini-css-extract-plugin\n // to handle CSS chunk mounting and unmounting, which it is able to do).\n if (!heap.mounted) {\n heap.mounted = true;\n window.CHUNK_GROUPS[chunkName].forEach((asset) => {\n if (!asset.endsWith('.css')) return;\n const path = `${publicPath}/${asset}`;\n let link = document.querySelector(`link[href=\"${path}\"]`);\n if (!link) {\n link = document.createElement('link');\n link.setAttribute('href', path);\n link.setAttribute('rel', 'stylesheet');\n\n const barrier = newBarrier();\n link.onload = barrier.resolve;\n\n // Even if the style load failed, still allow to mount the component,\n // abeit with broken styling.\n link.onerror = barrier.resolve;\n\n heap.pendingStyles.push(barrier);\n\n const head = document.querySelector('head');\n head.appendChild(link);\n }\n if (!link.dependants) link.dependants = new Set([chunkName]);\n else link.dependants.add(chunkName);\n });\n }\n\n // Async loading of React component necessary to render the chunk.\n const { data } = useAsyncData(\n `dr_pogodin_react_utils___split_components.${chunkName}`,\n getClientSide,\n { maxage: time.YEAR_MS },\n );\n\n const createRender = () => {\n const Scene = data.default || data;\n return (\n <div data-chunk-name={chunkName}>\n <Scene {...rest}>\n {children}\n </Scene>\n </div>\n );\n };\n\n const [render, setRender] = useState(() => {\n // No need to await anything, we can render the final component right away.\n if (data && !heap.pendingStyles.length) {\n heap.renderInitialized = true;\n return createRender();\n }\n\n // Try to reuse the markup rendered during SSR.\n const node = document.querySelector(`[data-chunk-name=${chunkName}]`);\n if (node) {\n return (\n <div\n /* eslint-disable react/no-danger */\n dangerouslySetInnerHTML={{ __html: node.innerHTML || '' }}\n /* eslint-disable react/no-danger */\n data-chunk-name={chunkName}\n />\n );\n }\n\n // Else render placeholder, or empty div.\n const Scene = placeholder || (() => null);\n return <div><Scene {...rest}>{children}</Scene></div>;\n });\n\n // At this point, if we have data, the absense of heap.renderInitialized flag\n // means we have to await styles loading; once it is done, and if we are still\n // mounted, we can set the final render.\n if (data && !heap.renderInitialized) {\n heap.renderInitialized = true;\n Promise.all(heap.pendingStyles).then(() => {\n if (heap.mounted) setRender(createRender());\n });\n }\n\n // This effectively fires only once, just before the component unmounts.\n useEffect(() => () => {\n heap.mounted = false;\n window.CHUNK_GROUPS[chunkName].forEach((item) => {\n if (!item.endsWith('.css')) return;\n const path = `${publicPath}/${item}`;\n const link = document.querySelector(`link[href=\"${path}\"]`);\n link.dependants.delete(chunkName);\n if (!link.dependants.size) {\n const head = document.querySelector('head');\n head.removeChild(link);\n }\n });\n }, [chunkName, heap, publicPath]);\n\n return render;\n}\n"],"file":"ClientSide.js"}
|
|
@@ -24,46 +24,12 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
/* eslint-disable react/jsx-props-no-spreading */
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* A specially wrapped `require()`, which is passed as an argument into
|
|
30
|
-
* the optional `getComponentServer` prop of <{@link CodeSplit}> component.
|
|
31
|
-
* @param {string} base Path resolution base, you want to pass in `__dirname`
|
|
32
|
-
* value from the host module using `<CodeSplit>`.
|
|
33
|
-
* @param {string} path The path of module to require.
|
|
34
|
-
* @return {object} Required module.
|
|
35
|
-
*/
|
|
36
|
-
function resolveRequire(base, path) {
|
|
37
|
-
// NOTE: A part of code here attempts to correctly load ES6 modules
|
|
38
|
-
// transformed by Babel; namely if required module has "default" field,
|
|
39
|
-
// all other fields (presumed to be named exports) are attached to
|
|
40
|
-
// the "default".
|
|
41
|
-
const p = require.resolve(path, {
|
|
42
|
-
paths: [base]
|
|
43
|
-
});
|
|
44
|
-
/* eslint-disable global-require, import/no-dynamic-require */
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const {
|
|
48
|
-
default: def,
|
|
49
|
-
...named
|
|
50
|
-
} = require(p);
|
|
51
|
-
/* eslint-enable global-require, import/no-dynamic-require */
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (!def) return named;
|
|
55
|
-
Object.entries(named).forEach(([key, value]) => {
|
|
56
|
-
if (def[key]) throw Error('Conflict between default and named exports');
|
|
57
|
-
def[key] = value;
|
|
58
|
-
});
|
|
59
|
-
return def;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
27
|
function ServerSide({
|
|
63
28
|
chunkName,
|
|
64
|
-
|
|
65
|
-
|
|
29
|
+
getClientSide,
|
|
30
|
+
serverSide,
|
|
66
31
|
placeholder,
|
|
32
|
+
children,
|
|
67
33
|
...rest
|
|
68
34
|
}) {
|
|
69
35
|
/* 1. The component, or its placeholder is rendered into HTML string.
|
|
@@ -73,14 +39,14 @@ function ServerSide({
|
|
|
73
39
|
* to load the component is provider, `useAsyncData(..)` is used to
|
|
74
40
|
* attempt to load and use the component via SSR mechanics. */
|
|
75
41
|
let Scene;
|
|
76
|
-
if (
|
|
42
|
+
if (serverSide) Scene = serverSide;else {
|
|
77
43
|
// In this case we are sure the condition won't change during the rendering
|
|
78
44
|
// loop, thus we can ignore the rule.
|
|
79
45
|
|
|
80
46
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
81
47
|
const {
|
|
82
48
|
data
|
|
83
|
-
} = (0, _reactGlobalState.useAsyncData)(`dr_pogodin_react_utils___split_components.${chunkName}`,
|
|
49
|
+
} = (0, _reactGlobalState.useAsyncData)(`dr_pogodin_react_utils___split_components.${chunkName}`, getClientSide);
|
|
84
50
|
Scene = data ? data.default || data : placeholder || (() => null);
|
|
85
51
|
/* eslint-enable react-hooks/rules-of-hooks */
|
|
86
52
|
}
|
|
@@ -94,7 +60,8 @@ function ServerSide({
|
|
|
94
60
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_server2.StaticRouter, {
|
|
95
61
|
basename: pathname,
|
|
96
62
|
location: globalState.ssrContext.req.url,
|
|
97
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Scene, { ...rest
|
|
63
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Scene, { ...rest,
|
|
64
|
+
children: children
|
|
98
65
|
})
|
|
99
66
|
})
|
|
100
67
|
}));
|
|
@@ -125,14 +92,20 @@ function ServerSide({
|
|
|
125
92
|
}
|
|
126
93
|
|
|
127
94
|
ServerSide.propTypes = {
|
|
95
|
+
children: _propTypes.default.node,
|
|
128
96
|
chunkName: _propTypes.default.string.isRequired,
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
97
|
+
// Note: it is not strictly required by <ServerSide> component per se,
|
|
98
|
+
// as it is expected that in most cases "serverSide" prop should be provided,
|
|
99
|
+
// however "getClientSide" prop is still used as a fallback at the server side
|
|
100
|
+
// and also it is required by the parent splitComponent() function, so no harm
|
|
101
|
+
// to declare it as required here.
|
|
102
|
+
getClientSide: _propTypes.default.func.isRequired,
|
|
103
|
+
placeholder: _propTypes.default.elementType,
|
|
104
|
+
serverSide: _propTypes.default.elementType
|
|
132
105
|
};
|
|
133
106
|
ServerSide.defaultProps = {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
107
|
+
children: undefined,
|
|
108
|
+
placeholder: null,
|
|
109
|
+
serverSide: undefined
|
|
137
110
|
};
|
|
138
111
|
//# sourceMappingURL=ServerSide.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/shared/components/CodeSplit/ServerSide.jsx"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../../../../src/shared/components/CodeSplit/ServerSide.jsx"],"names":["ServerSide","chunkName","getClientSide","serverSide","placeholder","children","rest","Scene","data","default","globalState","pathname","html","ReactDom","renderToString","ssrContext","req","url","chunks","includes","Error","push","__html","propTypes","PT","node","string","isRequired","func","elementType","defaultProps","undefined"],"mappings":";;;;;;;;;AAKA;;AACA;;AAEA;;AAMA;;AACA;;;;AAfA;AACA;AACA;;AACA;AAce,SAASA,UAAT,CAAoB;AACjCC,EAAAA,SADiC;AAEjCC,EAAAA,aAFiC;AAGjCC,EAAAA,UAHiC;AAIjCC,EAAAA,WAJiC;AAKjCC,EAAAA,QALiC;AAMjC,KAAGC;AAN8B,CAApB,EAOZ;AACD;AACF;AACA;AACA;AACA;AACA;AACE,MAAIC,KAAJ;AACA,MAAIJ,UAAJ,EAAgBI,KAAK,GAAGJ,UAAR,CAAhB,KACK;AACH;AACA;;AACA;AACA,UAAM;AAAEK,MAAAA;AAAF,QAAW,oCACd,6CAA4CP,SAAU,EADxC,EAEfC,aAFe,CAAjB;AAIAK,IAAAA,KAAK,GAAGC,IAAI,GAAIA,IAAI,CAACC,OAAL,IAAgBD,IAApB,GAA6BJ,WAAW,KAAK,MAAM,IAAX,CAApD;AACA;AACD;AAED,QAAMM,WAAW,GAAG,uCAApB;AACA,QAAM;AAAEC,IAAAA;AAAF,MAAe,qCAAgB,EAAhB,CAArB;;AACA,QAAMC,IAAI,GAAGC,gBAASC,cAAT,eACX,qBAAC,qCAAD;AAAqB,IAAA,UAAU,EAAEJ,WAAjC;AAAA,2BACE,qBAAC,qBAAD;AACE,MAAA,QAAQ,EAAEC,QADZ;AAEE,MAAA,QAAQ,EAAED,WAAW,CAACK,UAAZ,CAAuBC,GAAvB,CAA2BC,GAFvC;AAAA,6BAIE,qBAAC,KAAD,OAAWX,IAAX;AAAA,kBACGD;AADH;AAJF;AADF,IADW,CAAb;AAaA;;;AACA,QAAM;AAAEa,IAAAA;AAAF,MAAaR,WAAW,CAACK,UAA/B;;AACA,MAAIG,MAAM,CAACC,QAAP,CAAgBlB,SAAhB,CAAJ,EAAgC;AAC9B,UAAM,IAAImB,KAAJ,CAAW,oCAAmCnB,SAAU,GAAxD,CAAN;AACD,GAFD,MAEOiB,MAAM,CAACG,IAAP,CAAYpB,SAAZ;AAEP;AACF;AACA;;AACE;;;AACA,sBACE;AACE,IAAA,uBAAuB,EAAE;AAAEqB,MAAAA,MAAM,EAAEV;AAAV,KAD3B;AAEE,uBAAiBX;AAFnB,IADF;AAMA;AACD;;AAEDD,UAAU,CAACuB,SAAX,GAAuB;AACrBlB,EAAAA,QAAQ,EAAEmB,mBAAGC,IADQ;AAErBxB,EAAAA,SAAS,EAAEuB,mBAAGE,MAAH,CAAUC,UAFA;AAIrB;AACA;AACA;AACA;AACA;AACAzB,EAAAA,aAAa,EAAEsB,mBAAGI,IAAH,CAAQD,UATF;AAWrBvB,EAAAA,WAAW,EAAEoB,mBAAGK,WAXK;AAYrB1B,EAAAA,UAAU,EAAEqB,mBAAGK;AAZM,CAAvB;AAeA7B,UAAU,CAAC8B,YAAX,GAA0B;AACxBzB,EAAAA,QAAQ,EAAE0B,SADc;AAExB3B,EAAAA,WAAW,EAAE,IAFW;AAGxBD,EAAAA,UAAU,EAAE4B;AAHY,CAA1B","sourcesContent":["/**\n * Server-side implementation.\n */\n/* eslint-disable react/jsx-props-no-spreading */\n\nimport ReactDom from 'react-dom/server';\nimport PT from 'prop-types';\n\nimport {\n getGlobalState,\n GlobalStateProvider,\n useAsyncData,\n} from '@dr.pogodin/react-global-state';\n\nimport { useResolvedPath } from 'react-router-dom';\nimport { StaticRouter } from 'react-router-dom/server';\n\nexport default function ServerSide({\n chunkName,\n getClientSide,\n serverSide,\n placeholder,\n children,\n ...rest\n}) {\n /* 1. The component, or its placeholder is rendered into HTML string.\n * The component is wrapped into <GlobalStateProvider>, and <StaticRouter>\n * to ensure that global state, and react router will work inside\n * the component, if present there. Also, if no server-side (sync) way\n * to load the component is provider, `useAsyncData(..)` is used to\n * attempt to load and use the component via SSR mechanics. */\n let Scene;\n if (serverSide) Scene = serverSide;\n else {\n // In this case we are sure the condition won't change during the rendering\n // loop, thus we can ignore the rule.\n /* eslint-disable react-hooks/rules-of-hooks */\n const { data } = useAsyncData(\n `dr_pogodin_react_utils___split_components.${chunkName}`,\n getClientSide,\n );\n Scene = data ? (data.default || data) : (placeholder || (() => null));\n /* eslint-enable react-hooks/rules-of-hooks */\n }\n\n const globalState = getGlobalState();\n const { pathname } = useResolvedPath('');\n const html = ReactDom.renderToString((\n <GlobalStateProvider stateProxy={globalState}>\n <StaticRouter\n basename={pathname}\n location={globalState.ssrContext.req.url}\n >\n <Scene {...rest}>\n {children}\n </Scene>\n </StaticRouter>\n </GlobalStateProvider>\n ));\n\n /* 2. `chunks` array is used to record CSS chunks to inject. */\n const { chunks } = globalState.ssrContext;\n if (chunks.includes(chunkName)) {\n throw new Error(`CodeSplit: chunk name clash for (${chunkName})`);\n } else chunks.push(chunkName);\n\n /* The result is rendered using the container with `dangerouslySetInnerHTML`\n * to allow reproduce the same rendering result at the client side, even prior\n * to the async loading of the split code. */\n /* eslint-disable react/no-danger */\n return (\n <div\n dangerouslySetInnerHTML={{ __html: html }}\n data-chunk-name={chunkName}\n />\n );\n /* eslint-enable react/no-danger */\n}\n\nServerSide.propTypes = {\n children: PT.node,\n chunkName: PT.string.isRequired,\n\n // Note: it is not strictly required by <ServerSide> component per se,\n // as it is expected that in most cases \"serverSide\" prop should be provided,\n // however \"getClientSide\" prop is still used as a fallback at the server side\n // and also it is required by the parent splitComponent() function, so no harm\n // to declare it as required here.\n getClientSide: PT.func.isRequired,\n\n placeholder: PT.elementType,\n serverSide: PT.elementType,\n};\n\nServerSide.defaultProps = {\n children: undefined,\n placeholder: null,\n serverSide: undefined,\n};\n"],"file":"ServerSide.js"}
|
|
@@ -7,19 +7,15 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
});
|
|
8
8
|
exports.default = void 0;
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _webpack = require("../../utils/webpack");
|
|
11
11
|
|
|
12
12
|
var _ClientSide = _interopRequireDefault(require("./ClientSide"));
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// This module exposes client- or server-side version of the <CodeSplit>
|
|
15
|
+
// component, depending on the environment. That component is used internally
|
|
16
|
+
// to implement the code splitting. Library users should use splitComponent()
|
|
17
|
+
// function to use the code splitting (see "utils/splitComponent.js").
|
|
18
|
+
var _default = (0, _webpack.requireWeak)("./ServerSide", __dirname) || _ClientSide.default;
|
|
15
19
|
|
|
16
|
-
try {
|
|
17
|
-
Component = _utils.isomorphy.IS_SERVER_SIDE && _utils.webpack.requireWeak(`${__dirname}/ServerSide`);
|
|
18
|
-
} catch (error) {
|
|
19
|
-
Component = undefined;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (!Component) Component = _ClientSide.default;
|
|
23
|
-
var _default = Component;
|
|
24
20
|
exports.default = _default;
|
|
25
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/shared/components/CodeSplit/index.
|
|
1
|
+
{"version":3,"sources":["../../../../../src/shared/components/CodeSplit/index.jsx"],"names":["__dirname","ClientSide"],"mappings":";;;;;;;;;AAKA;;AACA;;AANA;AACA;AACA;AACA;eAKe,0CAA4BA,SAA5B,KAA0CC,mB","sourcesContent":["// This module exposes client- or server-side version of the <CodeSplit>\n// component, depending on the environment. That component is used internally\n// to implement the code splitting. Library users should use splitComponent()\n// function to use the code splitting (see \"utils/splitComponent.js\").\n\nimport { requireWeak } from 'utils/webpack';\nimport ClientSide from './ClientSide';\n\nexport default requireWeak('./ServerSide', __dirname) || ClientSide;\n"],"file":"index.js"}
|
|
@@ -23,12 +23,6 @@ Object.defineProperty(exports, "Checkbox", {
|
|
|
23
23
|
return _Checkbox.default;
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
|
-
Object.defineProperty(exports, "CodeSplit", {
|
|
27
|
-
enumerable: true,
|
|
28
|
-
get: function () {
|
|
29
|
-
return _CodeSplit.default;
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
26
|
Object.defineProperty(exports, "Dropdown", {
|
|
33
27
|
enumerable: true,
|
|
34
28
|
get: function () {
|
|
@@ -108,8 +102,6 @@ var _Checkbox = _interopRequireDefault(require("./Checkbox"));
|
|
|
108
102
|
|
|
109
103
|
var _client = _interopRequireDefault(require("../../client"));
|
|
110
104
|
|
|
111
|
-
var _CodeSplit = _interopRequireDefault(require("./CodeSplit"));
|
|
112
|
-
|
|
113
105
|
var _Dropdown = _interopRequireDefault(require("./Dropdown"));
|
|
114
106
|
|
|
115
107
|
var _Input = _interopRequireDefault(require("./Input"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/components/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/components/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA","sourcesContent":["/**\n * Just an aggregation of all exported components into a single module.\n */\n\nexport { default as Button } from 'components/Button';\nexport { default as Checkbox } from 'components/Checkbox';\nexport { default as client } from 'client';\nexport { default as Dropdown } from 'components/Dropdown';\nexport { default as Input } from 'components/Input';\nexport { default as Link } from 'components/Link';\nexport { default as PageLayout } from 'components/PageLayout';\nexport { default as MetaTags } from 'components/MetaTags';\nexport { default as Modal, BaseModal } from 'components/Modal';\nexport { default as NavLink } from 'components/NavLink';\nexport { default as ScalableRect } from 'components/ScalableRect';\nexport { default as Throbber } from 'components/Throbber';\nexport { default as WithTooltip } from 'components/WithTooltip';\nexport { default as YouTubeVideo } from 'components/YouTubeVideo';\n"],"file":"index.js"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _Barrier = require("./Barrier");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Implements a simple semaphore for async code logic.
|
|
12
|
+
*/
|
|
13
|
+
class Semaphore {
|
|
14
|
+
constructor(ready) {
|
|
15
|
+
this.#ready = !!ready;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get ready() {
|
|
19
|
+
return this.#ready;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setReady(ready) {
|
|
23
|
+
const bool = !!ready;
|
|
24
|
+
|
|
25
|
+
if (this.#ready !== bool) {
|
|
26
|
+
this.#ready = bool;
|
|
27
|
+
if (bool && !this.#draining) this.#drainQueue();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Waits until the semaphore is ready, and marks it as non-ready (seizes it).
|
|
32
|
+
* @return {Promise}
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async seize() {
|
|
37
|
+
await this.waitReady();
|
|
38
|
+
this.setReady(false);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async waitReady() {
|
|
42
|
+
if (!this.#ready || this.#queue.length) {
|
|
43
|
+
const barrier = (0, _Barrier.newBarrier)();
|
|
44
|
+
this.#queue.push(barrier);
|
|
45
|
+
await barrier;
|
|
46
|
+
}
|
|
47
|
+
} // Private members below this point.
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* If semaphore is ready, it releases the next barrier in the queue, if any,
|
|
51
|
+
* and reschedules itself for a call in the next event loop iteration.
|
|
52
|
+
* Otherwise, it breaks the queue draining loop, which will be restarted
|
|
53
|
+
* the next time the semaphore is set ready.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
#drainQueue() {
|
|
58
|
+
if (this.#ready && this.#queue.length) {
|
|
59
|
+
const next = this.#queue.shift();
|
|
60
|
+
next.resolve(); // Re-schedules itself for the next event loop iteration.
|
|
61
|
+
|
|
62
|
+
if (this.#queue.length) {
|
|
63
|
+
setTimeout(this.#drainQueue.bind(this));
|
|
64
|
+
this.#draining = true;
|
|
65
|
+
return; // Exit here to avoid the drain loop termination below.
|
|
66
|
+
}
|
|
67
|
+
} // Cleans up for the drain loop termination.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
this.#draining = false;
|
|
71
|
+
} // "true" when the drain queue process is running (and thus no need to start
|
|
72
|
+
// a new one).
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
#draining = false; // The array of barriers set for each async code flow awaiting for
|
|
76
|
+
// the Semaphore to become ready.
|
|
77
|
+
|
|
78
|
+
#queue = [];
|
|
79
|
+
#ready;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
exports.default = Semaphore;
|
|
83
|
+
//# sourceMappingURL=Semaphore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/utils/Semaphore.js"],"names":["Semaphore","constructor","ready","setReady","bool","draining","drainQueue","seize","waitReady","queue","length","barrier","push","next","shift","resolve","setTimeout","bind"],"mappings":";;;;;;;AAAA;;AAEA;AACA;AACA;AACe,MAAMA,SAAN,CAAgB;AAC7BC,EAAAA,WAAW,CAACC,KAAD,EAAQ;AACjB,SAAK,CAACA,KAAN,GAAc,CAAC,CAACA,KAAhB;AACD;;AAEQ,MAALA,KAAK,GAAG;AAAE,WAAO,KAAK,CAACA,KAAb;AAAqB;;AAEnCC,EAAAA,QAAQ,CAACD,KAAD,EAAQ;AACd,UAAME,IAAI,GAAG,CAAC,CAACF,KAAf;;AACA,QAAI,KAAK,CAACA,KAAN,KAAgBE,IAApB,EAA0B;AACxB,WAAK,CAACF,KAAN,GAAcE,IAAd;AACA,UAAIA,IAAI,IAAI,CAAC,KAAK,CAACC,QAAnB,EAA6B,KAAK,CAACC,UAAN;AAC9B;AACF;AAED;AACF;AACA;AACA;;;AACa,QAALC,KAAK,GAAG;AACZ,UAAM,KAAKC,SAAL,EAAN;AACA,SAAKL,QAAL,CAAc,KAAd;AACD;;AAEc,QAATK,SAAS,GAAG;AAChB,QAAI,CAAC,KAAK,CAACN,KAAP,IAAgB,KAAK,CAACO,KAAN,CAAYC,MAAhC,EAAwC;AACtC,YAAMC,OAAO,GAAG,0BAAhB;AACA,WAAK,CAACF,KAAN,CAAYG,IAAZ,CAAiBD,OAAjB;AACA,YAAMA,OAAN;AACD;AACF,GA9B4B,CAgC7B;;AAEA;AACF;AACA;AACA;AACA;AACA;;;AACE,GAACL,UAAU,GAAG;AACZ,QAAI,KAAK,CAACJ,KAAN,IAAe,KAAK,CAACO,KAAN,CAAYC,MAA/B,EAAuC;AACrC,YAAMG,IAAI,GAAG,KAAK,CAACJ,KAAN,CAAYK,KAAZ,EAAb;AACAD,MAAAA,IAAI,CAACE,OAAL,GAFqC,CAIrC;;AACA,UAAI,KAAK,CAACN,KAAN,CAAYC,MAAhB,EAAwB;AACtBM,QAAAA,UAAU,CAAC,KAAK,CAACV,UAAN,CAAiBW,IAAjB,CAAsB,IAAtB,CAAD,CAAV;AACA,aAAK,CAACZ,QAAN,GAAiB,IAAjB;AACA,eAHsB,CAGd;AACT;AACF,KAXW,CAaZ;;;AACA,SAAK,CAACA,QAAN,GAAiB,KAAjB;AACD,GAvD4B,CAyD7B;AACA;;;AACA,GAACA,QAAD,GAAY,KAAZ,CA3D6B,CA6D7B;AACA;;AACA,GAACI,KAAD,GAAS,EAAT;AAEA,GAACP,KAAD;AAjE6B","sourcesContent":["import { newBarrier } from './Barrier';\n\n/**\n * Implements a simple semaphore for async code logic.\n */\nexport default class Semaphore {\n constructor(ready) {\n this.#ready = !!ready;\n }\n\n get ready() { return this.#ready; }\n\n setReady(ready) {\n const bool = !!ready;\n if (this.#ready !== bool) {\n this.#ready = bool;\n if (bool && !this.#draining) this.#drainQueue();\n }\n }\n\n /**\n * Waits until the semaphore is ready, and marks it as non-ready (seizes it).\n * @return {Promise}\n */\n async seize() {\n await this.waitReady();\n this.setReady(false);\n }\n\n async waitReady() {\n if (!this.#ready || this.#queue.length) {\n const barrier = newBarrier();\n this.#queue.push(barrier);\n await barrier;\n }\n }\n\n // Private members below this point.\n\n /**\n * If semaphore is ready, it releases the next barrier in the queue, if any,\n * and reschedules itself for a call in the next event loop iteration.\n * Otherwise, it breaks the queue draining loop, which will be restarted\n * the next time the semaphore is set ready.\n */\n #drainQueue() {\n if (this.#ready && this.#queue.length) {\n const next = this.#queue.shift();\n next.resolve();\n\n // Re-schedules itself for the next event loop iteration.\n if (this.#queue.length) {\n setTimeout(this.#drainQueue.bind(this));\n this.#draining = true;\n return; // Exit here to avoid the drain loop termination below.\n }\n }\n\n // Cleans up for the drain loop termination.\n this.#draining = false;\n }\n\n // \"true\" when the drain queue process is running (and thus no need to start\n // a new one).\n #draining = false;\n\n // The array of barriers set for each async code flow awaiting for\n // the Semaphore to become ready.\n #queue = [];\n\n #ready;\n}\n"],"file":"Semaphore.js"}
|
|
@@ -5,14 +5,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var _isomorphy = require("./isomorphy");
|
|
9
|
-
|
|
10
8
|
var _webpack = require("./webpack");
|
|
11
9
|
|
|
12
10
|
/* global window */
|
|
13
11
|
|
|
14
12
|
/* eslint-disable global-require */
|
|
15
|
-
var _default =
|
|
13
|
+
var _default = (0, _webpack.requireWeak)('config') || window.CONFIG;
|
|
16
14
|
/* eslint-enable global-require */
|
|
17
15
|
|
|
18
16
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/utils/config.js"],"names":["
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/utils/config.js"],"names":["window","CONFIG"],"mappings":";;;;;;;AAEA;;AAFA;;AAIA;eACe,0BAAY,QAAZ,KAAyBA,MAAM,CAACC,M;AAC/C","sourcesContent":["/* global window */\n\nimport { requireWeak } from './webpack';\n\n/* eslint-disable global-require */\nexport default requireWeak('config') || window.CONFIG;\n/* eslint-enable global-require */\n"],"file":"config.js"}
|