diff options
Diffstat (limited to 'ui/lib/swatch')
| -rw-r--r-- | ui/lib/swatch/derive.js | 20 | ||||
| -rw-r--r-- | ui/lib/swatch/event-capture.svelte.js | 22 |
2 files changed, 42 insertions, 0 deletions
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); 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'); + * + * // … + * + * <EventLog events={capture.events} clear={capture.clear.bind(capture)} /> + */ +export default class EventCapture { + events = $state([]); + + on(event) { + return (...args) => this.events.push({ event, args }); + } + + clear() { + this.events = []; + } +} |
