@anansi/core 0.11.2 → 0.12.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.12.0](https://github.com/ntucker/anansi/compare/@anansi/core@0.11.2...@anansi/core@0.12.0) (2022-06-15)
7
+
8
+
9
+ ### 🚀 Features
10
+
11
+ * Add onError option to laySpouts ([a0ef72b](https://github.com/ntucker/anansi/commit/a0ef72bcaab1440a3d997d21636f81ca767a5a1c))
12
+
13
+
14
+ ### 💅 Enhancement
15
+
16
+ * Don't crash devserver on compiler errors ([3c764e4](https://github.com/ntucker/anansi/commit/3c764e4dd67a57409c64ff7dd144386623a1d93f))
17
+
18
+
19
+ ### 📦 Package
20
+
21
+ * Update babel monorepo to v7.18.5 ([#1545](https://github.com/ntucker/anansi/issues/1545)) ([aaaa8bc](https://github.com/ntucker/anansi/commit/aaaa8bcaa4d9188e9671ee31dc09b7aa9e3ce988))
22
+
23
+
24
+
6
25
  ### [0.11.2](https://github.com/ntucker/anansi/compare/@anansi/core@0.11.1...@anansi/core@0.11.2) (2022-06-13)
7
26
 
8
27
 
package/dist/server.js CHANGED
@@ -68,67 +68,59 @@ var external_crypto_default = /*#__PURE__*/__webpack_require__.n(external_crypto
68
68
 
69
69
 
70
70
  function laySpouts(spouts, {
71
- timeoutMS = 200
71
+ timeoutMS = 200,
72
+ onError
72
73
  } = {}) {
73
74
  const render = async (clientManifest, req, res) => {
74
75
  const nonce = external_crypto_default().randomBytes(16).toString('base64');
75
- const {
76
- app
77
- } = await spouts({
78
- clientManifest,
79
- req,
80
- res,
81
- nonce
82
- });
83
- let didError = false;
84
- const {
85
- pipe,
86
- abort
87
- } = (0,server_namespaceObject.renderToPipeableStream)(app,
88
- /*
89
- This is not documented, so included the types here for reference:
90
- type Options = {|
91
- identifierPrefix?: string,
92
- namespaceURI?: string,
93
- nonce?: string,
94
- bootstrapScriptContent?: string,
95
- bootstrapScripts?: Array<string>,
96
- bootstrapModules?: Array<string>,
97
- progressiveChunkSize?: number,
98
- onShellReady?: () => void,
99
- onShellError?: () => void,
100
- onAllReady?: () => void,
101
- onError?: (error: mixed) => void,
102
- |};
103
- */
104
- {
105
- nonce,
106
-
107
- //bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),
108
- onShellReady() {
109
- //managers.forEach(manager => manager.cleanup());
110
- // If something errored before we started streaming, we set the error code appropriately.
111
- res.statusCode = didError ? 500 : 200;
112
- res.setHeader('Content-type', 'text/html');
113
- pipe(res);
114
- },
115
-
116
- onShellError() {
117
- didError = true;
118
- res.statusCode = 500;
119
- pipe(res);
120
- },
121
-
122
- onError(x) {
123
- didError = true;
124
- console.error(x);
125
- res.statusCode = 500; //pipe(res); Removing this avoids, "React currently only supports piping to one writable stream."
126
- }
127
76
 
128
- }); // Abandon and switch to client rendering if enough time passes.
129
- // Try lowering this to see the client recover.
77
+ try {
78
+ const {
79
+ app
80
+ } = await spouts({
81
+ clientManifest,
82
+ req,
83
+ res,
84
+ nonce
85
+ });
86
+ let didError = false;
87
+ const {
88
+ pipe,
89
+ abort
90
+ } = (0,server_namespaceObject.renderToPipeableStream)(app, {
91
+ nonce,
92
+
93
+ //bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),
94
+ onShellReady() {
95
+ //managers.forEach(manager => manager.cleanup());
96
+ // If something errored before we started streaming, we set the error code appropriately.
97
+ res.statusCode = didError ? 500 : 200;
98
+ res.setHeader('Content-type', 'text/html');
99
+ pipe(res);
100
+ },
101
+
102
+ onShellError() {
103
+ didError = true;
104
+ res.statusCode = 500;
105
+ pipe(res);
106
+ },
107
+
108
+ onError(e) {
109
+ didError = true;
110
+ console.error(e);
111
+ res.statusCode = 500; //pipe(res); Removing this avoids, "React currently only supports piping to one writable stream."
112
+
113
+ if (onError) onError(e);
114
+ }
115
+
116
+ }); // Abandon and switch to client rendering if enough time passes.
117
+ // Try lowering this to see the client recover.
130
118
 
131
- setTimeout(abort, timeoutMS);
119
+ setTimeout(() => abort(`Timeout of ${timeoutMS}ms exceeded`), timeoutMS);
120
+ } catch (e) {
121
+ if (onError) onError(e);
122
+ throw e;
123
+ }
132
124
  };
133
125
 
134
126
  return render;
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","mappings":"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","sources":["/home/ntucker/src/anansi/packages/core/webpack/bootstrap","/home/ntucker/src/anansi/packages/core/webpack/runtime/compat get default export","/home/ntucker/src/anansi/packages/core/webpack/runtime/define property getters","/home/ntucker/src/anansi/packages/core/webpack/runtime/hasOwnProperty shorthand","/home/ntucker/src/anansi/packages/core/webpack/runtime/make namespace object","/home/ntucker/src/anansi/packages/core/external commonjs \"react-dom/server\"","/home/ntucker/src/anansi/packages/core/external node-commonjs \"crypto\"","/home/ntucker/src/anansi/packages/core/src/laySpouts.tsx","/home/ntucker/src/anansi/packages/core/external commonjs \"react\"","/home/ntucker/src/anansi/packages/core/src/spouts/csp.ts","/home/ntucker/src/anansi/packages/core/src/spouts/DocumentComponent.tsx","/home/ntucker/src/anansi/packages/core/src/spouts/document.server.tsx","/home/ntucker/src/anansi/packages/core/external commonjs \"@rest-hooks/core\"","/home/ntucker/src/anansi/packages/core/external commonjs \"rest-hooks\"","/home/ntucker/src/anansi/packages/core/external commonjs \"redux\"","/home/ntucker/src/anansi/packages/core/src/spouts/rhHelp.tsx","/home/ntucker/src/anansi/packages/core/src/spouts/restHooks.server.tsx","/home/ntucker/src/anansi/packages/core/external commonjs \"@anansi/router\"","/home/ntucker/src/anansi/packages/core/external commonjs \"history\"","/home/ntucker/src/anansi/packages/core/src/spouts/router.server.tsx","/home/ntucker/src/anansi/packages/core/src/spouts/prefetch.server.tsx","/home/ntucker/src/anansi/packages/core/src/spouts/json.server.tsx","/home/ntucker/src/anansi/packages/core/src/index.server.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"react-dom/server\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"crypto\");","import { renderToPipeableStream as reactRender } from 'react-dom/server';\nimport crypto from 'crypto';\n\nimport { Render } from './scripts/types';\nimport { ServerProps } from './spouts/types';\n\nexport default function laySpouts(\n spouts: (props: ServerProps) => Promise<{\n app: JSX.Element;\n }>,\n { timeoutMS = 200 }: { timeoutMS?: number } = {},\n) {\n const render: Render = async (clientManifest, req, res) => {\n const nonce = crypto.randomBytes(16).toString('base64');\n\n const { app } = await spouts({ clientManifest, req, res, nonce });\n let didError = false;\n const { pipe, abort } = reactRender(\n app,\n /*\n This is not documented, so included the types here for reference:\ntype Options = {|\n identifierPrefix?: string,\n namespaceURI?: string,\n nonce?: string,\n bootstrapScriptContent?: string,\n bootstrapScripts?: Array<string>,\n bootstrapModules?: Array<string>,\n progressiveChunkSize?: number,\n onShellReady?: () => void,\n onShellError?: () => void,\n onAllReady?: () => void,\n onError?: (error: mixed) => void,\n|};\n */\n {\n nonce,\n //bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),\n onShellReady() {\n //managers.forEach(manager => manager.cleanup());\n // If something errored before we started streaming, we set the error code appropriately.\n res.statusCode = didError ? 500 : 200;\n res.setHeader('Content-type', 'text/html');\n pipe(res);\n },\n onShellError() {\n didError = true;\n res.statusCode = 500;\n pipe(res);\n },\n onError(x: any) {\n didError = true;\n console.error(x);\n res.statusCode = 500;\n //pipe(res); Removing this avoids, \"React currently only supports piping to one writable stream.\"\n },\n },\n );\n // Abandon and switch to client rendering if enough time passes.\n // Try lowering this to see the client recover.\n setTimeout(abort, timeoutMS);\n };\n return render;\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"react\");","export interface Policy {\n [directive: string]: string | string[];\n}\n\n// TODO: memoize this\nexport function buildPolicy(policyObj: Policy) {\n return Object.keys(policyObj)\n .map(key => {\n const val = Array.isArray(policyObj[key])\n ? [...new Set(policyObj[key]).values()].filter(v => v).join(' ')\n : policyObj[key];\n\n // move strict dynamic to the end of the policy if it exists to be backwards compatible with csp2\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#strict-dynamic\n if (typeof val === 'string' && val.includes(\"'strict-dynamic'\")) {\n const newVal = `${val\n .replace(/\\s?'strict-dynamic'\\s?/gi, ' ')\n .trim()} 'strict-dynamic'`;\n return `${key} ${newVal}`;\n }\n\n return `${key} ${val}`;\n })\n .join('; ');\n}\n","import type { Policy } from './csp';\nimport { buildPolicy } from './csp';\n\ntype Props = {\n children: React.ReactNode;\n assets: { href: string; as?: string; rel?: string }[];\n head: React.ReactNode;\n scripts: React.ReactNode;\n title: string;\n rootId: string;\n charSet: string;\n csPolicy?: Policy;\n nonce?: string | undefined;\n};\n\nexport default function Document({\n assets,\n head,\n children,\n title,\n rootId,\n charSet,\n csPolicy,\n nonce,\n scripts,\n}: Props) {\n let cspMeta: null | React.ReactNode = null;\n if (csPolicy) {\n // add nonce to policy\n const policy = {\n ...csPolicy,\n };\n if (\n nonce &&\n // nonces negate 'unsafe-inline' so do not add it if that directive exists\n (!policy['script-src'] ||\n !policy['script-src'].includes(\"'unsafe-inline'\"))\n ) {\n if (typeof policy['script-src'] === 'string') {\n policy['script-src'] = [policy['script-src'], `'nonce-${nonce}'`];\n } else {\n policy['script-src'] = [...policy['script-src'], `'nonce-${nonce}'`];\n }\n }\n cspMeta = (\n <meta httpEquiv=\"Content-Security-Policy\" content={buildPolicy(policy)} />\n );\n }\n return (\n <html>\n <head>\n <meta charSet={charSet} />\n {cspMeta}\n {head}\n {assets.map((asset, i) => (\n <link key={i} rel=\"preload\" {...asset} />\n ))}\n <title>{title}</title>\n </head>\n <body>\n <div id={rootId}>{children}</div>\n {scripts}\n {assets\n .filter(({ href }) => href.endsWith('.js'))\n .map(({ href }, i) => (\n <script key={i} src={href} async />\n ))}\n </body>\n </html>\n );\n}\nDocument.defaultProps = {\n head: (\n <>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <link\n rel=\"shortcut icon\"\n href={`${process.env.WEBPACK_PUBLIC_PATH ?? '/'}favicon.ico`}\n />\n </>\n ),\n charSet: 'utf-8',\n rootId: 'anansi-root',\n scripts: null,\n};\n","import React from 'react';\nimport type { Route } from '@anansi/router';\nimport { StatsChunkGroup } from 'webpack';\n\nimport type { ServerProps, ResolveProps } from './types';\nimport type { Policy } from './csp';\nimport Document from './DocumentComponent';\n\ntype NeededProps = {\n matchedRoutes: Route<any>[];\n title?: string;\n scripts?: React.ReactNode[];\n} & ResolveProps;\n\nexport default function DocumentSpout(options: {\n head?: React.ReactNode;\n title: string;\n rootId?: string;\n charSet?: string;\n csPolicy?: Policy;\n}) {\n return function <T extends NeededProps>(\n next: (props: ServerProps) => Promise<T>,\n ) {\n return async (props: ServerProps) => {\n const nextProps = await next(props);\n\n const publicPath = props.clientManifest.publicPath;\n\n if (\n Object.keys(props.clientManifest?.entrypoints ?? {}).length < 1 ||\n publicPath === undefined\n )\n throw new Error('Manifest missing entries needed');\n\n // TODO: consider using this package for build stats in future:\n // https://github.com/facebook/react/tree/main/packages/react-server-dom-webpack\n const assetMap = (assets: { name: string; size?: number }[]) =>\n assets.map(({ name }) => `${publicPath}${name}`);\n\n const assetList: string[] = [];\n Object.values(props.clientManifest?.entrypoints ?? {}).forEach(\n entrypoint => {\n assetList.push(...assetMap(entrypoint.assets ?? []));\n },\n );\n new Set(\n assetMap(\n Object.values(props.clientManifest.namedChunkGroups ?? {})\n .filter(({ name }) =>\n nextProps.matchedRoutes.some(route => name?.includes(route.name)),\n )\n .flatMap(chunk => [\n ...(chunk.assets ?? []),\n // any chunk preloads\n ...childrenAssets(chunk),\n ]),\n ),\n ).forEach(asset => assetList.push(asset));\n\n // find additional assets to preload based on matched route\n const assets: {\n href: string;\n as?: string | undefined;\n rel?: string | undefined;\n }[] = assetList\n .filter(asset => !asset.endsWith('.hot-update.js'))\n .map(asset =>\n asset.endsWith('.css')\n ? { href: asset, rel: 'stylesheet' }\n : asset.endsWith('.js')\n ? { href: asset, as: 'script' }\n : { href: asset },\n );\n\n return {\n ...nextProps,\n app: (\n <Document\n {...options}\n title={nextProps.title ?? options.title}\n assets={assets}\n rootId={options.rootId}\n nonce={props.nonce}\n csPolicy={options.csPolicy}\n scripts={nextProps.scripts}\n >\n {nextProps.app}\n </Document>\n ),\n };\n };\n };\n}\n\nfunction childrenAssets(chunk: StatsChunkGroup) {\n return chunk.children\n ? Object.values(chunk.children).flatMap(preload =>\n preload.flatMap(c => c.assets ?? []),\n )\n : [];\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@rest-hooks/core\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"rest-hooks\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"redux\");","import { ExternalCacheProvider, PromiseifyMiddleware } from 'rest-hooks';\nimport {\n Controller,\n createReducer,\n initialState,\n Manager,\n applyManager,\n NetworkManager,\n} from '@rest-hooks/core';\nimport { createStore, applyMiddleware } from 'redux';\n\n// TODO: Rework this and upstream to rest hooks\nexport function createPersistedStore(managers?: Manager[]) {\n const controller = new Controller();\n managers = managers ?? [new NetworkManager()];\n const reducer = createReducer(controller);\n const enhancer = applyMiddleware(\n ...applyManager(managers, controller),\n PromiseifyMiddleware as any,\n );\n const store = createStore(reducer, initialState as any, enhancer);\n managers.forEach(manager => manager.init?.(store.getState()));\n\n const selector = (state: any) => state;\n function ServerCacheProvider({ children }: { children: React.ReactNode }) {\n return (\n <ExternalCacheProvider\n store={store}\n selector={selector}\n controller={controller}\n >\n {children}\n </ExternalCacheProvider>\n );\n }\n return [ServerCacheProvider, controller, store] as const;\n}\n","import { Manager, NetworkManager } from '@rest-hooks/core';\n\nimport { createPersistedStore } from './rhHelp';\nimport type { ResolveProps, ServerProps } from './types';\n\ntype NeededProps = { initData?: Record<string, () => unknown> } & ResolveProps;\n\nexport default function restHooksSpout(\n options: {\n getManagers: () => Manager[];\n } = { getManagers: () => [new NetworkManager()] },\n) {\n return function <T extends NeededProps>(\n next: (props: ServerProps) => Promise<T>,\n ) {\n return async (props: ServerProps) => {\n const [ServerCacheProvider, controller, store] = createPersistedStore(\n options.getManagers(),\n );\n\n const nextProps = await next(props);\n\n return {\n ...nextProps,\n controller,\n initData: {\n ...nextProps.initData,\n resthooks: () => store.getState(),\n },\n app: <ServerCacheProvider>{nextProps.app}</ServerCacheProvider>,\n };\n };\n };\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@anansi/router\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"history\");","import { Route, RouteProvider, RouteController } from '@anansi/router';\nimport React from 'react';\nimport { createMemoryHistory } from 'history';\n\nimport type { ResolveProps, ServerProps, CreateRouter } from './types';\n\ntype NeededProps = ResolveProps;\n\nexport default function routerSpout<ResolveWith>(options: {\n resolveWith?: any;\n useResolveWith: () => ResolveWith;\n createRouter: CreateRouter<ResolveWith>;\n}) {\n const createRouteComponent = (\n router: RouteController<Route<ResolveWith, any>>,\n ) =>\n function Router({ children }: { children: React.ReactNode }) {\n const resolveWith = options.useResolveWith();\n\n return (\n <RouteProvider router={router} resolveWith={resolveWith}>\n {children}\n </RouteProvider>\n );\n };\n\n return function <T extends NeededProps>(\n next: (props: ServerProps) => Promise<T>,\n ) {\n return async (props: ServerProps) => {\n const url = props.req.url || '';\n const router = options.createRouter(\n createMemoryHistory({ initialEntries: [url] }),\n );\n const matchedRoutes: Route<ResolveWith>[] = router.getMatchedRoutes(url);\n\n const nextProps = await next(props);\n\n const Router = createRouteComponent(router);\n return {\n ...nextProps,\n matchedRoutes,\n router,\n app: <Router>{nextProps.app}</Router>,\n };\n };\n };\n}\n","import { Route } from '@anansi/router';\n\nimport type { ResolveProps, ServerProps } from './types';\n\ntype NeededProps<RouteWith> = {\n matchedRoutes: Route<RouteWith>[];\n} & ResolveProps;\n\nexport default function prefetchSpout<F extends string>(field: F) {\n return function <RouteWith, T extends NeededProps<RouteWith>>(\n next: (props: ServerProps) => Promise<\n {\n [K in F]: RouteWith;\n } & T\n >,\n ) {\n return async (props: ServerProps) => {\n const nextProps = await next(props);\n\n try {\n const toFetch: Promise<unknown>[] = [];\n nextProps.matchedRoutes.forEach(route => {\n if (typeof route.resolveData === 'function') {\n toFetch.push(route.resolveData(nextProps[field], route));\n }\n });\n await Promise.all(toFetch);\n } catch (e) {\n console.error(e);\n }\n return nextProps;\n };\n };\n}\n","import React from 'react';\nimport type { Route } from '@anansi/router';\nimport { StatsChunkGroup } from 'webpack';\n\nimport type { ServerProps, ResolveProps } from './types';\nimport type { Policy } from './csp';\nimport Document from './DocumentComponent';\n\ntype NeededProps = {\n initData?: Record<string, () => unknown>;\n scripts?: React.ReactNode[];\n} & ResolveProps;\n\nexport default function JSONSpout({\n id = 'anansi-json',\n}: { id?: string } = {}) {\n return function <T extends NeededProps>(\n next: (props: ServerProps) => Promise<T>,\n ) {\n return async (props: ServerProps) => {\n const nextProps = await next(props);\n\n const scripts: React.ReactNode[] = nextProps.scripts ?? [];\n /*\n Object.entries(nextProps.initData ?? {}).forEach(([key, data]) => {\n try {\n const encoded = JSON.stringify(data);\n scripts.push(\n <script\n key={key}\n id={`${id}-${key}`}\n type=\"application/json\"\n dangerouslySetInnerHTML={{\n __html: encoded,\n }}\n nonce={props.nonce}\n />,\n );\n } catch (e) {\n // TODO: Use unified logging\n console.error(e);\n }\n });*/\n const Script = () => {\n try {\n const data: any = {};\n Object.entries(nextProps.initData ?? {}).forEach(([key, getData]) => {\n data[key] = getData();\n });\n const encoded = JSON.stringify(data);\n return (\n <script\n key={id}\n id={id}\n type=\"application/json\"\n dangerouslySetInnerHTML={{\n __html: encoded,\n }}\n nonce={props.nonce}\n />\n );\n } catch (e) {\n // TODO: Use unified logging\n console.error('Error serializing json');\n console.error(e);\n return null;\n }\n };\n scripts.push(<Script />);\n\n return {\n ...nextProps,\n scripts,\n };\n };\n };\n}\n","export { default as laySpouts } from './laySpouts';\nexport { default as documentSpout } from './spouts/document.server';\nexport { default as restHooksSpout } from './spouts/restHooks.server';\nexport { default as routerSpout } from './spouts/router.server';\nexport { default as prefetchSpout } from './spouts/prefetch.server';\nexport { default as JSONSpout } from './spouts/json.server';\n"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"server.js","mappings":"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","sources":["/home/ntucker/src/anansi/packages/core/webpack/bootstrap","/home/ntucker/src/anansi/packages/core/webpack/runtime/compat get default export","/home/ntucker/src/anansi/packages/core/webpack/runtime/define property getters","/home/ntucker/src/anansi/packages/core/webpack/runtime/hasOwnProperty shorthand","/home/ntucker/src/anansi/packages/core/webpack/runtime/make namespace object","/home/ntucker/src/anansi/packages/core/external commonjs \"react-dom/server\"","/home/ntucker/src/anansi/packages/core/external node-commonjs \"crypto\"","/home/ntucker/src/anansi/packages/core/src/laySpouts.tsx","/home/ntucker/src/anansi/packages/core/external commonjs \"react\"","/home/ntucker/src/anansi/packages/core/src/spouts/csp.ts","/home/ntucker/src/anansi/packages/core/src/spouts/DocumentComponent.tsx","/home/ntucker/src/anansi/packages/core/src/spouts/document.server.tsx","/home/ntucker/src/anansi/packages/core/external commonjs \"@rest-hooks/core\"","/home/ntucker/src/anansi/packages/core/external commonjs \"rest-hooks\"","/home/ntucker/src/anansi/packages/core/external commonjs \"redux\"","/home/ntucker/src/anansi/packages/core/src/spouts/rhHelp.tsx","/home/ntucker/src/anansi/packages/core/src/spouts/restHooks.server.tsx","/home/ntucker/src/anansi/packages/core/external commonjs \"@anansi/router\"","/home/ntucker/src/anansi/packages/core/external commonjs \"history\"","/home/ntucker/src/anansi/packages/core/src/spouts/router.server.tsx","/home/ntucker/src/anansi/packages/core/src/spouts/prefetch.server.tsx","/home/ntucker/src/anansi/packages/core/src/spouts/json.server.tsx","/home/ntucker/src/anansi/packages/core/src/index.server.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"react-dom/server\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"crypto\");","import { renderToPipeableStream as reactRender } from 'react-dom/server';\nimport crypto from 'crypto';\n\nimport { Render } from './scripts/types';\nimport { ServerProps } from './spouts/types';\n\nexport default function laySpouts(\n spouts: (props: ServerProps) => Promise<{\n app: JSX.Element;\n }>,\n {\n timeoutMS = 200,\n onError,\n }: { timeoutMS?: number; onError?: (error: unknown) => void } = {},\n) {\n const render: Render = async (clientManifest, req, res) => {\n const nonce = crypto.randomBytes(16).toString('base64');\n\n try {\n const { app } = await spouts({ clientManifest, req, res, nonce });\n\n let didError = false;\n const { pipe, abort } = reactRender(app, {\n nonce,\n //bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),\n onShellReady() {\n //managers.forEach(manager => manager.cleanup());\n // If something errored before we started streaming, we set the error code appropriately.\n res.statusCode = didError ? 500 : 200;\n res.setHeader('Content-type', 'text/html');\n pipe(res);\n },\n onShellError() {\n didError = true;\n res.statusCode = 500;\n pipe(res);\n },\n onError(e: any) {\n didError = true;\n console.error(e);\n res.statusCode = 500;\n //pipe(res); Removing this avoids, \"React currently only supports piping to one writable stream.\"\n if (onError) onError(e);\n },\n });\n // Abandon and switch to client rendering if enough time passes.\n // Try lowering this to see the client recover.\n setTimeout(\n () => (abort as any)(`Timeout of ${timeoutMS}ms exceeded`),\n timeoutMS,\n );\n } catch (e: unknown) {\n if (onError) onError(e);\n throw e;\n }\n };\n return render;\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"react\");","export interface Policy {\n [directive: string]: string | string[];\n}\n\n// TODO: memoize this\nexport function buildPolicy(policyObj: Policy) {\n return Object.keys(policyObj)\n .map(key => {\n const val = Array.isArray(policyObj[key])\n ? [...new Set(policyObj[key]).values()].filter(v => v).join(' ')\n : policyObj[key];\n\n // move strict dynamic to the end of the policy if it exists to be backwards compatible with csp2\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#strict-dynamic\n if (typeof val === 'string' && val.includes(\"'strict-dynamic'\")) {\n const newVal = `${val\n .replace(/\\s?'strict-dynamic'\\s?/gi, ' ')\n .trim()} 'strict-dynamic'`;\n return `${key} ${newVal}`;\n }\n\n return `${key} ${val}`;\n })\n .join('; ');\n}\n","import type { Policy } from './csp';\nimport { buildPolicy } from './csp';\n\ntype Props = {\n children: React.ReactNode;\n assets: { href: string; as?: string; rel?: string }[];\n head: React.ReactNode;\n scripts: React.ReactNode;\n title: string;\n rootId: string;\n charSet: string;\n csPolicy?: Policy;\n nonce?: string | undefined;\n};\n\nexport default function Document({\n assets,\n head,\n children,\n title,\n rootId,\n charSet,\n csPolicy,\n nonce,\n scripts,\n}: Props) {\n let cspMeta: null | React.ReactNode = null;\n if (csPolicy) {\n // add nonce to policy\n const policy = {\n ...csPolicy,\n };\n if (\n nonce &&\n // nonces negate 'unsafe-inline' so do not add it if that directive exists\n (!policy['script-src'] ||\n !policy['script-src'].includes(\"'unsafe-inline'\"))\n ) {\n if (typeof policy['script-src'] === 'string') {\n policy['script-src'] = [policy['script-src'], `'nonce-${nonce}'`];\n } else {\n policy['script-src'] = [...policy['script-src'], `'nonce-${nonce}'`];\n }\n }\n cspMeta = (\n <meta httpEquiv=\"Content-Security-Policy\" content={buildPolicy(policy)} />\n );\n }\n return (\n <html>\n <head>\n <meta charSet={charSet} />\n {cspMeta}\n {head}\n {assets.map((asset, i) => (\n <link key={i} rel=\"preload\" {...asset} />\n ))}\n <title>{title}</title>\n </head>\n <body>\n <div id={rootId}>{children}</div>\n {scripts}\n {assets\n .filter(({ href }) => href.endsWith('.js'))\n .map(({ href }, i) => (\n <script key={i} src={href} async />\n ))}\n </body>\n </html>\n );\n}\nDocument.defaultProps = {\n head: (\n <>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <link\n rel=\"shortcut icon\"\n href={`${process.env.WEBPACK_PUBLIC_PATH ?? '/'}favicon.ico`}\n />\n </>\n ),\n charSet: 'utf-8',\n rootId: 'anansi-root',\n scripts: null,\n};\n","import React from 'react';\nimport type { Route } from '@anansi/router';\nimport { StatsChunkGroup } from 'webpack';\n\nimport type { ServerProps, ResolveProps } from './types';\nimport type { Policy } from './csp';\nimport Document from './DocumentComponent';\n\ntype NeededProps = {\n matchedRoutes: Route<any>[];\n title?: string;\n scripts?: React.ReactNode[];\n} & ResolveProps;\n\nexport default function DocumentSpout(options: {\n head?: React.ReactNode;\n title: string;\n rootId?: string;\n charSet?: string;\n csPolicy?: Policy;\n}) {\n return function <T extends NeededProps>(\n next: (props: ServerProps) => Promise<T>,\n ) {\n return async (props: ServerProps) => {\n const nextProps = await next(props);\n\n const publicPath = props.clientManifest.publicPath;\n\n if (\n Object.keys(props.clientManifest?.entrypoints ?? {}).length < 1 ||\n publicPath === undefined\n )\n throw new Error('Manifest missing entries needed');\n\n // TODO: consider using this package for build stats in future:\n // https://github.com/facebook/react/tree/main/packages/react-server-dom-webpack\n const assetMap = (assets: { name: string; size?: number }[]) =>\n assets.map(({ name }) => `${publicPath}${name}`);\n\n const assetList: string[] = [];\n Object.values(props.clientManifest?.entrypoints ?? {}).forEach(\n entrypoint => {\n assetList.push(...assetMap(entrypoint.assets ?? []));\n },\n );\n new Set(\n assetMap(\n Object.values(props.clientManifest.namedChunkGroups ?? {})\n .filter(({ name }) =>\n nextProps.matchedRoutes.some(route => name?.includes(route.name)),\n )\n .flatMap(chunk => [\n ...(chunk.assets ?? []),\n // any chunk preloads\n ...childrenAssets(chunk),\n ]),\n ),\n ).forEach(asset => assetList.push(asset));\n\n // find additional assets to preload based on matched route\n const assets: {\n href: string;\n as?: string | undefined;\n rel?: string | undefined;\n }[] = assetList\n .filter(asset => !asset.endsWith('.hot-update.js'))\n .map(asset =>\n asset.endsWith('.css')\n ? { href: asset, rel: 'stylesheet' }\n : asset.endsWith('.js')\n ? { href: asset, as: 'script' }\n : { href: asset },\n );\n\n return {\n ...nextProps,\n app: (\n <Document\n {...options}\n title={nextProps.title ?? options.title}\n assets={assets}\n rootId={options.rootId}\n nonce={props.nonce}\n csPolicy={options.csPolicy}\n scripts={nextProps.scripts}\n >\n {nextProps.app}\n </Document>\n ),\n };\n };\n };\n}\n\nfunction childrenAssets(chunk: StatsChunkGroup) {\n return chunk.children\n ? Object.values(chunk.children).flatMap(preload =>\n preload.flatMap(c => c.assets ?? []),\n )\n : [];\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@rest-hooks/core\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"rest-hooks\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"redux\");","import { ExternalCacheProvider, PromiseifyMiddleware } from 'rest-hooks';\nimport {\n Controller,\n createReducer,\n initialState,\n Manager,\n applyManager,\n NetworkManager,\n} from '@rest-hooks/core';\nimport { createStore, applyMiddleware } from 'redux';\n\n// TODO: Rework this and upstream to rest hooks\nexport function createPersistedStore(managers?: Manager[]) {\n const controller = new Controller();\n managers = managers ?? [new NetworkManager()];\n const reducer = createReducer(controller);\n const enhancer = applyMiddleware(\n ...applyManager(managers, controller),\n PromiseifyMiddleware as any,\n );\n const store = createStore(reducer, initialState as any, enhancer);\n managers.forEach(manager => manager.init?.(store.getState()));\n\n const selector = (state: any) => state;\n function ServerCacheProvider({ children }: { children: React.ReactNode }) {\n return (\n <ExternalCacheProvider\n store={store}\n selector={selector}\n controller={controller}\n >\n {children}\n </ExternalCacheProvider>\n );\n }\n return [ServerCacheProvider, controller, store] as const;\n}\n","import { Manager, NetworkManager } from '@rest-hooks/core';\n\nimport { createPersistedStore } from './rhHelp';\nimport type { ResolveProps, ServerProps } from './types';\n\ntype NeededProps = { initData?: Record<string, () => unknown> } & ResolveProps;\n\nexport default function restHooksSpout(\n options: {\n getManagers: () => Manager[];\n } = { getManagers: () => [new NetworkManager()] },\n) {\n return function <T extends NeededProps>(\n next: (props: ServerProps) => Promise<T>,\n ) {\n return async (props: ServerProps) => {\n const [ServerCacheProvider, controller, store] = createPersistedStore(\n options.getManagers(),\n );\n\n const nextProps = await next(props);\n\n return {\n ...nextProps,\n controller,\n initData: {\n ...nextProps.initData,\n resthooks: () => store.getState(),\n },\n app: <ServerCacheProvider>{nextProps.app}</ServerCacheProvider>,\n };\n };\n };\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"@anansi/router\");","const __WEBPACK_NAMESPACE_OBJECT__ = require(\"history\");","import { Route, RouteProvider, RouteController } from '@anansi/router';\nimport React from 'react';\nimport { createMemoryHistory } from 'history';\n\nimport type { ResolveProps, ServerProps, CreateRouter } from './types';\n\ntype NeededProps = ResolveProps;\n\nexport default function routerSpout<ResolveWith>(options: {\n resolveWith?: any;\n useResolveWith: () => ResolveWith;\n createRouter: CreateRouter<ResolveWith>;\n}) {\n const createRouteComponent = (\n router: RouteController<Route<ResolveWith, any>>,\n ) =>\n function Router({ children }: { children: React.ReactNode }) {\n const resolveWith = options.useResolveWith();\n\n return (\n <RouteProvider router={router} resolveWith={resolveWith}>\n {children}\n </RouteProvider>\n );\n };\n\n return function <T extends NeededProps>(\n next: (props: ServerProps) => Promise<T>,\n ) {\n return async (props: ServerProps) => {\n const url = props.req.url || '';\n const router = options.createRouter(\n createMemoryHistory({ initialEntries: [url] }),\n );\n const matchedRoutes: Route<ResolveWith>[] = router.getMatchedRoutes(url);\n\n const nextProps = await next(props);\n\n const Router = createRouteComponent(router);\n return {\n ...nextProps,\n matchedRoutes,\n router,\n app: <Router>{nextProps.app}</Router>,\n };\n };\n };\n}\n","import { Route } from '@anansi/router';\n\nimport type { ResolveProps, ServerProps } from './types';\n\ntype NeededProps<RouteWith> = {\n matchedRoutes: Route<RouteWith>[];\n} & ResolveProps;\n\nexport default function prefetchSpout<F extends string>(field: F) {\n return function <RouteWith, T extends NeededProps<RouteWith>>(\n next: (props: ServerProps) => Promise<\n {\n [K in F]: RouteWith;\n } & T\n >,\n ) {\n return async (props: ServerProps) => {\n const nextProps = await next(props);\n\n try {\n const toFetch: Promise<unknown>[] = [];\n nextProps.matchedRoutes.forEach(route => {\n if (typeof route.resolveData === 'function') {\n toFetch.push(route.resolveData(nextProps[field], route));\n }\n });\n await Promise.all(toFetch);\n } catch (e) {\n console.error(e);\n }\n return nextProps;\n };\n };\n}\n","import React from 'react';\nimport type { Route } from '@anansi/router';\nimport { StatsChunkGroup } from 'webpack';\n\nimport type { ServerProps, ResolveProps } from './types';\nimport type { Policy } from './csp';\nimport Document from './DocumentComponent';\n\ntype NeededProps = {\n initData?: Record<string, () => unknown>;\n scripts?: React.ReactNode[];\n} & ResolveProps;\n\nexport default function JSONSpout({\n id = 'anansi-json',\n}: { id?: string } = {}) {\n return function <T extends NeededProps>(\n next: (props: ServerProps) => Promise<T>,\n ) {\n return async (props: ServerProps) => {\n const nextProps = await next(props);\n\n const scripts: React.ReactNode[] = nextProps.scripts ?? [];\n /*\n Object.entries(nextProps.initData ?? {}).forEach(([key, data]) => {\n try {\n const encoded = JSON.stringify(data);\n scripts.push(\n <script\n key={key}\n id={`${id}-${key}`}\n type=\"application/json\"\n dangerouslySetInnerHTML={{\n __html: encoded,\n }}\n nonce={props.nonce}\n />,\n );\n } catch (e) {\n // TODO: Use unified logging\n console.error(e);\n }\n });*/\n const Script = () => {\n try {\n const data: any = {};\n Object.entries(nextProps.initData ?? {}).forEach(([key, getData]) => {\n data[key] = getData();\n });\n const encoded = JSON.stringify(data);\n return (\n <script\n key={id}\n id={id}\n type=\"application/json\"\n dangerouslySetInnerHTML={{\n __html: encoded,\n }}\n nonce={props.nonce}\n />\n );\n } catch (e) {\n // TODO: Use unified logging\n console.error('Error serializing json');\n console.error(e);\n return null;\n }\n };\n scripts.push(<Script />);\n\n return {\n ...nextProps,\n scripts,\n };\n };\n };\n}\n","export { default as laySpouts } from './laySpouts';\nexport { default as documentSpout } from './spouts/document.server';\nexport { default as restHooksSpout } from './spouts/restHooks.server';\nexport { default as routerSpout } from './spouts/router.server';\nexport { default as prefetchSpout } from './spouts/prefetch.server';\nexport { default as JSONSpout } from './spouts/json.server';\n"],"names":[],"sourceRoot":""}
@@ -2,7 +2,8 @@ import { Render } from './scripts/types';
2
2
  import { ServerProps } from './spouts/types';
3
3
  export default function laySpouts(spouts: (props: ServerProps) => Promise<{
4
4
  app: JSX.Element;
5
- }>, { timeoutMS }?: {
5
+ }>, { timeoutMS, onError, }?: {
6
6
  timeoutMS?: number;
7
+ onError?: (error: unknown) => void;
7
8
  }): Render;
8
9
  //# sourceMappingURL=laySpouts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"laySpouts.d.ts","sourceRoot":"","sources":["../src/laySpouts.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC;IACtC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC;CAClB,CAAC,EACF,EAAE,SAAe,EAAE,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,UAqDjD"}
1
+ {"version":3,"file":"laySpouts.d.ts","sourceRoot":"","sources":["../src/laySpouts.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC;IACtC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC;CAClB,CAAC,EACF,EACE,SAAe,EACf,OAAO,GACR,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CAAO,UA4CnE"}
package/lib/laySpouts.js CHANGED
@@ -10,70 +10,61 @@ var _server = require("react-dom/server");
10
10
  var _crypto = _interopRequireDefault(require("crypto"));
11
11
 
12
12
  function laySpouts(spouts, {
13
- timeoutMS = 200
13
+ timeoutMS = 200,
14
+ onError
14
15
  } = {}) {
15
16
  const render = async (clientManifest, req, res) => {
16
17
  const nonce = _crypto.default.randomBytes(16).toString('base64');
17
18
 
18
- const {
19
- app
20
- } = await spouts({
21
- clientManifest,
22
- req,
23
- res,
24
- nonce
25
- });
26
- let didError = false;
27
- const {
28
- pipe,
29
- abort
30
- } = (0, _server.renderToPipeableStream)(app,
31
- /*
32
- This is not documented, so included the types here for reference:
33
- type Options = {|
34
- identifierPrefix?: string,
35
- namespaceURI?: string,
36
- nonce?: string,
37
- bootstrapScriptContent?: string,
38
- bootstrapScripts?: Array<string>,
39
- bootstrapModules?: Array<string>,
40
- progressiveChunkSize?: number,
41
- onShellReady?: () => void,
42
- onShellError?: () => void,
43
- onAllReady?: () => void,
44
- onError?: (error: mixed) => void,
45
- |};
46
- */
47
- {
48
- nonce,
19
+ try {
20
+ const {
21
+ app
22
+ } = await spouts({
23
+ clientManifest,
24
+ req,
25
+ res,
26
+ nonce
27
+ });
28
+ let didError = false;
29
+ const {
30
+ pipe,
31
+ abort
32
+ } = (0, _server.renderToPipeableStream)(app, {
33
+ nonce,
49
34
 
50
- //bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),
51
- onShellReady() {
52
- //managers.forEach(manager => manager.cleanup());
53
- // If something errored before we started streaming, we set the error code appropriately.
54
- res.statusCode = didError ? 500 : 200;
55
- res.setHeader('Content-type', 'text/html');
56
- pipe(res);
57
- },
35
+ //bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),
36
+ onShellReady() {
37
+ //managers.forEach(manager => manager.cleanup());
38
+ // If something errored before we started streaming, we set the error code appropriately.
39
+ res.statusCode = didError ? 500 : 200;
40
+ res.setHeader('Content-type', 'text/html');
41
+ pipe(res);
42
+ },
58
43
 
59
- onShellError() {
60
- didError = true;
61
- res.statusCode = 500;
62
- pipe(res);
63
- },
44
+ onShellError() {
45
+ didError = true;
46
+ res.statusCode = 500;
47
+ pipe(res);
48
+ },
64
49
 
65
- onError(x) {
66
- didError = true;
67
- console.error(x);
68
- res.statusCode = 500; //pipe(res); Removing this avoids, "React currently only supports piping to one writable stream."
69
- }
50
+ onError(e) {
51
+ didError = true;
52
+ console.error(e);
53
+ res.statusCode = 500; //pipe(res); Removing this avoids, "React currently only supports piping to one writable stream."
70
54
 
71
- }); // Abandon and switch to client rendering if enough time passes.
72
- // Try lowering this to see the client recover.
55
+ if (onError) onError(e);
56
+ }
73
57
 
74
- setTimeout(abort, timeoutMS);
58
+ }); // Abandon and switch to client rendering if enough time passes.
59
+ // Try lowering this to see the client recover.
60
+
61
+ setTimeout(() => abort(`Timeout of ${timeoutMS}ms exceeded`), timeoutMS);
62
+ } catch (e) {
63
+ if (onError) onError(e);
64
+ throw e;
65
+ }
75
66
  };
76
67
 
77
68
  return render;
78
69
  }
79
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJsYXlTcG91dHMiLCJzcG91dHMiLCJ0aW1lb3V0TVMiLCJyZW5kZXIiLCJjbGllbnRNYW5pZmVzdCIsInJlcSIsInJlcyIsIm5vbmNlIiwiY3J5cHRvIiwicmFuZG9tQnl0ZXMiLCJ0b1N0cmluZyIsImFwcCIsImRpZEVycm9yIiwicGlwZSIsImFib3J0IiwicmVhY3RSZW5kZXIiLCJvblNoZWxsUmVhZHkiLCJzdGF0dXNDb2RlIiwic2V0SGVhZGVyIiwib25TaGVsbEVycm9yIiwib25FcnJvciIsIngiLCJjb25zb2xlIiwiZXJyb3IiLCJzZXRUaW1lb3V0Il0sInNvdXJjZXMiOlsiLi4vc3JjL2xheVNwb3V0cy50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVuZGVyVG9QaXBlYWJsZVN0cmVhbSBhcyByZWFjdFJlbmRlciB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5pbXBvcnQgeyBSZW5kZXIgfSBmcm9tICcuL3NjcmlwdHMvdHlwZXMnO1xuaW1wb3J0IHsgU2VydmVyUHJvcHMgfSBmcm9tICcuL3Nwb3V0cy90eXBlcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxheVNwb3V0cyhcbiAgc3BvdXRzOiAocHJvcHM6IFNlcnZlclByb3BzKSA9PiBQcm9taXNlPHtcbiAgICBhcHA6IEpTWC5FbGVtZW50O1xuICB9PixcbiAgeyB0aW1lb3V0TVMgPSAyMDAgfTogeyB0aW1lb3V0TVM/OiBudW1iZXIgfSA9IHt9LFxuKSB7XG4gIGNvbnN0IHJlbmRlcjogUmVuZGVyID0gYXN5bmMgKGNsaWVudE1hbmlmZXN0LCByZXEsIHJlcykgPT4ge1xuICAgIGNvbnN0IG5vbmNlID0gY3J5cHRvLnJhbmRvbUJ5dGVzKDE2KS50b1N0cmluZygnYmFzZTY0Jyk7XG5cbiAgICBjb25zdCB7IGFwcCB9ID0gYXdhaXQgc3BvdXRzKHsgY2xpZW50TWFuaWZlc3QsIHJlcSwgcmVzLCBub25jZSB9KTtcbiAgICBsZXQgZGlkRXJyb3IgPSBmYWxzZTtcbiAgICBjb25zdCB7IHBpcGUsIGFib3J0IH0gPSByZWFjdFJlbmRlcihcbiAgICAgIGFwcCxcbiAgICAgIC8qXG4gICAgICBUaGlzIGlzIG5vdCBkb2N1bWVudGVkLCBzbyBpbmNsdWRlZCB0aGUgdHlwZXMgaGVyZSBmb3IgcmVmZXJlbmNlOlxudHlwZSBPcHRpb25zID0ge3xcbiAgaWRlbnRpZmllclByZWZpeD86IHN0cmluZyxcbiAgbmFtZXNwYWNlVVJJPzogc3RyaW5nLFxuICBub25jZT86IHN0cmluZyxcbiAgYm9vdHN0cmFwU2NyaXB0Q29udGVudD86IHN0cmluZyxcbiAgYm9vdHN0cmFwU2NyaXB0cz86IEFycmF5PHN0cmluZz4sXG4gIGJvb3RzdHJhcE1vZHVsZXM/OiBBcnJheTxzdHJpbmc+LFxuICBwcm9ncmVzc2l2ZUNodW5rU2l6ZT86IG51bWJlcixcbiAgb25TaGVsbFJlYWR5PzogKCkgPT4gdm9pZCxcbiAgb25TaGVsbEVycm9yPzogKCkgPT4gdm9pZCxcbiAgb25BbGxSZWFkeT86ICgpID0+IHZvaWQsXG4gIG9uRXJyb3I/OiAoZXJyb3I6IG1peGVkKSA9PiB2b2lkLFxufH07XG4gICovXG4gICAgICB7XG4gICAgICAgIG5vbmNlLFxuICAgICAgICAvL2Jvb3RzdHJhcFNjcmlwdHM6IGFzc2V0cy5maWx0ZXIoYXNzZXQgPT4gYXNzZXQuZW5kc1dpdGgoJy5qcycpKSxcbiAgICAgICAgb25TaGVsbFJlYWR5KCkge1xuICAgICAgICAgIC8vbWFuYWdlcnMuZm9yRWFjaChtYW5hZ2VyID0+IG1hbmFnZXIuY2xlYW51cCgpKTtcbiAgICAgICAgICAvLyBJZiBzb21ldGhpbmcgZXJyb3JlZCBiZWZvcmUgd2Ugc3RhcnRlZCBzdHJlYW1pbmcsIHdlIHNldCB0aGUgZXJyb3IgY29kZSBhcHByb3ByaWF0ZWx5LlxuICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gZGlkRXJyb3IgPyA1MDAgOiAyMDA7XG4gICAgICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC10eXBlJywgJ3RleHQvaHRtbCcpO1xuICAgICAgICAgIHBpcGUocmVzKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25TaGVsbEVycm9yKCkge1xuICAgICAgICAgIGRpZEVycm9yID0gdHJ1ZTtcbiAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDUwMDtcbiAgICAgICAgICBwaXBlKHJlcyk7XG4gICAgICAgIH0sXG4gICAgICAgIG9uRXJyb3IoeDogYW55KSB7XG4gICAgICAgICAgZGlkRXJyb3IgPSB0cnVlO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoeCk7XG4gICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSA1MDA7XG4gICAgICAgICAgLy9waXBlKHJlcyk7IFJlbW92aW5nIHRoaXMgYXZvaWRzLCBcIlJlYWN0IGN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIHBpcGluZyB0byBvbmUgd3JpdGFibGUgc3RyZWFtLlwiXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICk7XG4gICAgLy8gQWJhbmRvbiBhbmQgc3dpdGNoIHRvIGNsaWVudCByZW5kZXJpbmcgaWYgZW5vdWdoIHRpbWUgcGFzc2VzLlxuICAgIC8vIFRyeSBsb3dlcmluZyB0aGlzIHRvIHNlZSB0aGUgY2xpZW50IHJlY292ZXIuXG4gICAgc2V0VGltZW91dChhYm9ydCwgdGltZW91dE1TKTtcbiAgfTtcbiAgcmV0dXJuIHJlbmRlcjtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUtlLFNBQVNBLFNBQVQsQ0FDYkMsTUFEYSxFQUliO0VBQUVDLFNBQVMsR0FBRztBQUFkLElBQThDLEVBSmpDLEVBS2I7RUFDQSxNQUFNQyxNQUFjLEdBQUcsT0FBT0MsY0FBUCxFQUF1QkMsR0FBdkIsRUFBNEJDLEdBQTVCLEtBQW9DO0lBQ3pELE1BQU1DLEtBQUssR0FBR0MsZUFBQSxDQUFPQyxXQUFQLENBQW1CLEVBQW5CLEVBQXVCQyxRQUF2QixDQUFnQyxRQUFoQyxDQUFkOztJQUVBLE1BQU07TUFBRUM7SUFBRixJQUFVLE1BQU1WLE1BQU0sQ0FBQztNQUFFRyxjQUFGO01BQWtCQyxHQUFsQjtNQUF1QkMsR0FBdkI7TUFBNEJDO0lBQTVCLENBQUQsQ0FBNUI7SUFDQSxJQUFJSyxRQUFRLEdBQUcsS0FBZjtJQUNBLE1BQU07TUFBRUMsSUFBRjtNQUFRQztJQUFSLElBQWtCLElBQUFDLDhCQUFBLEVBQ3RCSixHQURzQjtJQUV0QjtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtJQUNNO01BQ0VKLEtBREY7O01BRUU7TUFDQVMsWUFBWSxHQUFHO1FBQ2I7UUFDQTtRQUNBVixHQUFHLENBQUNXLFVBQUosR0FBaUJMLFFBQVEsR0FBRyxHQUFILEdBQVMsR0FBbEM7UUFDQU4sR0FBRyxDQUFDWSxTQUFKLENBQWMsY0FBZCxFQUE4QixXQUE5QjtRQUNBTCxJQUFJLENBQUNQLEdBQUQsQ0FBSjtNQUNELENBVEg7O01BVUVhLFlBQVksR0FBRztRQUNiUCxRQUFRLEdBQUcsSUFBWDtRQUNBTixHQUFHLENBQUNXLFVBQUosR0FBaUIsR0FBakI7UUFDQUosSUFBSSxDQUFDUCxHQUFELENBQUo7TUFDRCxDQWRIOztNQWVFYyxPQUFPLENBQUNDLENBQUQsRUFBUztRQUNkVCxRQUFRLEdBQUcsSUFBWDtRQUNBVSxPQUFPLENBQUNDLEtBQVIsQ0FBY0YsQ0FBZDtRQUNBZixHQUFHLENBQUNXLFVBQUosR0FBaUIsR0FBakIsQ0FIYyxDQUlkO01BQ0Q7O0lBcEJILENBbEJzQixDQUF4QixDQUx5RCxDQThDekQ7SUFDQTs7SUFDQU8sVUFBVSxDQUFDVixLQUFELEVBQVFaLFNBQVIsQ0FBVjtFQUNELENBakREOztFQWtEQSxPQUFPQyxNQUFQO0FBQ0QifQ==
70
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJsYXlTcG91dHMiLCJzcG91dHMiLCJ0aW1lb3V0TVMiLCJvbkVycm9yIiwicmVuZGVyIiwiY2xpZW50TWFuaWZlc3QiLCJyZXEiLCJyZXMiLCJub25jZSIsImNyeXB0byIsInJhbmRvbUJ5dGVzIiwidG9TdHJpbmciLCJhcHAiLCJkaWRFcnJvciIsInBpcGUiLCJhYm9ydCIsInJlYWN0UmVuZGVyIiwib25TaGVsbFJlYWR5Iiwic3RhdHVzQ29kZSIsInNldEhlYWRlciIsIm9uU2hlbGxFcnJvciIsImUiLCJjb25zb2xlIiwiZXJyb3IiLCJzZXRUaW1lb3V0Il0sInNvdXJjZXMiOlsiLi4vc3JjL2xheVNwb3V0cy50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVuZGVyVG9QaXBlYWJsZVN0cmVhbSBhcyByZWFjdFJlbmRlciB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuXG5pbXBvcnQgeyBSZW5kZXIgfSBmcm9tICcuL3NjcmlwdHMvdHlwZXMnO1xuaW1wb3J0IHsgU2VydmVyUHJvcHMgfSBmcm9tICcuL3Nwb3V0cy90eXBlcyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxheVNwb3V0cyhcbiAgc3BvdXRzOiAocHJvcHM6IFNlcnZlclByb3BzKSA9PiBQcm9taXNlPHtcbiAgICBhcHA6IEpTWC5FbGVtZW50O1xuICB9PixcbiAge1xuICAgIHRpbWVvdXRNUyA9IDIwMCxcbiAgICBvbkVycm9yLFxuICB9OiB7IHRpbWVvdXRNUz86IG51bWJlcjsgb25FcnJvcj86IChlcnJvcjogdW5rbm93bikgPT4gdm9pZCB9ID0ge30sXG4pIHtcbiAgY29uc3QgcmVuZGVyOiBSZW5kZXIgPSBhc3luYyAoY2xpZW50TWFuaWZlc3QsIHJlcSwgcmVzKSA9PiB7XG4gICAgY29uc3Qgbm9uY2UgPSBjcnlwdG8ucmFuZG9tQnl0ZXMoMTYpLnRvU3RyaW5nKCdiYXNlNjQnKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGFwcCB9ID0gYXdhaXQgc3BvdXRzKHsgY2xpZW50TWFuaWZlc3QsIHJlcSwgcmVzLCBub25jZSB9KTtcblxuICAgICAgbGV0IGRpZEVycm9yID0gZmFsc2U7XG4gICAgICBjb25zdCB7IHBpcGUsIGFib3J0IH0gPSByZWFjdFJlbmRlcihhcHAsIHtcbiAgICAgICAgbm9uY2UsXG4gICAgICAgIC8vYm9vdHN0cmFwU2NyaXB0czogYXNzZXRzLmZpbHRlcihhc3NldCA9PiBhc3NldC5lbmRzV2l0aCgnLmpzJykpLFxuICAgICAgICBvblNoZWxsUmVhZHkoKSB7XG4gICAgICAgICAgLy9tYW5hZ2Vycy5mb3JFYWNoKG1hbmFnZXIgPT4gbWFuYWdlci5jbGVhbnVwKCkpO1xuICAgICAgICAgIC8vIElmIHNvbWV0aGluZyBlcnJvcmVkIGJlZm9yZSB3ZSBzdGFydGVkIHN0cmVhbWluZywgd2Ugc2V0IHRoZSBlcnJvciBjb2RlIGFwcHJvcHJpYXRlbHkuXG4gICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSBkaWRFcnJvciA/IDUwMCA6IDIwMDtcbiAgICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAndGV4dC9odG1sJyk7XG4gICAgICAgICAgcGlwZShyZXMpO1xuICAgICAgICB9LFxuICAgICAgICBvblNoZWxsRXJyb3IoKSB7XG4gICAgICAgICAgZGlkRXJyb3IgPSB0cnVlO1xuICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNTAwO1xuICAgICAgICAgIHBpcGUocmVzKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25FcnJvcihlOiBhbnkpIHtcbiAgICAgICAgICBkaWRFcnJvciA9IHRydWU7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDUwMDtcbiAgICAgICAgICAvL3BpcGUocmVzKTsgUmVtb3ZpbmcgdGhpcyBhdm9pZHMsIFwiUmVhY3QgY3VycmVudGx5IG9ubHkgc3VwcG9ydHMgcGlwaW5nIHRvIG9uZSB3cml0YWJsZSBzdHJlYW0uXCJcbiAgICAgICAgICBpZiAob25FcnJvcikgb25FcnJvcihlKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgLy8gQWJhbmRvbiBhbmQgc3dpdGNoIHRvIGNsaWVudCByZW5kZXJpbmcgaWYgZW5vdWdoIHRpbWUgcGFzc2VzLlxuICAgICAgLy8gVHJ5IGxvd2VyaW5nIHRoaXMgdG8gc2VlIHRoZSBjbGllbnQgcmVjb3Zlci5cbiAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICgpID0+IChhYm9ydCBhcyBhbnkpKGBUaW1lb3V0IG9mICR7dGltZW91dE1TfW1zIGV4Y2VlZGVkYCksXG4gICAgICAgIHRpbWVvdXRNUyxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgaWYgKG9uRXJyb3IpIG9uRXJyb3IoZSk7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHJlbmRlcjtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUtlLFNBQVNBLFNBQVQsQ0FDYkMsTUFEYSxFQUliO0VBQ0VDLFNBQVMsR0FBRyxHQURkO0VBRUVDO0FBRkYsSUFHZ0UsRUFQbkQsRUFRYjtFQUNBLE1BQU1DLE1BQWMsR0FBRyxPQUFPQyxjQUFQLEVBQXVCQyxHQUF2QixFQUE0QkMsR0FBNUIsS0FBb0M7SUFDekQsTUFBTUMsS0FBSyxHQUFHQyxlQUFBLENBQU9DLFdBQVAsQ0FBbUIsRUFBbkIsRUFBdUJDLFFBQXZCLENBQWdDLFFBQWhDLENBQWQ7O0lBRUEsSUFBSTtNQUNGLE1BQU07UUFBRUM7TUFBRixJQUFVLE1BQU1YLE1BQU0sQ0FBQztRQUFFSSxjQUFGO1FBQWtCQyxHQUFsQjtRQUF1QkMsR0FBdkI7UUFBNEJDO01BQTVCLENBQUQsQ0FBNUI7TUFFQSxJQUFJSyxRQUFRLEdBQUcsS0FBZjtNQUNBLE1BQU07UUFBRUMsSUFBRjtRQUFRQztNQUFSLElBQWtCLElBQUFDLDhCQUFBLEVBQVlKLEdBQVosRUFBaUI7UUFDdkNKLEtBRHVDOztRQUV2QztRQUNBUyxZQUFZLEdBQUc7VUFDYjtVQUNBO1VBQ0FWLEdBQUcsQ0FBQ1csVUFBSixHQUFpQkwsUUFBUSxHQUFHLEdBQUgsR0FBUyxHQUFsQztVQUNBTixHQUFHLENBQUNZLFNBQUosQ0FBYyxjQUFkLEVBQThCLFdBQTlCO1VBQ0FMLElBQUksQ0FBQ1AsR0FBRCxDQUFKO1FBQ0QsQ0FUc0M7O1FBVXZDYSxZQUFZLEdBQUc7VUFDYlAsUUFBUSxHQUFHLElBQVg7VUFDQU4sR0FBRyxDQUFDVyxVQUFKLEdBQWlCLEdBQWpCO1VBQ0FKLElBQUksQ0FBQ1AsR0FBRCxDQUFKO1FBQ0QsQ0Fkc0M7O1FBZXZDSixPQUFPLENBQUNrQixDQUFELEVBQVM7VUFDZFIsUUFBUSxHQUFHLElBQVg7VUFDQVMsT0FBTyxDQUFDQyxLQUFSLENBQWNGLENBQWQ7VUFDQWQsR0FBRyxDQUFDVyxVQUFKLEdBQWlCLEdBQWpCLENBSGMsQ0FJZDs7VUFDQSxJQUFJZixPQUFKLEVBQWFBLE9BQU8sQ0FBQ2tCLENBQUQsQ0FBUDtRQUNkOztNQXJCc0MsQ0FBakIsQ0FBeEIsQ0FKRSxDQTJCRjtNQUNBOztNQUNBRyxVQUFVLENBQ1IsTUFBT1QsS0FBRCxDQUFnQixjQUFhYixTQUFVLGFBQXZDLENBREUsRUFFUkEsU0FGUSxDQUFWO0lBSUQsQ0FqQ0QsQ0FpQ0UsT0FBT21CLENBQVAsRUFBbUI7TUFDbkIsSUFBSWxCLE9BQUosRUFBYUEsT0FBTyxDQUFDa0IsQ0FBRCxDQUFQO01BQ2IsTUFBTUEsQ0FBTjtJQUNEO0VBQ0YsQ0F4Q0Q7O0VBeUNBLE9BQU9qQixNQUFQO0FBQ0QifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"startDevserver.d.ts","sourceRoot":"","sources":["../../src/scripts/startDevserver.ts"],"names":[],"mappings":";AAgBA,OAAO,sBAAsB,CAAC;AAe9B,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,QAiOlC"}
1
+ {"version":3,"file":"startDevserver.d.ts","sourceRoot":"","sources":["../../src/scripts/startDevserver.ts"],"names":[],"mappings":";AAgBA,OAAO,sBAAsB,CAAC;AAe9B,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,QAqOlC"}
@@ -138,9 +138,14 @@ function startDevServer(entrypoint, env = {}) {
138
138
 
139
139
  if (clientStats !== null && clientStats !== void 0 && (_clientStats$compilat = clientStats.compilation) !== null && _clientStats$compilat !== void 0 && (_clientStats$compilat2 = _clientStats$compilat.errors) !== null && _clientStats$compilat2 !== void 0 && _clientStats$compilat2.length || serverStats !== null && serverStats !== void 0 && (_serverStats$compilat = serverStats.compilation) !== null && _serverStats$compilat !== void 0 && (_serverStats$compilat2 = _serverStats$compilat.errors) !== null && _serverStats$compilat2 !== void 0 && _serverStats$compilat2.length) {
140
140
  log.error('Errors for client build: ' + clientStats.compilation.errors);
141
- log.error('Errors for server build: ' + serverStats.compilation.errors); // TODO: handle more gracefully
141
+ log.error('Errors for server build: ' + serverStats.compilation.errors); // first time, rather than re-render
142
142
 
143
- process.exit(-1);
143
+ if (Array.isArray(initRender)) {
144
+ process.exit(-1);
145
+ }
146
+
147
+ log.error('Above compiler errors blocking reload');
148
+ return;
144
149
  } else {
145
150
  log.info('Launching SSR');
146
151
  } // ASSETS
@@ -244,4 +249,4 @@ function startDevServer(entrypoint, env = {}) {
244
249
  });
245
250
  runServer();
246
251
  }
247
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJyZXF1aXJlIiwibWFpbiIsIm1vZHVsZSIsImVudHJ5cG9pbnQiLCJwcm9jZXNzIiwiYXJndiIsImNvbnNvbGUiLCJsb2ciLCJleGl0Iiwic3RhcnREZXZTZXJ2ZXIiLCJlbnYiLCJ3ZWJwYWNrQ29uZmlnIiwicmVzb2x2ZSIsInBhdGgiLCJqb2luIiwiY3dkIiwibG9nZ2luZyIsImdldExvZ2dlciIsInZvbHVtZSIsIlZvbHVtZSIsImZzIiwiY3JlYXRlRnNGcm9tVm9sdW1lIiwidWZzIiwidXNlIiwiZGlza0ZzIiwiZnNSZXF1aXJlIiwiY3JlYXRlRnNSZXF1aXJlIiwicmVhZEZpbGUiLCJwcm9taXNpZnkiLCJzZXJ2ZXIiLCJob3RFbnRyeSIsImVudHJ5UGF0aCIsImdlbmVyYXRlZEVudHJ5cG9pbnQiLCJ0bXAiLCJmaWxlU3luYyIsInBvc3RmaXgiLCJ3cml0ZVN5bmMiLCJmZCIsIndlYnBhY2tDb25maWdzIiwiZW50cnlwYXRoIiwibmFtZSIsIm1vZGUiLCJyZXBsYWNlIiwiQlJPV1NFUlNMSVNUX0VOViIsInRhcmdldCIsImNvbXBpbGVyIiwid2VicGFjayIsInNvdXJjZU1hcFN1cHBvcnQiLCJpbnN0YWxsIiwiaG9va1JlcXVpcmUiLCJnZXRTZXJ2ZXJCdW5kbGUiLCJzZXJ2ZXJTdGF0cyIsInNlcnZlckpzb24iLCJ0b0pzb24iLCJhc3NldHMiLCJvdXRwdXRQYXRoIiwiaGFuZGxlRXJyb3JzIiwiZm4iLCJyZXEiLCJyZXMiLCJuZXh0IiwieCIsImluaXRSZW5kZXIiLCJyZW5kZXIiLCJhcmdzIiwiUHJvbWlzZSIsInB1c2giLCJpbXBvcnRSZW5kZXIiLCJzdGF0cyIsImNsaWVudFN0YXRzIiwiY29tcGlsYXRpb24iLCJlcnJvcnMiLCJsZW5ndGgiLCJlcnJvciIsImluZm8iLCJjbGllbnRNYW5pZmVzdCIsInNlcnZlckVudHJ5IiwiT2JqZWN0Iiwia2V5cyIsImNhY2hlIiwiZm9yRWFjaCIsImtleSIsImRlZmF1bHQiLCJiaW5kIiwidW5kZWZpbmVkIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5pdCIsImUiLCJkZXZTZXJ2ZXIiLCJXZWJwYWNrRGV2U2VydmVyIiwiZGV2TWlkZGxld2FyZSIsIm91dHB1dEZpbGVTeXN0ZW0iLCJzZXR1cE1pZGRsZXdhcmVzIiwibWlkZGxld2FyZXMiLCJFcnJvciIsIm90aGVyUm91dGVzIiwiV0VCUEFDS19QVUJMSUNfUEFUSCIsInByb3h5IiwiYXBwIiwiZ2V0IiwiUmVnRXhwIiwidXJsIiwiZW5kc1dpdGgiLCJzdGF0dXNDb2RlIiwic2V0SGVhZGVyIiwic2VuZCIsInNvY2tldCIsIm9uIiwicnVuU2VydmVyIiwic3RhcnQiLCJob29rcyIsImRvbmUiLCJ0YXAiLCJtdWx0aVN0YXRzIiwiaGFzT3duIiwic3RvcFNlcnZlciIsInN0b3AiLCJ3YXJuIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjcmlwdHMvc3RhcnREZXZzZXJ2ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJztcbmltcG9ydCBkaXNrRnMgZnJvbSAnZnMnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgd2VicGFjaywgeyBNdWx0aUNvbXBpbGVyIH0gZnJvbSAnd2VicGFjayc7XG5pbXBvcnQgeyBjcmVhdGVGc0Zyb21Wb2x1bWUsIFZvbHVtZSB9IGZyb20gJ21lbWZzJztcbmltcG9ydCB7IFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ2h0dHAnO1xuaW1wb3J0IHR5cGUgeyBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB0bXAgZnJvbSAndG1wJztcbmltcG9ydCBzb3VyY2VNYXBTdXBwb3J0IGZyb20gJ3NvdXJjZS1tYXAtc3VwcG9ydCc7XG5pbXBvcnQgeyB1ZnMgfSBmcm9tICd1bmlvbmZzJztcbmltcG9ydCBXZWJwYWNrRGV2U2VydmVyIGZyb20gJ3dlYnBhY2stZGV2LXNlcnZlcic7XG5pbXBvcnQgbG9nZ2luZyBmcm9tICd3ZWJwYWNrL2xpYi9sb2dnaW5nL3J1bnRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlRnNSZXF1aXJlIH0gZnJvbSAnZnMtcmVxdWlyZSc7XG5cbmltcG9ydCAnY3Jvc3MtZmV0Y2gvcG9seWZpbGwnO1xuaW1wb3J0IHsgQm91bmRSZW5kZXIgfSBmcm9tICcuL3R5cGVzJztcblxuLy8gcnVuIGRpcmVjdGx5IGZyb20gbm9kZVxuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIGNvbnN0IGVudHJ5cG9pbnQgPSBwcm9jZXNzLmFyZ3ZbMl07XG5cbiAgaWYgKCFlbnRyeXBvaW50KSB7XG4gICAgY29uc29sZS5sb2coYFVzYWdlOiBzdGFydC1hbmFuc2kgPGVudHJ5cG9pbnQtZmlsZT5gKTtcbiAgICBwcm9jZXNzLmV4aXQoLTEpO1xuICB9XG5cbiAgc3RhcnREZXZTZXJ2ZXIoZW50cnlwb2ludCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHN0YXJ0RGV2U2VydmVyKFxuICBlbnRyeXBvaW50OiBzdHJpbmcsXG4gIGVudjogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSxcbikge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICBjb25zdCB3ZWJwYWNrQ29uZmlnID0gcmVxdWlyZShyZXF1aXJlLnJlc29sdmUoXG4gICAgLy8gVE9ETzogdXNlIG5vcm1hbCByZXNvbHV0aW9uIGFsZ29yaXRobSB0byBmaW5kIHdlYnBhY2sgZmlsZVxuICAgIHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnd2VicGFjay5jb25maWcnKSxcbiAgKSk7XG5cbiAgY29uc3QgbG9nID0gbG9nZ2luZy5nZXRMb2dnZXIoJ2FuYW5zaS1kZXZzZXJ2ZXInKTtcblxuICAvLyBTZXQgdXAgaW4gbWVtb3J5IGZpbGVzeXN0ZW1cbiAgY29uc3Qgdm9sdW1lID0gbmV3IFZvbHVtZSgpO1xuICBjb25zdCBmcyA9IGNyZWF0ZUZzRnJvbVZvbHVtZSh2b2x1bWUpO1xuICB1ZnMudXNlKGRpc2tGcykudXNlKGZzIGFzIGFueSk7XG5cbiAgY29uc3QgZnNSZXF1aXJlID0gY3JlYXRlRnNSZXF1aXJlKHVmcyk7XG4gIGNvbnN0IHJlYWRGaWxlID0gcHJvbWlzaWZ5KHVmcy5yZWFkRmlsZSk7XG4gIGxldCBzZXJ2ZXI6IFNlcnZlciB8IHVuZGVmaW5lZDtcblxuICAvLyBHZW5lcmF0ZSBhIHRlbXBvcmFyeSBmaWxlIHNvIHdlIGNhbiBob3QgcmVsb2FkIGZyb20gdGhlIHJvb3Qgb2YgdGhlIGFwcGxpY2F0aW9uXG4gIGZ1bmN0aW9uIGhvdEVudHJ5KGVudHJ5UGF0aDogc3RyaW5nKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgLy8gQHRzLWlnbm9yZSBmb3Igc29tZSByZWFzb24gaXQncyBub3QgcGlja2luZyB1cCB0aGF0IG90aGVyIG9wdGlvbnMgYXJlIG9wdGlvbmFsXG4gICAgY29uc3QgZ2VuZXJhdGVkRW50cnlwb2ludCA9IHRtcC5maWxlU3luYyh7IHBvc3RmaXg6ICcuanMnIH0pO1xuICAgIGRpc2tGcy53cml0ZVN5bmMoXG4gICAgICBnZW5lcmF0ZWRFbnRyeXBvaW50LmZkLFxuICAgICAgYFxuICBpbXBvcnQgZW50cnkgZnJvbSBcIiR7cGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGVudHJ5UGF0aCl9XCI7XG5cbiAgaWYgKG1vZHVsZS5ob3QpIHtcbiAgICBtb2R1bGUuaG90LmFjY2VwdCgpO1xuICB9XG5cbiAgZXhwb3J0IGRlZmF1bHQgZW50cnk7XG4gICAgYCxcbiAgICApO1xuICAgIHJldHVybiBnZW5lcmF0ZWRFbnRyeXBvaW50O1xuICB9XG5cbiAgY29uc3Qgd2VicGFja0NvbmZpZ3MgPSBbXG4gICAgd2VicGFja0NvbmZpZyhcbiAgICAgIHtcbiAgICAgICAgLi4uZW52LFxuICAgICAgICBlbnRyeXBhdGg6IGhvdEVudHJ5KGVudHJ5cG9pbnQpLm5hbWUsXG4gICAgICAgIG5hbWU6ICdjbGllbnQnLFxuICAgICAgfSxcbiAgICAgIHsgbW9kZTogJ2RldmVsb3BtZW50JyB9LFxuICAgICksXG4gICAgd2VicGFja0NvbmZpZyhcbiAgICAgIHtcbiAgICAgICAgLi4uZW52LFxuICAgICAgICBlbnRyeXBhdGg6IGVudHJ5cG9pbnQucmVwbGFjZSgnLnRzeCcsICcuc2VydmVyLnRzeCcpLFxuICAgICAgICBuYW1lOiAnc2VydmVyJyxcbiAgICAgICAgQlJPV1NFUlNMSVNUX0VOVjogJ2N1cnJlbnQgbm9kZScsXG4gICAgICB9LFxuICAgICAgeyBtb2RlOiAnZGV2ZWxvcG1lbnQnLCB0YXJnZXQ6ICdub2RlJyB9LFxuICAgICksXG4gIF0gYXMgY29uc3Q7XG5cbiAgLy8gaW5pdGlhbGl6ZSB0aGUgd2VicGFjayBjb21waWxlclxuICBjb25zdCBjb21waWxlcjogTXVsdGlDb21waWxlciA9IHdlYnBhY2sod2VicGFja0NvbmZpZ3MpO1xuXG4gIHNvdXJjZU1hcFN1cHBvcnQuaW5zdGFsbCh7IGhvb2tSZXF1aXJlOiB0cnVlIH0pO1xuXG4gIGZ1bmN0aW9uIGdldFNlcnZlckJ1bmRsZShzZXJ2ZXJTdGF0czogd2VicGFjay5TdGF0cykge1xuICAgIGNvbnN0IHNlcnZlckpzb24gPSBzZXJ2ZXJTdGF0cy50b0pzb24oeyBhc3NldHM6IHRydWUgfSk7XG4gICAgcmV0dXJuIHBhdGguam9pbihzZXJ2ZXJKc29uLm91dHB1dFBhdGggPz8gJycsICdzZXJ2ZXIuanMnKTtcbiAgfVxuICBmdW5jdGlvbiBoYW5kbGVFcnJvcnM8XG4gICAgRiBleHRlbmRzIChcbiAgICAgIHJlcTogUmVxdWVzdCB8IEluY29taW5nTWVzc2FnZSxcbiAgICAgIHJlczogUmVzcG9uc2UgfCBTZXJ2ZXJSZXNwb25zZSxcbiAgICApID0+IFByb21pc2U8dm9pZD4sXG4gID4oZm46IEYpIHtcbiAgICByZXR1cm4gYXN5bmMgZnVuY3Rpb24gKFxuICAgICAgcmVxOiBSZXF1ZXN0IHwgSW5jb21pbmdNZXNzYWdlLFxuICAgICAgcmVzOiBSZXNwb25zZSB8IFNlcnZlclJlc3BvbnNlLFxuICAgICAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuICAgICkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZuKHJlcSwgcmVzKTtcbiAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgbmV4dCh4KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgbGV0IGluaXRSZW5kZXI6XG4gICAgfCB7IGFyZ3M6IFBhcmFtZXRlcnM8Qm91bmRSZW5kZXI+OyByZXNvbHZlOiAoKSA9PiB2b2lkIH1bXVxuICAgIHwgdW5kZWZpbmVkID0gW107XG4gIGxldCByZW5kZXI6IEJvdW5kUmVuZGVyID0gKC4uLmFyZ3MpID0+XG4gICAgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBpbml0UmVuZGVyPy5wdXNoKHsgYXJncywgcmVzb2x2ZSB9KTtcbiAgICB9KTtcblxuICBmdW5jdGlvbiBpbXBvcnRSZW5kZXIoc3RhdHM6IHdlYnBhY2suU3RhdHNbXSkge1xuICAgIGNvbnN0IFtjbGllbnRTdGF0cywgc2VydmVyU3RhdHNdID0gc3RhdHM7XG4gICAgaWYgKFxuICAgICAgY2xpZW50U3RhdHM/LmNvbXBpbGF0aW9uPy5lcnJvcnM/Lmxlbmd0aCB8fFxuICAgICAgc2VydmVyU3RhdHM/LmNvbXBpbGF0aW9uPy5lcnJvcnM/Lmxlbmd0aFxuICAgICkge1xuICAgICAgbG9nLmVycm9yKCdFcnJvcnMgZm9yIGNsaWVudCBidWlsZDogJyArIGNsaWVudFN0YXRzLmNvbXBpbGF0aW9uLmVycm9ycyk7XG4gICAgICBsb2cuZXJyb3IoJ0Vycm9ycyBmb3Igc2VydmVyIGJ1aWxkOiAnICsgc2VydmVyU3RhdHMuY29tcGlsYXRpb24uZXJyb3JzKTtcbiAgICAgIC8vIFRPRE86IGhhbmRsZSBtb3JlIGdyYWNlZnVsbHlcbiAgICAgIHByb2Nlc3MuZXhpdCgtMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZy5pbmZvKCdMYXVuY2hpbmcgU1NSJyk7XG4gICAgfVxuXG4gICAgLy8gQVNTRVRTXG4gICAgY29uc3QgY2xpZW50TWFuaWZlc3QgPSBjbGllbnRTdGF0cy50b0pzb24oKTtcblxuICAgIGNvbnN0IHNlcnZlckVudHJ5ID0gZ2V0U2VydmVyQnVuZGxlKHNlcnZlclN0YXRzKTtcbiAgICAvLyByZWxvYWQgbW9kdWxlc1xuICAgIE9iamVjdC5rZXlzKGZzUmVxdWlyZS5jYWNoZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgZGVsZXRlIGZzUmVxdWlyZS5jYWNoZVtrZXldO1xuICAgIH0pO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgcmVuZGVyID0gKGZzUmVxdWlyZShzZXJ2ZXJFbnRyeSkgYXMgYW55KS5kZWZhdWx0LmJpbmQoXG4gICAgICB1bmRlZmluZWQsXG4gICAgICBjbGllbnRNYW5pZmVzdCxcbiAgICApO1xuICAgIC8vIFNFUlZFUiBTSURFIEVOVFJZUE9JTlRcbiAgICBpZiAoQXJyYXkuaXNBcnJheShpbml0UmVuZGVyKSkge1xuICAgICAgaW5pdFJlbmRlci5mb3JFYWNoKGFzeW5jIGluaXQgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxvZy5pbmZvKCdSZXNvbHZpbmcgcXVldWVkIHJlcXVlc3RzJyk7XG4gICAgICAgICAgYXdhaXQgcmVuZGVyKC4uLmluaXQuYXJncyk7XG4gICAgICAgICAgaW5pdC5yZXNvbHZlKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBsb2cuZXJyb3IoJ0Vycm9yIHdoZW4gYXR0ZW1wdGluZyB0byByZW5kZXIgcXVldWVkIHJlcXVlc3RzJyk7XG4gICAgICAgICAgbG9nLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGluaXRSZW5kZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZGV2U2VydmVyID0gbmV3IFdlYnBhY2tEZXZTZXJ2ZXIoXG4gICAgLy8gd3JpdGUgdG8gbWVtb3J5IGZpbGVzeXN0ZW0gc28gd2UgY2FuIGltcG9ydFxuICAgIHtcbiAgICAgIC4uLndlYnBhY2tDb25maWdzWzBdLmRldlNlcnZlcixcbiAgICAgIGRldk1pZGRsZXdhcmU6IHtcbiAgICAgICAgLi4ud2VicGFja0NvbmZpZ3NbMF0/LmRldlNlcnZlcj8uZGV2TWlkZGxld2FyZSxcbiAgICAgICAgb3V0cHV0RmlsZVN5c3RlbToge1xuICAgICAgICAgIC4uLmZzLFxuICAgICAgICAgIGpvaW46IHBhdGguam9pbiBhcyBhbnksXG4gICAgICAgIH0gYXMgYW55IGFzIHR5cGVvZiBmcyxcbiAgICAgIH0sXG4gICAgICBzZXR1cE1pZGRsZXdhcmVzOiAobWlkZGxld2FyZXMsIGRldlNlcnZlcikgPT4ge1xuICAgICAgICBpZiAoIWRldlNlcnZlcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignd2VicGFjay1kZXYtc2VydmVyIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvdGhlclJvdXRlcyA9IFtcbiAgICAgICAgICBwcm9jZXNzLmVudi5XRUJQQUNLX1BVQkxJQ19QQVRILFxuICAgICAgICAgIC4uLk9iamVjdC5rZXlzKHdlYnBhY2tDb25maWdzWzBdLmRldlNlcnZlcj8ucHJveHkgPz8ge30pLFxuICAgICAgICBdO1xuICAgICAgICAvLyBzZXJ2ZSBTU1IgZm9yIG5vbi1XRUJQQUNLX1BVQkxJQ19QQVRIXG4gICAgICAgIGRldlNlcnZlci5hcHA/LmdldChcbiAgICAgICAgICBuZXcgUmVnRXhwKGBeKD8hJHtvdGhlclJvdXRlcy5qb2luKCd8Jyl9KWApLFxuICAgICAgICAgIGhhbmRsZUVycm9ycyhhc3luYyBmdW5jdGlvbiAocmVxOiBhbnksIHJlczogYW55KSB7XG4gICAgICAgICAgICBpZiAocmVxLnVybC5lbmRzV2l0aCgnZmF2aWNvbi5pY28nKSkge1xuICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQwNDtcbiAgICAgICAgICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC10eXBlJywgJ3RleHQvaHRtbCcpO1xuICAgICAgICAgICAgICByZXMuc2VuZCgnbm90IGZvdW5kJyk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlcy5zb2NrZXQub24oJ2Vycm9yJywgKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhdGFsJywgZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcihyZXEsIHJlcyk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHdlYnBhY2tDb25maWdzWzBdLmRldlNlcnZlcj8uc2V0dXBNaWRkbGV3YXJlcykge1xuICAgICAgICAgIHJldHVybiB3ZWJwYWNrQ29uZmlnc1swXS5kZXZTZXJ2ZXIuc2V0dXBNaWRkbGV3YXJlcyhcbiAgICAgICAgICAgIG1pZGRsZXdhcmVzLFxuICAgICAgICAgICAgZGV2U2VydmVyLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWlkZGxld2FyZXM7XG4gICAgICB9LFxuICAgIH0sXG4gICAgY29tcGlsZXIsXG4gICk7XG4gIGNvbnN0IHJ1blNlcnZlciA9IGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCBkZXZTZXJ2ZXIuc3RhcnQoKTtcbiAgICBkZXZTZXJ2ZXIuY29tcGlsZXIuaG9va3MuZG9uZS50YXAoXG4gICAgICAnQW5hbnNpIFNlcnZlcicsXG4gICAgICAobXVsdGlTdGF0czogd2VicGFjay5NdWx0aVN0YXRzIHwgd2VicGFjay5TdGF0cykgPT4ge1xuICAgICAgICBpZiAoIW11bHRpU3RhdHMpIHtcbiAgICAgICAgICBsb2cuZXJyb3IoJ3N0YXRzIG5vdCBzZW5kJyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghT2JqZWN0Lmhhc093bihtdWx0aVN0YXRzLCAnc3RhdHMnKSkgcmV0dXJuO1xuICAgICAgICBpZiAoKG11bHRpU3RhdHMgYXMgd2VicGFjay5NdWx0aVN0YXRzKS5zdGF0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGltcG9ydFJlbmRlcigobXVsdGlTdGF0cyBhcyB3ZWJwYWNrLk11bHRpU3RhdHMpLnN0YXRzKTtcbiAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIGxvZy5lcnJvcignRmFpbGVkIHRvIGxvYWQgc2VydmUgZW50cnlwb2ludCcpO1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9nLmVycm9yKCdPbmx5IGNvbXBpbGVyIG9uZSBzdGF0Jyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfTtcbiAgY29uc3Qgc3RvcFNlcnZlciA9IGFzeW5jICgpID0+IHtcbiAgICBsb2cuaW5mbygnU3RvcHBpbmcgc2VydmVyLi4uJyk7XG4gICAgYXdhaXQgZGV2U2VydmVyLnN0b3AoKTtcbiAgICBsb2cuaW5mbygnU2VydmVyIGNsb3NlZCcpO1xuICB9O1xuXG4gIHByb2Nlc3Mub24oJ1NJR0lOVCcsICgpID0+IHtcbiAgICBsb2cud2FybignUmVjZWl2ZWQgU0lHSU5ULCBkZXZzZXJ2ZXIgc2h1dHRpbmcgZG93bicpO1xuICAgIHN0b3BTZXJ2ZXIoKTtcbiAgICBwcm9jZXNzLmV4aXQoLTEpO1xuICB9KTtcblxuICBydW5TZXJ2ZXIoKTtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBR0E7QUFDQSxJQUFJQSxPQUFPLENBQUNDLElBQVIsS0FB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
252
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJyZXF1aXJlIiwibWFpbiIsIm1vZHVsZSIsImVudHJ5cG9pbnQiLCJwcm9jZXNzIiwiYXJndiIsImNvbnNvbGUiLCJsb2ciLCJleGl0Iiwic3RhcnREZXZTZXJ2ZXIiLCJlbnYiLCJ3ZWJwYWNrQ29uZmlnIiwicmVzb2x2ZSIsInBhdGgiLCJqb2luIiwiY3dkIiwibG9nZ2luZyIsImdldExvZ2dlciIsInZvbHVtZSIsIlZvbHVtZSIsImZzIiwiY3JlYXRlRnNGcm9tVm9sdW1lIiwidWZzIiwidXNlIiwiZGlza0ZzIiwiZnNSZXF1aXJlIiwiY3JlYXRlRnNSZXF1aXJlIiwicmVhZEZpbGUiLCJwcm9taXNpZnkiLCJzZXJ2ZXIiLCJob3RFbnRyeSIsImVudHJ5UGF0aCIsImdlbmVyYXRlZEVudHJ5cG9pbnQiLCJ0bXAiLCJmaWxlU3luYyIsInBvc3RmaXgiLCJ3cml0ZVN5bmMiLCJmZCIsIndlYnBhY2tDb25maWdzIiwiZW50cnlwYXRoIiwibmFtZSIsIm1vZGUiLCJyZXBsYWNlIiwiQlJPV1NFUlNMSVNUX0VOViIsInRhcmdldCIsImNvbXBpbGVyIiwid2VicGFjayIsInNvdXJjZU1hcFN1cHBvcnQiLCJpbnN0YWxsIiwiaG9va1JlcXVpcmUiLCJnZXRTZXJ2ZXJCdW5kbGUiLCJzZXJ2ZXJTdGF0cyIsInNlcnZlckpzb24iLCJ0b0pzb24iLCJhc3NldHMiLCJvdXRwdXRQYXRoIiwiaGFuZGxlRXJyb3JzIiwiZm4iLCJyZXEiLCJyZXMiLCJuZXh0IiwieCIsImluaXRSZW5kZXIiLCJyZW5kZXIiLCJhcmdzIiwiUHJvbWlzZSIsInB1c2giLCJpbXBvcnRSZW5kZXIiLCJzdGF0cyIsImNsaWVudFN0YXRzIiwiY29tcGlsYXRpb24iLCJlcnJvcnMiLCJsZW5ndGgiLCJlcnJvciIsIkFycmF5IiwiaXNBcnJheSIsImluZm8iLCJjbGllbnRNYW5pZmVzdCIsInNlcnZlckVudHJ5IiwiT2JqZWN0Iiwia2V5cyIsImNhY2hlIiwiZm9yRWFjaCIsImtleSIsImRlZmF1bHQiLCJiaW5kIiwidW5kZWZpbmVkIiwiaW5pdCIsImUiLCJkZXZTZXJ2ZXIiLCJXZWJwYWNrRGV2U2VydmVyIiwiZGV2TWlkZGxld2FyZSIsIm91dHB1dEZpbGVTeXN0ZW0iLCJzZXR1cE1pZGRsZXdhcmVzIiwibWlkZGxld2FyZXMiLCJFcnJvciIsIm90aGVyUm91dGVzIiwiV0VCUEFDS19QVUJMSUNfUEFUSCIsInByb3h5IiwiYXBwIiwiZ2V0IiwiUmVnRXhwIiwidXJsIiwiZW5kc1dpdGgiLCJzdGF0dXNDb2RlIiwic2V0SGVhZGVyIiwic2VuZCIsInNvY2tldCIsIm9uIiwicnVuU2VydmVyIiwic3RhcnQiLCJob29rcyIsImRvbmUiLCJ0YXAiLCJtdWx0aVN0YXRzIiwiaGFzT3duIiwic3RvcFNlcnZlciIsInN0b3AiLCJ3YXJuIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjcmlwdHMvc3RhcnREZXZzZXJ2ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG5pbXBvcnQgeyBwcm9taXNpZnkgfSBmcm9tICd1dGlsJztcbmltcG9ydCBkaXNrRnMgZnJvbSAnZnMnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgd2VicGFjaywgeyBNdWx0aUNvbXBpbGVyIH0gZnJvbSAnd2VicGFjayc7XG5pbXBvcnQgeyBjcmVhdGVGc0Zyb21Wb2x1bWUsIFZvbHVtZSB9IGZyb20gJ21lbWZzJztcbmltcG9ydCB7IFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ2h0dHAnO1xuaW1wb3J0IHR5cGUgeyBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB0bXAgZnJvbSAndG1wJztcbmltcG9ydCBzb3VyY2VNYXBTdXBwb3J0IGZyb20gJ3NvdXJjZS1tYXAtc3VwcG9ydCc7XG5pbXBvcnQgeyB1ZnMgfSBmcm9tICd1bmlvbmZzJztcbmltcG9ydCBXZWJwYWNrRGV2U2VydmVyIGZyb20gJ3dlYnBhY2stZGV2LXNlcnZlcic7XG5pbXBvcnQgbG9nZ2luZyBmcm9tICd3ZWJwYWNrL2xpYi9sb2dnaW5nL3J1bnRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlRnNSZXF1aXJlIH0gZnJvbSAnZnMtcmVxdWlyZSc7XG5cbmltcG9ydCAnY3Jvc3MtZmV0Y2gvcG9seWZpbGwnO1xuaW1wb3J0IHsgQm91bmRSZW5kZXIgfSBmcm9tICcuL3R5cGVzJztcblxuLy8gcnVuIGRpcmVjdGx5IGZyb20gbm9kZVxuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIGNvbnN0IGVudHJ5cG9pbnQgPSBwcm9jZXNzLmFyZ3ZbMl07XG5cbiAgaWYgKCFlbnRyeXBvaW50KSB7XG4gICAgY29uc29sZS5sb2coYFVzYWdlOiBzdGFydC1hbmFuc2kgPGVudHJ5cG9pbnQtZmlsZT5gKTtcbiAgICBwcm9jZXNzLmV4aXQoLTEpO1xuICB9XG5cbiAgc3RhcnREZXZTZXJ2ZXIoZW50cnlwb2ludCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHN0YXJ0RGV2U2VydmVyKFxuICBlbnRyeXBvaW50OiBzdHJpbmcsXG4gIGVudjogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSxcbikge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICBjb25zdCB3ZWJwYWNrQ29uZmlnID0gcmVxdWlyZShyZXF1aXJlLnJlc29sdmUoXG4gICAgLy8gVE9ETzogdXNlIG5vcm1hbCByZXNvbHV0aW9uIGFsZ29yaXRobSB0byBmaW5kIHdlYnBhY2sgZmlsZVxuICAgIHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnd2VicGFjay5jb25maWcnKSxcbiAgKSk7XG5cbiAgY29uc3QgbG9nID0gbG9nZ2luZy5nZXRMb2dnZXIoJ2FuYW5zaS1kZXZzZXJ2ZXInKTtcblxuICAvLyBTZXQgdXAgaW4gbWVtb3J5IGZpbGVzeXN0ZW1cbiAgY29uc3Qgdm9sdW1lID0gbmV3IFZvbHVtZSgpO1xuICBjb25zdCBmcyA9IGNyZWF0ZUZzRnJvbVZvbHVtZSh2b2x1bWUpO1xuICB1ZnMudXNlKGRpc2tGcykudXNlKGZzIGFzIGFueSk7XG5cbiAgY29uc3QgZnNSZXF1aXJlID0gY3JlYXRlRnNSZXF1aXJlKHVmcyk7XG4gIGNvbnN0IHJlYWRGaWxlID0gcHJvbWlzaWZ5KHVmcy5yZWFkRmlsZSk7XG4gIGxldCBzZXJ2ZXI6IFNlcnZlciB8IHVuZGVmaW5lZDtcblxuICAvLyBHZW5lcmF0ZSBhIHRlbXBvcmFyeSBmaWxlIHNvIHdlIGNhbiBob3QgcmVsb2FkIGZyb20gdGhlIHJvb3Qgb2YgdGhlIGFwcGxpY2F0aW9uXG4gIGZ1bmN0aW9uIGhvdEVudHJ5KGVudHJ5UGF0aDogc3RyaW5nKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgLy8gQHRzLWlnbm9yZSBmb3Igc29tZSByZWFzb24gaXQncyBub3QgcGlja2luZyB1cCB0aGF0IG90aGVyIG9wdGlvbnMgYXJlIG9wdGlvbmFsXG4gICAgY29uc3QgZ2VuZXJhdGVkRW50cnlwb2ludCA9IHRtcC5maWxlU3luYyh7IHBvc3RmaXg6ICcuanMnIH0pO1xuICAgIGRpc2tGcy53cml0ZVN5bmMoXG4gICAgICBnZW5lcmF0ZWRFbnRyeXBvaW50LmZkLFxuICAgICAgYFxuICBpbXBvcnQgZW50cnkgZnJvbSBcIiR7cGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGVudHJ5UGF0aCl9XCI7XG5cbiAgaWYgKG1vZHVsZS5ob3QpIHtcbiAgICBtb2R1bGUuaG90LmFjY2VwdCgpO1xuICB9XG5cbiAgZXhwb3J0IGRlZmF1bHQgZW50cnk7XG4gICAgYCxcbiAgICApO1xuICAgIHJldHVybiBnZW5lcmF0ZWRFbnRyeXBvaW50O1xuICB9XG5cbiAgY29uc3Qgd2VicGFja0NvbmZpZ3MgPSBbXG4gICAgd2VicGFja0NvbmZpZyhcbiAgICAgIHtcbiAgICAgICAgLi4uZW52LFxuICAgICAgICBlbnRyeXBhdGg6IGhvdEVudHJ5KGVudHJ5cG9pbnQpLm5hbWUsXG4gICAgICAgIG5hbWU6ICdjbGllbnQnLFxuICAgICAgfSxcbiAgICAgIHsgbW9kZTogJ2RldmVsb3BtZW50JyB9LFxuICAgICksXG4gICAgd2VicGFja0NvbmZpZyhcbiAgICAgIHtcbiAgICAgICAgLi4uZW52LFxuICAgICAgICBlbnRyeXBhdGg6IGVudHJ5cG9pbnQucmVwbGFjZSgnLnRzeCcsICcuc2VydmVyLnRzeCcpLFxuICAgICAgICBuYW1lOiAnc2VydmVyJyxcbiAgICAgICAgQlJPV1NFUlNMSVNUX0VOVjogJ2N1cnJlbnQgbm9kZScsXG4gICAgICB9LFxuICAgICAgeyBtb2RlOiAnZGV2ZWxvcG1lbnQnLCB0YXJnZXQ6ICdub2RlJyB9LFxuICAgICksXG4gIF0gYXMgY29uc3Q7XG5cbiAgLy8gaW5pdGlhbGl6ZSB0aGUgd2VicGFjayBjb21waWxlclxuICBjb25zdCBjb21waWxlcjogTXVsdGlDb21waWxlciA9IHdlYnBhY2sod2VicGFja0NvbmZpZ3MpO1xuXG4gIHNvdXJjZU1hcFN1cHBvcnQuaW5zdGFsbCh7IGhvb2tSZXF1aXJlOiB0cnVlIH0pO1xuXG4gIGZ1bmN0aW9uIGdldFNlcnZlckJ1bmRsZShzZXJ2ZXJTdGF0czogd2VicGFjay5TdGF0cykge1xuICAgIGNvbnN0IHNlcnZlckpzb24gPSBzZXJ2ZXJTdGF0cy50b0pzb24oeyBhc3NldHM6IHRydWUgfSk7XG4gICAgcmV0dXJuIHBhdGguam9pbihzZXJ2ZXJKc29uLm91dHB1dFBhdGggPz8gJycsICdzZXJ2ZXIuanMnKTtcbiAgfVxuICBmdW5jdGlvbiBoYW5kbGVFcnJvcnM8XG4gICAgRiBleHRlbmRzIChcbiAgICAgIHJlcTogUmVxdWVzdCB8IEluY29taW5nTWVzc2FnZSxcbiAgICAgIHJlczogUmVzcG9uc2UgfCBTZXJ2ZXJSZXNwb25zZSxcbiAgICApID0+IFByb21pc2U8dm9pZD4sXG4gID4oZm46IEYpIHtcbiAgICByZXR1cm4gYXN5bmMgZnVuY3Rpb24gKFxuICAgICAgcmVxOiBSZXF1ZXN0IHwgSW5jb21pbmdNZXNzYWdlLFxuICAgICAgcmVzOiBSZXNwb25zZSB8IFNlcnZlclJlc3BvbnNlLFxuICAgICAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuICAgICkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZuKHJlcSwgcmVzKTtcbiAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgbmV4dCh4KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgbGV0IGluaXRSZW5kZXI6XG4gICAgfCB7IGFyZ3M6IFBhcmFtZXRlcnM8Qm91bmRSZW5kZXI+OyByZXNvbHZlOiAoKSA9PiB2b2lkIH1bXVxuICAgIHwgdW5kZWZpbmVkID0gW107XG4gIGxldCByZW5kZXI6IEJvdW5kUmVuZGVyID0gKC4uLmFyZ3MpID0+XG4gICAgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBpbml0UmVuZGVyPy5wdXNoKHsgYXJncywgcmVzb2x2ZSB9KTtcbiAgICB9KTtcblxuICBmdW5jdGlvbiBpbXBvcnRSZW5kZXIoc3RhdHM6IHdlYnBhY2suU3RhdHNbXSkge1xuICAgIGNvbnN0IFtjbGllbnRTdGF0cywgc2VydmVyU3RhdHNdID0gc3RhdHM7XG4gICAgaWYgKFxuICAgICAgY2xpZW50U3RhdHM/LmNvbXBpbGF0aW9uPy5lcnJvcnM/Lmxlbmd0aCB8fFxuICAgICAgc2VydmVyU3RhdHM/LmNvbXBpbGF0aW9uPy5lcnJvcnM/Lmxlbmd0aFxuICAgICkge1xuICAgICAgbG9nLmVycm9yKCdFcnJvcnMgZm9yIGNsaWVudCBidWlsZDogJyArIGNsaWVudFN0YXRzLmNvbXBpbGF0aW9uLmVycm9ycyk7XG4gICAgICBsb2cuZXJyb3IoJ0Vycm9ycyBmb3Igc2VydmVyIGJ1aWxkOiAnICsgc2VydmVyU3RhdHMuY29tcGlsYXRpb24uZXJyb3JzKTtcbiAgICAgIC8vIGZpcnN0IHRpbWUsIHJhdGhlciB0aGFuIHJlLXJlbmRlclxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaW5pdFJlbmRlcikpIHtcbiAgICAgICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgICAgIH1cbiAgICAgIGxvZy5lcnJvcignQWJvdmUgY29tcGlsZXIgZXJyb3JzIGJsb2NraW5nIHJlbG9hZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cuaW5mbygnTGF1bmNoaW5nIFNTUicpO1xuICAgIH1cblxuICAgIC8vIEFTU0VUU1xuICAgIGNvbnN0IGNsaWVudE1hbmlmZXN0ID0gY2xpZW50U3RhdHMudG9Kc29uKCk7XG5cbiAgICBjb25zdCBzZXJ2ZXJFbnRyeSA9IGdldFNlcnZlckJ1bmRsZShzZXJ2ZXJTdGF0cyk7XG4gICAgLy8gcmVsb2FkIG1vZHVsZXNcbiAgICBPYmplY3Qua2V5cyhmc1JlcXVpcmUuY2FjaGUpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGRlbGV0ZSBmc1JlcXVpcmUuY2FjaGVba2V5XTtcbiAgICB9KTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICAgIHJlbmRlciA9IChmc1JlcXVpcmUoc2VydmVyRW50cnkpIGFzIGFueSkuZGVmYXVsdC5iaW5kKFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgY2xpZW50TWFuaWZlc3QsXG4gICAgKTtcbiAgICAvLyBTRVJWRVIgU0lERSBFTlRSWVBPSU5UXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoaW5pdFJlbmRlcikpIHtcbiAgICAgIGluaXRSZW5kZXIuZm9yRWFjaChhc3luYyBpbml0ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsb2cuaW5mbygnUmVzb2x2aW5nIHF1ZXVlZCByZXF1ZXN0cycpO1xuICAgICAgICAgIGF3YWl0IHJlbmRlciguLi5pbml0LmFyZ3MpO1xuICAgICAgICAgIGluaXQucmVzb2x2ZSgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgbG9nLmVycm9yKCdFcnJvciB3aGVuIGF0dGVtcHRpbmcgdG8gcmVuZGVyIHF1ZXVlZCByZXF1ZXN0cycpO1xuICAgICAgICAgIGxvZy5lcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpbml0UmVuZGVyID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGRldlNlcnZlciA9IG5ldyBXZWJwYWNrRGV2U2VydmVyKFxuICAgIC8vIHdyaXRlIHRvIG1lbW9yeSBmaWxlc3lzdGVtIHNvIHdlIGNhbiBpbXBvcnRcbiAgICB7XG4gICAgICAuLi53ZWJwYWNrQ29uZmlnc1swXS5kZXZTZXJ2ZXIsXG4gICAgICBkZXZNaWRkbGV3YXJlOiB7XG4gICAgICAgIC4uLndlYnBhY2tDb25maWdzWzBdPy5kZXZTZXJ2ZXI/LmRldk1pZGRsZXdhcmUsXG4gICAgICAgIG91dHB1dEZpbGVTeXN0ZW06IHtcbiAgICAgICAgICAuLi5mcyxcbiAgICAgICAgICBqb2luOiBwYXRoLmpvaW4gYXMgYW55LFxuICAgICAgICB9IGFzIGFueSBhcyB0eXBlb2YgZnMsXG4gICAgICB9LFxuICAgICAgc2V0dXBNaWRkbGV3YXJlczogKG1pZGRsZXdhcmVzLCBkZXZTZXJ2ZXIpID0+IHtcbiAgICAgICAgaWYgKCFkZXZTZXJ2ZXIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dlYnBhY2stZGV2LXNlcnZlciBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3RoZXJSb3V0ZXMgPSBbXG4gICAgICAgICAgcHJvY2Vzcy5lbnYuV0VCUEFDS19QVUJMSUNfUEFUSCxcbiAgICAgICAgICAuLi5PYmplY3Qua2V5cyh3ZWJwYWNrQ29uZmlnc1swXS5kZXZTZXJ2ZXI/LnByb3h5ID8/IHt9KSxcbiAgICAgICAgXTtcbiAgICAgICAgLy8gc2VydmUgU1NSIGZvciBub24tV0VCUEFDS19QVUJMSUNfUEFUSFxuICAgICAgICBkZXZTZXJ2ZXIuYXBwPy5nZXQoXG4gICAgICAgICAgbmV3IFJlZ0V4cChgXig/ISR7b3RoZXJSb3V0ZXMuam9pbignfCcpfSlgKSxcbiAgICAgICAgICBoYW5kbGVFcnJvcnMoYXN5bmMgZnVuY3Rpb24gKHJlcTogYW55LCByZXM6IGFueSkge1xuICAgICAgICAgICAgaWYgKHJlcS51cmwuZW5kc1dpdGgoJ2Zhdmljb24uaWNvJykpIHtcbiAgICAgICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSA0MDQ7XG4gICAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICd0ZXh0L2h0bWwnKTtcbiAgICAgICAgICAgICAgcmVzLnNlbmQoJ25vdCBmb3VuZCcpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMuc29ja2V0Lm9uKCdlcnJvcicsIChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYXRhbCcsIGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBhd2FpdCByZW5kZXIocmVxLCByZXMpO1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmICh3ZWJwYWNrQ29uZmlnc1swXS5kZXZTZXJ2ZXI/LnNldHVwTWlkZGxld2FyZXMpIHtcbiAgICAgICAgICByZXR1cm4gd2VicGFja0NvbmZpZ3NbMF0uZGV2U2VydmVyLnNldHVwTWlkZGxld2FyZXMoXG4gICAgICAgICAgICBtaWRkbGV3YXJlcyxcbiAgICAgICAgICAgIGRldlNlcnZlcixcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1pZGRsZXdhcmVzO1xuICAgICAgfSxcbiAgICB9LFxuICAgIGNvbXBpbGVyLFxuICApO1xuICBjb25zdCBydW5TZXJ2ZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgZGV2U2VydmVyLnN0YXJ0KCk7XG4gICAgZGV2U2VydmVyLmNvbXBpbGVyLmhvb2tzLmRvbmUudGFwKFxuICAgICAgJ0FuYW5zaSBTZXJ2ZXInLFxuICAgICAgKG11bHRpU3RhdHM6IHdlYnBhY2suTXVsdGlTdGF0cyB8IHdlYnBhY2suU3RhdHMpID0+IHtcbiAgICAgICAgaWYgKCFtdWx0aVN0YXRzKSB7XG4gICAgICAgICAgbG9nLmVycm9yKCdzdGF0cyBub3Qgc2VuZCcpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgtMSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIU9iamVjdC5oYXNPd24obXVsdGlTdGF0cywgJ3N0YXRzJykpIHJldHVybjtcbiAgICAgICAgaWYgKChtdWx0aVN0YXRzIGFzIHdlYnBhY2suTXVsdGlTdGF0cykuc3RhdHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpbXBvcnRSZW5kZXIoKG11bHRpU3RhdHMgYXMgd2VicGFjay5NdWx0aVN0YXRzKS5zdGF0cyk7XG4gICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICBsb2cuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHNlcnZlIGVudHJ5cG9pbnQnKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvZy5lcnJvcignT25seSBjb21waWxlciBvbmUgc3RhdCcpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG4gIH07XG4gIGNvbnN0IHN0b3BTZXJ2ZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgbG9nLmluZm8oJ1N0b3BwaW5nIHNlcnZlci4uLicpO1xuICAgIGF3YWl0IGRldlNlcnZlci5zdG9wKCk7XG4gICAgbG9nLmluZm8oJ1NlcnZlciBjbG9zZWQnKTtcbiAgfTtcblxuICBwcm9jZXNzLm9uKCdTSUdJTlQnLCAoKSA9PiB7XG4gICAgbG9nLndhcm4oJ1JlY2VpdmVkIFNJR0lOVCwgZGV2c2VydmVyIHNodXR0aW5nIGRvd24nKTtcbiAgICBzdG9wU2VydmVyKCk7XG4gICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgfSk7XG5cbiAgcnVuU2VydmVyKCk7XG59XG4iXSwi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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anansi/core",
3
- "version": "0.11.2",
3
+ "version": "0.12.0",
4
4
  "description": "React 18 Framework",
5
5
  "homepage": "https://github.com/ntucker/anansi/tree/master/packages/core#readme",
6
6
  "repository": {
@@ -65,11 +65,11 @@
65
65
  "browser"
66
66
  ],
67
67
  "devDependencies": {
68
- "@anansi/babel-preset": "^3.2.4",
68
+ "@anansi/babel-preset": "^3.2.5",
69
69
  "@anansi/browserslist-config": "1.3.3",
70
- "@anansi/webpack-config": "^11.6.4",
70
+ "@anansi/webpack-config": "^11.6.5",
71
71
  "@babel/cli": "7.17.10",
72
- "@babel/core": "7.18.2",
72
+ "@babel/core": "7.18.5",
73
73
  "@types/compression": "^1.7.2",
74
74
  "@types/source-map-support": "^0.5.4",
75
75
  "@types/tmp": "^0.2.3",
@@ -80,7 +80,7 @@
80
80
  "webpack-cli": "4.10.0"
81
81
  },
82
82
  "dependencies": {
83
- "@anansi/router": "^0.6.2",
83
+ "@anansi/router": "^0.6.3",
84
84
  "@babel/runtime": "^7.10.5",
85
85
  "@rest-hooks/ssr": "^0.2.0",
86
86
  "chalk": "^4.0.0",
package/src/laySpouts.tsx CHANGED
@@ -8,32 +8,19 @@ export default function laySpouts(
8
8
  spouts: (props: ServerProps) => Promise<{
9
9
  app: JSX.Element;
10
10
  }>,
11
- { timeoutMS = 200 }: { timeoutMS?: number } = {},
11
+ {
12
+ timeoutMS = 200,
13
+ onError,
14
+ }: { timeoutMS?: number; onError?: (error: unknown) => void } = {},
12
15
  ) {
13
16
  const render: Render = async (clientManifest, req, res) => {
14
17
  const nonce = crypto.randomBytes(16).toString('base64');
15
18
 
16
- const { app } = await spouts({ clientManifest, req, res, nonce });
17
- let didError = false;
18
- const { pipe, abort } = reactRender(
19
- app,
20
- /*
21
- This is not documented, so included the types here for reference:
22
- type Options = {|
23
- identifierPrefix?: string,
24
- namespaceURI?: string,
25
- nonce?: string,
26
- bootstrapScriptContent?: string,
27
- bootstrapScripts?: Array<string>,
28
- bootstrapModules?: Array<string>,
29
- progressiveChunkSize?: number,
30
- onShellReady?: () => void,
31
- onShellError?: () => void,
32
- onAllReady?: () => void,
33
- onError?: (error: mixed) => void,
34
- |};
35
- */
36
- {
19
+ try {
20
+ const { app } = await spouts({ clientManifest, req, res, nonce });
21
+
22
+ let didError = false;
23
+ const { pipe, abort } = reactRender(app, {
37
24
  nonce,
38
25
  //bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),
39
26
  onShellReady() {
@@ -48,17 +35,24 @@ type Options = {|
48
35
  res.statusCode = 500;
49
36
  pipe(res);
50
37
  },
51
- onError(x: any) {
38
+ onError(e: any) {
52
39
  didError = true;
53
- console.error(x);
40
+ console.error(e);
54
41
  res.statusCode = 500;
55
42
  //pipe(res); Removing this avoids, "React currently only supports piping to one writable stream."
43
+ if (onError) onError(e);
56
44
  },
57
- },
58
- );
59
- // Abandon and switch to client rendering if enough time passes.
60
- // Try lowering this to see the client recover.
61
- setTimeout(abort, timeoutMS);
45
+ });
46
+ // Abandon and switch to client rendering if enough time passes.
47
+ // Try lowering this to see the client recover.
48
+ setTimeout(
49
+ () => (abort as any)(`Timeout of ${timeoutMS}ms exceeded`),
50
+ timeoutMS,
51
+ );
52
+ } catch (e: unknown) {
53
+ if (onError) onError(e);
54
+ throw e;
55
+ }
62
56
  };
63
57
  return render;
64
58
  }
@@ -134,8 +134,12 @@ export default function startDevServer(
134
134
  ) {
135
135
  log.error('Errors for client build: ' + clientStats.compilation.errors);
136
136
  log.error('Errors for server build: ' + serverStats.compilation.errors);
137
- // TODO: handle more gracefully
138
- process.exit(-1);
137
+ // first time, rather than re-render
138
+ if (Array.isArray(initRender)) {
139
+ process.exit(-1);
140
+ }
141
+ log.error('Above compiler errors blocking reload');
142
+ return;
139
143
  } else {
140
144
  log.info('Launching SSR');
141
145
  }