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: