diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..9210db8 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "privatePackages": false, + "ignore": [] +} diff --git a/.changeset/dom-mutations-and-events.md b/.changeset/dom-mutations-and-events.md new file mode 100644 index 0000000..6949376 --- /dev/null +++ b/.changeset/dom-mutations-and-events.md @@ -0,0 +1,5 @@ +--- +'@clack/ui': minor +--- + +Add DOM tree navigation and mutation APIs, text and attribute updates, and event dispatch with capture, target, and bubbling phases. Support cancellation, propagation control, listener updates during dispatch, and nested events for framework integrations. diff --git a/.changeset/preact-integration.md b/.changeset/preact-integration.md new file mode 100644 index 0000000..953fe3c --- /dev/null +++ b/.changeset/preact-integration.md @@ -0,0 +1,6 @@ +--- +'@clack/ui': minor +'@clack/ui-preact': minor +--- + +Add Preact 11 bindings for mounting into Clack elements, with Clack-specific JSX types and disposable roots. Export the DOM classes and UI types needed by framework integrations from `@clack/ui`. diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9e61ede --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Unified diffs deliberately contain space-prefixed context lines and blank lines. +*.patch -whitespace diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 4330045..c7e833d 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -11,3 +11,4 @@ jobs: secrets: inherit with: publish: './packages/*' + template: './examples/*' diff --git a/examples/hello-world-preact/README.md b/examples/hello-world-preact/README.md new file mode 100644 index 0000000..c3c6919 --- /dev/null +++ b/examples/hello-world-preact/README.md @@ -0,0 +1,16 @@ +# Hello Preact + +A Preact component mounted on a nested Clack element, without styles or a global +`document`. It keeps `Hello ` on screen while erasing and typing `World!`, `DOM!`, +`Preact!`, and `Clack!` in a repeating loop. + +From the workspace root: + +```sh +pnpm install +pnpm build +pnpm --filter @examples/hello-world-preact start +``` + +Press Ctrl+C to exit. Unmounting cancels the animation timer, and disposing the UI +restores the terminal buffer and cursor. diff --git a/examples/hello-world-preact/package.json b/examples/hello-world-preact/package.json new file mode 100644 index 0000000..4484789 --- /dev/null +++ b/examples/hello-world-preact/package.json @@ -0,0 +1,20 @@ +{ + "name": "@examples/hello-world-preact", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "start": "node --import tsx src/main.tsx", + "dev": "tsx watch src/main.tsx", + "lint": "bsh lint" + }, + "dependencies": { + "@clack/ui": "workspace:*", + "@clack/ui-preact": "workspace:*", + "preact": "11.0.1" + }, + "devDependencies": { + "@types/node": "^22.20.0", + "tsx": "^4.19.0" + } +} diff --git a/examples/hello-world-preact/src/animation.ts b/examples/hello-world-preact/src/animation.ts new file mode 100644 index 0000000..9dff559 --- /dev/null +++ b/examples/hello-world-preact/src/animation.ts @@ -0,0 +1,34 @@ +export interface GreetingFrame { + text: string; + delay: number; +} + +const prefix = 'Hello '; +const greetings = ['World!', 'DOM!', 'Preact!', 'Clack!']; +const pause = 900; +const erase = 60; +const type = 100; + +/** Each frame says what to show and how long to leave it on screen. */ +export function* greetingFrames(): Generator { + let index = 0; + const suffix = [...greetings[index]!]; + yield { text: prefix + suffix.join(''), delay: pause }; + + while (true) { + while (suffix.length > 0) { + suffix.pop(); + yield { text: prefix + suffix.join(''), delay: erase }; + } + + index = (index + 1) % greetings.length; + const next = [...greetings[index]!]; + for (const character of next) { + suffix.push(character); + yield { + text: prefix + suffix.join(''), + delay: suffix.length === next.length ? pause : type, + }; + } + } +} diff --git a/examples/hello-world-preact/src/greeting.tsx b/examples/hello-world-preact/src/greeting.tsx new file mode 100644 index 0000000..2598c53 --- /dev/null +++ b/examples/hello-world-preact/src/greeting.tsx @@ -0,0 +1,22 @@ +import { useEffect, useState } from 'preact/hooks'; +import { greetingFrames } from './animation.ts'; + +export function Greeting() { + const [text, setText] = useState('Hello World!'); + + useEffect(() => { + const animation = greetingFrames(); + let timer: ReturnType; + + function advance() { + const frame = animation.next().value; + setText(frame.text); + timer = setTimeout(advance, frame.delay); + } + + advance(); + return () => clearTimeout(timer); + }, []); + + return {text}; +} diff --git a/examples/hello-world-preact/src/main.tsx b/examples/hello-world-preact/src/main.tsx new file mode 100644 index 0000000..b2cd500 --- /dev/null +++ b/examples/hello-world-preact/src/main.tsx @@ -0,0 +1,28 @@ +import { createUI } from '@clack/ui'; +import { createRoot } from '@clack/ui-preact'; +import { Greeting } from './greeting.tsx'; + +const shutdown = Promise.withResolvers(); +const stop = () => shutdown.resolve(); +process.once('SIGINT', stop); +process.once('SIGTERM', stop); + +try { + await using ui = await createUI({ + input: process.stdin, + output: process.stdout, + width: process.stdout.columns ?? 80, + height: process.stdout.rows ?? 24, + }); + + // A root can be mounted on any Clack element, not just the document root. + const mount = ui.document.createElement('div'); + ui.document.documentElement.appendChild(mount); + using root = createRoot(mount); + root.render(); + + await Promise.race([ui.main(), shutdown.promise]); +} finally { + process.off('SIGINT', stop); + process.off('SIGTERM', stop); +} diff --git a/examples/hello-world-preact/tsconfig.json b/examples/hello-world-preact/tsconfig.json new file mode 100644 index 0000000..36ea9bd --- /dev/null +++ b/examples/hello-world-preact/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["node"], + "jsx": "react-jsx", + "jsxImportSource": "@clack/ui-preact" + }, + "include": ["src"] +} diff --git a/package.json b/package.json index ed39166..4467a14 100644 --- a/package.json +++ b/package.json @@ -31,16 +31,17 @@ "build": "pnpm --filter \"@clack/*\" run build", "format": "bsh format", "format:check": "bsh format --check", - "lint": "bsh lint .", - "test": "bsh test" + "lint": "bsh lint && pnpm -r lint", + "test": "vitest run" }, "devDependencies": { - "@bomb.sh/tools": "^0.6.1", + "@bomb.sh/tools": "^0.8.0", + "@changesets/cli": "^2.30.0", "@termless/core": "^0.10.2", "@termless/test": "^0.10.2", "@types/node": "^22.20.0", "node-pty": "1.2.0-beta.15", - "vitest": "^4.1.9" + "vitest": "^5.0.5" }, "devEngines": { "packageManager": { diff --git a/packages/ui-preact/README.md b/packages/ui-preact/README.md new file mode 100644 index 0000000..dd896a4 --- /dev/null +++ b/packages/ui-preact/README.md @@ -0,0 +1,39 @@ +# `@clack/ui-preact` + +Mount Preact 11 into any Clack element. No browser DOM, global `document`, or DOM adapter is needed. + +```tsx +import { createUI } from '@clack/ui'; +import { createRoot } from '@clack/ui-preact'; + +await using ui = await createUI({ input: process.stdin, output: process.stdout }); +const container = ui.document.createElement('div'); +ui.document.documentElement.appendChild(container); + +using root = createRoot(container); +root.render(Hello World!); + +// Run until your application exits its scope and disposes the UI. +await ui.main(); +``` + +Configure TypeScript with `"jsx": "react-jsx"` and `"jsxImportSource": "@clack/ui-preact"`. +Use components and hooks from `preact` and `preact/hooks` as usual. JSX refs refer to Clack +elements, and event handlers receive Clack events, not browser events. + +`root.render(node)` updates the element's children. `root.unmount()` removes that tree and +allows a later render. Disposing the root with `using` calls `unmount()`. Preact owns effect +cleanup; passive effect cleanup follows Preact's asynchronous scheduling. + +Roots may be nested in an existing DOM tree or attached after rendering while detached. +Keep one root per container. Its contents belong to Preact; siblings outside the container +are unaffected. Separate roots can use separate Clack documents. Preact 11's `createPortal` +also accepts Clack elements directly. + +This first integration intentionally has no style support. Tags do not imply HTML semantics, +and `style`, HTML parsing, browser APIs, hydration, and `preact/compat` are not part of this +surface. Preact's reserved `svg`, `math`, and `template` tags are also unsupported. +Native keyboard and mouse input will be added separately; dispatched Clack events +already work with Preact handlers. + +See [the animated greeting example](../../examples/hello-world-preact/README.md). diff --git a/packages/ui-preact/package.json b/packages/ui-preact/package.json new file mode 100644 index 0000000..81c35fd --- /dev/null +++ b/packages/ui-preact/package.json @@ -0,0 +1,75 @@ +{ + "name": "@clack/ui-preact", + "version": "0.0.0", + "description": "Preact bindings for Clack's terminal DOM", + "keywords": [ + "bombshell", + "cli", + "preact" + ], + "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": "bsh test" + }, + "dependencies": { + "@clack/ui": "workspace:*" + }, + "devDependencies": { + "preact": "11.0.1" + }, + "peerDependencies": { + "preact": "^11.0.1" + }, + "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" + ] + } +} diff --git a/packages/ui-preact/src/elements.test.ts b/packages/ui-preact/src/elements.test.ts new file mode 100644 index 0000000..e77f37c --- /dev/null +++ b/packages/ui-preact/src/elements.test.ts @@ -0,0 +1,15 @@ +import type { Element, Event } from '@clack/ui'; +import type { Ref } from 'preact'; +import { expectTypeOf, it } from 'vitest'; +import type { JSX } from './jsx-runtime.ts'; + +it('types JSX against Clack without advertising browser-only APIs', () => { + type Props = JSX.IntrinsicElements['span']; + expectTypeOf().toEqualTypeOf | undefined>(); + expectTypeOf>().parameter(0).toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toEqualTypeOf(); + expectTypeOf().toBeNever(); + expectTypeOf().toBeNever(); + expectTypeOf().toBeNever(); +}); diff --git a/packages/ui-preact/src/elements.ts b/packages/ui-preact/src/elements.ts new file mode 100644 index 0000000..0a4300a --- /dev/null +++ b/packages/ui-preact/src/elements.ts @@ -0,0 +1,30 @@ +import type { Element, Event } from '@clack/ui'; +import type { ComponentChildren, Key, Ref } from 'preact'; + +export type EventHandler = (event: Event) => void; +export type AttributeValue = string | number | boolean | null | undefined; + +/** Attributes supported by the unstyled Clack DOM, not browser HTML elements. */ +export interface ElementProps { + children?: ComponentChildren; + key?: Key; + ref?: Ref; + id?: string; + class?: string; + title?: string; + [attribute: `data-${string}`]: AttributeValue; + [attribute: `aria-${string}`]: AttributeValue; + [event: `on${string}`]: EventHandler | undefined; + // These need APIs which are deliberately outside this initial integration. + style?: never; + dangerouslySetInnerHTML?: never; +} + +/** Ordinary tags are generic Clack elements, without browser behavior or styling. */ +export interface HostElements { + [tagName: string]: ElementProps; + // Preact reserves these names for browser APIs that Clack does not implement. + svg: never; + math: never; + template: never; +} diff --git a/packages/ui-preact/src/index.ts b/packages/ui-preact/src/index.ts new file mode 100644 index 0000000..79ff295 --- /dev/null +++ b/packages/ui-preact/src/index.ts @@ -0,0 +1,2 @@ +export { createRoot, type Root } from './root.ts'; +export type { AttributeValue, ElementProps, EventHandler, HostElements } from './elements.ts'; diff --git a/packages/ui-preact/src/jsx-dev-runtime.ts b/packages/ui-preact/src/jsx-dev-runtime.ts new file mode 100644 index 0000000..50c11cc --- /dev/null +++ b/packages/ui-preact/src/jsx-dev-runtime.ts @@ -0,0 +1,2 @@ +export { Fragment, jsxDEV } from 'preact/jsx-dev-runtime'; +export type { JSX } from './jsx-runtime.ts'; diff --git a/packages/ui-preact/src/jsx-runtime.ts b/packages/ui-preact/src/jsx-runtime.ts new file mode 100644 index 0000000..7c55da8 --- /dev/null +++ b/packages/ui-preact/src/jsx-runtime.ts @@ -0,0 +1,18 @@ +import type { JSX as PreactJSX } from 'preact/jsx-runtime'; +import type { HostElements } from './elements.ts'; + +export { Fragment, jsx, jsxs } from 'preact/jsx-runtime'; + +export declare namespace JSX { + type Element = PreactJSX.Element; + type ElementType = string | Exclude; + type ElementClass = PreactJSX.ElementClass; + type ElementAttributesProperty = PreactJSX.ElementAttributesProperty; + type ElementChildrenAttribute = PreactJSX.ElementChildrenAttribute; + type IntrinsicAttributes = PreactJSX.IntrinsicAttributes; + type LibraryManagedAttributes = PreactJSX.LibraryManagedAttributes< + Component, + Props + >; + interface IntrinsicElements extends HostElements {} +} diff --git a/packages/ui-preact/src/root.test.tsx b/packages/ui-preact/src/root.test.tsx new file mode 100644 index 0000000..16e203c --- /dev/null +++ b/packages/ui-preact/src/root.test.tsx @@ -0,0 +1,254 @@ +import assert from 'node:assert/strict'; +import { PassThrough, Writable } from 'node:stream'; +import { createUI, Document, Element, Event, type Node, Text } from '@clack/ui'; +import { createTestTerminal } from '@termless/test'; +import { createPortal, createRef } from 'preact'; +import { useLayoutEffect, useState } from 'preact/hooks'; +import { act } from 'preact/test-utils'; +import { describe, expect, it, vi } from 'vitest'; +import { createRoot } from './root.ts'; + +describe('createRoot', () => { + it('mounts into a nested element without touching its siblings or installing a global document', () => { + expect(globalThis).not.toHaveProperty('document'); + const document = new Document(vi.fn()); + const parent = document.createElement('div'); + const before = document.createTextNode('before'); + const container = document.createElement('span'); + const after = document.createTextNode('after'); + parent.appendChild(before); + parent.appendChild(container); + parent.appendChild(after); + document.documentElement.appendChild(parent); + + using root = createRoot(container); + const ref = createRef(); + expect(root.element).toBe(container); + root.render( +
+ hello +
, + ); + + const div = element(container.firstChild); + const span = element(div.firstChild); + expect(div.localName).toBe('div'); + expect(span.localName).toBe('span'); + expect(span.ownerDocument).toBe(document); + expect(ref.current).toBe(span); + expect(text(span.firstChild).data).toBe('hello'); + expect(parent.childNodes).toHaveLength(3); + expect(parent.childNodes[0]).toBe(before); + expect(parent.childNodes[1]).toBe(container); + expect(parent.childNodes[2]).toBe(after); + root.unmount(); + expect(ref.current).toBeNull(); + expect(container.childNodes).toHaveLength(0); + expect(parent.childNodes).toHaveLength(3); + expect(globalThis).not.toHaveProperty('document'); + }); + + it('prepares a detached subtree without requesting a frame until it is attached', () => { + const notify = vi.fn(); + const document = new Document(notify); + const container = document.createElement('div'); + using root = createRoot(container); + + root.render(prepared); + const span = element(container.firstChild); + expect(span.isConnected).toBe(false); + expect(notify).not.toHaveBeenCalled(); + + document.documentElement.appendChild(container); + expect(span.isConnected).toBe(true); + expect(notify).toHaveBeenCalled(); + expect(text(span.firstChild).data).toBe('prepared'); + }); + + it('updates attributes and text without replacing unchanged elements or text nodes', () => { + const document = new Document(vi.fn()); + using root = createRoot(document.documentElement); + root.render(hello); + const span = element(root.element.firstChild); + const content = text(span.firstChild); + + root.render(42); + + expect(root.element.firstChild).toBe(span); + expect(span.firstChild).toBe(content); + expect(content.data).toBe('42'); + expect(span.attributes.map(({ name, value }) => [name, value])).toEqual([ + ['data-state', 'after'], + ]); + }); + + it('creates nodes in the right document during asynchronous updates to independent roots', async () => { + const firstDocument = new Document(vi.fn()); + const secondDocument = new Document(vi.fn()); + using first = createRoot(firstDocument.documentElement); + using second = createRoot(secondDocument.documentElement); + const updates: Array<(value: number) => void> = []; + + function Counter({ index }: { index: number }) { + const [count, setCount] = useState(0); + updates[index] = setCount; + return count ?
{count}
: initial; + } + + first.render(); + second.render(); + const originalSecond = second.element.firstChild; + + await act(() => updates[0]?.(1)); + + const firstChild = element(first.element.firstChild); + expect(firstChild.localName).toBe('div'); + expect(firstChild.ownerDocument).toBe(firstDocument); + expect(text(firstChild.firstChild).ownerDocument).toBe(firstDocument); + expect(text(firstChild.firstChild).data).toBe('1'); + expect(second.element.firstChild).toBe(originalSecond); + + await act(() => updates[1]?.(2)); + + const secondChild = element(second.element.firstChild); + expect(secondChild.localName).toBe('div'); + expect(secondChild.ownerDocument).toBe(secondDocument); + expect(text(secondChild.firstChild).ownerDocument).toBe(secondDocument); + expect(text(secondChild.firstChild).data).toBe('2'); + expect(text(firstChild.firstChild).data).toBe('1'); + expect(globalThis).not.toHaveProperty('document'); + }); + + it('registers capture handlers and replaces or removes JSX event handlers', () => { + const document = new Document(vi.fn()); + using root = createRoot(document.documentElement); + const calls: string[] = []; + root.render( +
calls.push('capture')}> + calls.push(event.type)}>target +
, + ); + const target = element(element(root.element.firstChild).firstChild); + + target.dispatchEvent(new Event('keydown', { bubbles: true })); + expect(calls).toEqual(['capture', 'keydown']); + + root.render( +
+ calls.push('replacement')}>target +
, + ); + expect(element(root.element.firstChild).firstChild).toBe(target); + target.dispatchEvent(new Event('keydown', { bubbles: true })); + expect(calls).toEqual(['capture', 'keydown', 'replacement']); + + root.render( +
+ target +
, + ); + target.dispatchEvent(new Event('keydown', { bubbles: true })); + expect(calls).toEqual(['capture', 'keydown', 'replacement']); + }); + + it('preserves keyed nodes and runs layout-effect cleanup when removed or disposed', () => { + const document = new Document(vi.fn()); + const container = document.documentElement; + const cleanups: string[] = []; + + function Row({ name }: { name: string }) { + useLayoutEffect( + () => () => { + cleanups.push(name); + }, + [], + ); + return {name}; + } + + { + using root = createRoot(container); + root.render(['a', 'b', 'c'].map((name) => )); + const original = [...container.childNodes]; + + root.render(['c', 'a'].map((name) => )); + + expect(container.childNodes).toHaveLength(2); + expect(container.childNodes[0]).toBe(original[2]); + expect(container.childNodes[1]).toBe(original[0]); + expect(original[1]?.parentNode).toBeNull(); + expect(cleanups).toEqual(['b']); + } + + expect(container.childNodes).toHaveLength(0); + expect(cleanups).toEqual(['b', 'c', 'a']); + }); + + it('creates and removes portal contents in another document', () => { + const document = new Document(vi.fn()); + const destination = new Document(vi.fn()); + using root = createRoot(document.documentElement); + root.render( +
+ local + {createPortal(remote, destination.documentElement)} +
, + ); + + const remote = element(destination.documentElement.firstChild); + expect(remote.ownerDocument).toBe(destination); + expect(text(remote.firstChild).ownerDocument).toBe(destination); + expect(text(remote.firstChild).data).toBe('remote'); + expect(text(element(root.element.firstChild).firstChild).data).toBe('local'); + + root.unmount(); + expect(root.element.childNodes).toHaveLength(0); + expect(destination.documentElement.childNodes).toHaveLength(0); + root.unmount(); + expect(destination.documentElement.childNodes).toHaveLength(0); + }); + + it('repaints the terminal when a nested root renders, updates, and unmounts', async () => { + const terminal = createTestTerminal({ cols: 20, rows: 3 }); + await using _terminal = { [Symbol.asyncDispose]: () => terminal.close() }; + await using input = new PassThrough(); + const output = new Writable({ + write(chunk: Buffer, _encoding, callback) { + terminal.feed(chunk); + callback(); + }, + }); + using _output = { + [Symbol.dispose]() { + output.destroy(); + }, + }; + await using ui = await createUI({ input, output, width: 20, height: 3 }); + void ui.main(); + const parent = ui.document.createElement('div'); + const container = ui.document.createElement('span'); + parent.appendChild(container); + ui.document.documentElement.appendChild(parent); + using root = createRoot(container); + + root.render(hello); + await expect.poll(() => terminal.screen.getLines()).toEqual(['hello', '', '']); + + root.render(updated); + await expect.poll(() => terminal.screen.getLines()).toEqual(['updated', '', '']); + + root.unmount(); + await expect.poll(() => terminal.screen.getLines()).toEqual(['', '', '']); + expect(container.parentNode).toBe(parent); + }); +}); + +function element(node: Node | null): Element { + assert.ok(node instanceof Element, 'Expected an element'); + return node; +} + +function text(node: Node | null): Text { + assert.ok(node instanceof Text, 'Expected a text node'); + return node; +} diff --git a/packages/ui-preact/src/root.ts b/packages/ui-preact/src/root.ts new file mode 100644 index 0000000..4298937 --- /dev/null +++ b/packages/ui-preact/src/root.ts @@ -0,0 +1,27 @@ +import type { Element } from '@clack/ui'; +import { render, type ComponentChild } from 'preact'; + +export interface Root extends Disposable { + readonly element: Element; + /** Reconcile into this element, leaving its siblings alone. */ + render(node: ComponentChild): void; + /** Remove the rendered tree. The root can be rendered into again. */ + unmount(): void; +} + +// oxlint-disable-next-line bombshell-dev/exported-function-async -- Preact rendering is synchronous. +/** Mount Preact into any Clack element, including a detached element. */ +export function createRoot(element: Element): Root { + return { + element, + render(node) { + render(node, element); + }, + unmount() { + render(null, element); + }, + [Symbol.dispose]() { + this.unmount(); + }, + }; +} diff --git a/packages/ui-preact/tsconfig.json b/packages/ui-preact/tsconfig.json new file mode 100644 index 0000000..d32c980 --- /dev/null +++ b/packages/ui-preact/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "@clack/ui-preact", + "types": ["node"] + }, + "include": ["src"] +} diff --git a/packages/ui/src/dom.test.ts b/packages/ui/src/dom.test.ts new file mode 100644 index 0000000..204cd5b --- /dev/null +++ b/packages/ui/src/dom.test.ts @@ -0,0 +1,1177 @@ +import { describe, expect, it, vi } from 'vitest'; +import { Document, Event, type Node, type Text } from './dom.ts'; + +describe('DOM connectivity', () => { + it('preserves a subtree through connection, disconnection, and reconnection', () => { + const notify = vi.fn(); + const document = new Document(notify); + const root = document.documentElement; + const branch = document.createElement('div'); + const span = document.createElement('span'); + const text = document.createTextNode('initial'); + + expect(root.isConnected).toBe(true); + expect(branch.isConnected).toBe(false); + expect(span.isConnected).toBe(false); + expect(text.isConnected).toBe(false); + expect(branch.parentNode).toBeNull(); + + branch.appendChild(span); + span.appendChild(text); + text.data = 'prepared'; + branch.setAttribute('data-state', 'prepared'); + + expect(span.parentNode).toBe(branch); + expect(text.parentNode).toBe(span); + expect(branch.isConnected).toBe(false); + expect(span.isConnected).toBe(false); + expect(text.isConnected).toBe(false); + expect(text.data).toBe('prepared'); + expect(branch.attributes[0]).toMatchObject({ name: 'data-state', value: 'prepared' }); + expect(notify).not.toHaveBeenCalled(); + + root.appendChild(branch); + + expect(root.childNodes).toHaveLength(1); + expect(root.childNodes[0]).toBe(branch); + expect(branch.parentNode).toBe(root); + expect(branch.isConnected).toBe(true); + expect(span.isConnected).toBe(true); + expect(text.isConnected).toBe(true); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + text.data = 'connected'; + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + branch.setAttribute('data-state', 'connected'); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + const extra = document.createTextNode('!'); + span.appendChild(extra); + expect(extra.isConnected).toBe(true); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + root.removeChild(branch); + + expect(root.childNodes).toHaveLength(0); + expect(branch.parentNode).toBeNull(); + expect(span.parentNode).toBe(branch); + expect(text.parentNode).toBe(span); + expect(branch.isConnected).toBe(false); + expect(span.isConnected).toBe(false); + expect(text.isConnected).toBe(false); + expect(extra.isConnected).toBe(false); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + text.data = 'detached'; + branch.removeAttribute('data-state'); + span.removeChild(extra); + + expect(extra.parentNode).toBeNull(); + expect(span.childNodes).toHaveLength(1); + expect(span.childNodes[0]).toBe(text); + expect(text.data).toBe('detached'); + expect(branch.attributes).toHaveLength(0); + expect(notify).not.toHaveBeenCalled(); + + root.appendChild(branch); + + expect(root.childNodes).toHaveLength(1); + expect(root.childNodes[0]).toBe(branch); + expect(branch.parentNode).toBe(root); + expect(branch.isConnected).toBe(true); + expect(span.isConnected).toBe(true); + expect(text.isConnected).toBe(true); + expect(extra.isConnected).toBe(false); + expect(text.data).toBe('detached'); + expect(branch.attributes).toHaveLength(0); + expect(notify).toHaveBeenCalled(); + }); + + it('moves a subtree between detached parents without notifying', () => { + const notify = vi.fn(); + const document = new Document(notify); + const source = document.createElement('div'); + const destination = document.createElement('div'); + const branch = document.createElement('span'); + const text = document.createTextNode('before'); + branch.appendChild(text); + source.appendChild(branch); + notify.mockClear(); + + destination.appendChild(branch); + + expect(source.childNodes).toHaveLength(0); + expect(destination.childNodes).toHaveLength(1); + expect(destination.childNodes[0]).toBe(branch); + expect(branch.parentNode).toBe(destination); + expect(branch.childNodes).toHaveLength(1); + expect(branch.childNodes[0]).toBe(text); + expect(text.parentNode).toBe(branch); + expect(source.isConnected).toBe(false); + expect(destination.isConnected).toBe(false); + expect(branch.isConnected).toBe(false); + expect(text.isConnected).toBe(false); + expect(notify).not.toHaveBeenCalled(); + + text.data = 'after'; + expect(notify).not.toHaveBeenCalled(); + + branch.setAttribute('data-state', 'after'); + expect(notify).not.toHaveBeenCalled(); + }); + + it('connects a detached subtree and starts notifying when moved into a connected parent', () => { + const notify = vi.fn(); + const document = new Document(notify); + const source = document.createElement('div'); + const destination = document.createElement('div'); + const branch = document.createElement('span'); + const text = document.createTextNode('before'); + branch.appendChild(text); + source.appendChild(branch); + document.documentElement.appendChild(destination); + notify.mockClear(); + + destination.appendChild(branch); + + expect(source.childNodes).toHaveLength(0); + expect(destination.childNodes).toHaveLength(1); + expect(destination.childNodes[0]).toBe(branch); + expect(branch.parentNode).toBe(destination); + expect(branch.childNodes).toHaveLength(1); + expect(branch.childNodes[0]).toBe(text); + expect(text.parentNode).toBe(branch); + expect(source.isConnected).toBe(false); + expect(destination.isConnected).toBe(true); + expect(branch.isConnected).toBe(true); + expect(text.isConnected).toBe(true); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + text.data = 'after'; + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + branch.setAttribute('data-state', 'after'); + expect(notify).toHaveBeenCalled(); + }); + + it('notifies removal and stops notifying when a subtree moves into a detached parent', () => { + const notify = vi.fn(); + const document = new Document(notify); + const source = document.createElement('div'); + const destination = document.createElement('div'); + const branch = document.createElement('span'); + const text = document.createTextNode('before'); + branch.appendChild(text); + source.appendChild(branch); + document.documentElement.appendChild(source); + notify.mockClear(); + + destination.appendChild(branch); + + expect(source.childNodes).toHaveLength(0); + expect(destination.childNodes).toHaveLength(1); + expect(destination.childNodes[0]).toBe(branch); + expect(branch.parentNode).toBe(destination); + expect(branch.childNodes).toHaveLength(1); + expect(branch.childNodes[0]).toBe(text); + expect(text.parentNode).toBe(branch); + expect(source.isConnected).toBe(true); + expect(destination.isConnected).toBe(false); + expect(branch.isConnected).toBe(false); + expect(text.isConnected).toBe(false); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + text.data = 'after'; + expect(notify).not.toHaveBeenCalled(); + + branch.setAttribute('data-state', 'after'); + expect(notify).not.toHaveBeenCalled(); + }); + + it('keeps a subtree connected and notifying when moved between connected parents', () => { + const notify = vi.fn(); + const document = new Document(notify); + const source = document.createElement('div'); + const destination = document.createElement('div'); + const branch = document.createElement('span'); + const text = document.createTextNode('before'); + branch.appendChild(text); + source.appendChild(branch); + document.documentElement.appendChild(source); + document.documentElement.appendChild(destination); + notify.mockClear(); + + destination.appendChild(branch); + + expect(source.childNodes).toHaveLength(0); + expect(destination.childNodes).toHaveLength(1); + expect(destination.childNodes[0]).toBe(branch); + expect(branch.parentNode).toBe(destination); + expect(branch.childNodes).toHaveLength(1); + expect(branch.childNodes[0]).toBe(text); + expect(text.parentNode).toBe(branch); + expect(source.isConnected).toBe(true); + expect(destination.isConnected).toBe(true); + expect(branch.isConnected).toBe(true); + expect(text.isConnected).toBe(true); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + text.data = 'after'; + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + branch.setAttribute('data-state', 'after'); + expect(notify).toHaveBeenCalled(); + }); + + it('moves an existing child to the end without duplicating it', () => { + const notify = vi.fn(); + const document = new Document(notify); + const root = document.documentElement; + const first = document.createTextNode('first'); + const second = document.createTextNode('second'); + root.appendChild(first); + root.appendChild(second); + notify.mockClear(); + + root.appendChild(first); + + expect(root.childNodes).toHaveLength(2); + expect(root.childNodes[0]).toBe(second); + expect(root.childNodes[1]).toBe(first); + expect(first.parentNode).toBe(root); + expect(second.parentNode).toBe(root); + expect(first.isConnected).toBe(true); + expect(second.isConnected).toBe(true); + expect(notify).toHaveBeenCalled(); + }); + + it('rejects cycles and removal from the wrong parent without changing the tree', () => { + const notify = vi.fn(); + const document = new Document(notify); + const root = document.documentElement; + const parent = document.createElement('div'); + const other = document.createElement('div'); + const child = document.createElement('span'); + parent.appendChild(child); + root.appendChild(parent); + root.appendChild(other); + notify.mockClear(); + + for (const mutate of [ + () => child.appendChild(parent), + () => parent.appendChild(parent), + () => other.removeChild(child), + ]) { + expect(mutate).toThrow(); + + expect(root.childNodes).toHaveLength(2); + expect(root.childNodes[0]).toBe(parent); + expect(root.childNodes[1]).toBe(other); + expect(parent.parentNode).toBe(root); + expect(other.parentNode).toBe(root); + expect(parent.childNodes).toHaveLength(1); + expect(parent.childNodes[0]).toBe(child); + expect(child.parentNode).toBe(parent); + expect(child.childNodes).toHaveLength(0); + expect(other.childNodes).toHaveLength(0); + expect(notify).not.toHaveBeenCalled(); + } + }); +}); + +describe('createElementNS', () => { + it('creates HTML elements and text with the metadata used to match existing nodes', () => { + const document = new Document(vi.fn()); + const namespace = 'http://www.w3.org/1999/xhtml'; + const div = document.createElementNS(namespace, 'div'); + const span = document.createElement('span'); + const text = document.createTextNode('hello'); + + expect(document.documentElement.ownerDocument).toBe(document); + expect(document.documentElement.namespaceURI).toBe(namespace); + expect(document.documentElement.nodeType).toBe(1); + expect(div.ownerDocument).toBe(document); + expect(div.namespaceURI).toBe(namespace); + expect(div.localName).toBe('div'); + expect(div.nodeName).toBe('DIV'); + expect(div.nodeType).toBe(1); + expect(div.parentNode).toBeNull(); + expect(div.isConnected).toBe(false); + expect(span.namespaceURI).toBe(namespace); + expect(span.localName).toBe('span'); + expect(text.ownerDocument).toBe(document); + expect(text.nodeName).toBe('#text'); + expect(text.nodeType).toBe(3); + expect(text.firstChild).toBeNull(); + expect(text.nextSibling).toBeNull(); + }); +}); + +describe('createTextNode / data', () => { + it('coerces numeric text to strings and updates or clears it without replacing the node', () => { + const notify = vi.fn(); + const document = new Document(notify); + // Preact passes numbers directly from JavaScript, despite the DOM's string signature. + const text: Text = Reflect.apply(document.createTextNode, document, [42]); + + expect(text.data).toBe('42'); + expect(notify).not.toHaveBeenCalled(); + document.documentElement.appendChild(text); + notify.mockClear(); + + Reflect.set(text, 'data', 43n); + + expect(text.data).toBe('43'); + expect(document.documentElement.childNodes[0]).toBe(text); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + text.data = '43'; + expect(notify).not.toHaveBeenCalled(); + + text.data = ''; + expect(text.data).toBe(''); + expect(document.documentElement.childNodes).toHaveLength(1); + expect(document.documentElement.childNodes[0]).toBe(text); + expect(notify).toHaveBeenCalled(); + }); +}); + +describe('insertBefore', () => { + it('inserts before an anchor and appends with a null anchor', () => { + const notify = vi.fn(); + const document = new Document(notify); + const parent = document.createElement('div'); + const first = document.createTextNode('first'); + const middle = document.createElement('span'); + const last = document.createTextNode('last'); + + expect(parent.firstChild).toBeNull(); + expect(parent.insertBefore(last, null)).toBe(last); + expect(parent.insertBefore(first, last)).toBe(first); + expect(parent.insertBefore(middle, last)).toBe(middle); + + expect(parent.childNodes).toHaveLength(3); + expect(parent.childNodes[0]).toBe(first); + expect(parent.childNodes[1]).toBe(middle); + expect(parent.childNodes[2]).toBe(last); + expect(parent.firstChild).toBe(first); + expect(first.nextSibling).toBe(middle); + expect(middle.nextSibling).toBe(last); + expect(last.nextSibling).toBeNull(); + expect(first.parentNode).toBe(parent); + expect(middle.parentNode).toBe(parent); + expect(last.parentNode).toBe(parent); + expect(parent.children).toHaveLength(1); + expect(parent.children[0]).toBe(middle); + expect(notify).not.toHaveBeenCalled(); + }); + + it('reorders existing children in both directions without duplicating them', () => { + const notify = vi.fn(); + const document = new Document(notify); + const parent = document.documentElement; + const first = document.createElement('span'); + const middle = document.createTextNode('middle'); + const last = document.createElement('span'); + parent.appendChild(first); + parent.appendChild(middle); + parent.appendChild(last); + notify.mockClear(); + + parent.insertBefore(last, first); + + expect(parent.childNodes).toHaveLength(3); + expect(parent.firstChild).toBe(last); + expect(last.nextSibling).toBe(first); + expect(first.nextSibling).toBe(middle); + expect(middle.nextSibling).toBeNull(); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + parent.insertBefore(last, middle); + + expect(parent.childNodes).toHaveLength(3); + expect(parent.firstChild).toBe(first); + expect(first.nextSibling).toBe(last); + expect(last.nextSibling).toBe(middle); + expect(middle.nextSibling).toBeNull(); + expect(notify).toHaveBeenCalled(); + + parent.insertBefore(last, null); + parent.insertBefore(first, first); + + expect(parent.childNodes).toHaveLength(3); + expect(parent.childNodes[0]).toBe(first); + expect(parent.childNodes[1]).toBe(middle); + expect(parent.childNodes[2]).toBe(last); + expect(parent.firstChild).toBe(first); + expect(first.nextSibling).toBe(middle); + expect(middle.nextSibling).toBe(last); + expect(last.nextSibling).toBeNull(); + expect(first.parentNode).toBe(parent); + expect(middle.parentNode).toBe(parent); + expect(last.parentNode).toBe(parent); + }); + + it('connects and disconnects a subtree when inserting it into another parent', () => { + const notify = vi.fn(); + const document = new Document(notify); + const detached = document.createElement('div'); + const root = document.documentElement; + const branch = document.createElement('span'); + const text = document.createTextNode('before'); + const anchor = document.createTextNode('anchor'); + branch.appendChild(text); + detached.appendChild(branch); + root.appendChild(anchor); + notify.mockClear(); + + root.insertBefore(branch, anchor); + + expect(detached.childNodes).toHaveLength(0); + expect(detached.firstChild).toBeNull(); + expect(root.childNodes).toHaveLength(2); + expect(root.firstChild).toBe(branch); + expect(branch.nextSibling).toBe(anchor); + expect(branch.parentNode).toBe(root); + expect(branch.childNodes[0]).toBe(text); + expect(text.parentNode).toBe(branch); + expect(branch.isConnected).toBe(true); + expect(text.isConnected).toBe(true); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + text.data = 'connected'; + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + detached.insertBefore(branch, null); + + expect(root.childNodes).toHaveLength(1); + expect(root.firstChild).toBe(anchor); + expect(detached.childNodes).toHaveLength(1); + expect(detached.firstChild).toBe(branch); + expect(branch.parentNode).toBe(detached); + expect(branch.nextSibling).toBeNull(); + expect(branch.childNodes[0]).toBe(text); + expect(text.parentNode).toBe(branch); + expect(branch.isConnected).toBe(false); + expect(text.isConnected).toBe(false); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + text.data = 'detached'; + expect(notify).not.toHaveBeenCalled(); + }); + + it('rejects invalid insertion anchors and cycles before detaching any nodes', () => { + const notify = vi.fn(); + const document = new Document(notify); + const root = document.documentElement; + const parent = document.createElement('div'); + const other = document.createElement('div'); + const child = document.createElement('span'); + parent.appendChild(child); + root.appendChild(parent); + root.appendChild(other); + notify.mockClear(); + + expect(parent.insertBefore).toBeTypeOf('function'); + expect(() => other.insertBefore(child, parent)).toThrow(); + expect(parent.childNodes).toHaveLength(1); + expect(parent.childNodes[0]).toBe(child); + expect(child.parentNode).toBe(parent); + expect(other.childNodes).toHaveLength(0); + expect(notify).not.toHaveBeenCalled(); + + expect(() => child.insertBefore(parent, null)).toThrow(); + expect(root.childNodes).toHaveLength(2); + expect(root.childNodes[0]).toBe(parent); + expect(root.childNodes[1]).toBe(other); + expect(parent.parentNode).toBe(root); + expect(parent.childNodes[0]).toBe(child); + expect(child.parentNode).toBe(parent); + expect(child.childNodes).toHaveLength(0); + expect(notify).not.toHaveBeenCalled(); + + expect(() => parent.insertBefore(parent, child)).toThrow(); + expect(root.childNodes[0]).toBe(parent); + expect(parent.parentNode).toBe(root); + expect(parent.childNodes).toHaveLength(1); + expect(parent.childNodes[0]).toBe(child); + expect(child.parentNode).toBe(parent); + expect(notify).not.toHaveBeenCalled(); + }); +}); + +describe('remove', () => { + it('removes elements and text, updates sibling links, and ignores repeated removal', () => { + const notify = vi.fn(); + const document = new Document(notify); + const root = document.documentElement; + const branch = document.createElement('span'); + const nested = document.createTextNode('nested'); + const sibling = document.createTextNode('sibling'); + branch.appendChild(nested); + root.appendChild(branch); + root.appendChild(sibling); + notify.mockClear(); + + branch.remove(); + + expect(root.childNodes).toHaveLength(1); + expect(root.firstChild).toBe(sibling); + expect(branch.parentNode).toBeNull(); + expect(branch.nextSibling).toBeNull(); + expect(branch.firstChild).toBe(nested); + expect(nested.parentNode).toBe(branch); + expect(branch.isConnected).toBe(false); + expect(nested.isConnected).toBe(false); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + branch.remove(); + expect(notify).not.toHaveBeenCalled(); + + sibling.remove(); + + expect(root.childNodes).toHaveLength(0); + expect(root.firstChild).toBeNull(); + expect(sibling.parentNode).toBeNull(); + expect(sibling.nextSibling).toBeNull(); + expect(sibling.isConnected).toBe(false); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + sibling.remove(); + expect(notify).not.toHaveBeenCalled(); + }); +}); + +describe('setAttribute / removeAttribute', () => { + it('stores string attributes for existing-node matching and updates them without duplicates', () => { + const notify = vi.fn(); + const document = new Document(notify); + const element = document.createElement('span'); + + expect(element.attributes).toHaveLength(0); + element.setAttribute('title', 'before'); + // Attribute values arrive from JavaScript as numbers and booleans too. + Reflect.apply(element.setAttribute, element, ['data-count', 42]); + Reflect.apply(element.setAttribute, element, ['aria-hidden', false]); + + expect(element.attributes).toHaveLength(3); + expect(element.attributes[0]).toMatchObject({ name: 'title', value: 'before' }); + expect(element.attributes[1]).toMatchObject({ name: 'data-count', value: '42' }); + expect(element.attributes[2]).toMatchObject({ name: 'aria-hidden', value: 'false' }); + expect(notify).not.toHaveBeenCalled(); + + document.documentElement.appendChild(element); + notify.mockClear(); + element.setAttribute('title', 'after'); + + expect(element.attributes).toHaveLength(3); + expect(element.attributes[0]).toMatchObject({ name: 'title', value: 'after' }); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + element.removeAttribute('data-count'); + + expect(element.attributes).toHaveLength(2); + expect(element.attributes[0]).toMatchObject({ name: 'title', value: 'after' }); + expect(element.attributes[1]).toMatchObject({ name: 'aria-hidden', value: 'false' }); + expect(notify).toHaveBeenCalled(); + + notify.mockClear(); + element.removeAttribute('data-count'); + expect(element.attributes).toHaveLength(2); + expect(notify).not.toHaveBeenCalled(); + + document.documentElement.removeChild(element); + notify.mockClear(); + element.removeAttribute('title'); + element.removeAttribute('aria-hidden'); + expect(element.attributes).toHaveLength(0); + expect(notify).not.toHaveBeenCalled(); + }); +}); + +describe('events', () => { + describe('Event', () => { + it('starts with no dispatch state and allows framework bookkeeping', () => { + expect(Event).toBeTypeOf('function'); + const event = new Event('click'); + + expect(event.type).toBe('click'); + expect(event.bubbles).toBe(false); + expect(event.cancelable).toBe(false); + expect(event.defaultPrevented).toBe(false); + expect(event.target).toBeNull(); + expect(event.currentTarget).toBeNull(); + expect(event.eventPhase).toBe(Event.NONE); + expect(Event.NONE).toBe(0); + expect(Event.CAPTURING_PHASE).toBe(1); + expect(Event.AT_TARGET).toBe(2); + expect(Event.BUBBLING_PHASE).toBe(3); + + const dispatched = Symbol('dispatched'); + expect(Reflect.set(event, dispatched, 1)).toBe(true); + expect(Reflect.get(event, dispatched)).toBe(1); + }); + }); + + describe('addEventListener / removeEventListener', () => { + it('calls a stable listener with the element as this as its handler changes', () => { + const document = new Document(vi.fn()); + const first = vi.fn(); + const second = vi.fn(); + const element = Object.assign(document.createElement('span'), { handler: first }); + const listener = vi.fn(function (this: typeof element, event: Event): void { + this.handler(event); + }); + element.addEventListener('click', listener, false); + element.addEventListener('click', listener, false); + const initial = new Event('click'); + element.dispatchEvent(initial); + + expect(listener).toHaveBeenCalledTimes(1); + expect(listener.mock.contexts[0]).toBe(element); + expect(first).toHaveBeenCalledExactlyOnceWith(initial); + + element.handler = second; + const updated = new Event('click'); + element.dispatchEvent(updated); + + expect(first).toHaveBeenCalledTimes(1); + expect(second).toHaveBeenCalledExactlyOnceWith(updated); + + element.removeEventListener('click', listener, false); + element.dispatchEvent(new Event('click')); + + expect(listener).toHaveBeenCalledTimes(2); + expect(second).toHaveBeenCalledTimes(1); + }); + + it('keeps capture and non-capture registrations separate when removing listeners', () => { + const document = new Document(vi.fn()); + const element = document.createElement('span'); + const listener = vi.fn(); + element.addEventListener('click', listener, true); + element.addEventListener('click', listener, false); + element.dispatchEvent(new Event('click')); + expect(listener).toHaveBeenCalledTimes(2); + + listener.mockClear(); + element.removeEventListener('click', listener, true); + element.dispatchEvent(new Event('click')); + expect(listener).toHaveBeenCalledTimes(1); + + listener.mockClear(); + element.removeEventListener('click', listener, false); + element.dispatchEvent(new Event('click')); + expect(listener).not.toHaveBeenCalled(); + }); + + it('scopes listeners by node and event type without requesting a render', () => { + const notify = vi.fn(); + const document = new Document(notify); + const first = document.createElement('span'); + const second = document.createElement('span'); + document.documentElement.appendChild(first); + document.documentElement.appendChild(second); + notify.mockClear(); + const listener = vi.fn(); + first.addEventListener('click', listener); + first.addEventListener('keydown', listener); + second.addEventListener('click', listener); + + first.removeEventListener('click', listener); + first.removeEventListener('click', listener); + first.removeEventListener('missing', listener); + first.dispatchEvent(new Event('click')); + expect(listener).not.toHaveBeenCalled(); + + const keydown = new Event('keydown'); + first.dispatchEvent(keydown); + expect(listener).toHaveBeenCalledExactlyOnceWith(keydown); + + listener.mockClear(); + const click = new Event('click'); + second.dispatchEvent(click); + expect(listener).toHaveBeenCalledExactlyOnceWith(click); + expect(notify).not.toHaveBeenCalled(); + }); + }); + + describe('dispatchEvent', () => { + it('sets the target and clears transient state even when there are no listeners', () => { + const document = new Document(vi.fn()); + const target = document.createElement('span'); + const event = new Event('click', { bubbles: true, cancelable: true }); + + expect(target.dispatchEvent(event)).toBe(true); + + expect(event.bubbles).toBe(true); + expect(event.cancelable).toBe(true); + expect(event.target).toBe(target); + expect(event.currentTarget).toBeNull(); + expect(event.eventPhase).toBe(Event.NONE); + expect(event.defaultPrevented).toBe(false); + }); + + it('captures through the document, invokes the target, and bubbles back in order', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const parent = document.createElement('div'); + const target = document.createElement('span'); + root.appendChild(parent); + parent.appendChild(target); + const event = new Event('click', { bubbles: true }); + const calls: string[] = []; + const phases: number[] = []; + const contexts: boolean[] = []; + const targets: boolean[] = []; + const events: boolean[] = []; + function record(label: string, currentTarget: Node): (this: Node, received: Event) => void { + return function (this: Node, received: Event): void { + calls.push(label); + phases.push(received.eventPhase); + contexts.push(this === currentTarget && received.currentTarget === currentTarget); + targets.push(received.target === target); + events.push(received === event); + }; + } + document.addEventListener('click', record('document capture', document), true); + root.addEventListener('click', record('root capture', root), true); + parent.addEventListener('click', record('parent capture', parent), true); + // Register non-capture first to verify that phase order takes precedence. + target.addEventListener('click', record('target first', target)); + target.addEventListener('click', record('target capture', target), true); + target.addEventListener('click', record('target second', target)); + parent.addEventListener('click', record('parent bubble', parent)); + root.addEventListener('click', record('root bubble', root)); + document.addEventListener('click', record('document bubble', document)); + + expect(target.dispatchEvent(event)).toBe(true); + + expect(calls).toEqual([ + 'document capture', + 'root capture', + 'parent capture', + 'target capture', + 'target first', + 'target second', + 'parent bubble', + 'root bubble', + 'document bubble', + ]); + expect(phases).toEqual([ + Event.CAPTURING_PHASE, + Event.CAPTURING_PHASE, + Event.CAPTURING_PHASE, + Event.AT_TARGET, + Event.AT_TARGET, + Event.AT_TARGET, + Event.BUBBLING_PHASE, + Event.BUBBLING_PHASE, + Event.BUBBLING_PHASE, + ]); + expect(contexts.every(Boolean)).toBe(true); + expect(targets.every(Boolean)).toBe(true); + expect(events.every(Boolean)).toBe(true); + expect(event.target).toBe(target); + expect(event.currentTarget).toBeNull(); + expect(event.eventPhase).toBe(Event.NONE); + }); + + it('captures non-bubbling events and invokes both groups of target listeners', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const target = document.createElement('span'); + root.appendChild(target); + const calls: string[] = []; + root.addEventListener('click', () => calls.push('root capture'), true); + root.addEventListener('click', () => calls.push('root bubble')); + target.addEventListener('click', () => calls.push('target')); + target.addEventListener('click', () => calls.push('target capture'), true); + + target.dispatchEvent(new Event('click')); + + expect(calls).toEqual(['root capture', 'target capture', 'target']); + }); + + it('preserves listeners and dispatches within a detached subtree without rendering', () => { + const notify = vi.fn(); + const document = new Document(notify); + const parent = document.createElement('div'); + const target = document.createElement('span'); + parent.appendChild(target); + document.documentElement.appendChild(parent); + const calls: string[] = []; + document.addEventListener('click', () => calls.push('document')); + parent.addEventListener('click', () => calls.push('parent capture'), true); + parent.addEventListener('click', () => calls.push('parent bubble')); + target.addEventListener('click', () => calls.push('target')); + parent.remove(); + notify.mockClear(); + + target.dispatchEvent(new Event('click', { bubbles: true })); + + expect(target.isConnected).toBe(false); + expect(calls).toEqual(['parent capture', 'target', 'parent bubble']); + expect(notify).not.toHaveBeenCalled(); + }); + + it('keeps the original ancestor path when a listener reparents the target', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const original = document.createElement('div'); + const destination = document.createElement('div'); + const target = document.createElement('span'); + root.appendChild(original); + root.appendChild(destination); + original.appendChild(target); + const calls: string[] = []; + original.addEventListener( + 'click', + () => { + calls.push('original capture'); + destination.appendChild(target); + }, + true, + ); + original.addEventListener('click', () => calls.push('original bubble')); + destination.addEventListener('click', () => calls.push('destination capture'), true); + destination.addEventListener('click', () => calls.push('destination bubble')); + target.addEventListener('click', () => calls.push('target')); + root.addEventListener('click', () => calls.push('root bubble')); + + target.dispatchEvent(new Event('click', { bubbles: true })); + + expect(target.parentNode).toBe(destination); + expect(calls).toEqual(['original capture', 'target', 'original bubble', 'root bubble']); + + calls.length = 0; + target.dispatchEvent(new Event('click', { bubbles: true })); + expect(calls).toEqual(['destination capture', 'target', 'destination bubble', 'root bubble']); + }); + + it('skips a removed listener even if the same callback is registered again', () => { + const document = new Document(vi.fn()); + const target = document.createElement('span'); + const calls: string[] = []; + const later = (): number => calls.push('later'); + const replace = (): void => { + calls.push('replace'); + target.removeEventListener('click', later); + target.addEventListener('click', later); + }; + target.addEventListener('click', replace); + target.addEventListener('click', later); + + target.dispatchEvent(new Event('click')); + expect(calls).toEqual(['replace']); + + target.removeEventListener('click', replace); + calls.length = 0; + target.dispatchEvent(new Event('click')); + expect(calls).toEqual(['later']); + }); + + it('allows additions in a later phase but defers additions to the current listener list', () => { + const document = new Document(vi.fn()); + const target = document.createElement('span'); + const calls: string[] = []; + const later = (): number => calls.push('later'); + const added = (): void => { + calls.push('added'); + target.addEventListener('click', later); + }; + target.addEventListener( + 'click', + () => { + calls.push('capture'); + target.addEventListener('click', added); + }, + true, + ); + + target.dispatchEvent(new Event('click')); + expect(calls).toEqual(['capture', 'added']); + + calls.length = 0; + target.dispatchEvent(new Event('click')); + expect(calls).toEqual(['capture', 'added', 'later']); + }); + + it('supports nested events, rejects active-event redispatch, and permits later reuse', () => { + const document = new Document(vi.fn()); + const target = document.createElement('span'); + const outer = new Event('outer'); + const inner = new Event('inner'); + const calls: string[] = []; + const states: boolean[] = []; + let redispatchError: unknown; + let redispatching = false; + target.addEventListener('inner', (event: Event) => { + calls.push('inner'); + states.push(event.currentTarget === target && outer.currentTarget === target); + }); + target.addEventListener('outer', (event: Event) => { + if (redispatching) { + calls.push('unexpected redispatch'); + return; + } + calls.push('outer start'); + redispatching = true; + try { + target.dispatchEvent(event); + } catch (error) { + redispatchError = error; + } finally { + redispatching = false; + } + target.dispatchEvent(inner); + states.push(event.currentTarget === target && event.eventPhase === Event.AT_TARGET); + states.push(inner.currentTarget === null && inner.eventPhase === Event.NONE); + calls.push('outer end'); + }); + + target.dispatchEvent(outer); + + expect(redispatchError).toBeInstanceOf(Error); + expect(calls).toEqual(['outer start', 'inner', 'outer end']); + expect(states).toEqual([true, true, true]); + expect(outer.currentTarget).toBeNull(); + expect(outer.eventPhase).toBe(Event.NONE); + + calls.length = 0; + states.length = 0; + redispatchError = undefined; + target.dispatchEvent(outer); + expect(redispatchError).toBeInstanceOf(Error); + expect(calls).toEqual(['outer start', 'inner', 'outer end']); + expect(states).toEqual([true, true, true]); + }); + }); + + describe('stopPropagation', () => { + it('finishes the current ancestor capture listeners without reaching the target', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const target = document.createElement('span'); + root.appendChild(target); + const calls: string[] = []; + root.addEventListener( + 'click', + (event: Event) => { + calls.push('first capture'); + event.stopPropagation(); + }, + true, + ); + root.addEventListener('click', () => calls.push('second capture'), true); + root.addEventListener('click', () => calls.push('root bubble')); + target.addEventListener('click', () => calls.push('target capture'), true); + target.addEventListener('click', () => calls.push('target')); + + target.dispatchEvent(new Event('click', { bubbles: true })); + + expect(calls).toEqual(['first capture', 'second capture']); + }); + + it('stops capture before visiting another ancestor', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const parent = document.createElement('div'); + const target = document.createElement('span'); + root.appendChild(parent); + parent.appendChild(target); + const calls: string[] = []; + root.addEventListener( + 'click', + (event: Event) => { + calls.push('first root capture'); + event.stopPropagation(); + }, + true, + ); + root.addEventListener('click', () => calls.push('second root capture'), true); + parent.addEventListener('click', () => calls.push('parent capture'), true); + target.addEventListener('click', () => calls.push('target capture'), true); + target.addEventListener('click', () => calls.push('target')); + parent.addEventListener('click', () => calls.push('parent bubble')); + root.addEventListener('click', () => calls.push('root bubble')); + document.addEventListener('click', () => calls.push('document bubble')); + const event = new Event('click', { bubbles: true, cancelable: true }); + + expect(target.dispatchEvent(event)).toBe(true); + + expect(calls).toEqual(['first root capture', 'second root capture']); + expect(event.defaultPrevented).toBe(false); + expect(event.currentTarget).toBeNull(); + expect(event.eventPhase).toBe(Event.NONE); + }); + + it('finishes target capture listeners without entering the non-capture phase', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const target = document.createElement('span'); + root.appendChild(target); + const calls: string[] = []; + target.addEventListener( + 'click', + (event: Event) => { + calls.push('first capture'); + event.stopPropagation(); + }, + true, + ); + target.addEventListener('click', () => calls.push('second capture'), true); + target.addEventListener('click', () => calls.push('target')); + root.addEventListener('click', () => calls.push('root bubble')); + + target.dispatchEvent(new Event('click', { bubbles: true })); + + expect(calls).toEqual(['first capture', 'second capture']); + }); + + it('finishes target listeners without bubbling or canceling the event', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const target = document.createElement('span'); + root.appendChild(target); + const calls: string[] = []; + target.addEventListener('click', (event: Event) => { + calls.push('first'); + event.stopPropagation(); + }); + target.addEventListener('click', () => calls.push('second')); + root.addEventListener('click', () => calls.push('root bubble')); + const event = new Event('click', { bubbles: true, cancelable: true }); + + expect(target.dispatchEvent(event)).toBe(true); + + expect(calls).toEqual(['first', 'second']); + expect(event.defaultPrevented).toBe(false); + }); + + it('finishes the current ancestor bubble listeners without visiting further ancestors', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const parent = document.createElement('div'); + const target = document.createElement('span'); + root.appendChild(parent); + parent.appendChild(target); + const calls: string[] = []; + target.addEventListener('click', () => calls.push('target')); + parent.addEventListener('click', (event: Event) => { + calls.push('first parent bubble'); + event.stopPropagation(); + }); + parent.addEventListener('click', () => calls.push('second parent bubble')); + root.addEventListener('click', () => calls.push('root bubble')); + document.addEventListener('click', () => calls.push('document bubble')); + const event = new Event('click', { bubbles: true, cancelable: true }); + + expect(target.dispatchEvent(event)).toBe(true); + + expect(calls).toEqual(['target', 'first parent bubble', 'second parent bubble']); + expect(event.defaultPrevented).toBe(false); + expect(event.currentTarget).toBeNull(); + expect(event.eventPhase).toBe(Event.NONE); + }); + }); + + describe('stopImmediatePropagation', () => { + it('stops remaining ancestor bubble listeners and further ancestors', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const parent = document.createElement('div'); + const target = document.createElement('span'); + root.appendChild(parent); + parent.appendChild(target); + const calls: string[] = []; + target.addEventListener('click', () => calls.push('target')); + parent.addEventListener('click', (event: Event) => { + calls.push('first parent bubble'); + event.stopImmediatePropagation(); + }); + parent.addEventListener('click', () => calls.push('second parent bubble')); + root.addEventListener('click', () => calls.push('root bubble')); + document.addEventListener('click', () => calls.push('document bubble')); + const event = new Event('click', { bubbles: true, cancelable: true }); + + expect(target.dispatchEvent(event)).toBe(true); + + expect(calls).toEqual(['target', 'first parent bubble']); + expect(event.defaultPrevented).toBe(false); + expect(event.currentTarget).toBeNull(); + expect(event.eventPhase).toBe(Event.NONE); + }); + + it('stops remaining listeners and ancestors, then clears the stop flags for reuse', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const target = document.createElement('span'); + root.appendChild(target); + const calls: string[] = []; + const stop = (event: Event): void => { + calls.push('stop'); + event.stopImmediatePropagation(); + }; + target.addEventListener('click', stop); + target.addEventListener('click', () => calls.push('target')); + root.addEventListener('click', () => calls.push('root bubble')); + const event = new Event('click', { bubbles: true, cancelable: true }); + + expect(target.dispatchEvent(event)).toBe(true); + expect(calls).toEqual(['stop']); + expect(event.defaultPrevented).toBe(false); + expect(event.currentTarget).toBeNull(); + expect(event.eventPhase).toBe(Event.NONE); + + target.removeEventListener('click', stop); + calls.length = 0; + expect(target.dispatchEvent(event)).toBe(true); + expect(calls).toEqual(['target', 'root bubble']); + }); + }); + + describe('preventDefault', () => { + it('cancels only cancelable events without stopping propagation', () => { + const document = new Document(vi.fn()); + const root = document.documentElement; + const target = document.createElement('span'); + root.appendChild(target); + const prevented: boolean[] = []; + const prevent = (event: Event): void => event.preventDefault(); + target.addEventListener('click', prevent); + root.addEventListener('click', (event: Event) => prevented.push(event.defaultPrevented)); + const ordinary = new Event('click', { bubbles: true }); + const cancelable = new Event('click', { bubbles: true, cancelable: true }); + + expect(target.dispatchEvent(ordinary)).toBe(true); + expect(ordinary.defaultPrevented).toBe(false); + expect(target.dispatchEvent(cancelable)).toBe(false); + expect(cancelable.defaultPrevented).toBe(true); + expect(prevented).toEqual([false, true]); + + target.removeEventListener('click', prevent); + expect(target.dispatchEvent(cancelable)).toBe(false); + expect(cancelable.defaultPrevented).toBe(true); + }); + }); +}); diff --git a/packages/ui/src/dom.ts b/packages/ui/src/dom.ts index e56606e..ab5113c 100644 --- a/packages/ui/src/dom.ts +++ b/packages/ui/src/dom.ts @@ -5,71 +5,538 @@ export interface Elements { document: Element; } -export class Document { - readonly documentElement: Element; - readonly notify: () => void; +export const ELEMENT_NODE = 1; +export const ATTRIBUTE_NODE = 2; +export const TEXT_NODE = 3; +export const DOCUMENT_NODE = 9; - constructor(notify: () => void) { - this.notify = notify; - this.documentElement = new Element('document', notify); +export type NodeType = + | typeof ELEMENT_NODE + | typeof ATTRIBUTE_NODE + | typeof TEXT_NODE + | typeof DOCUMENT_NODE; + +export interface EventListener< + Type extends string = string, + Target extends EventTarget = EventTarget, +> { + (this: Target, event: Event): void; +} + +export abstract class EventTarget { + #registry = new Map< + string, + { + capture: Map; + bubble: Map; + } + >(); + + // oxlint-disable-next-line bombshell-dev/max-params -- Matches the DOM EventTarget signature. + addEventListener( + type: Type, + listener: EventListener, + capture = false, + ): void { + let listeners = this.#registry.get(type); + if (!listeners) { + listeners = { capture: new Map(), bubble: new Map() }; + this.#registry.set(type, listeners); + } + const map = capture ? listeners.capture : listeners.bubble; + const callback = listener as EventListener; + if (!map.has(callback)) { + map.set(callback, { listener: callback, removed: false }); + } } - createElement(tagName: keyof Elements) { - return new Element(tagName, this.notify); + // oxlint-disable-next-line bombshell-dev/max-params -- Matches the DOM EventTarget signature. + removeEventListener( + type: Type, + listener: EventListener, + capture?: boolean, + ): void { + const listeners = this.#registry.get(type); + const map = capture ? listeners?.capture : listeners?.bubble; + + if (map) { + const callback = listener as EventListener; + const registration = map.get(callback); + if (registration) { + registration.removed = true; + map.delete(callback); + } + } } - createTextNode(data: string): Text { - return new Text(data, this.notify); + abstract dispatchEvent(event: Event): boolean; + + protected listenersFor(eventType: string, capture: boolean): EventRegistration[] { + const listeners = this.#registry.get(eventType); + if (!listeners) { + return []; + } + const map = capture ? listeners.capture : listeners.bubble; + return [...map.values()]; } } -export class Node { +interface EventRegistration { + listener: EventListener; + removed: boolean; +} + +export abstract class Node extends EventTarget { + parentNode: Node | null; + readonly ownerDocument: Owner; readonly nodeName: string; - readonly childNodes: Node[]; + abstract readonly nodeType: NodeType; - protected readonly notify: () => void; + readonly #children: Node[] = []; - constructor(nodeName: string, notify: Node['notify']) { - this.notify = notify; + constructor(nodeName: string, owner: Owner) { + super(); this.nodeName = nodeName; - this.childNodes = []; + this.ownerDocument = owner; + this.parentNode = null; + } + + get namespaceURI() { + return 'http://www.w3.org/1999/xhtml'; + } + + get isConnected(): boolean { + return this.parentNode ? this.parentNode.isConnected : false; + } + + get childNodes(): ReadonlyArray { + return this.#children; + } + + get firstChild(): Node | null { + return this.#children[0] ?? null; + } + + get nextSibling(): Node | null { + if (this.parentNode) { + const index = this.parentNode.childNodes.indexOf(this); + return this.parentNode.childNodes[index + 1] ?? null; + } + return null; + } + + remove() { + this.parentNode?.removeChild(this); + return this; + } + + insertBefore(node: Node, anchor: Node | null): Node { + if (anchor && anchor.parentNode !== this) { + throw new NotFoundError('Anchor is not a child of this node'); + } + + if (node === this) { + throw new HierarchyRequestError(`cannot make a Node a child of itself`); + } + + if (ancestorOf(this, node)) { + throw new HierarchyRequestError(`cannot add an ancestor Node to its descendant`); + } + if (node === anchor) { + return node; + } + if (node.parentNode) { + if (node.parentNode === this) { + const currentIndex = this.#children.indexOf(node); + this.#children.splice(currentIndex, 1); + } else { + node.parentNode.removeChild(node); + } + } + const anchorIndex = anchor ? this.#children.indexOf(anchor) : this.#children.length; + this.#children.splice(anchorIndex, 0, node); + + node.parentNode = this; + this.notify(); + + return node; } appendChild(node: Node): Node { - this.childNodes.push(node); + return this.insertBefore(node, null); + } + + removeChild(node: Node): Node { + const currentIndex = this.#children.indexOf(node); + if (currentIndex < 0) { + throw new NotFoundError( + `cannot remove ${node.nodeName} from ${this.nodeName}. It is not a child`, + ); + } + + this.#children.splice(currentIndex, 1); + node.parentNode = null; + this.notify(); return node; } + + dispatchEvent(event: Event): boolean { + if (event.eventPhase !== Event.NONE) { + throw new InvalidStateError('cannot dispatch an event that is already dispatching'); + } + + const path: Node[] = []; + + for (let current = this.parentNode; current; current = current.parentNode) { + path.push(current); + } + + Event.prepare({ event, target: this, currentTarget: null, phase: Event.NONE }); + + const propagation = Event.currentPropagation(event); + + try { + for (let i = path.length - 1; i >= 0; i--) { + if (!propagation.ancestor) { + return !event.defaultPrevented; + } + const currentTarget = path[i]!; + const registrations = currentTarget.listenersFor(event.type, true); + for (const registration of registrations) { + if (registration.removed) { + continue; + } + Event.prepare({ event, target: this, currentTarget, phase: Event.CAPTURING_PHASE }); + registration.listener.call(currentTarget, event); + if (!propagation.immediate) { + return !event.defaultPrevented; + } + } + } + + if (!propagation.ancestor) { + return !event.defaultPrevented; + } + + const captures = [...this.listenersFor(event.type, true)]; + for (const registration of captures) { + if (registration.removed) { + continue; + } + Event.prepare({ event, target: this, currentTarget: this, phase: Event.AT_TARGET }); + registration.listener.call(this, event); + if (!propagation.immediate) { + return !event.defaultPrevented; + } + } + + if (!propagation.ancestor) { + return !event.defaultPrevented; + } + + const bubbles = [...this.listenersFor(event.type, false)]; + for (const registration of bubbles) { + if (registration.removed) { + continue; + } + Event.prepare({ event, target: this, currentTarget: this, phase: Event.AT_TARGET }); + registration.listener.call(this, event); + if (!propagation.immediate) { + return !event.defaultPrevented; + } + } + + if (!event.bubbles) { + return !event.defaultPrevented; + } + + for (let i = 0; i < path.length; i++) { + if (!propagation.ancestor) { + return !event.defaultPrevented; + } + const currentTarget = path[i]!; + const registrations = [...currentTarget.listenersFor(event.type, false)]; + for (const registration of registrations) { + if (registration.removed) { + continue; + } + Event.prepare({ event, target: this, currentTarget, phase: Event.BUBBLING_PHASE }); + registration.listener.call(currentTarget, event); + if (!propagation.immediate) { + return !event.defaultPrevented; + } + } + } + + return !event.defaultPrevented; + } finally { + Event.prepare({ event, target: this, currentTarget: null, phase: Event.NONE }); + propagation.ancestor = true; + propagation.immediate = true; + } + } + + protected notify(): void { + if (this.isConnected) { + this.ownerDocument?.notify(); + } + } +} + +export class Document extends Node { + readonly documentElement: Element; + override readonly notify: () => void; + + constructor(notify: () => void) { + super('#document', null); + this.documentElement = this.createElement('document'); + this.notify = () => {}; + this.appendChild(this.documentElement); + this.notify = notify; + } + + get nodeType(): NodeType { + return DOCUMENT_NODE; + } + + override get isConnected() { + return true; + } + + createElement(tagName: K): Elements[K]; + createElement(tagName: string): Element; + createElement(tagName: string): Element { + return new Element(tagName, this); + } + + createElementNS(namespace: string, tagName: string): Element { + if (namespace !== 'http://www.w3.org/1999/xhtml') { + throw new DOMExecption('only HTML namespace is supported'); + } + return this.createElement(tagName); + } + + createAttribute(name: string): Attr { + return new Attr(name, this); + } + + createTextNode(data: string): Text { + return new Text(String(data), this); + } } -export class Element extends Node { +export class Element extends Node { readonly tagName: string; - constructor(tagName: keyof Elements, notify: Node['notify']) { - super(tagName.toUpperCase(), notify); + #attributes = new Map(); + + constructor(tagName: string, document: Document) { + super(tagName.toUpperCase(), document); this.tagName = tagName; } + get nodeType(): NodeType { + return ELEMENT_NODE; + } + + get localName(): string { + return this.tagName; + } + get children(): Element[] { return this.childNodes.filter((node) => node instanceof Element); } + + get attributes(): Attr[] { + return [...this.#attributes.values()]; + } + + setAttribute(name: string, value: string): void { + let attr = this.#attributes.get(name); + if (!attr) { + attr = this.ownerDocument.createAttribute(name); + attr.ownerElement = this; + this.#attributes.set(name, attr); + } + if (value !== attr.value) { + attr.value = value; + this.notify(); + } + } + + removeAttribute(name: string) { + const attr = this.#attributes.get(name); + if (attr) { + this.#attributes.delete(name); + attr.ownerElement = null; + this.notify(); + } + } } -export class Text extends Node { +export class Text extends Node { #data: string; - constructor(data: string, notify: Node['notify']) { - super('#text', notify); + constructor(data: string, document: Document) { + super('#text', document); this.#data = data; } + get nodeType(): NodeType { + return TEXT_NODE; + } + get data() { return this.#data; } set data(data: string) { - if (data !== this.data) { - this.#data = data; + const value = String(data); + if (value !== this.data) { + this.#data = value; this.notify(); } } } + +export class Attr extends Node { + readonly name: string; + ownerElement: Element | null = null; + #value = ''; + + constructor(name: string, owner: Document) { + super(name, owner); + this.name = name; + } + + get nodeType(): NodeType { + return ATTRIBUTE_NODE; + } + + get value(): string { + return this.#value; + } + + set value(value: string) { + this.#value = String(value); + } +} + +export interface EventOptions { + bubbles?: boolean; + cancelable?: boolean; + composed?: boolean; +} + +export type EventPhase = 0 | 1 | 2 | 3; + +export class Event { + static readonly NONE = 0; + static readonly CAPTURING_PHASE = 1; + static readonly AT_TARGET = 2; + static readonly BUBBLING_PHASE = 3; + + readonly type: Type; + readonly bubbles: boolean; + readonly cancelable: boolean; + readonly composed: boolean; + + #eventPhase: EventPhase = Event.NONE; + #defaultPrevented = false; + #target: Node | null = null; + #currentTarget: Node | null = null; + #propagation = { ancestor: true, immediate: true }; + + static prepare(options: { + event: Event; + target: Node | null; + currentTarget: Node | null; + phase: EventPhase; + }) { + const { event, target, currentTarget, phase } = options; + event.#target = target; + event.#currentTarget = currentTarget; + event.#eventPhase = phase; + } + + static currentPropagation(event: Event) { + return event.#propagation; + } + + constructor(type: Type, options?: EventOptions) { + const { bubbles = false, cancelable = false, composed = false } = options ?? {}; + this.type = type; + this.bubbles = bubbles; + this.cancelable = cancelable; + this.composed = composed; + } + + get eventPhase() { + return this.#eventPhase; + } + + get defaultPrevented() { + return this.#defaultPrevented; + } + + get target() { + return this.#target; + } + + get currentTarget() { + return this.#currentTarget; + } + + stopPropagation(): void { + this.#propagation.ancestor = false; + } + + stopImmediatePropagation(): void { + this.#propagation.immediate = false; + } + + preventDefault(): void { + if (this.cancelable) { + this.#defaultPrevented = true; + } + } +} + +export class DOMExecption extends Error { + override name = 'DOMException'; + constructor(message: string, options?: ErrorOptions) { + super(message, options); + } +} + +export class HierarchyRequestError extends Error { + override name = 'HierarchyRequestError'; + constructor(message: string, options?: ErrorOptions) { + super(message, options); + } +} + +export class NotFoundError extends Error { + override name = 'NotFoundError'; + + constructor(message: string, options?: ErrorOptions) { + super(message, options); + } +} + +export class InvalidStateError extends Error { + override name = 'InvalidStateError'; + + constructor(message: string, options?: ErrorOptions) { + super(message, options); + } +} + +function ancestorOf(node: Node, candidate: Node) { + for (let current: Node | null = node; current; current = current.parentNode) { + if (current.parentNode === candidate) { + return true; + } + } + return false; +} diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index ca4a46a..12eb04c 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1 +1,2 @@ -export { createUI } from './ui.ts'; +export { createUI, type UI, type UIOptions } from './ui.ts'; +export { Document, Element, Event, Node, Text } from './dom.ts'; diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json index a055ad0..862e962 100644 --- a/packages/ui/tsconfig.json +++ b/packages/ui/tsconfig.json @@ -1,6 +1,7 @@ { - "extends": "@bomb.sh/tools/tsconfig.json", + "extends": "../../tsconfig.json", "compilerOptions": { "types": ["node"] - } + }, + "include": ["src", "test"] } diff --git a/patches/@bomb.sh__tools@0.6.1.patch b/patches/@bomb.sh__tools@0.6.1.patch deleted file mode 100644 index 1d37648..0000000 --- a/patches/@bomb.sh__tools@0.6.1.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/dist/commands/test.mjs b/dist/commands/test.mjs -index e07ebb287e5a450dfde4df7e973b459a4b5651b3..8fb3b952fef033bb32f749bc1bcfdccf6763a7a0 100644 ---- a/dist/commands/test.mjs -+++ b/dist/commands/test.mjs -@@ -18,6 +18,9 @@ async function test(ctx) { - ...ctx.args - ]); - for await (const line of stdio) console.info(line); -+ // Without forwarding Vitest's exit status, failing tests still make `bsh test` -+ // exit successfully, allowing CI to pass despite test failures. -+ process.exitCode = stdio.exitCode ?? 1; - } - //#endregion - export { test }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 056274d..bd92da0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,24 +10,22 @@ catalogs: specifier: ^0.7.0 version: 0.7.0 -patchedDependencies: - '@bomb.sh/tools@0.6.1': - hash: 233e8ef5a4ce472e66d681a69475318f4daad79a70ba5fdc88f9ce9904ae5603 - path: patches/@bomb.sh__tools@0.6.1.patch - importers: .: devDependencies: '@bomb.sh/tools': - specifier: ^0.6.1 - version: 0.6.1(patch_hash=233e8ef5a4ce472e66d681a69475318f4daad79a70ba5fdc88f9ce9904ae5603)(@types/node@22.20.0)(oxc-resolver@11.20.0)(unrun@0.2.39)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0)) + specifier: ^0.8.0 + version: 0.8.0(@types/node@22.20.0)(oxc-resolver@11.20.0)(tsx@4.23.15)(unrun@0.2.39)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) + '@changesets/cli': + specifier: ^2.30.0 + version: 2.31.1(@types/node@22.20.0) '@termless/core': specifier: ^0.10.2 version: 0.10.2(node-pty@1.2.0-beta.15) '@termless/test': specifier: ^0.10.2 - version: 0.10.2(@termless/core@0.10.2(node-pty@1.2.0-beta.15))(playwright@1.64.1)(vitest@4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0))) + version: 0.10.2(@termless/core@0.10.2(node-pty@1.2.0-beta.15))(playwright@1.64.1)(vitest@5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(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.0 @@ -35,14 +33,27 @@ importers: specifier: 1.2.0-beta.15 version: 1.2.0-beta.15 vitest: - specifier: ^4.1.9 - version: 4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0)) + specifier: ^5.0.5 + version: 5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) - examples/basic: + examples/hello-world-preact: dependencies: '@clack/ui': specifier: workspace:* version: link:../../packages/ui + '@clack/ui-preact': + specifier: workspace:* + version: link:../../packages/ui-preact + preact: + specifier: 11.0.1 + version: 11.0.1 + devDependencies: + '@types/node': + specifier: ^22.20.0 + version: 22.20.0 + tsx: + specifier: ^4.19.0 + version: 4.23.15 packages/ui: dependencies: @@ -50,57 +61,252 @@ importers: specifier: 'catalog:' version: 0.7.0 -packages: - - '@babel/generator@8.0.0': - resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-string-parser@8.0.0': - resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} - engines: {node: ^22.18.0 || >=24.11.0} - - '@babel/helper-validator-identifier@8.0.2': - resolution: {integrity: sha512-9Fr9QeyCAyi1BR1jKZ6uYQ24EIhQUx5ReHfQU7drOE+TPOb+w11/dsqLkMOT2U29OdCT71XajrOT8xDc1C7orA==} - engines: {node: ^22.18.0 || >=24.11.0} + packages/ui-preact: + dependencies: + '@clack/ui': + specifier: workspace:* + version: link:../ui + devDependencies: + preact: + specifier: 11.0.1 + version: 11.0.1 - '@babel/parser@8.0.0': - resolution: {integrity: sha512-aLxAE+imI9bCcyaPrUDjBv3uSkWieifjLe0kuFOZF0zli0L6GCsTmsePnTr55adbIAgYz2zhN1vnFimCBUYcRQ==} - engines: {node: ^22.18.0 || >=24.11.0} - hasBin: true +packages: - '@babel/types@8.0.0': - resolution: {integrity: sha512-K8ponJDxBwDHigkeFqaqT5wLGl4bTlwMafR8k7b5CPxr6Ww+UG9ls8Yx6Tcpboxu97eeGVEEyKcHmEyOwN1vSw==} - engines: {node: ^22.18.0 || >=24.11.0} + '@babel/runtime@7.29.10': + resolution: {integrity: sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==} + engines: {node: '>=6.9.0'} '@bomb.sh/args@0.3.1': resolution: {integrity: sha512-CwxKrfgcorUPP6KfYD59aRdBYWBTsfsxT+GmoLVnKo5Tmyoqbpo0UNcjngRMyU+6tiPbd18RuIYxhgAn44wU/Q==} - '@bomb.sh/tools@0.6.1': - resolution: {integrity: sha512-p3dLXau2JygQ9DTErUvHSn7GwqpRraIjiXdj/xeAU0+7opUZrtiHe18FLrU5opCSr16WZep0p0/OBX1HgMjgJQ==} + '@bomb.sh/tools@0.8.0': + resolution: {integrity: sha512-iaWws8S5kMuS6zImKXPSguUoQYA5M8XlK4ObVJI5jvubNeSlCI6feGPwex9GHyO+eIsi6izv/swO1ceO2MWEvw==} hasBin: true '@bomb.sh/tty@0.7.0': resolution: {integrity: sha512-htTavc3o84vR6uSoyF+Y9u81GG8NoTJkwOovahcNOY4nVeiM86vodCHdPvAXoj2ucmx04frpwMrOJ4ipLSSJfw==} engines: {node: '>= 22'} + '@changesets/apply-release-plan@7.1.1': + resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==} + + '@changesets/assemble-release-plan@6.0.10': + resolution: {integrity: sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/cli@2.31.1': + resolution: {integrity: sha512-uO05WTcRBwuVOJVSW8Cmpqw6q0WDL53ajGCMyszutvOe5toOnunbpM4jZzf+qxBOz7i0AzopZ8diBuewjmF40w==} + hasBin: true + + '@changesets/config@3.1.4': + resolution: {integrity: sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.4': + resolution: {integrity: sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==} + + '@changesets/get-release-plan@4.0.16': + resolution: {integrity: sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - '@emnapi/core@1.11.1': - resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} - '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - '@emnapi/runtime@1.11.1': - resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} - '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] '@humanfs/core@0.19.2': resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} @@ -118,19 +324,31 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + '@napi-rs/canvas-android-arm64@1.0.11': resolution: {integrity: sha512-dtJS4FQEfH9OwSYLtMrEnj7T8DzBbJc/97LI/OkiWOYpW/iW5t6R/gcxVrUXS8l45gCVpwMufgucRe/pe0ISqA==} engines: {node: '>= 10'} @@ -207,6 +425,18 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + '@oxc-parser/binding-android-arm-eabi@0.133.0': resolution: {integrity: sha512-l/44caGse+VpnY9gx0yvvc5QnnG3yG1FO3KZgYvNL1GZrfK86zIwAOgGEVlxDyRymzrU/KHiblPFpevKOmJmUA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -332,8 +562,8 @@ packages: '@oxc-project/types@0.133.0': resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} - '@oxc-project/types@0.137.0': - resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} + '@oxc-project/types@0.155.0': + resolution: {integrity: sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==} '@oxc-resolver/binding-android-arm-eabi@11.20.0': resolution: {integrity: sha512-IjfWOXRgJFNdORDl+Uf1aibNgZY2guOD3zmOhx1BGVb/MIiqlFTdmjpQNplSN58lhWehnX4UNqC3QwpUo8pjJg==} @@ -430,230 +660,230 @@ packages: cpu: [x64] os: [win32] - '@oxfmt/binding-android-arm-eabi@0.47.0': - resolution: {integrity: sha512-KrMQRdMi/upr81qT4ijK6X6BNp6jqpMY7FwILQnwIy9QLc3qpnhUx5rsCLGzn4ewsCQ0CNAspN2ogmP1GXLyLw==} + '@oxfmt/binding-android-arm-eabi@0.74.0': + resolution: {integrity: sha512-xxQwrf5EPI5zxvuCTW8r6tzCTjPQ+h6+HqJ0iRKRy2zS1yBllt/xLVjoIyUc+FnR7g0a5g1SZv2yyDYhTItLbA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxfmt/binding-android-arm64@0.47.0': - resolution: {integrity: sha512-r4ixS/PeUpAFKgrpDoZ5pSkthjZzVzKd95525Aazj+aOv9H4ulK5zYHGb7wFY5n5kZxHK8TbOJUZgoEb1ohddQ==} + '@oxfmt/binding-android-arm64@0.74.0': + resolution: {integrity: sha512-FJW3sATVvrWbV64al8xofCPZj4500Z/1W0ad7Tg1rcCUyh0EMbuSrsf3jsZS7CEbwQ5fQ0mRhmkc129GFgofSQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxfmt/binding-darwin-arm64@0.47.0': - resolution: {integrity: sha512-CLWxiKpMl+195cm09CuaWEhJK0CirRkoMa07aR9+9AFPat2LfIKtwx1JqxZM0MTvcMe6+adlJNdVL6jdInvq3g==} + '@oxfmt/binding-darwin-arm64@0.74.0': + resolution: {integrity: sha512-TfmNKBD30dGyMu9GCLiaw2rt/z7fms9LS+5cKcNOyWst0QgAs8oZs6wPxMbVaaDVE0/PCdCosgWM1vbu6f5NUg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxfmt/binding-darwin-x64@0.47.0': - resolution: {integrity: sha512-Xq5fjTYDC50faUeLSm0rZdBqoTgleXEdD7NpJdARtQIczkCJn3xNjMUSQQkUmh4CtxkKTNL68lytcOK3e/osgg==} + '@oxfmt/binding-darwin-x64@0.74.0': + resolution: {integrity: sha512-5Usf8+DfC4Q3o/MD8FkN47GrI6y0KbhQ4KhZ2HGzMZcXjcW1AeldwbUn51aKih+1TVuJFF9qkNm6X1nzm6NYng==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxfmt/binding-freebsd-x64@0.47.0': - resolution: {integrity: sha512-QOU9ZIJ52p5askcEC0QJvvr8trHAWoonul8bgISo6gYUL3s50zkqafBYcNAr9LJZQbsZtPfIWHk9+5+nUp1qJQ==} + '@oxfmt/binding-freebsd-x64@0.74.0': + resolution: {integrity: sha512-eL+1O3gykw1XihbZh2MRAciQvU2988LByrnjhyo/dmNG74X4oZ7XzigRoWPRFLfJCp8hzRkp/LbEhwe7uuT2eA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxfmt/binding-linux-arm-gnueabihf@0.47.0': - resolution: {integrity: sha512-oJxDM1aBhPvz9gmElBv8UpxyiqhwfjcbrSxT5F0xtuUzY6dQI27/AQPIt3eu3Z5Yvn0kQl5R7MA3Z+MbnRvCBw==} + '@oxfmt/binding-linux-arm-gnueabihf@0.74.0': + resolution: {integrity: sha512-Xt0QtO2hJ4stnul8IL4LJGVLyp0xnc6ccN9fZ30yuubv8FWSRYxWwd1Za62KsEqAfmPSazoS/cLSUUJpja6npA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm-musleabihf@0.47.0': - resolution: {integrity: sha512-g8Lh50VS4ibGz2q6v7r9UZY4D0dM16SdrFYOMzhqIoCwGcai8VMIRUAcqn1/jlCsOOzUXJ741+kCeJt0cofakQ==} + '@oxfmt/binding-linux-arm-musleabihf@0.74.0': + resolution: {integrity: sha512-/4wYQ0gZl4vUR0QoBTGaay73FmQ1GAjUa9z9101TR2xbGNrg4a+grazlR0yzEOe3/E+PJr5BGfj66MMzm/54vg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm64-gnu@0.47.0': - resolution: {integrity: sha512-YrNT1vQ0asaXoRbrvYENPqmBfOQ9Xr8enPNOULeYfg44VjCcrUowFy5QZr+WawE0zyP8cH9e9Gxxg0fDEFzhcg==} + '@oxfmt/binding-linux-arm64-gnu@0.74.0': + resolution: {integrity: sha512-846bKzF+HJd+JkOFh3rxzmYvSq4Cm+GMT+p+mW7S13ZYo6GAAGv8bL8cAOi/XcdeMqxEJDCIMTVQLVBXHMCdig==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxfmt/binding-linux-arm64-musl@0.47.0': - resolution: {integrity: sha512-IxtQC/sbBi4ubbY+MdwdanRWrG9InQJVZqyMsBa5IUaQcnSg86gQme574HxXMC1p4bo4YhV99zQ+wNnGCvEgzw==} + '@oxfmt/binding-linux-arm64-musl@0.74.0': + resolution: {integrity: sha512-nI5FJwZ4Flo6CBdscpwxymZXxO3m3IErQJX55ZS6h+ObfGXu8FostL85L/RWPFaCLnIVE4/WfLw+2q8XvVEeUA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxfmt/binding-linux-ppc64-gnu@0.47.0': - resolution: {integrity: sha512-EWXEhOMbWO0q6eJSbu0QLkU8cKi0ljlYLngeDs2Ocu/pm1rrLwyQiYzlFbdnMRURI4w9ndr1sI9rSbhlJ5o23Q==} + '@oxfmt/binding-linux-ppc64-gnu@0.74.0': + resolution: {integrity: sha512-BoQYKuqUdsKAFAkK6DLBvkdv4+t0hppSm79sB0wIcE2o/eOwNj+6Z3OlKY4q3Eta/tlssP65FaS9vHn8TeF7vQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@oxfmt/binding-linux-riscv64-gnu@0.47.0': - resolution: {integrity: sha512-tZrjS11TUiDuEpRaqdk8K9F9xETRyKXfuZKmdeW+Gj7coBnm7+8sBEfyt033EAFEQSlkniAXvBLh+Qja2ioGBQ==} + '@oxfmt/binding-linux-riscv64-gnu@0.74.0': + resolution: {integrity: sha512-FSroRrM12+jCdSQklF9aOxsKpI6wFs4ZCo/1cSYG80RWZS6z4LV+l9tXRMT8lDGu+yohIZBwi9M76FzGPFDE2A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxfmt/binding-linux-riscv64-musl@0.47.0': - resolution: {integrity: sha512-KBFy+2CFKUCZzYwX2ZOPQKck1vjQbz+hextuc19G4r0WRJwadfAeuQMQRQvB+Ivc8brlbOVg7et8K7E467440g==} + '@oxfmt/binding-linux-riscv64-musl@0.74.0': + resolution: {integrity: sha512-0VLQD0dhGBLY9Ik/w+otMvD81D0YXi4VDwql65macV+O9UzmSWmUr6CKf+dMtysDeC0PnG3y6kBkRO08BJx52g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxfmt/binding-linux-s390x-gnu@0.47.0': - resolution: {integrity: sha512-REUPFKVGSiK99B+9eaPhluEVglzaoj/SMykNC5SUiV2RSsBfV5lWN7Y0iCIc251Wz3GaeAGZsJ/zj3gjarxdFg==} + '@oxfmt/binding-linux-s390x-gnu@0.74.0': + resolution: {integrity: sha512-6X7BbZNz34+OHM6Oqjf6TRcUyRn6aRcB4VtIDZAF/uQRyeVhg+G2hv6MlMvmnRekVSyTJ/8rG/u8W2dRFW6glg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxfmt/binding-linux-x64-gnu@0.47.0': - resolution: {integrity: sha512-KVftVSVEDeIfRW3TIeLe3aNI/iY4m1fu5mDwHcisKMZSCMKLkrhFsjowC7o9RoqNPxbbglm2+/6KAKBIts2t0Q==} + '@oxfmt/binding-linux-x64-gnu@0.74.0': + resolution: {integrity: sha512-4kYIQK53yJXrxwxSzx8H2bojlf6/KezLGYLRXzV9QCCkoiCsvBTCid9Bg83dUPTLPa3g9K0730f6MKDbck1+OA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxfmt/binding-linux-x64-musl@0.47.0': - resolution: {integrity: sha512-DTsmGEaA2860Aq5VUyDO8/MT9NFxwVL93RnRYmpMwK6DsSkThmvEpqoUDDljziEpAedMRG19SCogrNbINSbLUQ==} + '@oxfmt/binding-linux-x64-musl@0.74.0': + resolution: {integrity: sha512-MfWz4wDREjp/JQDmuxtKieix4FHGa1z5rBvB3betdcPwZvf5fqeQrlCm1mmoyuUVQOh9Pt3M61HwN94kJCxw7Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxfmt/binding-openharmony-arm64@0.47.0': - resolution: {integrity: sha512-8r5BDro7fLOBoq1JXHLVSs55OlrxQhEso4HVo0TcY7OXJUPYfjPoOaYL5us+yIwqyP9rQwN+rxuiNFSmaxSuOQ==} + '@oxfmt/binding-openharmony-arm64@0.74.0': + resolution: {integrity: sha512-6rmAApkq5s1kbDjvNI6Nl5A+JqQkLORb2sR941pf5HWsrd01WGKyagK/B4vX9+kh1FfvRkNgEu59FHvVk4H8cQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxfmt/binding-win32-arm64-msvc@0.47.0': - resolution: {integrity: sha512-qtz/gzm8IjSPUlseZ0ofW8zyHLoZsuP5HTfcGGkWkUblB89JT8GNYH3ICqjbDsqsGqXum0/ZndXTFplSdXFIcg==} + '@oxfmt/binding-win32-arm64-msvc@0.74.0': + resolution: {integrity: sha512-+5SpRUnZNGeXTyumHnpHa791tQtt04qZs076WT8eTcGF2OJ631VLnf7S0kQSPuDG+PtJM0phadEB2WAr5n1w9g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxfmt/binding-win32-ia32-msvc@0.47.0': - resolution: {integrity: sha512-5vIcdcIDE7nCx+MXN6sm8kbC4zajDB31E86rez4i45iHNH/2NjdKlJ720xcHTr3eeiMcttCGPHPhE1TjtBDGZw==} + '@oxfmt/binding-win32-ia32-msvc@0.74.0': + resolution: {integrity: sha512-1Fg+wYBO3Dsti1QX+/6EYHjeQzLC84tLOAqPu/r7ah3UJlUs9C/DB703Ay9Vcg+8VMzqZA2P5VGhzJraVUD4OQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxfmt/binding-win32-x64-msvc@0.47.0': - resolution: {integrity: sha512-Sr59Y5ms54ONBjxFeWhVlGyQcHXxcl9DxC23f6yXlRkcos7LXBLoO+KDfxexjHIOZh7cWqrWduzvUjJ+pHp8cQ==} + '@oxfmt/binding-win32-x64-msvc@0.74.0': + resolution: {integrity: sha512-y9jXUgPBm2TZIWbQhMYRRYAQM57+r4fbykgc+j24ICIIZl+pcuoNhnq1CRGm3oFiHnEUnZO00qOtSPGQdJ2ziQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.69.0': - resolution: {integrity: sha512-DKQQbD5cZ/MYfDgDI7YGyGD9FSxABlsBsYFo5p26lloob543tP9+4N3guwdXIYJN+7HSZxLe8YJuwcOWw5qnHg==} + '@oxlint/binding-android-arm-eabi@1.89.0': + resolution: {integrity: sha512-Pflpba5F3gRAQ12sWglRxvWTHEdAusNDvmi4Y5N1T5SY1AGkM7AixOnET8qkrnLJ/F32qAlNokO6eCknT8tmnw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.69.0': - resolution: {integrity: sha512-lEhb+I5pr4inux+JFwfCa1HRq3Os7NirEFQ0H1I35SVEHPm6byX0Ah47xmRha3qi6LAkxUcxViL8o/9PivjzBg==} + '@oxlint/binding-android-arm64@1.89.0': + resolution: {integrity: sha512-dYmyD1x7LaPlb79vZWUcpTShk8dI9z1I+IubtqrBxWNJaDhQdPHwcsvg7q5StTU4xWyd9AwPfLaTYFZY8NZgtQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.69.0': - resolution: {integrity: sha512-GY2YE8lOZW59BW1Ia1y+1gR0XyjrZRvVWHAr8LGeGhYHE0OQJ/7cRKXTkx1P+E9/6awEc3SX8a68SFTjh/E//A==} + '@oxlint/binding-darwin-arm64@1.89.0': + resolution: {integrity: sha512-Z/oxOPiIqiS7fItRdxaaOEC+6GD3OpGi0IxoR0dMefzQHolsKLzScw2DNcu/5gUPok3tv+G9mslvYB5bo3i0qg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.69.0': - resolution: {integrity: sha512-ax1oZnOjHX3LB7myQyHEaQkDwfLb6str3/nSP6O7EVUviQGNkEGzGV0EqcBJWK+Ufwx0l4xPgyYayurvhAdl2Q==} + '@oxlint/binding-darwin-x64@1.89.0': + resolution: {integrity: sha512-eAjTkHSjAxrdCPJxO6y5sPQL5pYLKb2kvxZz9UU7tXnOZk9I/HLtkvx9S7GHY883k+AmL/eC7mqFt+w7WCwk0w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.69.0': - resolution: {integrity: sha512-kHWeHv4g2h8NY+mpCxzCtY4uerMJWTN/TSnNj1CPbakFpHEJ6cTya2wWV0pDSYWOJ2+0UiEbhn3AtXxHtsnKjg==} + '@oxlint/binding-freebsd-x64@1.89.0': + resolution: {integrity: sha512-0lNCA9Tl1n1FKpqy2/9ckp0kIuSrtJ/l9bMRgaEhOtM7TsOHshFuwOcvW8oA9teXLMOJT61LjEKWiaHDFGxF/w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.69.0': - resolution: {integrity: sha512-gq84vM1a1oEehXo27YCDzGVcxPsZDI1yswZwz2Da1/cbnWtrL16XZZnz0G/+gIU8edtHpfjxq5c+vWEHqJfWoQ==} + '@oxlint/binding-linux-arm-gnueabihf@1.89.0': + resolution: {integrity: sha512-OTFEvi9W+JczaZD1Caj17SGCoW8H7TE+fvx0D7ATEWa1Lohn91UMxFQ6r145SiGy/yCxeIwptMys/RAM7gSVSQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.69.0': - resolution: {integrity: sha512-kIqEa98JQ0VRyrcncxA417m2AzasqTlD+FyVT1AksjvjkqQcvm7pBWYvoW3/mpyOP2XYvi5nSCCTIe6De1yu5g==} + '@oxlint/binding-linux-arm-musleabihf@1.89.0': + resolution: {integrity: sha512-fRxgNHvBLswj6MrhW2uBq5UDhPRQlCbHeq/Nf8yuG9zOxhDsXqX/mi2PX1axgsQxMm88el7HLiJAzglAnflYxw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.69.0': - resolution: {integrity: sha512-j+xYiXozxGWx2cpjCrwwGR4awTxPFsRv3JZrv23RCogEPMc4R7UqjHW47p/RG0aRlbWiROCJ8coUfCwy0dvzHA==} + '@oxlint/binding-linux-arm64-gnu@1.89.0': + resolution: {integrity: sha512-v9ENzHvwrQoYSWTtviH1pOYc7R9UovDxVofnck50cNmPihRRTcrg5X0UlRbLOZ7IVtxPOlh2hb7kDO+FpE8SfQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/binding-linux-arm64-musl@1.69.0': - resolution: {integrity: sha512-xEPpNppTfN1l/nM7gYSf9iocscu/as+p/7vxkLeLEKnYU+09Dm+5V6IhDYDh+Uz6FajEupWwCLt5SOG0y1PCKg==} + '@oxlint/binding-linux-arm64-musl@1.89.0': + resolution: {integrity: sha512-vfffe8mQ484AzVadlUOFpgL+JDwhvs9hrzxTgQP1FVfi4ZEUUYeffXlzC9dFV7Dgnu5s/KrNKvfmG6HxBd/ISQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/binding-linux-ppc64-gnu@1.69.0': - resolution: {integrity: sha512-Ug0+eU7HJBlek+SjklYH62IlOMirEJsdxpihH0kSqX0XdrDD4NdHpQc10fK1JC35yn6KrrcN+uYzlHD38XAf8Q==} + '@oxlint/binding-linux-ppc64-gnu@1.89.0': + resolution: {integrity: sha512-Buonlp4hVS7RGNP5M7bPpGNQrenyzA2C64JcO/oz9C1c6dGOXJ7VEAnaiAMY7voou0JYyCJdvDVlFQc5DZX3DQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - '@oxlint/binding-linux-riscv64-gnu@1.69.0': - resolution: {integrity: sha512-iEyI3GIg0l/s3G4qy2TlaaWKdzj4PJJStwtlocpDTC00PY9hZueotf6OKUj9+yfQh0lrpBW/pLMgTztbAHKJEg==} + '@oxlint/binding-linux-riscv64-gnu@1.89.0': + resolution: {integrity: sha512-1eVwJJrJ3lYIPT+cm7BcBBZZXY6IQZP/oyonaruTor/MrVyWOpvnwt1oD5CLdsHg5aVBIxXodQSvt+1gK6ck5w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxlint/binding-linux-riscv64-musl@1.69.0': - resolution: {integrity: sha512-NjHjpiI4WIKSMwuoJSZi5VToPeoYOS1FR52HLIDG6lidMdqquusgtODb4iLk0+lb1q3Z0nv2/aPRcC/olmpQGg==} + '@oxlint/binding-linux-riscv64-musl@1.89.0': + resolution: {integrity: sha512-fRQQsKUGShdEL5Fl9o9uhj3grkZbeXKLv0icQ5tspUCNYSDy8wzzEcP1WC2bKdTQ0rSszbKlO3iiHORxV22DLg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - '@oxlint/binding-linux-s390x-gnu@1.69.0': - resolution: {integrity: sha512-Ai/prDewoItkDXbp38gwGZi41DycZbUTZJ3UidwoHgQC0/DaqC2TGdtBTQLJ6hSD+SAxASzh8+/eSBPmxfOacA==} + '@oxlint/binding-linux-s390x-gnu@1.89.0': + resolution: {integrity: sha512-dEtYjIy6+fHcjKklsmtmMkZRhwHr2UbzjmpvuPtQYSeN9awQ2hx5JLms5Wvri+8P/NZtD8v5hfgHALUql+/Ycg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - '@oxlint/binding-linux-x64-gnu@1.69.0': - resolution: {integrity: sha512-Gt3KHgp46mRKz4sJeaASmKvD8ayXookRw07RMf+NowhEztGGDZ7VrXpoW96XuKJLjFukWizOFVNjmYb/u7caNQ==} + '@oxlint/binding-linux-x64-gnu@1.89.0': + resolution: {integrity: sha512-hqjwIj5KOYM8Wjef/p7IruNi1iByLhSzbMBk62y22P/E8q7Jj0Pp+DeUTKTRYyZYCDtU1wEGlnWOnttHbyNIww==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/binding-linux-x64-musl@1.69.0': - resolution: {integrity: sha512-7tQhJ2+p/oHv1zcfnjYI7YVzC/7iBaVOfIvFYtxdJ5F45mWgEdrCyXZXZGfiLey5t/5JhOhsaMnnv1kAzckd7g==} + '@oxlint/binding-linux-x64-musl@1.89.0': + resolution: {integrity: sha512-iAQN3e6o9UgUCcdGwqRx/jYcKbG3HK7ur3rH6lTqVcQeNGZ85AeWIg6cgn/edwFQ0ofEZZItMwkzyCVTahnvEA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/binding-openharmony-arm64@1.69.0': - resolution: {integrity: sha512-vmWz6TKp/3hfA4lksR0zHBv/6xuX1jhym6eqOjdH2DXsDDHZWcp2f0KG0VCAnlVbIrjk29G4wAWMXb/Hn1YobA==} + '@oxlint/binding-openharmony-arm64@1.89.0': + resolution: {integrity: sha512-MNxjEByz3N/7Q4qFQuPWvc14TpN9LoD3pECEDsJTZbP/wyB7U+hduUXEl7QAbbgVezFwsb9sWtNUO6XVBndOhg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.69.0': - resolution: {integrity: sha512-9RExaLgmaw6IoIkU9cTpT71mLfI0xZ86iZH8x518LVsOkjquJMYqb9P7KpC8lgd1t0Dxs41p2pxynq4XR3Ttzw==} + '@oxlint/binding-win32-arm64-msvc@1.89.0': + resolution: {integrity: sha512-xxe+i9wfuFso/VnoL4mfj0UlzE+cfCFiUB06vkXCMyQdgVVmItF5FfAF4tATAktSU6uHruWR+FjqvAT9cHZZzg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.69.0': - resolution: {integrity: sha512-1907kRPF8/PrcIw1E7LMs9JbVrpgnt/MvFdss3an8oDkYNAACXzTntV3t3869ZZhMZxb2AzRGbz1pA/jdFatXA==} + '@oxlint/binding-win32-ia32-msvc@1.89.0': + resolution: {integrity: sha512-saFy07cO94E664glwgLmKLI40HgTL1PY86y4T6+ud4niX4H0Kdqjcmqmjps7mQNdBytV5guGbXDdyQtRfeLbLA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.69.0': - resolution: {integrity: sha512-w8SOXv3mT9Fi6jY8OXdXCfnvX/3KNLXGNr4HEz2TA7S4Mv/PYAOmpB8y/ge40mxvBMgGNaSaaDwZpAsQn7HtWA==} + '@oxlint/binding-win32-x64-msvc@1.89.0': + resolution: {integrity: sha512-hLFJ/o0f/dTJh/EW0vmcbREYSQO9tYgfiAAlsOkiLFiJuRRWvYtFELUXN5o2ijpSo/tlO1n+YlWN58tZwPG18A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -741,6 +971,12 @@ packages: resolution: {integrity: sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q==} engines: {node: '>= 10'} + '@rolldown/binding-android-arm-eabi@1.2.15': + resolution: {integrity: sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + '@rolldown/binding-android-arm64@1.0.0-rc.17': resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -753,8 +989,8 @@ packages: cpu: [arm64] os: [android] - '@rolldown/binding-android-arm64@1.1.2': - resolution: {integrity: sha512-2cZ+7xRS+DBcuJBJKnfzsbleumJhBqSlJVpuzHC0nTqfd3QQ7Vx2/x5YR/D7cBamKSeWplwo82Fn9lqYUDEMfA==} + '@rolldown/binding-android-arm64@1.2.15': + resolution: {integrity: sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] @@ -771,8 +1007,8 @@ packages: cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-arm64@1.1.2': - resolution: {integrity: sha512-RkPMJnygxsgOYdkfqgpwY0/Fzm8d0VQe6HGU2/B00Xa9eqdLbrII+DOKAodbJAn3ZL1AJxGHkZRPYazgGY6Ljw==} + '@rolldown/binding-darwin-arm64@1.2.15': + resolution: {integrity: sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] @@ -789,8 +1025,8 @@ packages: cpu: [x64] os: [darwin] - '@rolldown/binding-darwin-x64@1.1.2': - resolution: {integrity: sha512-Uiczh6vFhwyfd7WNe7Q7mCA4KxAiLdz7jPE/WGizfRpIieoyFuNVMmM8HqZ9HwudTkY6/AeMQwlNJ9NJijguWw==} + '@rolldown/binding-darwin-x64@1.2.15': + resolution: {integrity: sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] @@ -807,8 +1043,8 @@ packages: cpu: [x64] os: [freebsd] - '@rolldown/binding-freebsd-x64@1.1.2': - resolution: {integrity: sha512-+TpdtTRgHiJFjCVFbw311SuLk3KfytPOQQn+VlAEv+gBxYPtL7E6JS9e/tk+8CwxhIZvemJKo4rTKgfWNsKkkA==} + '@rolldown/binding-freebsd-x64@1.2.15': + resolution: {integrity: sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] @@ -825,8 +1061,8 @@ packages: cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.1.2': - resolution: {integrity: sha512-4lv1/tkmi7ueIVHnyreaOeUpiZP26BH9rRy6hoYfR9310A2B9nUEVRDvBx69vx64Nr3eTPPRkyciqJJs+j9Jmw==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.15': + resolution: {integrity: sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -843,8 +1079,8 @@ packages: cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.1.2': - resolution: {integrity: sha512-gBSUVO0eaWgw1JMjK3gB8BMlX2Mk148s2lTiVT3e9vjVxbl7UDfMWWY8CfIaaqiXuM9fVTMxIpUz6CAo/B6Vlw==} + '@rolldown/binding-linux-arm64-gnu@1.2.15': + resolution: {integrity: sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -861,8 +1097,8 @@ packages: cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.1.2': - resolution: {integrity: sha512-LjQP/iZLBu8o8PjIfk4x3At0/mT6h282pvz8Z5LAyhGbu/kDezyO7ea62rF5uoqmgnIYqbN/MqJ3Si3Aymi7xQ==} + '@rolldown/binding-linux-arm64-musl@1.2.15': + resolution: {integrity: sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -879,8 +1115,8 @@ packages: cpu: [ppc64] os: [linux] - '@rolldown/binding-linux-ppc64-gnu@1.1.2': - resolution: {integrity: sha512-X/7bVLWelEsbyWDUSXt7zVsTniLLPIY2n1rH58qr78l9i7MNbbxBWD8gI2vRfBWf4NUXJCUuQnfZDsp32LqsfQ==} + '@rolldown/binding-linux-ppc64-gnu@1.2.15': + resolution: {integrity: sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] @@ -897,8 +1133,8 @@ packages: cpu: [s390x] os: [linux] - '@rolldown/binding-linux-s390x-gnu@1.1.2': - resolution: {integrity: sha512-gb6dYKW/1KDorGXyy48glEBJs/sxVSC5pcVrox/pFGV4mvwSFeg2sK5L2tRkVsVlh7kueqOgg4GEcuipJcGuKg==} + '@rolldown/binding-linux-s390x-gnu@1.2.15': + resolution: {integrity: sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] @@ -915,8 +1151,8 @@ packages: cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.1.2': - resolution: {integrity: sha512-JY4w85pU3iAiJVMh5nuk4/Mh9GjMsupe8MrIN53rwxAZW64GKrWeJBuN6SxQg9QTU5uB1cxyhDzW8jqRn1EABw==} + '@rolldown/binding-linux-x64-gnu@1.2.15': + resolution: {integrity: sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -933,8 +1169,8 @@ packages: cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.1.2': - resolution: {integrity: sha512-xvpA7o5KCYLB0Rwscmuylb1/zHHSUx4g4xilm4prC5jP76pEUlzBmMbgpbh7bVDbId4NcfT96gN5i6mE6UDaiw==} + '@rolldown/binding-linux-x64-musl@1.2.15': + resolution: {integrity: sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -951,8 +1187,8 @@ packages: cpu: [arm64] os: [openharmony] - '@rolldown/binding-openharmony-arm64@1.1.2': - resolution: {integrity: sha512-p/ts6KBLjuk49Bp21XH77poQGt02iNz7ChgHep7tudPOaLinR/De/RHdxF8w8Yj4r/bF/bqXwH6PZrB2sA+Nvw==} + '@rolldown/binding-openharmony-arm64@1.2.15': + resolution: {integrity: sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] @@ -967,11 +1203,6 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-wasm32-wasi@1.1.2': - resolution: {integrity: sha512-VMu/wmrZ9hJzYlRhbw7jK5PODlugyKZ5mOdX78+lS8OvuFkWNQdz1pFLrI2p3P0pjXOmUZ7B48o5VnMH9QOGtg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -984,8 +1215,8 @@ packages: cpu: [arm64] os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.1.2': - resolution: {integrity: sha512-xtUJqs8qEkuSviS0n1tsohaPuz3a1SPhZywOji4Oo+sgrJs8daEDMZ0QtqL0OS7dx8PoVpg2J/ZZycPY5I2+Zg==} + '@rolldown/binding-win32-arm64-msvc@1.2.15': + resolution: {integrity: sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] @@ -1002,8 +1233,8 @@ packages: cpu: [x64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.1.2': - resolution: {integrity: sha512-85YiLQqjUKgSO/Zjnf9e0XIn5Ymrh1fLDWBeAkZqpuBR/3R8TpfoHXuyblqyQrftSSgWO9qpcHN8mkyKsLraoA==} + '@rolldown/binding-win32-x64-msvc@1.2.15': + resolution: {integrity: sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1014,9 +1245,6 @@ packages: '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@termless/core@0.10.2': resolution: {integrity: sha512-xr/TvnhzB0R7g24W3EcwP8UQ+ztYd5ybk4oxR/PkcEh92O5NRjl9mCkqz/wvTcGX3u77AcmA8w5Ox16T22DOCA==} engines: {bun: '>=1.0.0', node: '>=23.6.0'} @@ -1055,66 +1283,136 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - '@types/jsesc@2.5.1': - resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} '@types/node@22.20.0': resolution: {integrity: sha512-QWlFW2wf3nTjC13/DqRnBpR4ZO36VJH/JVBkA/vcnmbTBNQIlnObqyqZE1tUR7+Ni23Lda8R1BxMfbXRpCUx5g==} - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260623.1': - resolution: {integrity: sha512-8AX9NwC+G6Sbh5hNLnx8YgxoRV/8BH8FQRtZ86OTtUQfESMRvwszOGTtfcC32g86O5jsEQPDHXKVSnsIzWh6lg==} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [darwin] - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260623.1': - resolution: {integrity: sha512-ef+JmOjtTu0BRdhAq69WbzCWjZsG6gqS8xDI4fKABdWXlrVojPkrD2OObog3PC7Qte8us6QspQvvnKTf7yKFSQ==} + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} engines: {node: '>=16.20.0'} cpu: [x64] os: [darwin] - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260623.1': - resolution: {integrity: sha512-xb9m0WXvIPHOogGTC02iBv3cwRJ7q+Ql2ABcsu4kHYc1p02JSbIBEfu3g58TpcFZyODsO+8WaDylx/hBiGzlVw==} + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [linux] - '@typescript/native-preview-linux-arm@7.0.0-dev.20260623.1': - resolution: {integrity: sha512-8f9dT1RaOK3Wy/puboAcCik4HBX6mfWt5hOMipWehDfInNFI6XP3ZYErShowBQ0Tkln5qdGqDIoq452PO/ZwCA==} + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} engines: {node: '>=16.20.0'} cpu: [arm] os: [linux] - '@typescript/native-preview-linux-x64@7.0.0-dev.20260623.1': - resolution: {integrity: sha512-AZRp6q0SyVw9xe9kpyfTmavqkQKizDhmOLglDHbxAu4Y3inL6r2GSE7q3w/eO4R259dIwl5TM52DZKK8onoT6Q==} + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} engines: {node: '>=16.20.0'} cpu: [x64] os: [linux] - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260623.1': - resolution: {integrity: sha512-DXRMXOe/JEmf2CULZZn1xvRuJrnZ9DxzDubxtW85pE0aSLgl+VuplWCsZrBxaCZDrWMRIfMDV8Y0y+Yftx/jeQ==} + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} engines: {node: '>=16.20.0'} cpu: [arm64] - os: [win32] + os: [netbsd] - '@typescript/native-preview-win32-x64@7.0.0-dev.20260623.1': - resolution: {integrity: sha512-kYB1I6tdxWHjhSt8B2v9CHmpOJwJvD88LUCxiBS9C59pwrGe+LAwZvbTTJxvULNaUEjxdiMomYerWWhD/09Y3g==} + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} engines: {node: '>=16.20.0'} cpu: [x64] - os: [win32] + os: [netbsd] - '@typescript/native-preview@7.0.0-dev.20260623.1': - resolution: {integrity: sha512-33AkAhmRu1/w4nRFLnJ9lic7FSzW4zWfU1u5DP7A2+j1445SSNvf3Q4WGtDzdAR5HSlk8vXEa0B4xUHR5vM1tg==} + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} engines: {node: '>=16.20.0'} - hasBin: true + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] - '@vitest/expect@4.1.9': - resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] - '@vitest/mocker@4.1.9': - resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} + '@vitest/mocker@5.0.5': + resolution: {integrity: sha512-xLL3lkDegJZw+MGoGaCCsFayDZthGgpAtr3Vziyfc4p7xH89K7KRPcRBBh/kEYm0Aqkt5DtTmkYpBtRV/FrHZg==} peerDependencies: - msw: ^2.4.9 + msw: ^2.4.9 || ^3.0.0 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: @@ -1122,54 +1420,132 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.9': - resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} + '@vitest/spy@5.0.5': + resolution: {integrity: sha512-lwJRExuH417257Q5wv9QYugN9IMJkoxcrKrYxGPQkBzl7wlNpTUxD/5yNX4ESKVUIShKPgkGchYPFMWOOk0wzw==} - '@vitest/runner@4.1.9': - resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} + '@yuku-core/binding-android-arm64@0.19.0': + resolution: {integrity: sha512-wdL2XmTiZixAOaHk9Z0JJZ8u9Qm8d333Zjpc6gaxXFX+UR5BlsfxZ7a2+2Rm71pamppsPYGUGFq2oVLbh6DISw==} + cpu: [arm64] + os: [android] - '@vitest/snapshot@4.1.9': - resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} + '@yuku-core/binding-darwin-arm64@0.19.0': + resolution: {integrity: sha512-7sNJa6XJhyetnTy64jw3NEi4YgUcezHk1G5GH9FSvXAuC8wIlbaOwT9lgq5qo5sspjrZJQlBR1TWflP49uRpMw==} + cpu: [arm64] + os: [darwin] - '@vitest/spy@4.1.9': - resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} + '@yuku-core/binding-darwin-x64@0.19.0': + resolution: {integrity: sha512-pTC7dYEc59isdyizc3nsuyFNBu2LU5wMYZ1be6UMr59PY/AJNtO1aBLWV0MgL/z7C1nv/2sX4TNjGgKLoeevJw==} + cpu: [x64] + os: [darwin] - '@vitest/utils@4.1.9': - resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} + '@yuku-core/binding-freebsd-x64@0.19.0': + resolution: {integrity: sha512-xrZjF6XOEwyLOiDIfrwDdRCS6ghxcJeirNC1KivQhVcUwlRonaU79S3/Uiyx3lBylPnT8qKJ3/aMT+H52nGTJQ==} + cpu: [x64] + os: [freebsd] - ansis@4.3.1: - resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} - engines: {node: '>=14'} + '@yuku-core/binding-linux-arm-gnu@0.19.0': + resolution: {integrity: sha512-0OyIH53C0I1CbADHn9FSdCfX5qbpeLwJhmOVhonFJNYheybOnkSJ50qGMfTJIb8y5zrwqvLs7FVBvz6Fk8maZg==} + cpu: [arm] + os: [linux] + + '@yuku-core/binding-linux-arm-musl@0.19.0': + resolution: {integrity: sha512-z/iPfkCOCSXE34VXNt0uP1ORSW+4mEa9b5CiJcWZeqZH08g49bFU/jRM2T04f+Wpw5mJ6HIzNBiojxeAbrHjeg==} + cpu: [arm] + os: [linux] + + '@yuku-core/binding-linux-arm64-gnu@0.19.0': + resolution: {integrity: sha512-jLNTi+gzaRwBJ+gwhCJ+rDb5dmx/8hEBx93UWd7hjMSqPTL1D1wvVSvXVAldV5kALvju7b0/m51EHEhs4+I1fA==} + cpu: [arm64] + os: [linux] + + '@yuku-core/binding-linux-arm64-musl@0.19.0': + resolution: {integrity: sha512-YwyPIdW/rN2Fmv0MTFWi47FaB3F9g+2b+sJISyAw83Yd60RWH4T3Nx6XkAHHVN+uKJNBAd6So7/BVihSiFYvuQ==} + cpu: [arm64] + os: [linux] + + '@yuku-core/binding-linux-x64-gnu@0.19.0': + resolution: {integrity: sha512-/vskaAXVX3ESR43FiTdfiYS7z1b9uoQJwVQ/0RgUHgN2sWoAyCZs+aX4CgU7eKGIHTVfp9VFwv+c+2XchYiEtQ==} + cpu: [x64] + os: [linux] + + '@yuku-core/binding-linux-x64-musl@0.19.0': + resolution: {integrity: sha512-FuXL5igeSKib9Rye02TdH+D6SQezTyGxIATMu1Qsn/QywrzwpGl35OLpS2C1x5vpGLeVE2XgiLd5mVPFHmIglQ==} + cpu: [x64] + os: [linux] + + '@yuku-core/binding-win32-arm64@0.19.0': + resolution: {integrity: sha512-YuJAe7zEKT1Xa7LuHlhGJpPnYQeVtvo0rZvNjJRqkH0hQGOw4C8QeP30Tg5VKGzZfo2x8CjhjEhKt4TmLwfmdg==} + cpu: [arm64] + os: [win32] + + '@yuku-core/binding-win32-x64@0.19.0': + resolution: {integrity: sha512-o8iY/mXwlRkedp0LNTr4+TEfXTPQwoNZmv6k+1WIAd1ZXEn8xJJTBCtB0osaVvdZo/x/cNmV16UrWrrGpM5Mvw==} + cpu: [x64] + os: [win32] + + '@yuku-toolchain/types@0.19.0': + resolution: {integrity: sha512-tFkNbsP4WXX9UMUC5syJGdK9dPMLK0PPaIuXCcCYH75sZ8MrebfBZ2XvCILRTw8AgLivSSCfDa4R67iYBDa4Kg==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-kit@3.0.0: - resolution: {integrity: sha512-8OG92q3R35qjC/4i6BLBMg8IB+fClWu/1PEwg2Z9Rn+BuNaiEgJzpzn+pxWOdHJWDCAwu2JP0wCDTozAM4QirQ==} - engines: {node: ^22.18.0 || >=24.11.0} + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} - birpc@4.0.0: - resolution: {integrity: sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} - cac@7.0.0: - resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + cac@7.1.0: + resolution: {integrity: sha512-LMDU/U2yA4IPIY8KT0NsNPWEYZvAMkbgyspxJ6btJaYV+WMDOHAZCmB0lsTObiHaRS1V/ztKAl7+TSkTqXyeoA==} engines: {node: '>=20.19.0'} - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + chai@6.3.0: + resolution: {integrity: sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==} engines: {node: '>=18'} - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + chardet@2.2.0: + resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} defu@6.1.7: resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dts-resolver@3.0.0: resolution: {integrity: sha512-1T1f+z+4tl9XD+m+0HBgWoL/nm0bOIffyWaUuUSBlFg/86IWvfx+wjNaO/ybU0AJzG9/Mi5hBUgGV6zCmWEN7Q==} engines: {node: ^22.18.0 || >=24.0.0} @@ -1179,20 +1555,44 @@ packages: oxc-resolver: optional: true - empathic@2.0.1: - resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + empathic@2.1.0: + resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} engines: {node: '>=14'} - es-module-lexer@2.1.0: - resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.20.3: + resolution: {integrity: sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==} + fd-package-json@2.0.0: resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==} @@ -1205,11 +1605,27 @@ packages: picomatch: optional: true - formatly@0.3.0: + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + formatly@0.3.0: resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==} engines: {node: '>=18.3.0'} hasBin: true + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1218,8 +1634,8 @@ packages: get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} - get-tsconfig@5.0.0-beta.5: - resolution: {integrity: sha512-/6gFNr0N04nob252sTQxyFLi3eKFRqIg1I87YcqAMT1i6SQrSF6KujUEQrtrjMV0H/eejTCltLdDSTEMzHbnsQ==} + get-tsconfig@5.0.0-beta.6: + resolution: {integrity: sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw==} engines: {node: '>=20.20.0'} ghostty-web@0.4.0: @@ -1228,22 +1644,74 @@ packages: gifenc@1.0.3: resolution: {integrity: sha512-xdr6AdrfGBcfzncONUOlXMBuc5wJDtOueE3c5rdG0oNgtINLD+f2iFZltrBRZYzACRbKr+mSVU/x98zv2u3jmw==} - hookable@6.1.1: - resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + hookable@6.1.2: + resolution: {integrity: sha512-+abwxtiEA52GCVIsQqut3S/uKTbUwYIp4Pe/vv+6py5XiXBCqMZHg6pA6Y5qhgLSEys0/cYuPbO0z1QFj5ZCmg==} + + human-id@4.2.2: + resolution: {integrity: sha512-Z+8unD6em/MJwyrkWQ2M3wygRGI1+MztbutiNwk1DCuEPXOZRWGjtcMPZYP1exY9iNZMhd7ZOSMQSo9WYtiQRw==} + hasBin: true + + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} - import-without-cache@0.4.0: - resolution: {integrity: sha512-NkJQA7oZ4YHQhd2+H3BoRFKF3d/XNsiKpHZCQEMH9pDX27hQQLsTyOocyRgaIVtf8gHX3Nt3LPkR4e5EdtPAGQ==} + import-without-cache@0.4.1: + resolution: {integrity: sha512-vXoV9PjKHEednCUu01e98TkImxy67e3BJXbTIOmIq4Hyzw3IAwYRcuPkfeTzJzwyyts4kjuA73x+pWJLc4f86A==} engines: {node: ^22.18.0 || >=24.0.0} + 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'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} + js-yaml@3.15.2: + resolution: {integrity: sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==} + hasBin: true + + js-yaml@4.3.2: + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} hasBin: true + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + knip@6.16.1: resolution: {integrity: sha512-TKMn1rxgH6h9vXR9Y0B+Cq7AdPTr9EI02IwoT65NzqYUkvoDQAaJ/aPybiFpAhZ1px6cNYYwXf86iHkBgzCo9w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1319,8 +1787,23 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + magic-string@1.4.3: + resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -1337,10 +1820,13 @@ packages: node-pty@1.2.0-beta.15: resolution: {integrity: sha512-vORSzHXi4Ofl7HemVWpuudLqCPdaQb4LfpRCUpE5HPxhp4JYscl8zZwxh11p26v2wvW24WMwnMfLjhRLixrfxA==} - obug@2.1.3: - resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} engines: {node: '>=12.20.0'} + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + oxc-parser@0.133.0: resolution: {integrity: sha512-661RSx+ZcjBmjBYid+Fpp/2F5EbtildpeoZh5HdgnGs+jZ03nqQEQW8yGkt4BGyOC3OMPDQQRl8M5kqD2/g6jw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1348,17 +1834,28 @@ packages: oxc-resolver@11.20.0: resolution: {integrity: sha512-CblytBiV/a/ZXY34dsVU2NxhIOxMXst8CvDCtyBelVITgd7PLrKzbEbA6oKLdPjvDKDzCiW48qzmzZ+mYaqn+g==} - oxfmt@0.47.0: - resolution: {integrity: sha512-OFbkbzxKCpooQEnRmpTDnuwTX8KHXzZTQ4Df/hz85fpS67Pl+lxPEFvUtin56HIIS0B1k4X8oIzTXRZPufA2CA==} + oxfmt@0.74.0: + resolution: {integrity: sha512-G4OP7FgwGYZR5ttRpCOOfJdyRsSyvtn34vSXnjDq6Oqed5Dufg5mB44mank+51nAdHOKuTJ0lj0mksY7L+N61A==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + peerDependencies: + '@astrojs/compiler-rs': ^0.4.0 || ^0.5.0 + svelte: ^5.0.0 + vite-plus: '*' + peerDependenciesMeta: + '@astrojs/compiler-rs': + optional: true + svelte: + optional: true + vite-plus: + optional: true - oxlint@1.69.0: - resolution: {integrity: sha512-ypZkK/aDc5NQV8zIR6s2H2Tl3aNW8FmJ1m9+2qsaYuRenl8vgnHNCGwTHviWJdUQzglOlHFchgopdtGhSy17Rw==} + oxlint@1.89.0: + resolution: {integrity: sha512-a25hkfo61okGPvJz432fRIPoxlKtNnOVy9w4rzrmGgNm4iVTPwpSQlmdqNWnp6p9QyyPVfAZRgnf5XvSBZFk/A==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.22.1' + oxlint-tsgolint: '>=7.0.2003' vite-plus: '*' peerDependenciesMeta: oxlint-tsgolint: @@ -1366,22 +1863,66 @@ packages: vite-plus: optional: true + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} 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.4: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} + 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'} + playwright-core@1.64.1: resolution: {integrity: sha512-BC4s8y6SEVA6Q1rSxZTto8hI1KUI3xXlHGZgvGqP4IqPdI/a6FX9H29IDNz7vKo9l21b6LfYosScPL6M3xxyDQ==} engines: {node: '>=20'} @@ -1396,31 +1937,65 @@ packages: resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} + preact@11.0.1: + resolution: {integrity: sha512-TNNwEq++jYNHy747LziCjPRVgEwnLSOIOAw/oYcjI3Tdnubx2EXtt76I0an8PATvUWtx/DX1kFIg1eFN+O/fkw==} + peerDependencies: + preact-render-to-string: '>=6.7.0' + peerDependenciesMeta: + preact-render-to-string: + optional: true + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + publint@0.3.21: resolution: {integrity: sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ==} engines: {node: '>=18'} hasBin: true + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + quansync@1.0.0: resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - rolldown-plugin-dts@0.26.0: - resolution: {integrity: sha512-e+kEPtUiDES0htk5iqkSeF4EzAV7R+vugGB44iPDuw1Kw9E+WyL1VG7PaV0IIjGHLiacztMBcMTyrr8ON9CT1Q==} - engines: {node: ^22.18.0 || >=24.11.0} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rolldown-plugin-dts@0.28.8: + resolution: {integrity: sha512-FVhfqxorCWcc20BVT5eVRfRjzLLl6mgzjcMR4gSBf0K4oQMXT0qoHhhzfXy0L7y83fQy7Ug5ZDNk90xM3/LiCQ==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} peerDependencies: - '@ts-macro/tsc': ^0.3.6 - '@typescript/native-preview': '>=7.0.0-dev.20260325.1' - rolldown: ^1.0.0 - typescript: ^5.0.0 || ^6.0.0 + '@typescript/native-preview': '*' + '@volar/typescript': ~2.4.0 + '@vue/language-core': ~3.2.0 || ~3.3.0 + rolldown: ^1.2.0 + typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 vue-tsc: ~3.2.0 || ~3.3.0 peerDependenciesMeta: - '@ts-macro/tsc': - optional: true '@typescript/native-preview': optional: true + '@volar/typescript': + optional: true + '@vue/language-core': + optional: true typescript: optional: true vue-tsc: @@ -1436,22 +2011,41 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rolldown@1.1.2: - resolution: {integrity: sha512-x0CrQQqCXWGeI8dTvFfN/Dnv3yMKT9hv5jFjlOreKAx9wqLq9wz7VvLLHyaAXC90/CpggTu9SisSbsJJTPSjNQ==} + rolldown@1.2.15: + resolution: {integrity: sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + semver@7.8.4: resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} engines: {node: '>=10'} hasBin: true - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} smol-toml@1.6.1: resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} @@ -1461,52 +2055,72 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - std-env@4.1.0: - resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + std-env@4.3.0: + resolution: {integrity: sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} strip-json-comments@5.0.3: resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} engines: {node: '>=14.16'} - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + tinybench@6.2.2: + resolution: {integrity: sha512-nIZ2N2dFpjBsg2hgitKu7mA+FvsIJuGJOwysRngmVRRmWgR/UyPjwJj8c/fT/dhm8EkHnF5EOogRf+0Z2qrimA==} + engines: {node: '>=20.0.0'} tinyexec@1.2.4: resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} engines: {node: '>=18'} + tinyexec@1.3.1: + resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} + engines: {node: '>=18'} + tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} - tinypool@2.1.0: - resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} + tinypool@2.2.0: + resolution: {integrity: sha512-jBrmx4lYmaC9k/mgPbylxs7kBUxHtD8256up+HjLaDFfXScKJQyil+SWXSvhAtT7XHo+yTVlpB81PGmHP8oLSQ==} engines: {node: ^20.0.0 || >=22.0.0} - tinyrainbow@3.1.0: - resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} - 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 - tsdown@0.22.3: - resolution: {integrity: sha512-louqbfA8Qf//B9jTTL0FPtXTNpjCWv1VPkbcmQMph2pTpzs+LnB1tbe4tDDRVpo2BjF5SgUXaTZe45SxB8pWHg==} - engines: {node: ^22.18.0 || >=24.11.0} + tsdown@0.23.1: + resolution: {integrity: sha512-MSC2WSOts3in95J334/VIS7KPfor3eCSvndJ6KdoVj9Aak9Kh1aNfz9ws5owhdukuTNSXRdfkPEzA/ihpDD6SA==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} hasBin: true peerDependencies: '@arethetypeswrong/core': ^0.18.1 - '@tsdown/css': 0.22.3 - '@tsdown/exe': 0.22.3 + '@tsdown/css': 0.23.1 + '@tsdown/exe': 0.23.1 '@vitejs/devtools': '*' publint: ^0.3.8 tsx: '*' - typescript: ^5.0.0 || ^6.0.0 - unplugin-unused: ^0.5.0 + typescript: ^5.0.0 || ^6.0.0 || ^7.0.0 + unplugin-unused: '>=0.5.0' unrun: '*' peerDependenciesMeta: '@arethetypeswrong/core': @@ -1531,8 +2145,15 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - ultramatter@0.0.4: - resolution: {integrity: sha512-1f/hO3mR+/Hgue4eInOF/Qm/wzDqwhYha4DxM0hre9YIUyso3fE2XtrAU6B4njLqTC8CM49EZaYgsVSa+dXHGw==} + tsx@4.23.15: + resolution: {integrity: sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true unbash@3.0.0: resolution: {integrity: sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA==} @@ -1544,6 +2165,10 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + unrun@0.2.39: resolution: {integrity: sha512-h9FxYVpztY/wwq+bauLOh6Y3CWu2IVeRLq5lxzneBiIU9Tn86OGp9xiQrGhnYspAmg5dzdY0Cc8+Y70kuTARCg==} engines: {node: '>=20.19.0'} @@ -1557,6 +2182,10 @@ packages: upng-js@2.1.0: resolution: {integrity: sha512-d3xzZzpMP64YkjP5pr8gNyvBt7dLk/uGI67EctzDuVp4lCZyVMo0aJO6l/VDlgbInJYDY6cnClLoBp29eKWI6g==} + verkit@0.5.0: + resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} + engines: {node: '>=18.12.0'} + vite@8.0.16: resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1600,28 +2229,28 @@ packages: yaml: optional: true - vitest-ansi-serializer@0.2.1: - resolution: {integrity: sha512-IC60vT8raDlHwk2tZAy9wfetJMJkVOGC50jyjcC1HTYBAYfJEXVeKe72Jd5Jzcw1Xt73Nri2cdE98p+K2mnDrA==} + vitest-ansi-serializer@0.3.1: + resolution: {integrity: sha512-XZ4T7TnO1KrE6xDOjBFCiChq++0uNEWaYi/t6mJfxDqUQzJ/oBLU+ntYO6itGew9Th9aFb2c6jmjpJJEGVj0DA==} peerDependencies: - vitest: ^3.0.0 || ^4.0.0 + vitest: ^3.0.0 || ^4.0.0 || ^5.0.0 - vitest@4.1.9: - resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + vitest@5.0.5: + resolution: {integrity: sha512-cPODOMF8YnkiiYtDdHo6n4wWmBrOBBbOIYH2d33M4l3CdNn72h+qMmO6uXffUN6A5AZFXNND/d+krS9mgkXRfg==} + engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.9 - '@vitest/browser-preview': 4.1.9 - '@vitest/browser-webdriverio': 4.1.9 - '@vitest/coverage-istanbul': 4.1.9 - '@vitest/coverage-v8': 4.1.9 - '@vitest/ui': 4.1.9 + '@types/node': ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 5.0.5 + '@vitest/browser-preview': 5.0.5 + '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 + '@vitest/coverage-istanbul': 5.0.5 + '@vitest/coverage-v8': 5.0.5 + '@vitest/ui': 5.0.5 happy-dom: '*' jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + vite: ^6.4.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -1650,68 +2279,70 @@ packages: resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==} engines: {node: 20 || >=22} - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} hasBin: true - yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + why-is-node-running@3.2.1: + resolution: {integrity: sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==} + engines: {node: '>=20.11'} + hasBin: true + + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} engines: {node: '>= 14.6'} hasBin: true - zod@4.4.3: - resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + yuku-ast@0.19.0: + resolution: {integrity: sha512-PyCsiScaelhxBGzL8dyeJkLqvRZycoh78R31Vrt/WqYrm0hMFoKwIw/X7Dx5mBKLWAMlV9I9HEyBOHnj2gZVyw==} + engines: {node: '>=14.18.0'} -snapshots: + yuku-codegen@0.19.0: + resolution: {integrity: sha512-uymAKHjDuaP4BEpkXC/BSLz4DUEF5oArZ5AuD3888nb2miChjWSgpPdojEJxm3pjpXkgUaCRJQyNAbnMN33wHg==} + engines: {node: '>=14.18.0'} - '@babel/generator@8.0.0': - dependencies: - '@babel/parser': 8.0.0 - '@babel/types': 8.0.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - '@types/jsesc': 2.5.1 - jsesc: 3.1.0 + yuku-core@0.19.0: + resolution: {integrity: sha512-kYK9e1XdfirNhkipzW0wmMcSWcVF/CWnuugodfVYRCUwvoBefweL9HzB96OiKEhsx78V5WbUxbJqlizMX869Qg==} + engines: {node: '>=14.18.0'} - '@babel/helper-string-parser@8.0.0': {} + yuku-parser@0.19.0: + resolution: {integrity: sha512-XrBh9ZiQK5mJVRxZBAvD6LwRyAYrK3MFtH3+onyuxFL5hFD44EC3QOmIC1FjTj6H2MMwq46/NAI+NZxLZPZgxg==} + engines: {node: '>=14.18.0'} - '@babel/helper-validator-identifier@8.0.2': {} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} - '@babel/parser@8.0.0': - dependencies: - '@babel/types': 8.0.0 +snapshots: - '@babel/types@8.0.0': - dependencies: - '@babel/helper-string-parser': 8.0.0 - '@babel/helper-validator-identifier': 8.0.2 + '@babel/runtime@7.29.10': {} '@bomb.sh/args@0.3.1': {} - '@bomb.sh/tools@0.6.1(patch_hash=233e8ef5a4ce472e66d681a69475318f4daad79a70ba5fdc88f9ce9904ae5603)(@types/node@22.20.0)(oxc-resolver@11.20.0)(unrun@0.2.39)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0))': + '@bomb.sh/tools@0.8.0(@types/node@22.20.0)(oxc-resolver@11.20.0)(tsx@4.23.15)(unrun@0.2.39)(vite@8.0.16(@types/node@22.20.0)(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.16.1 - oxfmt: 0.47.0 - oxlint: 1.69.0 + oxfmt: 0.74.0 + oxlint: 1.89.0 publint: 0.3.21 tinyexec: 1.2.4 - tsdown: 0.22.3(@typescript/native-preview@7.0.0-dev.20260623.1)(oxc-resolver@11.20.0)(publint@0.3.21)(unrun@0.2.39) - ultramatter: 0.0.4 - vitest: 4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0)) - vitest-ansi-serializer: 0.2.1(vitest@4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0))) + tsdown: 0.23.1(oxc-resolver@11.20.0)(publint@0.3.21)(tsx@4.23.15)(typescript@7.0.2)(unrun@0.2.39) + typescript: 7.0.2 + vitest: 5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) + vitest-ansi-serializer: 0.3.1(vitest@5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1))) + yaml: 2.9.1 transitivePeerDependencies: - '@arethetypeswrong/core' + - '@astrojs/compiler-rs' - '@edge-runtime/vm' - '@opentelemetry/api' - - '@ts-macro/tsc' - '@tsdown/css' - '@tsdown/exe' - '@types/node' + - '@typescript/native-preview' - '@vitejs/devtools' - '@vitest/browser-playwright' - '@vitest/browser-preview' @@ -1719,13 +2350,15 @@ snapshots: - '@vitest/coverage-istanbul' - '@vitest/coverage-v8' - '@vitest/ui' + - '@volar/typescript' + - '@vue/language-core' - happy-dom - jsdom - msw - oxc-resolver - oxlint-tsgolint + - svelte - tsx - - typescript - unplugin-unused - unrun - vite @@ -1734,36 +2367,241 @@ snapshots: '@bomb.sh/tty@0.7.0': {} + '@changesets/apply-release-plan@7.1.1': + dependencies: + '@changesets/config': 3.1.4 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.8.4 + + '@changesets/assemble-release-plan@6.0.10': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.8.4 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.31.1(@types/node@22.20.0)': + dependencies: + '@changesets/apply-release-plan': 7.1.1 + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.4 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/get-release-plan': 4.0.16 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@22.20.0) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.8.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + + '@changesets/config@3.1.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.4': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.8.4 + + '@changesets/get-release-plan@4.0.16': + dependencies: + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/config': 3.1.4 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.3': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.3.2 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.7': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.2.2 + prettier: 2.8.8 + '@emnapi/core@1.10.0': dependencies: '@emnapi/wasi-threads': 1.2.1 tslib: 2.8.1 optional: true - '@emnapi/core@1.11.1': + '@emnapi/runtime@1.10.0': dependencies: - '@emnapi/wasi-threads': 1.2.2 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.10.0': + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.11.1': - dependencies: - tslib: 2.8.1 + '@esbuild/aix-ppc64@0.28.2': optional: true - '@emnapi/wasi-threads@1.2.1': - dependencies: - tslib: 2.8.1 + '@esbuild/android-arm64@0.28.2': optional: true - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.2': optional: true '@humanfs/core@0.19.2': @@ -1780,19 +2618,37 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@jridgewell/gen-mapping@0.3.13': + '@inquirer/external-editor@1.0.3(@types/node@22.20.0)': dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 + chardet: 2.2.0 + iconv-lite: 0.7.3 + optionalDependencies: + '@types/node': 22.20.0 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/sourcemap-codec@1.6.0': {} '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.29.10 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.29.10 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 '@napi-rs/canvas-android-arm64@1.0.11': optional: true @@ -1849,12 +2705,17 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true - '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + '@nodelib/fs.scandir@2.1.5': dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@tybys/wasm-util': 0.10.2 - optional: true + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.3 '@oxc-parser/binding-android-arm-eabi@0.133.0': optional: true @@ -1925,7 +2786,7 @@ snapshots: '@oxc-project/types@0.133.0': {} - '@oxc-project/types@0.137.0': {} + '@oxc-project/types@0.155.0': {} '@oxc-resolver/binding-android-arm-eabi@11.20.0': optional: true @@ -1988,118 +2849,118 @@ snapshots: '@oxc-resolver/binding-win32-x64-msvc@11.20.0': optional: true - '@oxfmt/binding-android-arm-eabi@0.47.0': + '@oxfmt/binding-android-arm-eabi@0.74.0': optional: true - '@oxfmt/binding-android-arm64@0.47.0': + '@oxfmt/binding-android-arm64@0.74.0': optional: true - '@oxfmt/binding-darwin-arm64@0.47.0': + '@oxfmt/binding-darwin-arm64@0.74.0': optional: true - '@oxfmt/binding-darwin-x64@0.47.0': + '@oxfmt/binding-darwin-x64@0.74.0': optional: true - '@oxfmt/binding-freebsd-x64@0.47.0': + '@oxfmt/binding-freebsd-x64@0.74.0': optional: true - '@oxfmt/binding-linux-arm-gnueabihf@0.47.0': + '@oxfmt/binding-linux-arm-gnueabihf@0.74.0': optional: true - '@oxfmt/binding-linux-arm-musleabihf@0.47.0': + '@oxfmt/binding-linux-arm-musleabihf@0.74.0': optional: true - '@oxfmt/binding-linux-arm64-gnu@0.47.0': + '@oxfmt/binding-linux-arm64-gnu@0.74.0': optional: true - '@oxfmt/binding-linux-arm64-musl@0.47.0': + '@oxfmt/binding-linux-arm64-musl@0.74.0': optional: true - '@oxfmt/binding-linux-ppc64-gnu@0.47.0': + '@oxfmt/binding-linux-ppc64-gnu@0.74.0': optional: true - '@oxfmt/binding-linux-riscv64-gnu@0.47.0': + '@oxfmt/binding-linux-riscv64-gnu@0.74.0': optional: true - '@oxfmt/binding-linux-riscv64-musl@0.47.0': + '@oxfmt/binding-linux-riscv64-musl@0.74.0': optional: true - '@oxfmt/binding-linux-s390x-gnu@0.47.0': + '@oxfmt/binding-linux-s390x-gnu@0.74.0': optional: true - '@oxfmt/binding-linux-x64-gnu@0.47.0': + '@oxfmt/binding-linux-x64-gnu@0.74.0': optional: true - '@oxfmt/binding-linux-x64-musl@0.47.0': + '@oxfmt/binding-linux-x64-musl@0.74.0': optional: true - '@oxfmt/binding-openharmony-arm64@0.47.0': + '@oxfmt/binding-openharmony-arm64@0.74.0': optional: true - '@oxfmt/binding-win32-arm64-msvc@0.47.0': + '@oxfmt/binding-win32-arm64-msvc@0.74.0': optional: true - '@oxfmt/binding-win32-ia32-msvc@0.47.0': + '@oxfmt/binding-win32-ia32-msvc@0.74.0': optional: true - '@oxfmt/binding-win32-x64-msvc@0.47.0': + '@oxfmt/binding-win32-x64-msvc@0.74.0': optional: true - '@oxlint/binding-android-arm-eabi@1.69.0': + '@oxlint/binding-android-arm-eabi@1.89.0': optional: true - '@oxlint/binding-android-arm64@1.69.0': + '@oxlint/binding-android-arm64@1.89.0': optional: true - '@oxlint/binding-darwin-arm64@1.69.0': + '@oxlint/binding-darwin-arm64@1.89.0': optional: true - '@oxlint/binding-darwin-x64@1.69.0': + '@oxlint/binding-darwin-x64@1.89.0': optional: true - '@oxlint/binding-freebsd-x64@1.69.0': + '@oxlint/binding-freebsd-x64@1.89.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.69.0': + '@oxlint/binding-linux-arm-gnueabihf@1.89.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.69.0': + '@oxlint/binding-linux-arm-musleabihf@1.89.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.69.0': + '@oxlint/binding-linux-arm64-gnu@1.89.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.69.0': + '@oxlint/binding-linux-arm64-musl@1.89.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.69.0': + '@oxlint/binding-linux-ppc64-gnu@1.89.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.69.0': + '@oxlint/binding-linux-riscv64-gnu@1.89.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.69.0': + '@oxlint/binding-linux-riscv64-musl@1.89.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.69.0': + '@oxlint/binding-linux-s390x-gnu@1.89.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.69.0': + '@oxlint/binding-linux-x64-gnu@1.89.0': optional: true - '@oxlint/binding-linux-x64-musl@1.69.0': + '@oxlint/binding-linux-x64-musl@1.89.0': optional: true - '@oxlint/binding-openharmony-arm64@1.69.0': + '@oxlint/binding-openharmony-arm64@1.89.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.69.0': + '@oxlint/binding-win32-arm64-msvc@1.89.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.69.0': + '@oxlint/binding-win32-ia32-msvc@1.89.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.69.0': + '@oxlint/binding-win32-x64-msvc@1.89.0': optional: true '@publint/pack@0.1.4': {} @@ -2160,13 +3021,16 @@ snapshots: '@resvg/resvg-js-win32-x64-msvc': 2.6.2 optional: true + '@rolldown/binding-android-arm-eabi@1.2.15': + optional: true + '@rolldown/binding-android-arm64@1.0.0-rc.17': optional: true '@rolldown/binding-android-arm64@1.0.3': optional: true - '@rolldown/binding-android-arm64@1.1.2': + '@rolldown/binding-android-arm64@1.2.15': optional: true '@rolldown/binding-darwin-arm64@1.0.0-rc.17': @@ -2175,7 +3039,7 @@ snapshots: '@rolldown/binding-darwin-arm64@1.0.3': optional: true - '@rolldown/binding-darwin-arm64@1.1.2': + '@rolldown/binding-darwin-arm64@1.2.15': optional: true '@rolldown/binding-darwin-x64@1.0.0-rc.17': @@ -2184,7 +3048,7 @@ snapshots: '@rolldown/binding-darwin-x64@1.0.3': optional: true - '@rolldown/binding-darwin-x64@1.1.2': + '@rolldown/binding-darwin-x64@1.2.15': optional: true '@rolldown/binding-freebsd-x64@1.0.0-rc.17': @@ -2193,7 +3057,7 @@ snapshots: '@rolldown/binding-freebsd-x64@1.0.3': optional: true - '@rolldown/binding-freebsd-x64@1.1.2': + '@rolldown/binding-freebsd-x64@1.2.15': optional: true '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': @@ -2202,7 +3066,7 @@ snapshots: '@rolldown/binding-linux-arm-gnueabihf@1.0.3': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.1.2': + '@rolldown/binding-linux-arm-gnueabihf@1.2.15': optional: true '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': @@ -2211,7 +3075,7 @@ snapshots: '@rolldown/binding-linux-arm64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-arm64-gnu@1.1.2': + '@rolldown/binding-linux-arm64-gnu@1.2.15': optional: true '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': @@ -2220,7 +3084,7 @@ snapshots: '@rolldown/binding-linux-arm64-musl@1.0.3': optional: true - '@rolldown/binding-linux-arm64-musl@1.1.2': + '@rolldown/binding-linux-arm64-musl@1.2.15': optional: true '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': @@ -2229,7 +3093,7 @@ snapshots: '@rolldown/binding-linux-ppc64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.1.2': + '@rolldown/binding-linux-ppc64-gnu@1.2.15': optional: true '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': @@ -2238,7 +3102,7 @@ snapshots: '@rolldown/binding-linux-s390x-gnu@1.0.3': optional: true - '@rolldown/binding-linux-s390x-gnu@1.1.2': + '@rolldown/binding-linux-s390x-gnu@1.2.15': optional: true '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': @@ -2247,7 +3111,7 @@ snapshots: '@rolldown/binding-linux-x64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-x64-gnu@1.1.2': + '@rolldown/binding-linux-x64-gnu@1.2.15': optional: true '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': @@ -2256,7 +3120,7 @@ snapshots: '@rolldown/binding-linux-x64-musl@1.0.3': optional: true - '@rolldown/binding-linux-x64-musl@1.1.2': + '@rolldown/binding-linux-x64-musl@1.2.15': optional: true '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': @@ -2265,7 +3129,7 @@ snapshots: '@rolldown/binding-openharmony-arm64@1.0.3': optional: true - '@rolldown/binding-openharmony-arm64@1.1.2': + '@rolldown/binding-openharmony-arm64@1.2.15': optional: true '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': @@ -2282,20 +3146,13 @@ snapshots: '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-wasm32-wasi@1.1.2': - dependencies: - '@emnapi/core': 1.11.1 - '@emnapi/runtime': 1.11.1 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) - optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': optional: true '@rolldown/binding-win32-arm64-msvc@1.0.3': optional: true - '@rolldown/binding-win32-arm64-msvc@1.1.2': + '@rolldown/binding-win32-arm64-msvc@1.2.15': optional: true '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': @@ -2304,7 +3161,7 @@ snapshots: '@rolldown/binding-win32-x64-msvc@1.0.3': optional: true - '@rolldown/binding-win32-x64-msvc@1.1.2': + '@rolldown/binding-win32-x64-msvc@1.2.15': optional: true '@rolldown/pluginutils@1.0.0-rc.17': @@ -2312,8 +3169,6 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@standard-schema/spec@1.1.0': {} - '@termless/core@0.10.2(node-pty@1.2.0-beta.15)': optionalDependencies: '@napi-rs/canvas': 1.0.11 @@ -2325,10 +3180,10 @@ snapshots: playwright: 1.64.1 upng-js: 2.1.0 - '@termless/test@0.10.2(@termless/core@0.10.2(node-pty@1.2.0-beta.15))(playwright@1.64.1)(vitest@4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0)))': + '@termless/test@0.10.2(@termless/core@0.10.2(node-pty@1.2.0-beta.15))(playwright@1.64.1)(vitest@5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)))': dependencies: '@termless/core': 0.10.2(node-pty@1.2.0-beta.15) - vitest: 4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0)) + vitest: 5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) optionalDependencies: '@napi-rs/canvas': 1.0.11 '@resvg/resvg-js': 2.6.2 @@ -2351,119 +3206,228 @@ snapshots: '@types/estree@1.0.9': {} - '@types/jsesc@2.5.1': {} + '@types/node@12.20.55': {} '@types/node@22.20.0': dependencies: undici-types: 6.21.0 - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260623.1': + '@typescript/typescript-aix-ppc64@7.0.2': optional: true - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260623.1': + '@typescript/typescript-darwin-arm64@7.0.2': optional: true - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260623.1': + '@typescript/typescript-darwin-x64@7.0.2': optional: true - '@typescript/native-preview-linux-arm@7.0.0-dev.20260623.1': + '@typescript/typescript-freebsd-arm64@7.0.2': optional: true - '@typescript/native-preview-linux-x64@7.0.0-dev.20260623.1': + '@typescript/typescript-freebsd-x64@7.0.2': optional: true - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260623.1': + '@typescript/typescript-linux-arm64@7.0.2': optional: true - '@typescript/native-preview-win32-x64@7.0.0-dev.20260623.1': + '@typescript/typescript-linux-arm@7.0.2': optional: true - '@typescript/native-preview@7.0.0-dev.20260623.1': - optionalDependencies: - '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260623.1 - '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260623.1 - '@typescript/native-preview-linux-arm': 7.0.0-dev.20260623.1 - '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260623.1 - '@typescript/native-preview-linux-x64': 7.0.0-dev.20260623.1 - '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260623.1 - '@typescript/native-preview-win32-x64': 7.0.0-dev.20260623.1 + '@typescript/typescript-linux-loong64@7.0.2': + optional: true - '@vitest/expect@4.1.9': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 - chai: 6.2.2 - tinyrainbow: 3.1.0 + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true - '@vitest/mocker@4.1.9(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0))': + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + '@vitest/mocker@5.0.5(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1))': dependencies: - '@vitest/spy': 4.1.9 + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/spy': 5.0.5 estree-walker: 3.0.3 - magic-string: 0.30.21 + magic-string: 1.4.3 optionalDependencies: - vite: 8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0) + vite: 8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1) - '@vitest/pretty-format@4.1.9': - dependencies: - tinyrainbow: 3.1.0 + '@vitest/spy@5.0.5': {} - '@vitest/runner@4.1.9': - dependencies: - '@vitest/utils': 4.1.9 - pathe: 2.0.3 + '@yuku-core/binding-android-arm64@0.19.0': + optional: true - '@vitest/snapshot@4.1.9': - dependencies: - '@vitest/pretty-format': 4.1.9 - '@vitest/utils': 4.1.9 - magic-string: 0.30.21 - pathe: 2.0.3 + '@yuku-core/binding-darwin-arm64@0.19.0': + optional: true + + '@yuku-core/binding-darwin-x64@0.19.0': + optional: true - '@vitest/spy@4.1.9': {} + '@yuku-core/binding-freebsd-x64@0.19.0': + optional: true - '@vitest/utils@4.1.9': + '@yuku-core/binding-linux-arm-gnu@0.19.0': + optional: true + + '@yuku-core/binding-linux-arm-musl@0.19.0': + optional: true + + '@yuku-core/binding-linux-arm64-gnu@0.19.0': + optional: true + + '@yuku-core/binding-linux-arm64-musl@0.19.0': + optional: true + + '@yuku-core/binding-linux-x64-gnu@0.19.0': + optional: true + + '@yuku-core/binding-linux-x64-musl@0.19.0': + optional: true + + '@yuku-core/binding-win32-arm64@0.19.0': + optional: true + + '@yuku-core/binding-win32-x64@0.19.0': + optional: true + + '@yuku-toolchain/types@0.19.0': {} + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + argparse@1.0.10: dependencies: - '@vitest/pretty-format': 4.1.9 - convert-source-map: 2.0.0 - tinyrainbow: 3.1.0 + sprintf-js: 1.0.3 - ansis@4.3.1: {} + argparse@2.0.1: {} + + array-union@2.1.0: {} assertion-error@2.0.1: {} - ast-kit@3.0.0: + better-path-resolve@1.0.0: dependencies: - '@babel/parser': 8.0.0 - estree-walker: 3.0.3 - pathe: 2.0.3 + is-windows: 1.0.2 - birpc@4.0.0: {} + braces@3.0.3: + dependencies: + fill-range: 7.1.1 - cac@7.0.0: {} + cac@7.1.0: {} - chai@6.2.2: {} + chai@6.3.0: {} - convert-source-map@2.0.0: {} + chardet@2.2.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 defu@6.1.7: {} + detect-indent@6.1.0: {} + detect-libc@2.1.2: {} + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + dts-resolver@3.0.0(oxc-resolver@11.20.0): optionalDependencies: oxc-resolver: 11.20.0 - empathic@2.0.1: {} + empathic@2.1.0: {} + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + es-module-lexer@2.3.2: {} - es-module-lexer@2.1.0: {} + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + + esprima@4.0.1: {} estree-walker@3.0.3: dependencies: '@types/estree': 1.0.9 - expect-type@1.3.0: {} + expect-type@1.4.0: {} + + extendable-error@0.1.7: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.20.3: + dependencies: + reusify: 1.1.0 fd-package-json@2.0.0: dependencies: @@ -2473,10 +3437,31 @@ snapshots: optionalDependencies: picomatch: 4.0.4 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + formatly@0.3.0: dependencies: fd-package-json: 2.0.0 + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + fsevents@2.3.3: optional: true @@ -2484,7 +3469,7 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - get-tsconfig@5.0.0-beta.5: + get-tsconfig@5.0.0-beta.6: dependencies: resolve-pkg-maps: 1.0.0 @@ -2494,13 +3479,63 @@ snapshots: gifenc@1.0.3: optional: true - hookable@6.1.1: {} + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + graceful-fs@4.2.11: {} + + hookable@6.1.2: {} + + human-id@4.2.2: {} + + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + import-without-cache@0.4.1: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 - import-without-cache@0.4.0: {} + is-windows@1.0.2: {} + + isexe@2.0.0: {} jiti@2.7.0: {} - jsesc@3.1.0: {} + js-yaml@3.15.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.3.2: + dependencies: + argparse: 2.0.1 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 knip@6.16.1: dependencies: @@ -2515,7 +3550,7 @@ snapshots: strip-json-comments: 5.0.3 tinyglobby: 0.2.17 unbash: 3.0.0 - yaml: 2.9.0 + yaml: 2.9.1 zod: 4.4.3 lightningcss-android-arm64@1.32.0: @@ -2567,9 +3602,22 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 - magic-string@0.30.21: + locate-path@5.0.0: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + p-locate: 4.1.0 + + lodash.startcase@4.4.0: {} + + magic-string@1.4.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 mri@1.2.0: {} @@ -2581,7 +3629,9 @@ snapshots: dependencies: node-addon-api: 7.1.1 - obug@2.1.3: {} + obug@3.0.0: {} + + outdent@0.5.0: {} oxc-parser@0.133.0: dependencies: @@ -2630,63 +3680,93 @@ snapshots: '@oxc-resolver/binding-win32-arm64-msvc': 11.20.0 '@oxc-resolver/binding-win32-x64-msvc': 11.20.0 - oxfmt@0.47.0: + oxfmt@0.74.0: dependencies: - tinypool: 2.1.0 + tinypool: 2.2.0 optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.47.0 - '@oxfmt/binding-android-arm64': 0.47.0 - '@oxfmt/binding-darwin-arm64': 0.47.0 - '@oxfmt/binding-darwin-x64': 0.47.0 - '@oxfmt/binding-freebsd-x64': 0.47.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.47.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.47.0 - '@oxfmt/binding-linux-arm64-gnu': 0.47.0 - '@oxfmt/binding-linux-arm64-musl': 0.47.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.47.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.47.0 - '@oxfmt/binding-linux-riscv64-musl': 0.47.0 - '@oxfmt/binding-linux-s390x-gnu': 0.47.0 - '@oxfmt/binding-linux-x64-gnu': 0.47.0 - '@oxfmt/binding-linux-x64-musl': 0.47.0 - '@oxfmt/binding-openharmony-arm64': 0.47.0 - '@oxfmt/binding-win32-arm64-msvc': 0.47.0 - '@oxfmt/binding-win32-ia32-msvc': 0.47.0 - '@oxfmt/binding-win32-x64-msvc': 0.47.0 - - oxlint@1.69.0: + '@oxfmt/binding-android-arm-eabi': 0.74.0 + '@oxfmt/binding-android-arm64': 0.74.0 + '@oxfmt/binding-darwin-arm64': 0.74.0 + '@oxfmt/binding-darwin-x64': 0.74.0 + '@oxfmt/binding-freebsd-x64': 0.74.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.74.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.74.0 + '@oxfmt/binding-linux-arm64-gnu': 0.74.0 + '@oxfmt/binding-linux-arm64-musl': 0.74.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.74.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.74.0 + '@oxfmt/binding-linux-riscv64-musl': 0.74.0 + '@oxfmt/binding-linux-s390x-gnu': 0.74.0 + '@oxfmt/binding-linux-x64-gnu': 0.74.0 + '@oxfmt/binding-linux-x64-musl': 0.74.0 + '@oxfmt/binding-openharmony-arm64': 0.74.0 + '@oxfmt/binding-win32-arm64-msvc': 0.74.0 + '@oxfmt/binding-win32-ia32-msvc': 0.74.0 + '@oxfmt/binding-win32-x64-msvc': 0.74.0 + + oxlint@1.89.0: optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.69.0 - '@oxlint/binding-android-arm64': 1.69.0 - '@oxlint/binding-darwin-arm64': 1.69.0 - '@oxlint/binding-darwin-x64': 1.69.0 - '@oxlint/binding-freebsd-x64': 1.69.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.69.0 - '@oxlint/binding-linux-arm-musleabihf': 1.69.0 - '@oxlint/binding-linux-arm64-gnu': 1.69.0 - '@oxlint/binding-linux-arm64-musl': 1.69.0 - '@oxlint/binding-linux-ppc64-gnu': 1.69.0 - '@oxlint/binding-linux-riscv64-gnu': 1.69.0 - '@oxlint/binding-linux-riscv64-musl': 1.69.0 - '@oxlint/binding-linux-s390x-gnu': 1.69.0 - '@oxlint/binding-linux-x64-gnu': 1.69.0 - '@oxlint/binding-linux-x64-musl': 1.69.0 - '@oxlint/binding-openharmony-arm64': 1.69.0 - '@oxlint/binding-win32-arm64-msvc': 1.69.0 - '@oxlint/binding-win32-ia32-msvc': 1.69.0 - '@oxlint/binding-win32-x64-msvc': 1.69.0 + '@oxlint/binding-android-arm-eabi': 1.89.0 + '@oxlint/binding-android-arm64': 1.89.0 + '@oxlint/binding-darwin-arm64': 1.89.0 + '@oxlint/binding-darwin-x64': 1.89.0 + '@oxlint/binding-freebsd-x64': 1.89.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.89.0 + '@oxlint/binding-linux-arm-musleabihf': 1.89.0 + '@oxlint/binding-linux-arm64-gnu': 1.89.0 + '@oxlint/binding-linux-arm64-musl': 1.89.0 + '@oxlint/binding-linux-ppc64-gnu': 1.89.0 + '@oxlint/binding-linux-riscv64-gnu': 1.89.0 + '@oxlint/binding-linux-riscv64-musl': 1.89.0 + '@oxlint/binding-linux-s390x-gnu': 1.89.0 + '@oxlint/binding-linux-x64-gnu': 1.89.0 + '@oxlint/binding-linux-x64-musl': 1.89.0 + '@oxlint/binding-openharmony-arm64': 1.89.0 + '@oxlint/binding-win32-arm64-msvc': 1.89.0 + '@oxlint/binding-win32-ia32-msvc': 1.89.0 + '@oxlint/binding-win32-x64-msvc': 1.89.0 + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 package-manager-detector@1.6.0: {} pako@1.0.11: optional: true - pathe@2.0.3: {} + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-type@4.0.0: {} picocolors@1.1.1: {} + picomatch@2.3.2: {} + picomatch@4.0.4: {} + picomatch@4.0.7: {} + + pify@4.0.1: {} + playwright-core@1.64.1: optional: true @@ -2701,6 +3781,10 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + preact@11.0.1: {} + + prettier@2.8.8: {} + publint@0.3.21: dependencies: '@publint/pack': 0.1.4 @@ -2708,23 +3792,36 @@ snapshots: picocolors: 1.1.1 sade: 1.8.1 + quansync@0.2.11: {} + quansync@1.0.0: {} + queue-microtask@1.2.3: {} + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.15.2 + pify: 4.0.1 + strip-bom: 3.0.0 + + resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} - rolldown-plugin-dts@0.26.0(@typescript/native-preview@7.0.0-dev.20260623.1)(oxc-resolver@11.20.0)(rolldown@1.1.2): + reusify@1.1.0: {} + + rolldown-plugin-dts@0.28.8(oxc-resolver@11.20.0)(rolldown@1.2.15)(typescript@7.0.2): dependencies: - '@babel/generator': 8.0.0 - '@babel/helper-validator-identifier': 8.0.2 - '@babel/parser': 8.0.0 - ast-kit: 3.0.0 - birpc: 4.0.0 dts-resolver: 3.0.0(oxc-resolver@11.20.0) - get-tsconfig: 5.0.0-beta.5 - obug: 2.1.3 - rolldown: 1.1.2 + get-tsconfig: 5.0.0-beta.6 + obug: 3.0.0 + rolldown: 1.2.15 + yuku-ast: 0.19.0 + yuku-codegen: 0.19.0 + yuku-parser: 0.19.0 optionalDependencies: - '@typescript/native-preview': 7.0.0-dev.20260623.1 + typescript: 7.0.2 transitivePeerDependencies: - oxc-resolver @@ -2771,90 +3868,150 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.3 '@rolldown/binding-win32-x64-msvc': 1.0.3 - rolldown@1.1.2: + rolldown@1.2.15: dependencies: - '@oxc-project/types': 0.137.0 + '@oxc-project/types': 0.155.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.1.2 - '@rolldown/binding-darwin-arm64': 1.1.2 - '@rolldown/binding-darwin-x64': 1.1.2 - '@rolldown/binding-freebsd-x64': 1.1.2 - '@rolldown/binding-linux-arm-gnueabihf': 1.1.2 - '@rolldown/binding-linux-arm64-gnu': 1.1.2 - '@rolldown/binding-linux-arm64-musl': 1.1.2 - '@rolldown/binding-linux-ppc64-gnu': 1.1.2 - '@rolldown/binding-linux-s390x-gnu': 1.1.2 - '@rolldown/binding-linux-x64-gnu': 1.1.2 - '@rolldown/binding-linux-x64-musl': 1.1.2 - '@rolldown/binding-openharmony-arm64': 1.1.2 - '@rolldown/binding-wasm32-wasi': 1.1.2 - '@rolldown/binding-win32-arm64-msvc': 1.1.2 - '@rolldown/binding-win32-x64-msvc': 1.1.2 + '@rolldown/binding-android-arm-eabi': 1.2.15 + '@rolldown/binding-android-arm64': 1.2.15 + '@rolldown/binding-darwin-arm64': 1.2.15 + '@rolldown/binding-darwin-x64': 1.2.15 + '@rolldown/binding-freebsd-x64': 1.2.15 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.15 + '@rolldown/binding-linux-arm64-gnu': 1.2.15 + '@rolldown/binding-linux-arm64-musl': 1.2.15 + '@rolldown/binding-linux-ppc64-gnu': 1.2.15 + '@rolldown/binding-linux-s390x-gnu': 1.2.15 + '@rolldown/binding-linux-x64-gnu': 1.2.15 + '@rolldown/binding-linux-x64-musl': 1.2.15 + '@rolldown/binding-openharmony-arm64': 1.2.15 + '@rolldown/binding-win32-arm64-msvc': 1.2.15 + '@rolldown/binding-win32-x64-msvc': 1.2.15 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 sade@1.8.1: dependencies: mri: 1.2.0 + safer-buffer@2.1.2: {} + semver@7.8.4: {} - siginfo@2.0.0: {} + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@4.1.0: {} + + slash@3.0.0: {} smol-toml@1.6.1: {} source-map-js@1.2.1: {} - stackback@0.0.2: {} + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 - std-env@4.1.0: {} + sprintf-js@1.0.3: {} + + std-env@4.3.0: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: {} strip-json-comments@5.0.3: {} - tinybench@2.9.0: {} + term-size@2.2.1: {} + + tinybench@6.2.2: {} tinyexec@1.2.4: {} + tinyexec@1.3.1: {} + tinyglobby@0.2.17: dependencies: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - tinypool@2.1.0: {} + tinypool@2.2.0: {} - tinyrainbow@3.1.0: {} + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 tree-kill@1.2.2: {} - tsdown@0.22.3(@typescript/native-preview@7.0.0-dev.20260623.1)(oxc-resolver@11.20.0)(publint@0.3.21)(unrun@0.2.39): + tsdown@0.23.1(oxc-resolver@11.20.0)(publint@0.3.21)(tsx@4.23.15)(typescript@7.0.2)(unrun@0.2.39): dependencies: - ansis: 4.3.1 - cac: 7.0.0 + cac: 7.1.0 defu: 6.1.7 - empathic: 2.0.1 - hookable: 6.1.1 - import-without-cache: 0.4.0 - obug: 2.1.3 - picomatch: 4.0.4 - rolldown: 1.1.2 - rolldown-plugin-dts: 0.26.0(@typescript/native-preview@7.0.0-dev.20260623.1)(oxc-resolver@11.20.0)(rolldown@1.1.2) - semver: 7.8.4 - tinyexec: 1.2.4 + empathic: 2.1.0 + hookable: 6.1.2 + import-without-cache: 0.4.1 + obug: 3.0.0 + picomatch: 4.0.7 + rolldown: 1.2.15 + rolldown-plugin-dts: 0.28.8(oxc-resolver@11.20.0)(rolldown@1.2.15)(typescript@7.0.2) + tinyexec: 1.3.1 tinyglobby: 0.2.17 tree-kill: 1.2.2 unconfig-core: 7.5.0 + verkit: 0.5.0 optionalDependencies: publint: 0.3.21 + tsx: 4.23.15 + typescript: 7.0.2 unrun: 0.2.39 transitivePeerDependencies: - - '@ts-macro/tsc' - '@typescript/native-preview' + - '@volar/typescript' + - '@vue/language-core' - oxc-resolver - vue-tsc tslib@2.8.1: optional: true - ultramatter@0.0.4: {} + tsx@4.23.15: + dependencies: + esbuild: 0.28.2 + optionalDependencies: + fsevents: 2.3.3 + + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 unbash@3.0.0: {} @@ -2865,6 +4022,8 @@ snapshots: undici-types@6.21.0: {} + universalify@0.1.2: {} + unrun@0.2.39: dependencies: rolldown: 1.0.0-rc.17 @@ -2875,45 +4034,43 @@ snapshots: pako: 1.0.11 optional: true - vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0): + verkit@0.5.0: {} + + vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1): dependencies: lightningcss: 1.32.0 - picomatch: 4.0.4 + picomatch: 4.0.7 postcss: 8.5.15 rolldown: 1.0.3 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.0 + esbuild: 0.28.2 fsevents: 2.3.3 jiti: 2.7.0 - yaml: 2.9.0 - - vitest-ansi-serializer@0.2.1(vitest@4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0))): - dependencies: - vitest: 4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0)) - - vitest@4.1.9(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0)): - dependencies: - '@vitest/expect': 4.1.9 - '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.9 - '@vitest/runner': 4.1.9 - '@vitest/snapshot': 4.1.9 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 - es-module-lexer: 2.1.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.3 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.2.4 + tsx: 4.23.15 + yaml: 2.9.1 + + vitest-ansi-serializer@0.3.1(vitest@5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1))): + dependencies: + vitest: 5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) + + vitest@5.0.5(@types/node@22.20.0)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)): + dependencies: + '@types/chai': 5.2.3 + '@vitest/mocker': 5.0.5(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1)) + chai: 6.3.0 + es-module-lexer: 2.3.2 + expect-type: 1.4.0 + magic-string: 1.4.3 + obug: 3.0.0 + picomatch: 4.0.7 + std-env: 4.3.0 + tinybench: 6.2.2 + tinyexec: 1.3.1 tinyglobby: 0.2.17 - tinyrainbow: 3.1.0 - vite: 8.0.16(@types/node@22.20.0)(jiti@2.7.0)(yaml@2.9.0) - why-is-node-running: 2.3.0 + vite: 8.0.16(@types/node@22.20.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15)(yaml@2.9.1) + why-is-node-running: 3.2.1 optionalDependencies: '@types/node': 22.20.0 transitivePeerDependencies: @@ -2921,11 +4078,42 @@ snapshots: walk-up-path@4.0.0: {} - why-is-node-running@2.3.0: + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@3.2.1: {} + + yaml@2.9.1: {} + + yuku-ast@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 + + yuku-codegen@0.19.0: dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 + '@yuku-toolchain/types': 0.19.0 - yaml@2.9.0: {} + yuku-core@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 + optionalDependencies: + '@yuku-core/binding-android-arm64': 0.19.0 + '@yuku-core/binding-darwin-arm64': 0.19.0 + '@yuku-core/binding-darwin-x64': 0.19.0 + '@yuku-core/binding-freebsd-x64': 0.19.0 + '@yuku-core/binding-linux-arm-gnu': 0.19.0 + '@yuku-core/binding-linux-arm-musl': 0.19.0 + '@yuku-core/binding-linux-arm64-gnu': 0.19.0 + '@yuku-core/binding-linux-arm64-musl': 0.19.0 + '@yuku-core/binding-linux-x64-gnu': 0.19.0 + '@yuku-core/binding-linux-x64-musl': 0.19.0 + '@yuku-core/binding-win32-arm64': 0.19.0 + '@yuku-core/binding-win32-x64': 0.19.0 + + yuku-parser@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 + yuku-core: 0.19.0 zod@4.4.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c8fba15..b086959 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -11,6 +11,3 @@ onlyBuiltDependencies: publicHoistPattern: - oxlint - oxfmt - -patchedDependencies: - '@bomb.sh/tools@0.6.1': patches/@bomb.sh__tools@0.6.1.patch diff --git a/tsconfig.json b/tsconfig.json index 276d375..1f37c8a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,3 +1,13 @@ { - "extends": "@bomb.sh/tools/tsconfig.json" + "extends": "@bomb.sh/tools/tsconfig.json", + "compilerOptions": { + "paths": { + "@clack/ui": ["./packages/ui/src/index.ts"], + "@clack/ui-preact": ["./packages/ui-preact/src/index.ts"], + "@clack/ui-preact/jsx-runtime": ["./packages/ui-preact/src/jsx-runtime.ts"], + "@clack/ui-preact/jsx-dev-runtime": ["./packages/ui-preact/src/jsx-dev-runtime.ts"] + }, + "composite": false + }, + "include": ["*.ts"] } diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..2b6223c --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,34 @@ +import shared from '@bomb.sh/tools/test-utils/vitest.config.mjs'; +import { fileURLToPath } from 'node:url'; +import { defineConfig, mergeConfig } from 'vitest/config'; + +export default mergeConfig( + shared, + defineConfig({ + resolve: { + alias: [ + { + find: /^@clack\/ui$/, + replacement: fileURLToPath(new URL('./packages/ui/src/index.ts', import.meta.url)), + }, + { + find: /^@clack\/ui-preact$/, + replacement: fileURLToPath(new URL('./packages/ui-preact/src/index.ts', import.meta.url)), + }, + { + find: /^@clack\/ui-preact\/jsx-runtime$/, + replacement: fileURLToPath( + new URL('./packages/ui-preact/src/jsx-runtime.ts', import.meta.url), + ), + }, + { + find: /^@clack\/ui-preact\/jsx-dev-runtime$/, + replacement: fileURLToPath( + new URL('./packages/ui-preact/src/jsx-dev-runtime.ts', import.meta.url), + ), + }, + ], + }, + test: { exclude: ['**/dist/**', '**/node_modules/**'] }, + }), +);