From aeb159c401ef446e6564e5a3643027560a3e22f4 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 8 Jul 2025 01:49:07 -0400 Subject: Create "derivers," as an exception-free option for working with structured data in swatches. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is meant to be used alongside `$derive`, for inputs with complex structure. For example: ```js let jsonInput = $state('{}'); let json = $derived(deriver.json(jsonInput)); // … ``` This allows textual editing of the data, while preventing exceptions due to syntax or logical errors in partially-edited data from breaking Svelte's derive process (see comments). Note that these exceptions are not considered [unexpected errors] by SvelteKit, because they do not arise "while handling a request;" they are considered errors by Svelte, but Svelte doesn't appear to provide any affordances for handling errors in this context, so we have to bring our own. [unexpected errors]: https://svelte.dev/docs/kit/errors#Unexpected-errors --- ui/lib/swatch/derive.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 ui/lib/swatch/derive.js (limited to 'ui/lib') diff --git a/ui/lib/swatch/derive.js b/ui/lib/swatch/derive.js new file mode 100644 index 0000000..85547e8 --- /dev/null +++ b/ui/lib/swatch/derive.js @@ -0,0 +1,20 @@ +// A fun fact about $derive: if the deriving expression throws an error, then Svelte (at least as of +// 5.20.2) _permanently_ stops evaluating it, even if the inputs change. To prevent this, you need +// to ensure that derive expressions never raise an exception. +function tryDerive(args, func, fallback) { + try { + return func(...args); + } catch (e) { + console.debug('deriver threw exception', e, func, args); + return fallback; + } +} + +// A "deriver" is a function that never raises; if the underlying function would raise, the +// corresponding deriver instead returns a fallback value (or `undefined`). +export function makeDeriver(func, fallback) { + return (...args) => tryDerive(args, func, fallback); +} + +// Some widely-used derivers, for convenience. +export const json = makeDeriver(JSON.parse); -- cgit v1.2.3 From c631c8fc855b1854f14fc7fbf1d8afedaa37a0db Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 8 Jul 2025 01:35:28 -0400 Subject: Event capture and display tools. This is meant to be used in swatches, to display the events and callbacks generated by a component as part of the swatch. The usage pattern is described in the comments (in both places). Naturally, this has its own swatch. --- ui/lib/components/swatch/EventLog.svelte | 37 +++++++++++++++++++++ ui/lib/swatch/event-capture.svelte.js | 22 +++++++++++++ ui/routes/(swatch)/.swatch/+page.svelte | 4 ++- .../(swatch)/.swatch/swatch/EventLog/+page.svelte | 38 ++++++++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 ui/lib/components/swatch/EventLog.svelte create mode 100644 ui/lib/swatch/event-capture.svelte.js create mode 100644 ui/routes/(swatch)/.swatch/swatch/EventLog/+page.svelte (limited to 'ui/lib') diff --git a/ui/lib/components/swatch/EventLog.svelte b/ui/lib/components/swatch/EventLog.svelte new file mode 100644 index 0000000..2d8c5c0 --- /dev/null +++ b/ui/lib/components/swatch/EventLog.svelte @@ -0,0 +1,37 @@ + + + + + + + + + + + + {#each events as { event, args }} + + + + + {/each} + +
eventarguments
{event}{JSON.stringify(args)}
diff --git a/ui/lib/swatch/event-capture.svelte.js b/ui/lib/swatch/event-capture.svelte.js new file mode 100644 index 0000000..32c0f39 --- /dev/null +++ b/ui/lib/swatch/event-capture.svelte.js @@ -0,0 +1,22 @@ +/* + * The interface exposed by this class is designed to closely match the interface expected by + * the `EventLog` component, so that you can do this: + * + * let capture = $state(new EventCapture()); + * const someEvent = capture.on('someEvent'); + * + * // … + * + * + */ +export default class EventCapture { + events = $state([]); + + on(event) { + return (...args) => this.events.push({ event, args }); + } + + clear() { + this.events = []; + } +} diff --git a/ui/routes/(swatch)/.swatch/+page.svelte b/ui/routes/(swatch)/.swatch/+page.svelte index 8d03c8d..abcb53f 100644 --- a/ui/routes/(swatch)/.swatch/+page.svelte +++ b/ui/routes/(swatch)/.swatch/+page.svelte @@ -7,4 +7,6 @@

components

-
    + diff --git a/ui/routes/(swatch)/.swatch/swatch/EventLog/+page.svelte b/ui/routes/(swatch)/.swatch/swatch/EventLog/+page.svelte new file mode 100644 index 0000000..a751ca3 --- /dev/null +++ b/ui/routes/(swatch)/.swatch/swatch/EventLog/+page.svelte @@ -0,0 +1,38 @@ + + +

    swatch/EventLog

    + + + +

    properties

    + +
    + +
    + +

    rendered

    + +
    + +
    + +

    events

    + + -- cgit v1.2.3