diff --git a/src/constants.js b/src/constants.js index bedbc8ab..301ef1fa 100644 --- a/src/constants.js +++ b/src/constants.js @@ -14,3 +14,8 @@ export const PARENT = '__'; export const VNODE = '__v'; export const DIRTY = '__d'; export const NEXT_STATE = '__s'; + +// Rendering modes +export const MODE_SYNC = 0; +export const MODE_ASYNC = 1; +export const MODE_STREAM = 2; diff --git a/src/index.d.ts b/src/index.d.ts index 81db2bd7..cc462b88 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -11,6 +11,10 @@ export function renderToStringAsync
( vnode: VNode
,
context?: any
): string | Promise (
+ vnode: VNode ,
+ context?: any
+): ReadableStream (
vnode: VNode ,
context?: any
diff --git a/src/index.js b/src/index.js
index 6be17849..e35cd93e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -14,6 +14,9 @@ import {
DIFF,
DIFFED,
DIRTY,
+ MODE_ASYNC,
+ MODE_STREAM,
+ MODE_SYNC,
NEXT_STATE,
PARENT,
RENDER,
@@ -30,13 +33,7 @@ const assign = Object.assign;
// Global state for the current render pass
let beforeDiff, afterDiff, renderHook, ummountHook;
-/**
- * Render Preact JSX + Components to an HTML string.
- * @param {VNode} vnode JSX Element / VNode to render
- * @param {Object} [context={}] Initial root context object
- * @returns {string} serialized HTML
- */
-export function renderToString(vnode, context) {
+function prepare() {
// Performance optimization: `renderToString` is synchronous and we
// therefore don't execute any effects. To do that we pass an empty
// array to `options._commit` (`__c`). But we can go one step further
@@ -51,6 +48,30 @@ export function renderToString(vnode, context) {
renderHook = options[RENDER];
ummountHook = options.unmount;
+ return previousSkipEffects;
+}
+
+/**
+ * @param {VNode} vnode
+ * @param {any} previousSkipEffects
+ */
+function finalize(vnode, previousSkipEffects) {
+ // options._commit, we don't schedule any effects in this library right now,
+ // so we can pass an empty queue to this hook.
+ if (options[COMMIT]) options[COMMIT](vnode, EMPTY_ARR);
+ options[SKIP_EFFECTS] = previousSkipEffects;
+ EMPTY_ARR.length = 0;
+}
+
+/**
+ * Render Preact JSX + Components to an HTML string.
+ * @param {VNode} vnode JSX Element / VNode to render
+ * @param {Object} [context={}] Initial root context object
+ * @returns {string} serialized HTML
+ */
+export function renderToString(vnode, context) {
+ const previousSkipEffects = prepare();
+
const parent = h(Fragment, null);
parent[CHILDREN] = [vnode];
@@ -61,7 +82,7 @@ export function renderToString(vnode, context) {
false,
undefined,
parent,
- false
+ MODE_SYNC
);
} catch (e) {
if (e.then) {
@@ -70,11 +91,7 @@ export function renderToString(vnode, context) {
throw e;
} finally {
- // options._commit, we don't schedule any effects in this library right now,
- // so we can pass an empty queue to this hook.
- if (options[COMMIT]) options[COMMIT](vnode, EMPTY_ARR);
- options[SKIP_EFFECTS] = previousSkipEffects;
- EMPTY_ARR.length = 0;
+ finalize(vnode, previousSkipEffects);
}
}
@@ -82,22 +99,10 @@ export function renderToString(vnode, context) {
* Render Preact JSX + Components to an HTML string.
* @param {VNode} vnode JSX Element / VNode to render
* @param {Object} [context={}] Initial root context object
- * @returns {string} serialized HTML
+ * @returns {Promise