From d22df1bc39f1c6d8da74fd73b2a51d26e1e6113c Mon Sep 17 00:00:00 2001 From: Paolo Ricciuti Date: Sat, 4 Feb 2023 12:17:37 +0100 Subject: [PATCH] Handle rejected promises --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- .github/workflows/lint.yml | 14 ++--- .github/workflows/publish-to-npm.yml | 4 +- CODE_OF_CONDUCT.md | 22 +++---- README.md | 82 +++++++++++++------------- src/lib/defer.ts | 18 ++++-- src/lib/store.ts | 7 ++- 7 files changed, 81 insertions(+), 68 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index a487c12..eaddcc5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -25,5 +25,5 @@ body: id: logs attributes: label: Logs - description: "Please include browser console and server logs around the time this bug occurred. Optional if provided reproduction. Please try not to insert an image but copy paste the log text." + description: 'Please include browser console and server logs around the time this bug occurred. Optional if provided reproduction. Please try not to insert an image but copy paste the log text.' render: shell diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c8c6f6f..1cd9e50 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,5 @@ name: Run Lint -on: +on: pull_request: branches: - main @@ -8,10 +8,10 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: '16' - - run: npm install - - run: npm lint + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: '16' + - run: npm install + - run: npm lint # - run: npm test diff --git a/.github/workflows/publish-to-npm.yml b/.github/workflows/publish-to-npm.yml index 9892ee2..c9be2a0 100644 --- a/.github/workflows/publish-to-npm.yml +++ b/.github/workflows/publish-to-npm.yml @@ -10,8 +10,8 @@ jobs: # Setup .npmrc file to publish to npm - uses: actions/setup-node@v3 with: - node-version: "16.x" - registry-url: "https://registry.npmjs.org" + node-version: '16.x' + registry-url: 'https://registry.npmjs.org' - run: npm i - run: npm run build - working-directory: package diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index fa6873e..6921fbe 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -17,23 +17,23 @@ diverse, inclusive, and healthy community. Examples of behavior that contributes to a positive environment for our community include: -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -* Focusing on what is best not just for us as individuals, but for the +- Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: -* The use of sexualized language or imagery, and sexual attention or +- The use of sexualized language or imagery, and sexual attention or advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities @@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an +standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within diff --git a/README.md b/README.md index 6477d63..d9389f7 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,21 @@ This package allows you to transfare Promises over the wire in sveltekit. It use Here's an example of what you would write; **hooks.server.ts** + ```ts import { defer_handle } from 'sveltekit-defer'; import type { Handle } from '@sveltejs/kit'; export const handle: Handle = defer_handle; - ``` if you have other handles you can chain them with the utility function `sequence` provided by sveltekit. **hooks.server.ts** + ```ts import { defer_handle } from 'sveltekit-defer'; -import { sequence } from "@sveltejs/kit/hooks"; +import { sequence } from '@sveltejs/kit/hooks'; import type { Handle } from '@sveltejs/kit'; export const handle: Handle = sequence(defer_handle, your_handle); @@ -34,62 +35,61 @@ import { defer } from 'sveltekit-defer'; import type { PageServerLoad } from './$types'; async function get_blog() { - await new Promise(r => setTimeout(r, 7000)); - return "A long blog post that it's very critical so the user need to see it right away"; + await new Promise((r) => setTimeout(r, 7000)); + return "A long blog post that it's very critical so the user need to see it right away"; } async function get_comments() { - await new Promise(r => setTimeout(r, 10000)); - return [ - { author: "Antonio", comment: "Very cool" }, - { author: "Oskar", comment: "Yeah it's wonderful" }, - ]; + await new Promise((r) => setTimeout(r, 10000)); + return [ + { author: 'Antonio', comment: 'Very cool' }, + { author: 'Oskar', comment: "Yeah it's wonderful" } + ]; } /** * Wrap you actual load function inside our defer function to unlock the defer functionality */ -export const load: PageServerLoad = defer((async (event: ServerLoadEvent) => { - // start the fetch for the comments right away without awaiting - const comments = get_comments(); - // await the blog post given that is critical content - const blog = await get_blog(); - //return the promise (comments) and the blog post - return { - blog, - comments, - }; -})); - +export const load: PageServerLoad = defer(async (event: ServerLoadEvent) => { + // start the fetch for the comments right away without awaiting + const comments = get_comments(); + // await the blog post given that is critical content + const blog = await get_blog(); + //return the promise (comments) and the blog post + return { + blog, + comments + }; +}); ``` then on the client side you can access the data via the store provided by `sveltekit-defer` ```svelte
-
- - {$data.blog} -
-
-
    - - {#await $data.comments} - Loading... - {:then comments} - {#each comments as comment} -
  • {comment.author} - {comment.comment}
  • - {/each} - {/await} -
-
+
+ + {$data.blog} +
+
+
    + + {#await $data.comments} + Loading... + {:then comments} + {#each comments as comment} +
  • {comment.author} - {comment.comment}
  • + {/each} + {/await} +
+
``` @@ -108,4 +108,4 @@ Here's how it works: There's a lot to do, but the first thing is to make sure that this doesn't create some super-huge security/performance issue and generally if there are things that can be done better. -Feel free to open an issue if you found something that is not working or if you have some ideas on how to improve. \ No newline at end of file +Feel free to open an issue if you found something that is not working or if you have some ideas on how to improve. diff --git a/src/lib/defer.ts b/src/lib/defer.ts index b345121..16eee55 100644 --- a/src/lib/defer.ts +++ b/src/lib/defer.ts @@ -1,6 +1,13 @@ import type { ServerLoadEvent } from '@sveltejs/kit'; import { COOKIE_NAME, STREAM_PATHNAME } from './constants'; +function pushEvent(event: ServerLoadEvent, data: any) { + event.fetch(`${STREAM_PATHNAME}?load=${event.url}`, { + method: 'POST', + body: JSON.stringify(data) + }); +} + export function defer any>( func: T ): (event: ServerLoadEvent) => Promise> { @@ -20,12 +27,13 @@ export function defer any>( returnVal.promises = []; } returnVal.promises.push(key); - returnVal[key].then((res: any) => { - event.fetch(`${STREAM_PATHNAME}?load=${event.url}`, { - method: 'POST', - body: JSON.stringify({ value: JSON.stringify(res), key }) + returnVal[key] + .then((res: any) => { + pushEvent(event, { value: JSON.stringify(res), key, kind: 'resolve' }); + }) + .catch((error: any) => { + pushEvent(event, { value: JSON.stringify(error), key, kind: 'reject' }); }); - }); returnVal[key] = '__PROMISE_TO_DEFER__'; } }); diff --git a/src/lib/store.ts b/src/lib/store.ts index 3b3dd48..a2e1fc1 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -14,7 +14,12 @@ export function get_data() { }); eventSource?.addEventListener(STREAM_EVENT, (evt) => { const resolved = JSON.parse(evt.data); - resolvers.get(resolved.key)?.resolve(JSON.parse(resolved.value)); + const resolver = resolvers.get(resolved.key); + if (resolved.kind === 'resolve') { + resolver?.resolve(JSON.parse(resolved.value)); + } else { + resolver?.reject(JSON.parse(resolved.value)); + } }); }); onDestroy(() => {