react-streaming
Advanced tools
Comparing version 0.3.18 to 0.3.19-commit-20b3bc7
export { renderToStream }; | ||
export { disable }; | ||
export { renderToNodeStream_set }; | ||
import React from 'react'; | ||
import type { renderToPipeableStream as RenderToPipeableStream, renderToReadableStream as RenderToReadableStream } from 'react-dom/server'; | ||
import { Pipe } from './renderToStream/createPipeWrapper'; | ||
import type { Pipe } from './renderToStream/createPipeWrapper'; | ||
import { SeoStrategy } from './renderToStream/resolveSeoStrategy'; | ||
import type { renderToNodeStream as RenderToNodeStream } from './renderToStream/renderToNodeStream'; | ||
declare type Options = { | ||
@@ -29,1 +31,2 @@ webStream?: boolean; | ||
declare function renderToStream(element: React.ReactNode, options?: Options): Promise<Result>; | ||
declare function renderToNodeStream_set(renderToNodeStream: typeof RenderToNodeStream): void; |
@@ -29,3 +29,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.disable = exports.renderToStream = void 0; | ||
exports.renderToNodeStream_set = exports.disable = exports.renderToStream = void 0; | ||
const react_1 = __importDefault(require("react")); | ||
@@ -35,9 +35,10 @@ const server_1 = __importStar(require("react-dom/server")); | ||
const useStream_1 = require("./useStream"); | ||
const createPipeWrapper_1 = require("./renderToStream/createPipeWrapper"); | ||
const createReadableWrapper_1 = require("./renderToStream/createReadableWrapper"); | ||
const resolveSeoStrategy_1 = require("./renderToStream/resolveSeoStrategy"); | ||
const utils_1 = require("./utils"); | ||
const loadNodeStreamModule_1 = require("./renderToStream/loadNodeStreamModule"); | ||
const import_1 = __importDefault(require("@brillout/import")); | ||
const debug = (0, utils_1.createDebugger)('react-streaming:flow'); | ||
const renderToWebStream_1 = require("./renderToStream/renderToWebStream"); | ||
const misc_1 = require("./renderToStream/misc"); | ||
const globalObject = (0, utils_1.getGlobalObject)('renderToStream.ts', { | ||
renderToNodeStream: null | ||
}); | ||
assertReact(); | ||
@@ -66,10 +67,10 @@ const globalConfig = (globalThis.__react_streaming = globalThis | ||
const webStream = (_b = options.webStream) !== null && _b !== void 0 ? _b : !(await (0, loadNodeStreamModule_1.nodeStreamModuleIsAvailable)()); | ||
debug(`disable === ${disable} && webStream === ${webStream}`); | ||
(0, misc_1.debugFlow)(`disable === ${disable} && webStream === ${webStream}`); | ||
let result; | ||
const resultPartial = { disabled: disable }; | ||
if (!webStream) { | ||
result = Object.assign(Object.assign({}, resultPartial), (await renderToNodeStream(element, disable, options))); | ||
result = Object.assign(Object.assign({}, resultPartial), (await globalObject.renderToNodeStream(element, disable, options))); | ||
} | ||
else { | ||
result = Object.assign(Object.assign({}, resultPartial), (await renderToWebStream(element, disable, options))); | ||
result = Object.assign(Object.assign({}, resultPartial), (await (0, renderToWebStream_1.renderToWebStream)(element, disable, options))); | ||
} | ||
@@ -79,141 +80,10 @@ injectToStream = result.injectToStream; | ||
buffer.length = 0; | ||
debug('promise `await renderToStream()` resolved'); | ||
(0, misc_1.debugFlow)('promise `await renderToStream()` resolved'); | ||
return result; | ||
} | ||
exports.renderToStream = renderToStream; | ||
async function renderToNodeStream(element, disable, options) { | ||
var _a; | ||
debug('creating Node.js Stream Pipe'); | ||
let onAllReady; | ||
const allReady = new Promise((r) => { | ||
onAllReady = () => r(); | ||
}); | ||
let onShellReady; | ||
const shellReady = new Promise((r) => { | ||
onShellReady = () => r(); | ||
}); | ||
let didError = false; | ||
let firstErr = null; | ||
let reactBug = null; | ||
const onError = (err) => { | ||
debug('[react] onError() / onShellError()'); | ||
didError = true; | ||
firstErr !== null && firstErr !== void 0 ? firstErr : (firstErr = err); | ||
onShellReady(); | ||
afterReactBugCatch(() => { | ||
var _a; | ||
// Is not a React internal error (i.e. a React bug) | ||
if (err !== reactBug) { | ||
(_a = options.onBoundaryError) === null || _a === void 0 ? void 0 : _a.call(options, err); | ||
} | ||
}); | ||
}; | ||
const renderToPipeableStream = (_a = options.renderToPipeableStream) !== null && _a !== void 0 ? _a : | ||
// We don't directly use import() because it shouldn't be bundled for Cloudflare Workers: the module react-dom/server.node contains a require('stream') which fails on Cloudflare Workers | ||
(await (0, import_1.default)('react-dom/server.node')).renderToPipeableStream; | ||
assertReactImport(renderToPipeableStream, 'renderToPipeableStream'); | ||
const { pipe: pipeOriginal } = renderToPipeableStream(element, { | ||
onShellReady() { | ||
debug('[react] onShellReady()'); | ||
onShellReady(); | ||
}, | ||
onAllReady() { | ||
debug('[react] onAllReady()'); | ||
onShellReady(); | ||
onAllReady(); | ||
}, | ||
onShellError: onError, | ||
onError | ||
}); | ||
let promiseResolved = false; | ||
const { pipeForUser, injectToStream, streamEnd } = await (0, createPipeWrapper_1.createPipeWrapper)(pipeOriginal, { | ||
onReactBug(err) { | ||
debug('react bug'); | ||
didError = true; | ||
firstErr !== null && firstErr !== void 0 ? firstErr : (firstErr = err); | ||
reactBug = err; | ||
// Only log if it wasn't used as rejection for `await renderToStream()` | ||
if (reactBug !== firstErr || promiseResolved) { | ||
console.error(reactBug); | ||
} | ||
} | ||
}); | ||
await shellReady; | ||
if (didError) | ||
throw firstErr; | ||
if (disable) | ||
await allReady; | ||
if (didError) | ||
throw firstErr; | ||
promiseResolved = true; | ||
return { | ||
pipe: pipeForUser, | ||
readable: null, | ||
streamEnd: wrapStreamEnd(streamEnd, didError), | ||
injectToStream | ||
}; | ||
function renderToNodeStream_set(renderToNodeStream) { | ||
globalObject.renderToNodeStream = renderToNodeStream; | ||
} | ||
async function renderToWebStream(element, disable, options) { | ||
var _a; | ||
debug('creating Web Stream Pipe'); | ||
let didError = false; | ||
let firstErr = null; | ||
let reactBug = null; | ||
const onError = (err) => { | ||
didError = true; | ||
firstErr = firstErr || err; | ||
afterReactBugCatch(() => { | ||
var _a; | ||
// Is not a React internal error (i.e. a React bug) | ||
if (err !== reactBug) { | ||
(_a = options.onBoundaryError) === null || _a === void 0 ? void 0 : _a.call(options, err); | ||
} | ||
}); | ||
}; | ||
const renderToReadableStream = (_a = options.renderToReadableStream) !== null && _a !== void 0 ? _a : | ||
// We directly use import() because it needs to be bundled for Cloudflare Workers | ||
(await import('react-dom/server.browser')).renderToReadableStream; | ||
assertReactImport(renderToReadableStream, 'renderToReadableStream'); | ||
const readableOriginal = await renderToReadableStream(element, { onError }); | ||
const { allReady } = readableOriginal; | ||
let promiseResolved = false; | ||
// Upon React internal errors (i.e. React bugs), React rejects `allReady`. | ||
// React doesn't reject `allReady` upon boundary errors. | ||
allReady.catch((err) => { | ||
debug('react bug'); | ||
didError = true; | ||
firstErr = firstErr || err; | ||
reactBug = err; | ||
// Only log if it wasn't used as rejection for `await renderToStream()` | ||
if (reactBug !== firstErr || promiseResolved) { | ||
console.error(reactBug); | ||
} | ||
}); | ||
if (didError) | ||
throw firstErr; | ||
if (disable) | ||
await allReady; | ||
if (didError) | ||
throw firstErr; | ||
const { readableForUser, streamEnd, injectToStream } = (0, createReadableWrapper_1.createReadableWrapper)(readableOriginal); | ||
promiseResolved = true; | ||
return { | ||
readable: readableForUser, | ||
pipe: null, | ||
streamEnd: wrapStreamEnd(streamEnd, didError), | ||
injectToStream | ||
}; | ||
} | ||
// Needed for the hacky solution to workaround https://github.com/facebook/react/issues/24536 | ||
function afterReactBugCatch(fn) { | ||
setTimeout(() => { | ||
fn(); | ||
}, 0); | ||
} | ||
function wrapStreamEnd(streamEnd, didError) { | ||
return (streamEnd | ||
// Needed because of the `afterReactBugCatch()` hack above, otherwise `onBoundaryError` triggers after `streamEnd` resolved | ||
.then(() => new Promise((r) => setTimeout(r, 0))) | ||
.then(() => !didError)); | ||
} | ||
exports.renderToNodeStream_set = renderToNodeStream_set; | ||
// To debug wrong peer dependency loading: | ||
@@ -228,5 +98,1 @@ // - https://stackoverflow.com/questions/21056748/seriously-debugging-node-js-cannot-find-module-xyz-abcd | ||
} | ||
function assertReactImport(fn, fnName) { | ||
(0, utils_1.assert)(typeof fn === 'function'); | ||
(0, utils_1.assertUsage)(fn, `Couldn't import ${fnName}() from 'react-dom'`); | ||
} |
@@ -32,10 +32,9 @@ "use strict"; | ||
}); | ||
const { StreamContext } = globalObject; | ||
const StreamProvider = StreamContext.Provider; | ||
const StreamProvider = globalObject.StreamContext.Provider; | ||
exports.StreamProvider = StreamProvider; | ||
function useStream() { | ||
const streamUtils = (0, react_1.useContext)(StreamContext); | ||
(0, utils_1.assert)(streamUtils); | ||
const streamUtils = (0, react_1.useContext)(globalObject.StreamContext); | ||
(0, utils_1.assertUsage)(streamUtils, `react-streaming isn't installed`); | ||
return streamUtils; | ||
} | ||
exports.useStream = useStream; |
export declare function getGlobalObject<T extends Record<string, unknown> = never>(key: `${string}.ts`, defaultValue: T): T; | ||
declare global { | ||
var __react_streaming: undefined | Record<string, Record<string, unknown>>; | ||
} |
@@ -5,8 +5,10 @@ "use strict"; | ||
function getGlobalObject( | ||
// We use the filename as key; each `getGlobalObject()` call should live in a unique filename. | ||
// We use the filename as key; each `getGlobalObject()` call should live inside a file with a unique filename. | ||
key, defaultValue) { | ||
const allGlobalObjects = (globalThis.__react_streaming = globalThis.__react_streaming || {}); | ||
const globalObject = (allGlobalObjects[key] = allGlobalObjects[key] || defaultValue); | ||
// @ts-ignore | ||
const globalObjectsAll = (globalThis[projectKey] = globalThis[projectKey] || {}); | ||
const globalObject = (globalObjectsAll[key] = globalObjectsAll[key] || defaultValue); | ||
return globalObject; | ||
} | ||
exports.getGlobalObject = getGlobalObject; | ||
const projectKey = '_react_streaming'; |
@@ -1,2 +0,3 @@ | ||
export declare const projectInfo: { | ||
export { projectInfo }; | ||
declare const projectInfo: { | ||
projectName: "react-streaming"; | ||
@@ -7,4 +8,1 @@ projectVersion: string; | ||
}; | ||
declare global { | ||
var __vite_plugin_ssr__instances: undefined | string[]; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.projectInfo = void 0; | ||
const PROJECT_VERSION = '0.3.18'; | ||
exports.projectInfo = { | ||
const getGlobalObject_1 = require("./getGlobalObject"); | ||
const PROJECT_VERSION = '0.3.19-commit-20b3bc7'; | ||
const projectInfo = { | ||
projectName: 'react-streaming', | ||
@@ -11,4 +12,12 @@ projectVersion: PROJECT_VERSION, | ||
}; | ||
// Trick: since `utils/asserts.ts` depends on this file (`utils/projectInfo.ts`), we can have confidence that this file is always instantiated. So that we don't have to initialize this code snippet at every possible entry. (There are a *lot* of entries: `client/router/`, `client/`, `node/`, `node/plugin/`, `node/cli`, etc.) | ||
globalThis.__vite_plugin_ssr__instances = globalThis.__vite_plugin_ssr__instances || []; | ||
globalThis.__vite_plugin_ssr__instances.push(exports.projectInfo.projectVersion); | ||
exports.projectInfo = projectInfo; | ||
const { versions } = (0, getGlobalObject_1.getGlobalObject)('projectInfo.ts', { | ||
versions: new Set() | ||
}); | ||
versions.add(projectInfo.projectVersion); | ||
if (versions.size >= 2) { | ||
const versionsStr = Array.from(versions) | ||
.map((v) => `${projectInfo.projectName}@${v}`) | ||
.join('and'); | ||
throw new Error(`Using different versions is forbidden, but ${versionsStr} are loaded. Make sure only one version is loaded.`); | ||
} |
export { renderToStream }; | ||
export { disable }; | ||
export { renderToNodeStream_set }; | ||
import React from 'react'; | ||
import type { renderToPipeableStream as RenderToPipeableStream, renderToReadableStream as RenderToReadableStream } from 'react-dom/server'; | ||
import { Pipe } from './renderToStream/createPipeWrapper'; | ||
import type { Pipe } from './renderToStream/createPipeWrapper'; | ||
import { SeoStrategy } from './renderToStream/resolveSeoStrategy'; | ||
import type { renderToNodeStream as RenderToNodeStream } from './renderToStream/renderToNodeStream'; | ||
declare type Options = { | ||
@@ -29,1 +31,2 @@ webStream?: boolean; | ||
declare function renderToStream(element: React.ReactNode, options?: Options): Promise<Result>; | ||
declare function renderToNodeStream_set(renderToNodeStream: typeof RenderToNodeStream): void; |
export { renderToStream }; | ||
export { disable }; | ||
export { renderToNodeStream_set }; | ||
import React from 'react'; | ||
@@ -7,9 +8,10 @@ import ReactDOMServer, { version as reactDomVersion } from 'react-dom/server'; | ||
import { StreamProvider } from './useStream'; | ||
import { createPipeWrapper } from './renderToStream/createPipeWrapper'; | ||
import { createReadableWrapper } from './renderToStream/createReadableWrapper'; | ||
import { resolveSeoStrategy } from './renderToStream/resolveSeoStrategy'; | ||
import { assert, assertUsage, createDebugger } from './utils'; | ||
import { assert, assertUsage, getGlobalObject } from './utils'; | ||
import { nodeStreamModuleIsAvailable } from './renderToStream/loadNodeStreamModule'; | ||
import import_ from '@brillout/import'; | ||
const debug = createDebugger('react-streaming:flow'); | ||
import { renderToWebStream } from './renderToStream/renderToWebStream'; | ||
import { debugFlow } from './renderToStream/misc'; | ||
const globalObject = getGlobalObject('renderToStream.ts', { | ||
renderToNodeStream: null | ||
}); | ||
assertReact(); | ||
@@ -37,7 +39,7 @@ const globalConfig = (globalThis.__react_streaming = globalThis | ||
const webStream = (_b = options.webStream) !== null && _b !== void 0 ? _b : !(await nodeStreamModuleIsAvailable()); | ||
debug(`disable === ${disable} && webStream === ${webStream}`); | ||
debugFlow(`disable === ${disable} && webStream === ${webStream}`); | ||
let result; | ||
const resultPartial = { disabled: disable }; | ||
if (!webStream) { | ||
result = { ...resultPartial, ...(await renderToNodeStream(element, disable, options)) }; | ||
result = { ...resultPartial, ...(await globalObject.renderToNodeStream(element, disable, options)) }; | ||
} | ||
@@ -50,140 +52,8 @@ else { | ||
buffer.length = 0; | ||
debug('promise `await renderToStream()` resolved'); | ||
debugFlow('promise `await renderToStream()` resolved'); | ||
return result; | ||
} | ||
async function renderToNodeStream(element, disable, options) { | ||
var _a; | ||
debug('creating Node.js Stream Pipe'); | ||
let onAllReady; | ||
const allReady = new Promise((r) => { | ||
onAllReady = () => r(); | ||
}); | ||
let onShellReady; | ||
const shellReady = new Promise((r) => { | ||
onShellReady = () => r(); | ||
}); | ||
let didError = false; | ||
let firstErr = null; | ||
let reactBug = null; | ||
const onError = (err) => { | ||
debug('[react] onError() / onShellError()'); | ||
didError = true; | ||
firstErr !== null && firstErr !== void 0 ? firstErr : (firstErr = err); | ||
onShellReady(); | ||
afterReactBugCatch(() => { | ||
var _a; | ||
// Is not a React internal error (i.e. a React bug) | ||
if (err !== reactBug) { | ||
(_a = options.onBoundaryError) === null || _a === void 0 ? void 0 : _a.call(options, err); | ||
} | ||
}); | ||
}; | ||
const renderToPipeableStream = (_a = options.renderToPipeableStream) !== null && _a !== void 0 ? _a : | ||
// We don't directly use import() because it shouldn't be bundled for Cloudflare Workers: the module react-dom/server.node contains a require('stream') which fails on Cloudflare Workers | ||
(await import_('react-dom/server.node')).renderToPipeableStream; | ||
assertReactImport(renderToPipeableStream, 'renderToPipeableStream'); | ||
const { pipe: pipeOriginal } = renderToPipeableStream(element, { | ||
onShellReady() { | ||
debug('[react] onShellReady()'); | ||
onShellReady(); | ||
}, | ||
onAllReady() { | ||
debug('[react] onAllReady()'); | ||
onShellReady(); | ||
onAllReady(); | ||
}, | ||
onShellError: onError, | ||
onError | ||
}); | ||
let promiseResolved = false; | ||
const { pipeForUser, injectToStream, streamEnd } = await createPipeWrapper(pipeOriginal, { | ||
onReactBug(err) { | ||
debug('react bug'); | ||
didError = true; | ||
firstErr !== null && firstErr !== void 0 ? firstErr : (firstErr = err); | ||
reactBug = err; | ||
// Only log if it wasn't used as rejection for `await renderToStream()` | ||
if (reactBug !== firstErr || promiseResolved) { | ||
console.error(reactBug); | ||
} | ||
} | ||
}); | ||
await shellReady; | ||
if (didError) | ||
throw firstErr; | ||
if (disable) | ||
await allReady; | ||
if (didError) | ||
throw firstErr; | ||
promiseResolved = true; | ||
return { | ||
pipe: pipeForUser, | ||
readable: null, | ||
streamEnd: wrapStreamEnd(streamEnd, didError), | ||
injectToStream | ||
}; | ||
function renderToNodeStream_set(renderToNodeStream) { | ||
globalObject.renderToNodeStream = renderToNodeStream; | ||
} | ||
async function renderToWebStream(element, disable, options) { | ||
var _a; | ||
debug('creating Web Stream Pipe'); | ||
let didError = false; | ||
let firstErr = null; | ||
let reactBug = null; | ||
const onError = (err) => { | ||
didError = true; | ||
firstErr = firstErr || err; | ||
afterReactBugCatch(() => { | ||
var _a; | ||
// Is not a React internal error (i.e. a React bug) | ||
if (err !== reactBug) { | ||
(_a = options.onBoundaryError) === null || _a === void 0 ? void 0 : _a.call(options, err); | ||
} | ||
}); | ||
}; | ||
const renderToReadableStream = (_a = options.renderToReadableStream) !== null && _a !== void 0 ? _a : | ||
// We directly use import() because it needs to be bundled for Cloudflare Workers | ||
(await import('react-dom/server.browser')).renderToReadableStream; | ||
assertReactImport(renderToReadableStream, 'renderToReadableStream'); | ||
const readableOriginal = await renderToReadableStream(element, { onError }); | ||
const { allReady } = readableOriginal; | ||
let promiseResolved = false; | ||
// Upon React internal errors (i.e. React bugs), React rejects `allReady`. | ||
// React doesn't reject `allReady` upon boundary errors. | ||
allReady.catch((err) => { | ||
debug('react bug'); | ||
didError = true; | ||
firstErr = firstErr || err; | ||
reactBug = err; | ||
// Only log if it wasn't used as rejection for `await renderToStream()` | ||
if (reactBug !== firstErr || promiseResolved) { | ||
console.error(reactBug); | ||
} | ||
}); | ||
if (didError) | ||
throw firstErr; | ||
if (disable) | ||
await allReady; | ||
if (didError) | ||
throw firstErr; | ||
const { readableForUser, streamEnd, injectToStream } = createReadableWrapper(readableOriginal); | ||
promiseResolved = true; | ||
return { | ||
readable: readableForUser, | ||
pipe: null, | ||
streamEnd: wrapStreamEnd(streamEnd, didError), | ||
injectToStream | ||
}; | ||
} | ||
// Needed for the hacky solution to workaround https://github.com/facebook/react/issues/24536 | ||
function afterReactBugCatch(fn) { | ||
setTimeout(() => { | ||
fn(); | ||
}, 0); | ||
} | ||
function wrapStreamEnd(streamEnd, didError) { | ||
return (streamEnd | ||
// Needed because of the `afterReactBugCatch()` hack above, otherwise `onBoundaryError` triggers after `streamEnd` resolved | ||
.then(() => new Promise((r) => setTimeout(r, 0))) | ||
.then(() => !didError)); | ||
} | ||
// To debug wrong peer dependency loading: | ||
@@ -198,5 +68,1 @@ // - https://stackoverflow.com/questions/21056748/seriously-debugging-node-js-cannot-find-module-xyz-abcd | ||
} | ||
function assertReactImport(fn, fnName) { | ||
assert(typeof fn === 'function'); | ||
assertUsage(fn, `Couldn't import ${fnName}() from 'react-dom'`); | ||
} |
export { useStream }; | ||
export { StreamProvider }; | ||
import React, { useContext } from 'react'; | ||
import { assert, getGlobalObject } from './utils'; | ||
import { assertUsage, getGlobalObject } from './utils'; | ||
const globalObject = getGlobalObject('useStream.ts', { | ||
StreamContext: React.createContext(null) | ||
}); | ||
const { StreamContext } = globalObject; | ||
const StreamProvider = StreamContext.Provider; | ||
const StreamProvider = globalObject.StreamContext.Provider; | ||
function useStream() { | ||
const streamUtils = useContext(StreamContext); | ||
assert(streamUtils); | ||
const streamUtils = useContext(globalObject.StreamContext); | ||
assertUsage(streamUtils, `react-streaming isn't installed`); | ||
return streamUtils; | ||
} |
export declare function getGlobalObject<T extends Record<string, unknown> = never>(key: `${string}.ts`, defaultValue: T): T; | ||
declare global { | ||
var __react_streaming: undefined | Record<string, Record<string, unknown>>; | ||
} |
export function getGlobalObject( | ||
// We use the filename as key; each `getGlobalObject()` call should live in a unique filename. | ||
// We use the filename as key; each `getGlobalObject()` call should live inside a file with a unique filename. | ||
key, defaultValue) { | ||
const allGlobalObjects = (globalThis.__react_streaming = globalThis.__react_streaming || {}); | ||
const globalObject = (allGlobalObjects[key] = allGlobalObjects[key] || defaultValue); | ||
// @ts-ignore | ||
const globalObjectsAll = (globalThis[projectKey] = globalThis[projectKey] || {}); | ||
const globalObject = (globalObjectsAll[key] = globalObjectsAll[key] || defaultValue); | ||
return globalObject; | ||
} | ||
const projectKey = '_react_streaming'; |
@@ -1,2 +0,3 @@ | ||
export declare const projectInfo: { | ||
export { projectInfo }; | ||
declare const projectInfo: { | ||
projectName: "react-streaming"; | ||
@@ -7,4 +8,1 @@ projectVersion: string; | ||
}; | ||
declare global { | ||
var __vite_plugin_ssr__instances: undefined | string[]; | ||
} |
@@ -1,3 +0,5 @@ | ||
const PROJECT_VERSION = '0.3.18'; | ||
export const projectInfo = { | ||
export { projectInfo }; | ||
import { getGlobalObject } from './getGlobalObject'; | ||
const PROJECT_VERSION = '0.3.19-commit-20b3bc7'; | ||
const projectInfo = { | ||
projectName: 'react-streaming', | ||
@@ -8,4 +10,11 @@ projectVersion: PROJECT_VERSION, | ||
}; | ||
// Trick: since `utils/asserts.ts` depends on this file (`utils/projectInfo.ts`), we can have confidence that this file is always instantiated. So that we don't have to initialize this code snippet at every possible entry. (There are a *lot* of entries: `client/router/`, `client/`, `node/`, `node/plugin/`, `node/cli`, etc.) | ||
globalThis.__vite_plugin_ssr__instances = globalThis.__vite_plugin_ssr__instances || []; | ||
globalThis.__vite_plugin_ssr__instances.push(projectInfo.projectVersion); | ||
const { versions } = getGlobalObject('projectInfo.ts', { | ||
versions: new Set() | ||
}); | ||
versions.add(projectInfo.projectVersion); | ||
if (versions.size >= 2) { | ||
const versionsStr = Array.from(versions) | ||
.map((v) => `${projectInfo.projectName}@${v}`) | ||
.join('and'); | ||
throw new Error(`Using different versions is forbidden, but ${versionsStr} are loaded. Make sure only one version is loaded.`); | ||
} |
{ | ||
"name": "react-streaming", | ||
"description": "React 18 Streaming. Full-fledged & Easy.", | ||
"version": "0.3.18", | ||
"main": "./dist/cjs/server/hooks.js", | ||
"version": "0.3.19-commit-20b3bc7", | ||
"peerDependencies": { | ||
@@ -15,2 +14,19 @@ "react": ">=18", | ||
}, | ||
"main": "./dist/cjs/server/hooks.js", | ||
"exports": { | ||
".": { | ||
"node": "./dist/cjs/server/hooks.js", | ||
"worker": "./dist/esm/server/hooks.js", | ||
"deno": "./dist/esm/server/hooks.js", | ||
"browser": "./dist/esm/client/hooks.js", | ||
"types": "./dist/cjs/server/hooks.d.ts" | ||
}, | ||
"./server": { | ||
"node": "./dist/cjs/server/index.node.js", | ||
"worker": "./dist/esm/server/index.js", | ||
"deno": "./dist/esm/server/index.js", | ||
"browser": "./dist/esm/server/client-poison-pill.js", | ||
"types": "./dist/cjs/server/index.d.ts" | ||
} | ||
}, | ||
"scripts": { | ||
@@ -33,18 +49,2 @@ "// === Test ===": "", | ||
}, | ||
"exports": { | ||
".": { | ||
"node": "./dist/cjs/server/hooks.js", | ||
"worker": "./dist/esm/server/hooks.js", | ||
"deno": "./dist/esm/server/hooks.js", | ||
"browser": "./dist/esm/client/hooks.js", | ||
"types": "./dist/cjs/server/hooks.d.ts" | ||
}, | ||
"./server": { | ||
"node": "./dist/cjs/server/index.js", | ||
"worker": "./dist/esm/server/index.js", | ||
"deno": "./dist/esm/server/index.js", | ||
"browser": "./dist/esm/server/client-poison-pill.js", | ||
"types": "./dist/cjs/server/index.d.ts" | ||
} | ||
}, | ||
"devDependencies": { | ||
@@ -51,0 +51,0 @@ "@brillout/part-regex": "^0.1.2", |
@@ -70,3 +70,3 @@ <p align="center"> | ||
> `react-streaming` makes it easy to build the libraries of tomorrow, for example: | ||
> - Use [Telefunc](https://telefunc.com/) to easily fetch data for your Next.js app or your Vite + [`vite-plugin-ssr`](https://vite-plugin-ssr.com/) app. (Replacing Next.js's `getServerSideProps()` and `vite-plugin-ssr`'s `onBeforeRender()`.) | ||
> - Use [Telefunc](https://telefunc.com) to fetch data for your Next.js or [Vike](https://vike.dev) app. (Instead of Next.js's `getServerSideProps()` / `Vike`'s `data()`.) | ||
> - Better GraphQL tools, e.g. [Vilay](https://github.com/XiNiHa/vilay). | ||
@@ -73,0 +73,0 @@ |
127540
149
2809