From d76a972ceb69de8bc729a7ec0007af81fbaebd56 Mon Sep 17 00:00:00 2001 From: Alex Thomsen Date: Fri, 31 Oct 2025 11:16:16 -0600 Subject: [PATCH 1/3] Add retry and loading state to payload decoder --- .../components/event/payload-decoder.svelte | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/lib/components/event/payload-decoder.svelte b/src/lib/components/event/payload-decoder.svelte index df6071666..15b048f85 100644 --- a/src/lib/components/event/payload-decoder.svelte +++ b/src/lib/components/event/payload-decoder.svelte @@ -23,15 +23,19 @@ key?: string; onDecode?: (decodedValue: string) => void; children: Snippet<[decodedValue: string]>; + error?: Snippet<[retry: () => Promise, err: unknown]>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + loading?: Snippet<[keyedVal: any]>; } - let { children, value, key = '', onDecode }: Props = $props(); + let { children, value, key = '', onDecode, error, loading }: Props = $props(); let keyedValue = key && value?.[key] ? value[key] : value; - let decodedValue = $state(stringifyWithBigInt(keyedValue)); + + let decodeValuePromise = $state | null>(null); onMount(() => { - decodePayloads(value); + decodeValuePromise = decodePayloads(value); }); const decodePayloads = async ( @@ -61,14 +65,21 @@ if (Array.isArray(finalValue) && finalValue.length === 1) { finalValue = finalValue[0]; } - decodedValue = stringifyWithBigInt(finalValue); + let decodedValue = stringifyWithBigInt(finalValue); if (onDecode) { onDecode(decodedValue); } + return decodedValue; } catch (e) { console.error('Could not decode payloads'); } }; -{@render children(decodedValue)} +{#await decodeValuePromise} + {@render loading?.(keyedValue)} +{:then decoded} + {@render children(decoded)} +{:catch err} + {@render error?.(() => decodePayloads(value), err)} +{/await} From 04e28892a76a6cb9ed0debbbac027c6edc7b1b27 Mon Sep 17 00:00:00 2001 From: Alex Thomsen Date: Fri, 31 Oct 2025 11:19:24 -0600 Subject: [PATCH 2/3] More cleanup --- .../components/event/payload-decoder.svelte | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/lib/components/event/payload-decoder.svelte b/src/lib/components/event/payload-decoder.svelte index 15b048f85..2a687daa2 100644 --- a/src/lib/components/event/payload-decoder.svelte +++ b/src/lib/components/event/payload-decoder.svelte @@ -1,7 +1,7 @@ {#await decodeValuePromise} From 0be3f8b3a000779d4e37f9b7c8c9284def93040f Mon Sep 17 00:00:00 2001 From: Alex Thomsen Date: Fri, 31 Oct 2025 11:28:32 -0600 Subject: [PATCH 3/3] Some defaults and using the retry by default --- .../components/event/payload-decoder.svelte | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/lib/components/event/payload-decoder.svelte b/src/lib/components/event/payload-decoder.svelte index 2a687daa2..4a8fc556e 100644 --- a/src/lib/components/event/payload-decoder.svelte +++ b/src/lib/components/event/payload-decoder.svelte @@ -3,6 +3,7 @@ import { page } from '$app/state'; + import Button from '$lib/holocene/button.svelte'; import { authUser } from '$lib/stores/auth-user'; import type { Memo } from '$lib/types'; import type { EventAttribute, WorkflowEvent } from '$lib/types/events'; @@ -24,13 +25,21 @@ onDecode?: (decodedValue: string) => void; children: Snippet<[decodedValue: string]>; error?: Snippet<[retry: () => Promise, err: unknown]>; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - loading?: Snippet<[keyedVal: any]>; + loading?: Snippet<[keyedVal: string]>; } - let { children, value, key = '', onDecode, error, loading }: Props = $props(); + let { + children, + value, + key = '', + onDecode, + error = errorSnip, + loading = loadingSnip, + }: Props = $props(); - let keyedValue = key && value?.[key] ? value[key] : value; + let keyedValue = stringifyWithBigInt( + key && value?.[key] ? value[key] : value, + ); let decodeValuePromise = $state>(decodePayloads(value)); @@ -68,10 +77,25 @@ return decodedValue; } catch (e) { console.error('Could not decode payloads'); + // hmm before this just ate the error we want to throw this to get an error here + // but maybe this is leaking information to the users? But it also might be good + // to allow that? Think about this harder maybe ask app sec about if this is an okay + // design choice + throw e; } } +{#snippet loadingSnip(val)} + {val} +{/snippet} + +{#snippet errorSnip(retry, error)} +
{error}
+ + +{/snippet} + {#await decodeValuePromise} {@render loading?.(keyedValue)} {:then decoded}