Skip to content

Commit

Permalink
[breaking] merge resolve options when using sequence (#6401)
Browse files Browse the repository at this point in the history
Closes #4051
  • Loading branch information
Rich-Harris authored Aug 30, 2022
1 parent 63c7515 commit aa76bdc
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-rice-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

[breaking] merge resolve options when using sequence helper
27 changes: 24 additions & 3 deletions packages/kit/src/exports/hooks/sequence.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,40 @@ export function sequence(...handlers) {
if (!length) return ({ event, resolve }) => resolve(event);

return ({ event, resolve }) => {
return apply_handle(0, event);
return apply_handle(0, event, {});

/**
* @param {number} i
* @param {import('types').RequestEvent} event
* @param {import('types').ResolveOptions | undefined} parent_options
* @returns {import('types').MaybePromise<Response>}
*/
function apply_handle(i, event) {
function apply_handle(i, event, parent_options) {
const handle = handlers[i];

return handle({
event,
resolve: i < length - 1 ? (event) => apply_handle(i + 1, event) : resolve
resolve: (event, options) => {
/** @param {{ html: string, done: boolean }} opts */
const transformPageChunk = async ({ html, done }) => {
if (options?.transformPageChunk) {
html = (await options.transformPageChunk({ html, done })) ?? '';
}

if (parent_options?.transformPageChunk) {
html = (await parent_options.transformPageChunk({ html, done })) ?? '';
}

return html;
};

// TODO remove post-https://github.com/sveltejs/kit/pull/6197
const ssr = options?.ssr ?? parent_options?.ssr;

return i < length - 1
? apply_handle(i + 1, event, { transformPageChunk, ssr })
: resolve(event, { transformPageChunk, ssr });
}
});
}
};
Expand Down
106 changes: 106 additions & 0 deletions packages/kit/src/exports/hooks/sequence.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { test } from 'uvu';
import * as assert from 'uvu/assert';
import { sequence } from './sequence.js';
import { installPolyfills } from '../node/polyfills.js';

installPolyfills();

test('applies handlers in sequence', async () => {
/** @type {string[]} */
const order = [];

const handler = sequence(
async ({ event, resolve }) => {
order.push('1a');
const response = await resolve(event);
order.push('1b');
return response;
},
async ({ event, resolve }) => {
order.push('2a');
const response = await resolve(event);
order.push('2b');
return response;
},
async ({ event, resolve }) => {
order.push('3a');
const response = await resolve(event);
order.push('3b');
return response;
}
);

const event = /** @type {import('types').RequestEvent} */ ({});
const response = new Response();

assert.equal(await handler({ event, resolve: () => response }), response);
assert.equal(order, ['1a', '2a', '3a', '3b', '2b', '1b']);
});

test('uses transformPageChunk option passed to non-terminal handle function', async () => {
const handler = sequence(
async ({ event, resolve }) => {
return resolve(event, {
transformPageChunk: ({ html, done }) => html + (done ? '-1-done' : '-1')
});
},
async ({ event, resolve }) => resolve(event),
async ({ event, resolve }) => resolve(event)
);

const event = /** @type {import('types').RequestEvent} */ ({});
const response = await handler({
event,
resolve: async (_event, opts = {}) => {
let html = '';

const { transformPageChunk = ({ html }) => html } = opts;

html += await transformPageChunk({ html: '0', done: false });
html += await transformPageChunk({ html: ' 0', done: true });

return new Response(html);
}
});

assert.equal(await response.text(), '0-1 0-1-done');
});

test('merges transformPageChunk option', async () => {
const handler = sequence(
async ({ event, resolve }) => {
return resolve(event, {
transformPageChunk: ({ html, done }) => html + (done ? '-1-done' : '-1')
});
},
async ({ event, resolve }) => {
return resolve(event, {
transformPageChunk: ({ html, done }) => html + (done ? '-2-done' : '-2')
});
},
async ({ event, resolve }) => {
return resolve(event, {
transformPageChunk: ({ html, done }) => html + (done ? '-3-done' : '-3')
});
}
);

const event = /** @type {import('types').RequestEvent} */ ({});
const response = await handler({
event,
resolve: async (_event, opts = {}) => {
let html = '';

const { transformPageChunk = ({ html }) => html } = opts;

html += await transformPageChunk({ html: '0', done: false });
html += await transformPageChunk({ html: ' 0', done: true });

return new Response(html);
}
});

assert.equal(await response.text(), '0-3-2-1 0-3-done-2-done-1-done');
});

test.run();
17 changes: 15 additions & 2 deletions packages/kit/types/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,26 @@ declare module '@sveltejs/kit/hooks' {
* /** @type {import('@sveltejs/kit').Handle} *\/
* async function first({ event, resolve }) {
* console.log('first pre-processing');
* const result = await resolve(event);
* const result = await resolve(event, {
* transformPageChunk: ({ html }) => {
* // transforms are applied in reverse order
* console.log('first transform');
* return html;
* }
* });
* console.log('first post-processing');
* return result;
* }
*
* /** @type {import('@sveltejs/kit').Handle} *\/
* async function second({ event, resolve }) {
* console.log('second pre-processing');
* const result = await resolve(event);
* const result = await resolve(event, {
* transformPageChunk: ({ html }) => {
* console.log('second transform');
* return html;
* }
* });
* console.log('second post-processing');
* return result;
* }
Expand All @@ -274,6 +285,8 @@ declare module '@sveltejs/kit/hooks' {
* ```
* first pre-processing
* second pre-processing
* second transform
* first transform
* second post-processing
* first post-processing
* ```
Expand Down

0 comments on commit aa76bdc

Please sign in to comment.