react-imported-component
Version:
I will import your component, and help to handle it
71 lines (70 loc) • 2.29 kB
JavaScript
import { checkStream, clearStream, defaultStream } from './stream';
import { markerOverlap } from './utils';
const LOADABLE_MARKS = new Map();
export const consumeMark = (stream = defaultStream, marks) => {
checkStream(stream);
if (marks && marks.length) {
marks.forEach((a) => (stream.marks[a] = true));
}
};
export const assignLoadableMark = (mark, loadable) => {
LOADABLE_MARKS.set(JSON.stringify(mark), { mark, loadable });
};
/**
* returns marks used in the stream
* @param stream
*/
export const getUsedMarks = (stream = defaultStream) => (stream ? Object.keys(stream.marks) : []);
/**
* SSR
* @returns list or marks used
*/
export const drainHydrateMarks = (stream = defaultStream) => {
checkStream(stream);
const marks = getUsedMarks(stream);
clearStream(stream);
return marks;
};
/**
* Loads a given marks/chunks
* @see returns a promise for a given marks only. In order to await all requests currently in flight use {@link waitForMarks}
* @param marks
* @returns a resolution promise
*/
export const rehydrateMarks = (marks) => {
const rehydratedMarks = marks || global.___REACT_DEFERRED_COMPONENT_MARKS || [];
const tasks = [];
const usedMarks = new Set();
LOADABLE_MARKS.forEach(({ mark, loadable }) => {
if (markerOverlap(mark, rehydratedMarks)) {
mark.forEach((m) => usedMarks.add(m));
tasks.push(loadable.load());
}
});
rehydratedMarks.forEach((m) => {
if (!usedMarks.has(m)) {
throw new Error(`react-imported-component: unknown mark(${m}) has been used. Client and Server should have the same babel configuration.`);
}
});
return Promise.all(tasks);
};
/**
* waits for the given marks to load
* @param marks
*/
export const waitForMarks = (marks) => {
const tasks = [];
LOADABLE_MARKS.forEach(({ mark, loadable }) => {
if (markerOverlap(mark, marks)) {
tasks.push(loadable.resolution);
}
});
return Promise.all(tasks);
};
/**
* @returns a <script> tag with all used marks
*/
export const printDrainHydrateMarks = (stream) => {
checkStream(stream);
return `<script>window.___REACT_DEFERRED_COMPONENT_MARKS=${JSON.stringify(drainHydrateMarks(stream))};</script>`;
};