From 7d4d15d326a87940196ad1ce196d89ba03e2ff74 Mon Sep 17 00:00:00 2001 From: Charles Lowell Date: Thu, 6 Aug 2026 23:42:17 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20solid:=20add=20adapter=20and=20hell?= =?UTF-8?q?o-world=20example?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/hello-world-solid/babel.config.json | 18 + examples/hello-world-solid/package.json | 24 + examples/hello-world-solid/src/app.tsx | 44 + examples/hello-world-solid/src/index.tsx | 9 + examples/hello-world-solid/tsconfig.json | 13 + package.json | 2 +- packages/ui-solid/package.json | 79 ++ packages/ui-solid/src/components.ts | 20 + packages/ui-solid/src/elements.test.ts | 49 + packages/ui-solid/src/elements.ts | 21 + packages/ui-solid/src/index.ts | 19 + packages/ui-solid/src/jsx-dev-runtime.ts | 10 + packages/ui-solid/src/jsx-runtime.ts | 10 + packages/ui-solid/src/renderer.ts | 193 ++++ packages/ui-solid/src/root.test.ts | 232 +++++ packages/ui-solid/src/types.ts | 12 + packages/ui-solid/tsconfig.json | 6 + packages/ui-solid/vitest.config.ts | 20 + pnpm-lock.yaml | 911 +++++++++++++++++++ 19 files changed, 1691 insertions(+), 1 deletion(-) create mode 100644 examples/hello-world-solid/babel.config.json create mode 100644 examples/hello-world-solid/package.json create mode 100644 examples/hello-world-solid/src/app.tsx create mode 100644 examples/hello-world-solid/src/index.tsx create mode 100644 examples/hello-world-solid/tsconfig.json create mode 100644 packages/ui-solid/package.json create mode 100644 packages/ui-solid/src/components.ts create mode 100644 packages/ui-solid/src/elements.test.ts create mode 100644 packages/ui-solid/src/elements.ts create mode 100644 packages/ui-solid/src/index.ts create mode 100644 packages/ui-solid/src/jsx-dev-runtime.ts create mode 100644 packages/ui-solid/src/jsx-runtime.ts create mode 100644 packages/ui-solid/src/renderer.ts create mode 100644 packages/ui-solid/src/root.test.ts create mode 100644 packages/ui-solid/src/types.ts create mode 100644 packages/ui-solid/tsconfig.json create mode 100644 packages/ui-solid/vitest.config.ts diff --git a/examples/hello-world-solid/babel.config.json b/examples/hello-world-solid/babel.config.json new file mode 100644 index 0000000..404af1e --- /dev/null +++ b/examples/hello-world-solid/babel.config.json @@ -0,0 +1,18 @@ +{ + "presets": [ + [ + "@babel/preset-typescript", + { + "allExtensions": true, + "isTSX": true + } + ], + [ + "babel-preset-solid", + { + "generate": "universal", + "moduleName": "@clack/ui-solid" + } + ] + ] +} diff --git a/examples/hello-world-solid/package.json b/examples/hello-world-solid/package.json new file mode 100644 index 0000000..e2804f0 --- /dev/null +++ b/examples/hello-world-solid/package.json @@ -0,0 +1,24 @@ +{ + "name": "@examples/hello-world-solid", + "private": true, + "type": "module", + "scripts": { + "build": "babel src --extensions .ts,.tsx --out-dir dist --keep-file-extension --delete-dir-on-start", + "prestart": "pnpm run build", + "start": "tsx --conditions=browser dist/index.tsx" + }, + "dependencies": { + "@bomb.sh/tty": "^0.7.0", + "@clack/ui": "workspace:*", + "@clack/ui-solid": "workspace:*", + "solid-js": "1.9.14" + }, + "devDependencies": { + "@babel/cli": "7.29.7", + "@babel/core": "7.29.7", + "@babel/preset-typescript": "7.29.7", + "@types/node": "^22.20.0", + "babel-preset-solid": "1.9.12", + "tsx": "^4.19.0" + } +} diff --git a/examples/hello-world-solid/src/app.tsx b/examples/hello-world-solid/src/app.tsx new file mode 100644 index 0000000..ff53e2f --- /dev/null +++ b/examples/hello-world-solid/src/app.tsx @@ -0,0 +1,44 @@ +// oxlint-disable bombshell-dev/exported-function-async -- Solid components render synchronously. +import { fixed, grow, percent } from '@bomb.sh/tty'; +import { type JSXElement, rgba } from '@clack/ui-solid'; +import { createSignal } from 'solid-js'; + +/** Render the interactive hello-world example. */ +export function HelloWorld(): JSXElement { + const [say, setSay] = createSignal('Hello'); + const [to, setTo] = createSignal('World'); + + return ( + + + {say()}, {to()}! + + + + + say: + + + to: + + + + setSay(event.value)} /> + setTo(event.value)} /> + + + + ); +} + +const blue = rgba(0, 0, 238); +const cyan = rgba(0, 205, 205); +const gray = rgba(127, 127, 127); diff --git a/examples/hello-world-solid/src/index.tsx b/examples/hello-world-solid/src/index.tsx new file mode 100644 index 0000000..00c5b5f --- /dev/null +++ b/examples/hello-world-solid/src/index.tsx @@ -0,0 +1,9 @@ +import { stdin, stdout } from 'node:process'; +import { createUI } from '@clack/ui'; +import { createRoot } from '@clack/ui-solid'; +import { HelloWorld } from './app.tsx'; + +await using ui = await createUI({ input: stdin, output: stdout }); +const root = createRoot(ui.host.element); +root.render(() => ); +await ui.main(); diff --git a/examples/hello-world-solid/tsconfig.json b/examples/hello-world-solid/tsconfig.json new file mode 100644 index 0000000..fbbfe90 --- /dev/null +++ b/examples/hello-world-solid/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "@bomb.sh/tools/tsconfig.json", + "compilerOptions": { + "composite": false, + "declaration": false, + "declarationMap": false, + "jsx": "preserve", + "jsxImportSource": "@clack/ui-solid", + "noEmit": true, + "types": ["node"] + }, + "exclude": ["dist"] +} diff --git a/package.json b/package.json index fb3e027..36363d9 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "format": "bsh format", "format:check": "bsh format --check", "lint": "bsh lint .", - "test": "bsh test" + "test": "pnpm --filter @clack/ui build && bsh test" }, "devDependencies": { "@bomb.sh/tools": "^0.6.1", diff --git a/packages/ui-solid/package.json b/packages/ui-solid/package.json new file mode 100644 index 0000000..4636afc --- /dev/null +++ b/packages/ui-solid/package.json @@ -0,0 +1,79 @@ +{ + "name": "@clack/ui-solid", + "version": "0.0.0", + "keywords": [ + "bombshell", + "cli", + "solid", + "solid-js" + ], + "homepage": "https://bomb.sh/docs/ui", + "license": "MIT", + "author": { + "name": "Bombshell", + "email": "oss@bomb.sh", + "url": "https://bomb.sh" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/bombshell-dev/ui.git" + }, + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.mts", + "import": "./dist/index.mjs" + }, + "./jsx-runtime": { + "types": "./dist/jsx-runtime.d.mts", + "import": "./dist/jsx-runtime.mjs" + }, + "./jsx-dev-runtime": { + "types": "./dist/jsx-dev-runtime.d.mts", + "import": "./dist/jsx-dev-runtime.mjs" + }, + "./package.json": "./package.json" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "dev": "bsh dev", + "build": "bsh build --dts", + "format": "bsh format", + "lint": "bsh lint", + "test": "vitest run" + }, + "dependencies": { + "@clack/ui": "workspace:*" + }, + "devDependencies": { + "@bomb.sh/tools": "^0.5.4", + "@types/node": "^22.20.0", + "solid-js": "1.9.14", + "vitest": "^4.1.9" + }, + "peerDependencies": { + "solid-js": "^1.9.14" + }, + "devEngines": { + "packageManager": { + "name": "pnpm", + "version": "^10.7.0", + "onFail": "error" + }, + "runtime": { + "name": "node", + "version": "^22.14.0", + "onFail": "error" + } + }, + "knip": { + "entry": [ + "src/index.ts", + "src/jsx-runtime.ts", + "src/jsx-dev-runtime.ts", + "src/*.test.ts" + ] + } +} diff --git a/packages/ui-solid/src/components.ts b/packages/ui-solid/src/components.ts new file mode 100644 index 0000000..2fc90e2 --- /dev/null +++ b/packages/ui-solid/src/components.ts @@ -0,0 +1,20 @@ +// oxlint-disable bombshell-dev/exported-function-async -- Solid components synchronously return Host elements. +import type { HostElement } from '@clack/ui/elements'; +import type { BoxProps, TextProps } from './elements.ts'; +import { createElement, spread } from './renderer.ts'; + +export type { BoxProps, TextProps } from './elements.ts'; + +/** A layout container backed by the Host's `box` element. */ +export function Box(props: BoxProps): HostElement { + const element = createElement('box') as HostElement; + spread(element, props); + return element; +} + +/** A styled text scope backed by the Host's `text` element. */ +export function Text(props: TextProps): HostElement { + const element = createElement('text') as HostElement; + spread(element, props); + return element; +} diff --git a/packages/ui-solid/src/elements.test.ts b/packages/ui-solid/src/elements.test.ts new file mode 100644 index 0000000..d43cb40 --- /dev/null +++ b/packages/ui-solid/src/elements.test.ts @@ -0,0 +1,49 @@ +import type { HostElements as CoreHostElements, InputEvent } from '@clack/ui'; +import { describe, expectTypeOf, test } from 'vitest'; +import type { JSX } from './jsx-runtime.ts'; +import type { JSXElement } from './types.ts'; + +interface SolidProbeEvent { + readonly value: number; +} + +interface SolidProbeProps { + count: number; + onprobe?: (event: SolidProbeEvent) => void; +} + +declare module '@clack/ui/elements' { + interface HostElements { + '@test/solid-probe': SolidProbeProps; + } +} + +describe('Solid host elements', () => { + test('maps box and text properties from the core registry', () => { + expectTypeOf().toEqualTypeOf< + CoreHostElements['box']['layout'] + >(); + expectTypeOf().toEqualTypeOf< + CoreHostElements['text']['color'] + >(); + expectTypeOf().toEqualTypeOf< + JSXElement | undefined + >(); + }); + + test('maps lowercase host event properties to Solid casing', () => { + expectTypeOf>() + .parameter(0) + .toEqualTypeOf(); + expectTypeOf< + 'oninput' extends keyof JSX.IntrinsicElements['input'] ? true : false + >().toEqualTypeOf(); + }); + + test('derives custom elements from core registry augmentation', () => { + expectTypeOf().toEqualTypeOf(); + expectTypeOf>() + .parameter(0) + .toEqualTypeOf(); + }); +}); diff --git a/packages/ui-solid/src/elements.ts b/packages/ui-solid/src/elements.ts new file mode 100644 index 0000000..d71683a --- /dev/null +++ b/packages/ui-solid/src/elements.ts @@ -0,0 +1,21 @@ +import type { HostElements as CoreHostElements } from '@clack/ui'; +import type { HostRef, JSXElement } from './types.ts'; + +type SolidProperties = { + [Name in keyof Properties as Name extends string + ? Name extends `on${infer Type}` + ? `on${Capitalize}` + : Name + : Name]: Properties[Name]; +} & { + children?: JSXElement; + ref?: HostRef; +}; + +export type HostElements = { + [Name in keyof CoreHostElements]: SolidProperties; +}; + +export type BoxProps = HostElements['box']; +export type InputProps = HostElements['input']; +export type TextProps = HostElements['text']; diff --git a/packages/ui-solid/src/index.ts b/packages/ui-solid/src/index.ts new file mode 100644 index 0000000..401c515 --- /dev/null +++ b/packages/ui-solid/src/index.ts @@ -0,0 +1,19 @@ +export { rgba } from '@clack/ui'; +export { Box, Text } from './components.ts'; +export type { BoxProps, HostElements, InputProps, TextProps } from './elements.ts'; +export { + createRoot, + type Root, + effect, + memo, + createComponent, + createElement, + createTextNode, + insertNode, + insert, + spread, + setProp, + mergeProps, + use, +} from './renderer.ts'; +export type { HostRef, JSXElement } from './types.ts'; diff --git a/packages/ui-solid/src/jsx-dev-runtime.ts b/packages/ui-solid/src/jsx-dev-runtime.ts new file mode 100644 index 0000000..cd1ed3f --- /dev/null +++ b/packages/ui-solid/src/jsx-dev-runtime.ts @@ -0,0 +1,10 @@ +import type { HostElements } from './index.ts'; +import type { JSXElement } from './types.ts'; + +export declare namespace JSX { + type Element = JSXElement; + interface ElementChildrenAttribute { + children: unknown; + } + interface IntrinsicElements extends HostElements {} +} diff --git a/packages/ui-solid/src/jsx-runtime.ts b/packages/ui-solid/src/jsx-runtime.ts new file mode 100644 index 0000000..8de8c8f --- /dev/null +++ b/packages/ui-solid/src/jsx-runtime.ts @@ -0,0 +1,10 @@ +import type { HostElements } from './index.ts'; +import type { JSXElement } from './types.ts'; + +export declare namespace JSX { + type Element = JSXElement; + interface ElementChildrenAttribute { + children: unknown; + } + type IntrinsicElements = HostElements; +} diff --git a/packages/ui-solid/src/renderer.ts b/packages/ui-solid/src/renderer.ts new file mode 100644 index 0000000..ad97973 --- /dev/null +++ b/packages/ui-solid/src/renderer.ts @@ -0,0 +1,193 @@ +// oxlint-disable bombshell-dev/exported-function-async -- Solid renderer setup and Host roots are synchronous. +// oxlint-disable max-params -- Renderer option signatures are fixed by solid-js. +import { HostApi, type Host } from '@clack/ui'; +import type { HostElement, HostElementChild, HostLiteral } from '@clack/ui/elements'; +import type { HostEventListener, HostEventType } from '@clack/ui/events'; +import { getOwner, type Owner } from 'solid-js'; +import { createRenderer as createUniversalRenderer } from 'solid-js/universal'; +import type { JSXElement } from './types.ts'; + +export { + effect, + memo, + createComponent, + createElement, + createTextNode, + insertNode, + insert, + spread, + setProp, + mergeProps, + use, +}; + +export interface Root { + readonly element: HostElement; + readonly host: Host; + /** Reconcile a Solid component tree into the Host. */ + render(code: () => JSXElement): void; + /** Dispose the Solid owner and detach its Host subtree. */ + unmount(): void; +} + +/** Create a Solid root which reconciles into an attached Host element. */ +export function createRoot(element: HostElement): Root { + const host = HostApi.at(element.node!).getHost(); + nodeHosts.set(element, host); + let dispose: (() => void) | undefined; + + function unmount(): void { + dispose?.(); + dispose = undefined; + for (const child of element.children.slice()) { + host.removeChild(element, child); + } + } + + return { + element, + host, + render(code) { + unmount(); + dispose = universal.render(() => { + const owner = getOwner(); + if (!owner) throw new MissingSolidHostError(owner); + ownerHosts.set(owner, host); + return code() as unknown as HostElementChild; + }, element); + }, + unmount, + }; +} + +const universal = createUniversalRenderer({ + createElement(name) { + const host = currentHost(); + const element = host.createElement(name); + nodeHosts.set(element, host); + return element; + }, + createTextNode(value) { + const host = currentHost(); + const text = host.createLiteral(String(value)); + nodeHosts.set(text, host); + return text; + }, + replaceText(node, value) { + hostFor(node).setText(expectText(node, 'replaceText'), String(value)); + }, + isTextNode(node) { + return node.type === 'literal'; + }, + setProperty(node, name, value, previous) { + const host = hostFor(node); + const element = expectElement(node, 'setProperty'); + const type = eventType(name); + if (type) { + const previousListener = eventListener(previous); + const nextListener = eventListener(value); + if (previousListener) host.removeEventListener(element, type, previousListener); + if (nextListener) host.addEventListener(element, type, nextListener); + } else { + host.setProperty(element, name, value); + } + }, + insertNode(parent, node, anchor) { + const host = hostFor(parent); + nodeHosts.set(node, host); + host.insertBefore(expectElement(parent, 'insertNode'), node, anchor); + }, + removeNode(parent, node) { + hostFor(parent).removeChild(expectElement(parent, 'removeNode'), node); + }, + getParentNode(node) { + return node.parent ?? undefined; + }, + getFirstChild(node) { + return node.type === 'element' ? node.children[0] : undefined; + }, + getNextSibling(node) { + const parent = node.parent; + if (!parent) return undefined; + const index = parent.children.indexOf(node); + return parent.children[index + 1]; + }, +}); + +const { + effect, + memo, + createComponent, + createElement, + createTextNode, + insertNode, + insert, + spread, + setProp, + mergeProps, + use, +} = universal; + +const ownerHosts = new WeakMap(); +const nodeHosts = new WeakMap(); + +class MissingSolidHostError extends Error { + readonly code = 'CLACK_SOLID_MISSING_HOST'; + readonly owner: Owner | null; + + constructor(owner: Owner | null) { + super('Solid renderer operation does not belong to a Host root'); + this.name = 'MissingSolidHostError'; + this.owner = owner; + } +} + +class InvalidSolidHostNodeError extends Error { + readonly code = 'CLACK_SOLID_INVALID_HOST_NODE'; + readonly operation: string; + readonly node: HostElementChild; + + constructor(operation: string, node: HostElementChild) { + super(`Solid renderer ${operation} received a ${node.type} node`); + this.name = 'InvalidSolidHostNodeError'; + this.operation = operation; + this.node = node; + } +} + +function currentHost(): Host { + let owner = getOwner(); + const initialOwner = owner; + while (owner) { + const host = ownerHosts.get(owner); + if (host) return host; + owner = owner.owner; + } + throw new MissingSolidHostError(initialOwner); +} + +function hostFor(node: HostElementChild): Host { + const host = nodeHosts.get(node); + if (!host) throw new MissingSolidHostError(getOwner()); + return host; +} + +function expectElement(node: HostElementChild, operation: string): HostElement { + if (node.type !== 'element') throw new InvalidSolidHostNodeError(operation, node); + return node; +} + +function expectText(node: HostElementChild, operation: string): HostLiteral { + if (node.type !== 'literal') throw new InvalidSolidHostNodeError(operation, node); + return node; +} + +function eventType(name: string): HostEventType | undefined { + const first = name[2]; + if (!name.startsWith('on') || !first || first === first.toLowerCase()) return; + return `${first.toLowerCase()}${name.slice(3)}` as HostEventType; +} + +function eventListener(value: unknown): HostEventListener | undefined { + return typeof value === 'function' ? (value as HostEventListener) : undefined; +} diff --git a/packages/ui-solid/src/root.test.ts b/packages/ui-solid/src/root.test.ts new file mode 100644 index 0000000..9d2650f --- /dev/null +++ b/packages/ui-solid/src/root.test.ts @@ -0,0 +1,232 @@ +import { + HostApi, + createHost, + type HostElement, + type HostElementChild, + type HostLiteral, +} from '@clack/ui'; +import type { InputEvent } from '@clack/ui'; +import type { HostEventListener } from '@clack/ui/events'; +import { createSignal } from 'solid-js'; +import { assert, describe, expect, test, vi } from 'vitest'; +import { + Box, + Text, + createComponent, + createElement, + createRoot, + effect, + insert, + setProp, +} from './index.ts'; + +const reactiveRuntime = (() => { + const [value, setValue] = createSignal(0); + let observed = -1; + effect(() => (observed = value())); + setValue(1); + return observed === 1; +})(); + +function element(child: HostElementChild): HostElement { + assert(child.type === 'element'); + return child; +} + +function literal(child: HostElementChild): HostLiteral { + assert(child.type === 'literal'); + return child; +} + +describe('createRoot', () => { + test('builds and attaches a Solid subtree through the Host', () => { + const host = createHost(); + const root = createRoot(host.element); + + root.render(() => + createComponent(Box, { + layout: { direction: 'ttb' }, + get children() { + return createComponent(Text, { color: 15, children: 'hello' }); + }, + }), + ); + + const box = element(host.element.children[0]!); + const text = element(box.children[0]!); + expect(box.name).toBe('box'); + expect(box.properties).toEqual({ layout: { direction: 'ttb' } }); + expect(box.node).not.toBeNull(); + expect(text.name).toBe('text'); + expect(text.properties).toEqual({ color: 15 }); + expect(text.node).not.toBeNull(); + expect(literal(text.children[0]!)).toMatchObject({ content: 'hello', parent: text }); + }); + + test('mounts within the supplied attached element', () => { + const host = createHost(); + const container = host.createElement('container'); + host.insertBefore(host.element, container); + const root = createRoot(container); + + root.render(() => createElement('probe')); + + expect(root.element).toBe(container); + expect(host.element.children).toEqual([container]); + expect(element(container.children[0]!)).toMatchObject({ name: 'probe' }); + + root.unmount(); + + expect(container.children).toEqual([]); + expect(container.node).not.toBeNull(); + }); + + test.runIf(reactiveRuntime)('updates and removes properties and updates text literals', () => { + const host = createHost(); + const root = createRoot(host.element); + const [state, setState] = createSignal({ + added: undefined as number | undefined, + content: 'first', + nullable: null, + removable: 'yes' as string | undefined, + }); + let probe!: HostElement; + + root.render(() => { + probe = element(createElement('probe')); + effect((previous: ReturnType | undefined) => { + const current = state(); + setProp(probe, 'added', current.added, previous?.added); + setProp(probe, 'nullable', current.nullable, previous?.nullable); + setProp(probe, 'removable', current.removable, previous?.removable); + return current; + }); + insert(probe, () => state().content); + return probe; + }); + + const text = literal(probe.children[0]!); + setState({ added: 0, content: 'second', nullable: null, removable: undefined }); + + expect(probe.properties).toEqual({ added: 0, nullable: null }); + expect(literal(probe.children[0]!)).toBe(text); + expect(text.content).toBe('second'); + }); + + test.runIf(reactiveRuntime)( + 'moves reactive children within the same parent without recreating them', + () => { + const host = createHost(); + const root = createRoot(host.element); + const [order, setOrder] = createSignal([]); + let list!: HostElement; + let first!: HostElement; + let second!: HostElement; + let third!: HostElement; + + root.render(() => { + list = element(createElement('list')); + first = element(createElement('item')); + second = element(createElement('item')); + third = element(createElement('item')); + setOrder([first, second, third]); + insert(list, order); + return list; + }); + + setOrder([third, first, second]); + + expect(list.children).toEqual([third, first, second]); + }, + ); + + test('routes element creation through Host middleware', () => { + const host = createHost(); + const createElementCall = vi.fn(); + HostApi.decorate(host.root, () => ({ + createElement(name) { + createElementCall(name); + return super.createElement(name); + }, + })); + const root = createRoot(host.element); + + root.render(() => createElement('custom-element')); + + expect(createElementCall).toHaveBeenCalledWith('custom-element'); + }); + + test('delivers Host events through Solid event properties', () => { + const host = createHost(); + let listener: HostEventListener<'input'> | undefined; + HostApi.decorate(host.root, () => ({ + addEventListener(target, type, current) { + if (type === 'input') listener = current as HostEventListener<'input'>; + return super.addEventListener(target, type, current); + }, + removeEventListener(target, type, current) { + if (current === listener) listener = undefined; + return super.removeEventListener(target, type, current); + }, + })); + const root = createRoot(host.element); + const first = vi.fn(); + const second = vi.fn(); + let input!: HostElement; + + root.render(() => { + input = element(createElement('input')); + setProp(input, 'onInput', first); + return input; + }); + const event: InputEvent = { type: 'input', target: input, value: 'hello' }; + listener!(event); + + expect(first).toHaveBeenCalledWith(event); + expect(input.properties).toEqual({}); + + setProp(input, 'onInput', second, first); + listener!(event); + + expect(first).toHaveBeenCalledTimes(1); + expect(second).toHaveBeenCalledWith(event); + }); + + test.runIf(reactiveRuntime)('applies fine-grained updates scheduled by Solid signals', () => { + const host = createHost(); + const root = createRoot(host.element); + const [count, setCount] = createSignal(0); + let text!: HostElement; + + root.render(() => { + text = element(createElement('text')); + insert(text, count); + return text; + }); + + const instance = literal(text.children[0]!); + setCount(1); + + expect(literal(text.children[0]!)).toBe(instance); + expect(instance.content).toBe('1'); + }); + + test('unmounts and detaches the Solid subtree', () => { + const host = createHost(); + const root = createRoot(host.element); + let box!: HostElement; + let text!: HostElement; + root.render(() => { + box = element(createElement('box')); + text = element(createElement('text')); + insert(box, text); + return box; + }); + + root.unmount(); + + expect(host.element.children).toEqual([]); + expect(box.node).toBeNull(); + expect(text.node).toBeNull(); + }); +}); diff --git a/packages/ui-solid/src/types.ts b/packages/ui-solid/src/types.ts new file mode 100644 index 0000000..5a00fc5 --- /dev/null +++ b/packages/ui-solid/src/types.ts @@ -0,0 +1,12 @@ +import type { HostElement, HostElementChild } from '@clack/ui/elements'; + +export type JSXElement = + | HostElementChild + | readonly JSXElement[] + | string + | number + | boolean + | null + | undefined; + +export type HostRef = HostElement | ((element: HostElement) => void); diff --git a/packages/ui-solid/tsconfig.json b/packages/ui-solid/tsconfig.json new file mode 100644 index 0000000..a055ad0 --- /dev/null +++ b/packages/ui-solid/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@bomb.sh/tools/tsconfig.json", + "compilerOptions": { + "types": ["node"] + } +} diff --git a/packages/ui-solid/vitest.config.ts b/packages/ui-solid/vitest.config.ts new file mode 100644 index 0000000..f420ed4 --- /dev/null +++ b/packages/ui-solid/vitest.config.ts @@ -0,0 +1,20 @@ +// oxlint-disable import/no-default-export -- Vitest loads configuration through a default export. +import { fileURLToPath } from 'node:url'; +import { defineConfig } from 'vitest/config'; + +const solid = fileURLToPath(new URL('./node_modules/solid-js/dist/solid.js', import.meta.url)); +const universal = fileURLToPath( + new URL('./node_modules/solid-js/universal/dist/universal.js', import.meta.url), +); + +export default defineConfig({ + resolve: { + alias: [ + { find: 'solid-js/universal', replacement: universal }, + { find: /^solid-js$/, replacement: solid }, + ], + }, + ssr: { + noExternal: ['solid-js'], + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c7fd563..7e704e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,17 +56,214 @@ importers: specifier: ^4.19.0 version: 4.23.15 + examples/hello-world-solid: + dependencies: + '@bomb.sh/tty': + specifier: ^0.7.0 + version: 0.7.0 + '@clack/ui': + specifier: workspace:* + version: link:../../packages/ui + '@clack/ui-solid': + specifier: workspace:* + version: link:../../packages/ui-solid + solid-js: + specifier: 1.9.14 + version: 1.9.14 + devDependencies: + '@babel/cli': + specifier: 7.29.7 + version: 7.29.7(@babel/core@7.29.7) + '@babel/core': + specifier: 7.29.7 + version: 7.29.7 + '@babel/preset-typescript': + specifier: 7.29.7 + version: 7.29.7(@babel/core@7.29.7) + '@types/node': + specifier: ^22.20.0 + version: 22.20.4 + babel-preset-solid: + specifier: 1.9.12 + version: 1.9.12(@babel/core@7.29.7)(solid-js@1.9.14) + tsx: + specifier: ^4.19.0 + version: 4.23.15 + packages/ui: dependencies: '@bomb.sh/tty': specifier: 'catalog:' version: 0.7.0 + packages/ui-solid: + dependencies: + '@clack/ui': + specifier: workspace:* + version: link:../ui + devDependencies: + '@bomb.sh/tools': + specifier: ^0.5.4 + version: 0.5.6(@types/node@22.20.4)(oxc-resolver@11.24.2)(tsx@4.23.15)(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) + '@types/node': + specifier: ^22.20.0 + version: 22.20.4 + solid-js: + specifier: 1.9.14 + version: 1.9.14 + vitest: + specifier: ^4.1.9 + version: 4.1.11(@types/node@22.20.4)(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) + packages: + '@babel/cli@7.29.7': + resolution: {integrity: sha512-/75HwRbAYPqXv/Ax1h7Fg3IZfXgdU98jnA8H93/m/QBaPV3Hp5ICoLqzGYye1yHBCgpmXvtqgSUN8oOKX5tojQ==} + engines: {node: '>=6.9.0'} + hasBin: true + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.8': + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.29.7': + resolution: {integrity: sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.29.7': + resolution: {integrity: sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.29.7': + resolution: {integrity: sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.18.6': + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.29.7': + resolution: {integrity: sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.29.7': + resolution: {integrity: sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.29.7': + resolution: {integrity: sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': + resolution: {integrity: sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.9': + resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.29.7': + resolution: {integrity: sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.29.7': + resolution: {integrity: sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.29.7': + resolution: {integrity: sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.29.9': + resolution: {integrity: sha512-FFwIwzU+7SCOuxxV4YtJql6T9981ZVTm+FHO5GhVsRqCTdy0WwrEZh3l42ARpXruJUDGOptdduHW6Zr7pNPLNg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.29.7': + resolution: {integrity: sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.8': + resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + '@bomb.sh/args@0.3.1': resolution: {integrity: sha512-CwxKrfgcorUPP6KfYD59aRdBYWBTsfsxT+GmoLVnKo5Tmyoqbpo0UNcjngRMyU+6tiPbd18RuIYxhgAn44wU/Q==} + '@bomb.sh/tools@0.5.6': + resolution: {integrity: sha512-bQffZ8EvaZ2G4p5Ksvr3HGaI5JLe7vqMn9n8+X6kmXQqqGT2Lsp2a0WYTlGWLMQk/VaRKHRMooSw6gCnUgWUxg==} + hasBin: true + '@bomb.sh/tools@0.6.1': resolution: {integrity: sha512-p3dLXau2JygQ9DTErUvHSn7GwqpRraIjiXdj/xeAU0+7opUZrtiHe18FLrU5opCSr16WZep0p0/OBX1HgMjgJQ==} hasBin: true @@ -256,9 +453,22 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + '@jridgewell/sourcemap-codec@1.6.0': resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@napi-rs/wasm-runtime@1.2.4': resolution: {integrity: sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g==} engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} @@ -266,6 +476,9 @@ packages: '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 + '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': + resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} + '@oxc-parser/binding-android-arm-eabi@0.150.0': resolution: {integrity: sha512-oQef2Zu4Prz1KLKznz3HqZzU9uVoA5PMoDZuuLmqms7hKmKSAPzlaMnLllJq3t+rgKmfJJ2siPrpZfFrW06btw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1030,21 +1243,89 @@ packages: resolution: {integrity: sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==} engines: {node: '>=14'} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + babel-plugin-jsx-dom-expressions@0.40.10: + resolution: {integrity: sha512-lxve6Y02YiZTldB7efKpnbf1BH00XCFZNYYW235jSGsYaJNFtHrYlKV6/O+miHbjqpIr9FTe5+0no4hofAMbfA==} + peerDependencies: + '@babel/core': ^7.20.12 + + babel-preset-solid@1.9.12: + resolution: {integrity: sha512-LLqnuKVDlKpyBlMPcH6qEvs/wmS9a+NczppxJ3ryS/c0O5IiSFOIBQi9GzyiGDSbcJpx4Gr87jyFTos1MyEuWg==} + peerDependencies: + '@babel/core': ^7.0.0 + solid-js: ^1.9.12 + peerDependenciesMeta: + solid-js: + optional: true + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.11.25: + resolution: {integrity: sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==} + engines: {node: '>=6.0.0'} + hasBin: true + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + brace-expansion@1.1.21: + resolution: {integrity: sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.29.0: + resolution: {integrity: sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + cac@7.0.0: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} + caniuse-lite@1.0.30001812: + resolution: {integrity: sha512-qN+QNNBr93TCmFrmte0bBCjSDMuRvt78VlHT99qIGPszm4QsqCX8lnyWUFkHi8B7ZBAPq8SH+UqyXNy/odMdng==} + chai@6.2.2: resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} engines: {node: '>=18'} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + defu@6.1.7: resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} @@ -1061,10 +1342,17 @@ packages: oxc-resolver: optional: true + electron-to-chromium@1.5.438: + resolution: {integrity: sha512-AN9xMU1hJiT65LkCUPL1DZm5TCbOPb2Qsm5pYwFLEXp6/qj9SdT4yMiqs7Qqstwvkn1zF7l36SRGt+s6XcJ0FA==} + empathic@2.1.0: resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} engines: {node: '>=14'} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + es-module-lexer@2.3.2: resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} @@ -1073,6 +1361,10 @@ packages: engines: {node: '>=18'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -1092,16 +1384,30 @@ packages: picomatch: optional: true + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + formatly@0.7.1: resolution: {integrity: sha512-ESuCEJE0SGgabl9q+zABI8LhJDmF+8nhpuqDzuM48HfJ9QTD5o6PqFJDFZY7w6f8xsh5lixuj5nJsQNvYOWvKQ==} engines: {node: '>=18.3.0'} hasBin: true + fs-readdir-recursive@1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-tsconfig@4.14.3: resolution: {integrity: sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==} @@ -1109,17 +1415,64 @@ packages: resolution: {integrity: sha512-/6gFNr0N04nob252sTQxyFLi3eKFRqIg1I87YcqAMT1i6SQrSF6KujUEQrtrjMV0H/eejTCltLdDSTEMzHbnsQ==} engines: {node: '>=20.20.0'} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hookable@6.1.2: resolution: {integrity: sha512-+abwxtiEA52GCVIsQqut3S/uKTbUwYIp4Pe/vv+6py5XiXBCqMZHg6pA6Y5qhgLSEys0/cYuPbO0z1QFj5ZCmg==} + html-entities@2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + import-without-cache@0.4.1: resolution: {integrity: sha512-vXoV9PjKHEednCUu01e98TkImxy67e3BJXbTIOmIq4Hyzw3IAwYRcuPkfeTzJzwyyts4kjuA73x+pWJLc4f86A==} engines: {node: ^22.18.0 || >=24.0.0} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + knip@6.38.0: resolution: {integrity: sha512-umytiMCaZf02MV9SOO1FEDgbDf6h20VZk3ruJE0kh52kkGjYZFRUAXHJWYoLhvhoHGINO/7GXVJmQ2vxTBvl6A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1195,22 +1548,46 @@ packages: resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + nanoid@3.3.19: resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + node-releases@2.0.57: + resolution: {integrity: sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==} + engines: {node: '>=18'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + obug@2.2.1: resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} engines: {node: '>=12.20.0'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + oxc-parser@0.150.0: resolution: {integrity: sha512-zwajKw1GUa57IOdafIS7/yOObGF2NihwIfZfs5yJTRprMSkiwhWOc/k+n8bwnUPbHr2/XsjfBO8KyTPaW3VpWg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1239,16 +1616,31 @@ packages: package-manager-detector@1.8.0: resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + picomatch@4.0.7: resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} engines: {node: '>=12'} + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + postcss@8.5.28: resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} engines: {node: ^10 || ^12 || >=14} @@ -1261,6 +1653,10 @@ packages: quansync@1.0.0: resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -1292,13 +1688,38 @@ packages: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + seroval-plugins@1.5.6: + resolution: {integrity: sha512-HXuLAX2pu/UByPpaeo/TaMfvMIi+1QqIoPJYCcAtU8QkVNwgR6MPlGuCQTErV1JwraaMbYaWVIBX7mppzGLATQ==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.5.6: + resolution: {integrity: sha512-rVQVWjjSvlINzaQPZH5JFqsqEsIWdTxY3iJZCnTL/5gQbXIRooVZKI60tVCkOVfzcRPejboxO2t0P89dg5mQaA==} + engines: {node: '>=10'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + slash@2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + smol-toml@1.9.0: resolution: {integrity: sha512-hpd+HLON7HdZXqYchMM/+LaTTbdK0AU3NngIJ4KVyWbY9bfQqdL9cD+4yf6dUoU2Ap4VsU0JkQi6FxAI1B2mXQ==} engines: {node: '>= 18'} + solid-js@1.9.14: + resolution: {integrity: sha512-sAEXC0Kk0S1EDg+8ysEWJDbYhA3RRoEjwuySUGlKIemeo0I5YZfOyumNjNs9Sv3y2nmhD+0rW66ag2HsMuQiGQ==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -1332,6 +1753,10 @@ packages: resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==} engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -1391,6 +1816,12 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + update-browserslist-db@1.3.3: + resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + verkit@0.3.2: resolution: {integrity: sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==} engines: {node: '>=18.12.0'} @@ -1493,6 +1924,12 @@ packages: engines: {node: '>=8'} hasBin: true + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml@2.9.1: resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} engines: {node: '>= 14.6'} @@ -1512,8 +1949,255 @@ packages: snapshots: + '@babel/cli@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@jridgewell/trace-mapping': 0.3.31 + commander: 6.2.1 + convert-source-map: 2.0.0 + fs-readdir-recursive: 1.1.0 + glob: 7.2.3 + make-dir: 2.1.0 + slash: 2.0.0 + optionalDependencies: + '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 + chokidar: 3.6.0 + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.7': {} + + '@babel/core@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.8': + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.29.7': + dependencies: + '@babel/types': 7.29.8 + + '@babel/helper-compilation-targets@7.29.7': + dependencies: + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + browserslist: 4.29.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/traverse': 7.29.8 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-member-expression-to-functions@7.29.7': + dependencies: + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.18.6': + dependencies: + '@babel/types': 7.29.8 + + '@babel/helper-module-imports@7.29.7': + dependencies: + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.29.7': + dependencies: + '@babel/types': 7.29.8 + + '@babel/helper-plugin-utils@7.29.7': {} + + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-optimise-call-expression': 7.29.7 + '@babel/traverse': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.29.7': + dependencies: + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-option@7.29.7': {} + + '@babel/helpers@7.29.7': + dependencies: + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + + '@babel/parser@7.29.9': + dependencies: + '@babel/types': 7.29.8 + + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + + '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helper-plugin-utils': 7.29.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.29.9(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-annotate-as-pure': 7.29.7 + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-plugin-utils': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-typescript': 7.29.9(@babel/core@7.29.7) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + + '@babel/traverse@7.29.8': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.9 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@bomb.sh/args@0.3.1': {} + '@bomb.sh/tools@0.5.6(@types/node@22.20.4)(oxc-resolver@11.24.2)(tsx@4.23.15)(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1))': + dependencies: + '@bomb.sh/args': 0.3.1 + '@humanfs/node': 0.16.8 + '@humanfs/types': 0.15.0 + '@typescript/native-preview': 7.0.0-dev.20260623.1 + knip: 6.38.0 + oxfmt: 0.47.0 + oxlint: 1.85.0 + publint: 0.3.24 + tinyexec: 1.3.1 + tsdown: 0.22.14(@typescript/native-preview@7.0.0-dev.20260623.1)(oxc-resolver@11.24.2)(publint@0.3.24)(tsx@4.23.15) + ultramatter: 0.0.4 + vitest: 4.1.11(@types/node@22.20.4)(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) + vitest-ansi-serializer: 0.2.1(vitest@4.1.11(@types/node@22.20.4)(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1))) + transitivePeerDependencies: + - '@arethetypeswrong/core' + - '@edge-runtime/vm' + - '@opentelemetry/api' + - '@tsdown/css' + - '@tsdown/exe' + - '@types/node' + - '@vitejs/devtools' + - '@vitest/browser-playwright' + - '@vitest/browser-preview' + - '@vitest/browser-webdriverio' + - '@vitest/coverage-istanbul' + - '@vitest/coverage-v8' + - '@vitest/ui' + - '@volar/typescript' + - happy-dom + - jsdom + - msw + - oxc-resolver + - oxlint-tsgolint + - tsx + - typescript + - unplugin-unused + - unrun + - vite + - vite-plus + - vue-tsc + '@bomb.sh/tools@0.6.1(@types/node@22.20.4)(oxc-resolver@11.24.2)(tsx@4.23.15)(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1))': dependencies: '@bomb.sh/args': 0.3.1 @@ -1667,8 +2351,25 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/sourcemap-codec@1.6.0': {} + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + '@napi-rs/wasm-runtime@1.2.4(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': dependencies: '@emnapi/core': 1.11.2 @@ -1676,6 +2377,9 @@ snapshots: '@tybys/wasm-util': 0.10.4 optional: true + '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': + optional: true + '@oxc-parser/binding-android-arm-eabi@0.150.0': optional: true @@ -2135,14 +2839,86 @@ snapshots: ansis@4.4.0: {} + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + optional: true + assertion-error@2.0.1: {} + babel-plugin-jsx-dom-expressions@0.40.10(@babel/core@7.29.7): + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) + '@babel/types': 7.29.8 + html-entities: 2.3.3 + parse5: 7.3.0 + + babel-preset-solid@1.9.12(@babel/core@7.29.7)(solid-js@1.9.14): + dependencies: + '@babel/core': 7.29.7 + babel-plugin-jsx-dom-expressions: 0.40.10(@babel/core@7.29.7) + optionalDependencies: + solid-js: 1.9.14 + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.11.25: {} + + binary-extensions@2.3.0: + optional: true + + brace-expansion@1.1.21: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + optional: true + + browserslist@4.29.0: + dependencies: + baseline-browser-mapping: 2.11.25 + caniuse-lite: 1.0.30001812 + electron-to-chromium: 1.5.438 + node-releases: 2.0.57 + update-browserslist-db: 1.3.3(browserslist@4.29.0) + cac@7.0.0: {} + caniuse-lite@1.0.30001812: {} + chai@6.2.2: {} + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + optional: true + + commander@6.2.1: {} + + concat-map@0.0.1: {} + convert-source-map@2.0.0: {} + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + defu@6.1.7: {} detect-libc@2.1.2: {} @@ -2151,8 +2927,12 @@ snapshots: optionalDependencies: oxc-resolver: 11.24.2 + electron-to-chromium@1.5.438: {} + empathic@2.1.0: {} + entities@6.0.1: {} + es-module-lexer@2.3.2: {} esbuild@0.28.2: @@ -2184,6 +2964,8 @@ snapshots: '@esbuild/win32-ia32': 0.28.2 '@esbuild/win32-x64': 0.28.2 + escalade@3.2.0: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.9 @@ -2198,14 +2980,25 @@ snapshots: optionalDependencies: picomatch: 4.0.7 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + optional: true + formatly@0.7.1: dependencies: fd-package-json: 2.0.0 package-manager-detector: 1.8.0 + fs-readdir-recursive@1.1.0: {} + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true + gensync@1.0.0-beta.2: {} + get-tsconfig@4.14.3: dependencies: resolve-pkg-maps: 1.0.0 @@ -2214,12 +3007,57 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + optional: true + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + hookable@6.1.2: {} + html-entities@2.3.3: {} + import-without-cache@0.4.1: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + optional: true + + is-extglob@2.1.1: + optional: true + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + optional: true + + is-number@7.0.0: + optional: true + jiti@2.7.0: {} + js-tokens@4.0.0: {} + + jsesc@3.1.0: {} + + json5@2.2.3: {} + knip@6.38.0: dependencies: fdir: 6.5.0(picomatch@4.0.7) @@ -2285,16 +3123,40 @@ snapshots: lightningcss-win32-arm64-msvc: 1.33.0 lightningcss-win32-x64-msvc: 1.33.0 + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.6.0 + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.21 + mri@1.2.0: {} + ms@2.1.3: {} + nanoid@3.3.19: {} + node-releases@2.0.57: {} + + normalize-path@3.0.0: + optional: true + obug@2.2.1: {} + once@1.4.0: + dependencies: + wrappy: 1.0.2 + oxc-parser@0.150.0: dependencies: '@oxc-project/types': 0.150.0 @@ -2389,12 +3251,23 @@ snapshots: package-manager-detector@1.8.0: {} + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + path-is-absolute@1.0.1: {} + pathe@2.0.3: {} picocolors@1.1.1: {} + picomatch@2.3.2: + optional: true + picomatch@4.0.7: {} + pify@4.0.1: {} + postcss@8.5.28: dependencies: nanoid: 3.3.19 @@ -2410,6 +3283,11 @@ snapshots: quansync@1.0.0: {} + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + optional: true + resolve-pkg-maps@1.0.0: {} rolldown-plugin-dts@0.27.14(@typescript/native-preview@7.0.0-dev.20260623.1)(oxc-resolver@11.24.2)(rolldown@1.2.10): @@ -2451,10 +3329,28 @@ snapshots: dependencies: mri: 1.2.0 + semver@5.7.2: {} + + semver@6.3.1: {} + + seroval-plugins@1.5.6(seroval@1.5.6): + dependencies: + seroval: 1.5.6 + + seroval@1.5.6: {} + siginfo@2.0.0: {} + slash@2.0.0: {} + smol-toml@1.9.0: {} + solid-js@1.9.14: + dependencies: + csstype: 3.2.3 + seroval: 1.5.6 + seroval-plugins: 1.5.6(seroval@1.5.6) + source-map-js@1.2.1: {} stackback@0.0.2: {} @@ -2476,6 +3372,11 @@ snapshots: tinyrainbow@3.1.1: {} + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + optional: true + tree-kill@1.2.2: {} tsdown@0.22.14(@typescript/native-preview@7.0.0-dev.20260623.1)(oxc-resolver@11.24.2)(publint@0.3.24)(tsx@4.23.15): @@ -2524,6 +3425,12 @@ snapshots: undici-types@6.21.0: {} + update-browserslist-db@1.3.3(browserslist@4.29.0): + dependencies: + browserslist: 4.29.0 + escalade: 3.2.0 + picocolors: 1.1.1 + verkit@0.3.2: {} vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1): @@ -2579,6 +3486,10 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + wrappy@1.0.2: {} + + yallist@3.1.1: {} + yaml@2.9.1: {} yuku-ast@0.8.7: