Skip to content

Instantly share code, notes, and snippets.

@theetrain
Last active May 17, 2024 15:01
Show Gist options
  • Save theetrain/c0989cf699cddcf1f0d136d3612d1538 to your computer and use it in GitHub Desktop.
Save theetrain/c0989cf699cddcf1f0d136d3612d1538 to your computer and use it in GitHub Desktop.
MaybStream
import { maybeStream } from '$lib/utils'
/** @type {import('./$types').PageServerLoad} */
export async function load({ isDataRequest }) {
const combinationResponse = maybeStream(pretendAPI(), { isDataRequest })
const otherCombinationResponse = maybeStream(pretendAPI(), { isDataRequest })
let [combination, other] = await Promise.all([
combinationResponse,
otherCombinationResponse
])
// If the winner is 'wait' AND this is an enhanced request
// stream the API request.
// Otherwise, server-render the page.
return {
combination: combination(),
other: other()
}
}
export type NotFunction<T> = T extends Function ? never : T;
export type MaybePromise<T> = T | Promise<T>
/**
* @typedef {import('$lib/types').MaybePromise<T>} MaybePromise
* @template {any} T
*/
/**
* @typedef {import('$lib/types').NotFunction<T>} NotFunction
* @template {any} T
*/
/**
* Decides whether or not to stream a provided task.
* @param {Promise<NotFunction<T>>} asyncTask A promise, usually an API request.
* @template {any} T
* @param {object} [options]
* @param {number} [options.waitTime=600] Amount of time in milliseconds to wait
* before returning a promise. Default is `600`.
* @param {boolean} [options.isDataRequest=false] Flag that indicates request
* comes from an enhanced `fetch` and not a browser page request. Default is `false`.
*
* @return {Promise<() => MaybePromise<T>>}
*/
export async function maybeStream(
asyncTask,
options = { waitTime: 600, isDataRequest: false }
) {
// Exit early for
if (options.isDataRequest) return () => asyncTask
const wait = new Promise((res) =>
setTimeout(res, options.waitTime, 'delayed')
)
return Promise.race([asyncTask, wait]).then((value) => {
if (value === 'delayed') {
return () => asyncTask
} else {
return () => value
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment