From fb074f8a15b5858d4346735dd72f7636241e243c Mon Sep 17 00:00:00 2001 From: David-Emmanuel DIVERNOIS Date: Tue, 12 Nov 2024 19:00:59 +0100 Subject: [PATCH] Benchmarks from js-reactivity-benchmark in CI --- .github/workflows/ci.yml | 21 +- .gitignore | 3 + benchmarks/effect.ts | 33 + benchmarks/gc.ts | 6 + .../cellxBench.bench.ts | 94 ++ .../js-reactivity-benchmarks/dynamic.bench.ts | 329 +++++++ .../kairo/avoidable.bench.ts | 42 + .../kairo/broad.bench.ts | 44 + .../kairo/deep.bench.ts | 44 + .../kairo/diamond.bench.ts | 40 + .../kairo/mux.bench.ts | 37 + .../kairo/repeated.bench.ts | 44 + .../kairo/triangle.bench.ts | 57 ++ .../kairo/unstable.bench.ts | 43 + .../molBench.bench.ts | 48 + .../js-reactivity-benchmarks/sBench.bench.ts | 260 ++++++ benchmarks/jsonArrayReporter.ts | 38 + package.json | 6 +- pnpm-lock.yaml | 864 ++++++++++++------ vite.config.ts | 9 + 20 files changed, 1757 insertions(+), 305 deletions(-) create mode 100644 benchmarks/effect.ts create mode 100644 benchmarks/gc.ts create mode 100644 benchmarks/js-reactivity-benchmarks/cellxBench.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/dynamic.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/kairo/avoidable.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/kairo/broad.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/kairo/deep.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/kairo/diamond.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/kairo/mux.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/kairo/repeated.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/kairo/triangle.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/kairo/unstable.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/molBench.bench.ts create mode 100644 benchmarks/js-reactivity-benchmarks/sBench.bench.ts create mode 100644 benchmarks/jsonArrayReporter.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8a1b21..8bd6b13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,17 +10,20 @@ concurrency: group: ci-${{ github.head_ref || github.ref }} cancel-in-progress: true +permissions: + contents: write + jobs: test: name: 'Test ${{ matrix.testenv.name }}' runs-on: ubuntu-latest - timeout-minutes: 5 + timeout-minutes: 15 strategy: matrix: testenv: - {name: 'Node', args: ''} - - {name: 'Chrome', args: '--browser.name=chrome --browser.headless'} - - {name: 'Firefox', args: '--browser.name=firefox --browser.headless'} + - {name: 'Chrome', args: '--browser.provider=webdriverio --browser.name=chrome --browser.headless'} + - {name: 'Firefox', args: '--browser.provider=webdriverio --browser.name=firefox --browser.headless'} steps: - uses: actions/checkout@v4 @@ -29,3 +32,15 @@ jobs: - run: pnpm lint - run: pnpm build - run: pnpm vitest ${{ matrix.testenv.args }} + - run: pnpm vitest bench + if: matrix.testenv.name == 'Node' + - uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 #v1.20.4 + if: matrix.testenv.name == 'Node' + with: + name: Benchmarks + tool: 'customBiggerIsBetter' + output-file-path: benchmarks.json + auto-push: ${{ github.event_name == 'push' }} + github-token: ${{ secrets.GITHUB_TOKEN }} + comment-on-alert: true + summary-always: true diff --git a/.gitignore b/.gitignore index 9e344c5..508341f 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,6 @@ build dist/ *.tsbuildinfo .DS_Store + +# Benchmarks result: +benchmarks.json diff --git a/benchmarks/effect.ts b/benchmarks/effect.ts new file mode 100644 index 0000000..1f1131c --- /dev/null +++ b/benchmarks/effect.ts @@ -0,0 +1,33 @@ +import {Signal} from '../src'; + +const queue: Signal.Computed[] = []; + +export const effect = (fn: () => void) => { + const c = new Signal.Computed(fn); + const watcher = new Signal.subtle.Watcher(() => { + if (inBatch === 0) { + throw new Error('signal changed outside of batch'); + } + queue.push(c); + watcher.watch(); // re-enable watcher + }); + c.get(); + watcher.watch(c); +}; + +const processQueue = () => { + while (queue.length) { + queue.shift()!.get(); + } +}; + +let inBatch = 0; +export const batch = (fn: () => void) => { + inBatch++; + try { + fn(); + } finally { + inBatch--; + if (inBatch === 0) processQueue(); + } +}; diff --git a/benchmarks/gc.ts b/benchmarks/gc.ts new file mode 100644 index 0000000..6c9c583 --- /dev/null +++ b/benchmarks/gc.ts @@ -0,0 +1,6 @@ +const gc = globalThis.gc; +export const setup = gc + ? () => { + gc(); + } + : () => {}; diff --git a/benchmarks/js-reactivity-benchmarks/cellxBench.bench.ts b/benchmarks/js-reactivity-benchmarks/cellxBench.bench.ts new file mode 100644 index 0000000..1f04020 --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/cellxBench.bench.ts @@ -0,0 +1,94 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/cellxBench.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../src'; +import {setup} from '../gc'; +import {effect, batch} from '../effect'; + +// The following is an implementation of the cellx benchmark https://github.com/Riim/cellx/blob/master/perf/perf.html + +const cellx = ( + layers: number, + expectedBefore: readonly [number, number, number, number], + expectedAfter: readonly [number, number, number, number], +) => { + const start = { + prop1: new Signal.State(1), + prop2: new Signal.State(2), + prop3: new Signal.State(3), + prop4: new Signal.State(4), + }; + + let layer: { + prop1: Signal.Computed | Signal.State; + prop2: Signal.Computed | Signal.State; + prop3: Signal.Computed | Signal.State; + prop4: Signal.Computed | Signal.State; + } = start; + + for (let i = layers; i > 0; i--) { + const m = layer; + const s = { + prop1: new Signal.Computed(() => m.prop2.get()), + prop2: new Signal.Computed(() => m.prop1.get() - m.prop3.get()), + prop3: new Signal.Computed(() => m.prop2.get() + m.prop4.get()), + prop4: new Signal.Computed(() => m.prop3.get()), + }; + + effect(() => s.prop1.get()); + effect(() => s.prop2.get()); + effect(() => s.prop3.get()); + effect(() => s.prop4.get()); + + s.prop1.get(); + s.prop2.get(); + s.prop3.get(); + s.prop4.get(); + + layer = s; + } + + const end = layer; + + expect(end.prop1.get()).toBe(expectedBefore[0]); + expect(end.prop2.get()).toBe(expectedBefore[1]); + expect(end.prop3.get()).toBe(expectedBefore[2]); + expect(end.prop4.get()).toBe(expectedBefore[3]); + + batch(() => { + start.prop1.set(4); + start.prop2.set(3); + start.prop3.set(2); + start.prop4.set(1); + }); + + expect(end.prop1.get()).toBe(expectedAfter[0]); + expect(end.prop2.get()).toBe(expectedAfter[1]); + expect(end.prop3.get()).toBe(expectedAfter[2]); + expect(end.prop4.get()).toBe(expectedAfter[3]); +}; + +type BenchmarkResults = [ + readonly [number, number, number, number], + readonly [number, number, number, number], +]; + +const expected: Record = { + 1000: [ + [-3, -6, -2, 2], + [-2, -4, 2, 3], + ], + 2500: [ + [-3, -6, -2, 2], + [-2, -4, 2, 3], + ], + 5000: [ + [2, 4, -1, -6], + [-2, 1, -4, -4], + ], +}; + +for (const layers in expected) { + const params = expected[layers]; + bench(`cellx${layers}`, () => cellx(+layers, params[0], params[1]), {throws: true, setup}); +} diff --git a/benchmarks/js-reactivity-benchmarks/dynamic.bench.ts b/benchmarks/js-reactivity-benchmarks/dynamic.bench.ts new file mode 100644 index 0000000..5b9518f --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/dynamic.bench.ts @@ -0,0 +1,329 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/dynamicBench.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../src'; +import {setup} from '../gc'; +import {batch} from '../effect'; + +// from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/util/pseudoRandom.ts + +export function pseudoRandom(seed = 'seed'): () => number { + const hash = xmur3a(seed); + const rng = sfc32(hash(), hash(), hash(), hash()); + return rng; +} + +/* these are adapted from https://github.com/bryc/code/blob/master/jshash/PRNGs.md + * (License: Public domain) */ + +/** random number generator originally in PractRand */ +function sfc32(a: number, b: number, c: number, d: number): () => number { + return function () { + a >>>= 0; + b >>>= 0; + c >>>= 0; + d >>>= 0; + let t = (a + b) | 0; + a = b ^ (b >>> 9); + b = (c + (c << 3)) | 0; + c = (c << 21) | (c >>> 11); + d = (d + 1) | 0; + t = (t + d) | 0; + c = (c + t) | 0; + return (t >>> 0) / 4294967296; + }; +} + +/** MurmurHash3 */ +export function xmur3a(str: string): () => number { + let h = 2166136261 >>> 0; + for (let k: number, i = 0; i < str.length; i++) { + k = Math.imul(str.charCodeAt(i), 3432918353); + k = (k << 15) | (k >>> 17); + h ^= Math.imul(k, 461845907); + h = (h << 13) | (h >>> 19); + h = (Math.imul(h, 5) + 3864292196) | 0; + } + h ^= str.length; + return function () { + h ^= h >>> 16; + h = Math.imul(h, 2246822507); + h ^= h >>> 13; + h = Math.imul(h, 3266489909); + h ^= h >>> 16; + return h >>> 0; + }; +} + +// from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/util/perfTests.ts + +export interface TestResult { + sum: number; + count: number; +} + +// from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/util/frameworkTypes.ts + +interface TestConfig { + /** friendly name for the test, should be unique */ + name?: string; + + /** width of dependency graph to construct */ + width: number; + + /** depth of dependency graph to construct */ + totalLayers: number; + + /** fraction of nodes that are static */ // TODO change to dynamicFraction + staticFraction: number; + + /** construct a graph with number of sources in each node */ + nSources: number; + + /** fraction of [0, 1] elements in the last layer from which to read values in each test iteration */ + readFraction: number; + + /** number of test iterations */ + iterations: number; + + /** sum and count of all iterations, for verification */ + expected: Partial; +} + +// from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/util/dependencyGraph.ts + +interface Graph { + sources: Signal.State[]; + layers: Signal.Computed[][]; +} + +interface GraphAndCounter { + graph: Graph; + counter: Counter; +} + +/** + * Make a rectangular dependency graph, with an equal number of source elements + * and computation elements at every layer. + * + * @param width number of source elements and number of computed elements per layer + * @param totalLayers total number of source and computed layers + * @param staticFraction every nth computed node is static (1 = all static, 3 = 2/3rd are dynamic) + * @returns the graph + */ +function makeGraph(config: TestConfig): GraphAndCounter { + const {width, totalLayers, staticFraction, nSources} = config; + + const sources = new Array(width).fill(0).map((_, i) => new Signal.State(i)); + const counter = new Counter(); + const rows = makeDependentRows(sources, totalLayers - 1, counter, staticFraction, nSources); + const graph = {sources, layers: rows}; + return {graph, counter}; +} + +/** + * Execute the graph by writing one of the sources and reading some or all of the leaves. + * + * @return the sum of all leaf values + */ +function runGraph(graph: Graph, iterations: number, readFraction: number): number { + const rand = pseudoRandom(); + const {sources, layers} = graph; + const leaves = layers[layers.length - 1]; + const skipCount = Math.round(leaves.length * (1 - readFraction)); + const readLeaves = removeElems(leaves, skipCount, rand); + + for (let i = 0; i < iterations; i++) { + const sourceDex = i % sources.length; + batch(() => { + sources[sourceDex].set(i + sourceDex); + }); + for (const leaf of readLeaves) { + leaf.get(); + } + } + + const sum = readLeaves.reduce((total, leaf) => leaf.get() + total, 0); + return sum; +} + +function removeElems(src: T[], rmCount: number, rand: () => number): T[] { + const copy = src.slice(); + for (let i = 0; i < rmCount; i++) { + const rmDex = Math.floor(rand() * copy.length); + copy.splice(rmDex, 1); + } + return copy; +} + +class Counter { + count = 0; +} + +function makeDependentRows( + sources: (Signal.Computed | Signal.State)[], + numRows: number, + counter: Counter, + staticFraction: number, + nSources: number, +): Signal.Computed[][] { + let prevRow = sources; + const random = pseudoRandom(); + const rows: Signal.Computed[][] = []; + for (let l = 0; l < numRows; l++) { + const row = makeRow(prevRow, counter, staticFraction, nSources, l, random); + rows.push(row); + prevRow = row; + } + return rows; +} + +function makeRow( + sources: (Signal.Computed | Signal.State)[], + counter: Counter, + staticFraction: number, + nSources: number, + layer: number, + random: () => number, +): Signal.Computed[] { + return sources.map((_, myDex) => { + const mySources: (Signal.Computed | Signal.State)[] = []; + for (let sourceDex = 0; sourceDex < nSources; sourceDex++) { + mySources.push(sources[(myDex + sourceDex) % sources.length]); + } + + const staticNode = random() < staticFraction; + if (staticNode) { + // static node, always reference sources + return new Signal.Computed(() => { + counter.count++; + + let sum = 0; + for (const src of mySources) { + sum += src.get(); + } + return sum; + }); + } else { + // dynamic node, drops one of the sources depending on the value of the first element + const first = mySources[0]; + const tail = mySources.slice(1); + const node = new Signal.Computed(() => { + counter.count++; + let sum = first.get(); + const shouldDrop = sum & 0x1; + const dropDex = sum % tail.length; + + for (let i = 0; i < tail.length; i++) { + if (shouldDrop && i === dropDex) continue; + sum += tail[i].get(); + } + + return sum; + }); + return node; + } + }); +} + +// cf https://github.com/milomg/js-reactivity-benchmark/blob/main/src/config.ts +const perfTests = [ + { + name: 'simple component', + width: 10, // can't change for decorator tests + staticFraction: 1, // can't change for decorator tests + nSources: 2, // can't change for decorator tests + totalLayers: 5, + readFraction: 0.2, + iterations: 600000, + expected: { + sum: 19199968, + count: 3480000, + }, + }, + { + name: 'dynamic component', + width: 10, + totalLayers: 10, + staticFraction: 3 / 4, + nSources: 6, + readFraction: 0.2, + iterations: 15000, + expected: { + sum: 302310782860, + count: 1155000, + }, + }, + { + name: 'large web app', + width: 1000, + totalLayers: 12, + staticFraction: 0.95, + nSources: 4, + readFraction: 1, + iterations: 7000, + expected: { + sum: 29355933696000, + count: 1463000, + }, + }, + { + name: 'wide dense', + width: 1000, + totalLayers: 5, + staticFraction: 1, + nSources: 25, + readFraction: 1, + iterations: 3000, + expected: { + sum: 1171484375000, + count: 732000, + }, + }, + { + name: 'deep', + width: 5, + totalLayers: 500, + staticFraction: 1, + nSources: 3, + readFraction: 1, + iterations: 500, + expected: { + sum: 3.0239642676898464e241, + count: 1246500, + }, + }, + { + name: 'very dynamic', + width: 100, + totalLayers: 15, + staticFraction: 0.5, + nSources: 6, + readFraction: 1, + iterations: 2000, + expected: { + sum: 15664996402790400, + count: 1078000, + }, + }, +]; + +for (const config of perfTests) { + const {graph, counter} = makeGraph(config); + + bench( + `dynamic ${config.name}`, + () => { + counter.count = 0; + const sum = runGraph(graph, config.iterations, config.readFraction); + + if (config.expected.sum) { + expect(sum).toBe(config.expected.sum); + } + if (config.expected.count) { + expect(counter.count).toBe(config.expected.count); + } + }, + {throws: true, setup}, + ); +} diff --git a/benchmarks/js-reactivity-benchmarks/kairo/avoidable.bench.ts b/benchmarks/js-reactivity-benchmarks/kairo/avoidable.bench.ts new file mode 100644 index 0000000..9b1a7eb --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/kairo/avoidable.bench.ts @@ -0,0 +1,42 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/kairo/avoidable.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../../src'; +import {setup} from '../../gc'; +import {batch, effect} from '../../effect'; + +function busy() { + let a = 0; + for (let i = 0; i < 1_00; i++) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + a++; + } +} + +const head = new Signal.State(0); +const computed1 = new Signal.Computed(() => head.get()); +const computed2 = new Signal.Computed(() => (computed1.get(), 0)); +const computed3 = new Signal.Computed(() => (busy(), computed2.get() + 1)); // heavy computation +const computed4 = new Signal.Computed(() => computed3.get() + 2); +const computed5 = new Signal.Computed(() => computed4.get() + 3); +effect(() => { + computed5.get(); + busy(); // heavy side effect +}); + +bench( + 'avoidablePropagation', + () => { + batch(() => { + head.set(1); + }); + expect(computed5.get()).toBe(6); + for (let i = 0; i < 1000; i++) { + batch(() => { + head.set(i); + }); + expect(computed5.get()).toBe(6); + } + }, + {throws: true, setup}, +); diff --git a/benchmarks/js-reactivity-benchmarks/kairo/broad.bench.ts b/benchmarks/js-reactivity-benchmarks/kairo/broad.bench.ts new file mode 100644 index 0000000..7a239c7 --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/kairo/broad.bench.ts @@ -0,0 +1,44 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/kairo/broad.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../../src'; +import {setup} from '../../gc'; +import {batch, effect} from '../../effect'; + +const loopCount = 50; + +const head = new Signal.State(0); +let last: Signal.Computed | Signal.State = head; +let callCounter = 0; +for (let i = 0; i < loopCount; i++) { + const current = new Signal.Computed(() => { + return head.get() + i; + }); + const current2 = new Signal.Computed(() => { + return current.get() + 1; + }); + effect(() => { + current2.get(); + callCounter++; + }); + last = current2; +} + +bench( + 'broad', + () => { + batch(() => { + head.set(1); + }); + const atleast = loopCount * loopCount; + callCounter = 0; + for (let i = 0; i < loopCount; i++) { + batch(() => { + head.set(i); + }); + expect(last.get()).toBe(i + loopCount); + } + expect(callCounter).toBe(atleast); + }, + {throws: true, setup}, +); diff --git a/benchmarks/js-reactivity-benchmarks/kairo/deep.bench.ts b/benchmarks/js-reactivity-benchmarks/kairo/deep.bench.ts new file mode 100644 index 0000000..c751676 --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/kairo/deep.bench.ts @@ -0,0 +1,44 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/kairo/deep.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../../src'; +import {setup} from '../../gc'; +import {batch, effect} from '../../effect'; + +const len = 50; + +const head = new Signal.State(0); +let current: Signal.State | Signal.Computed = head; +for (let i = 0; i < len; i++) { + const c = current; + current = new Signal.Computed(() => { + return c.get() + 1; + }); +} +let callCounter = 0; + +effect(() => { + current.get(); + callCounter++; +}); + +const iter = 50; + +bench( + 'deep', + () => { + batch(() => { + head.set(1); + }); + const atleast = iter; + callCounter = 0; + for (let i = 0; i < iter; i++) { + batch(() => { + head.set(i); + }); + expect(current.get()).toBe(len + i); + } + expect(callCounter).toBe(atleast); + }, + {throws: true, setup}, +); diff --git a/benchmarks/js-reactivity-benchmarks/kairo/diamond.bench.ts b/benchmarks/js-reactivity-benchmarks/kairo/diamond.bench.ts new file mode 100644 index 0000000..d854c9f --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/kairo/diamond.bench.ts @@ -0,0 +1,40 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/kairo/diamond.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../../src'; +import {setup} from '../../gc'; +import {batch, effect} from '../../effect'; + +const width = 5; + +const head = new Signal.State(0); +const current: Signal.Computed[] = []; +for (let i = 0; i < width; i++) { + current.push(new Signal.Computed(() => head.get() + 1)); +} +const sum = new Signal.Computed(() => current.map((x) => x.get()).reduce((a, b) => a + b, 0)); +let callCounter = 0; +effect(() => { + sum.get(); + callCounter++; +}); + +bench( + 'diamond', + () => { + batch(() => { + head.set(1); + }); + expect(sum.get()).toBe(2 * width); + const atleast = 500; + callCounter = 0; + for (let i = 0; i < 500; i++) { + batch(() => { + head.set(i); + }); + expect(sum.get()).toBe((i + 1) * width); + } + expect(callCounter).toBe(atleast); + }, + {throws: true, setup}, +); diff --git a/benchmarks/js-reactivity-benchmarks/kairo/mux.bench.ts b/benchmarks/js-reactivity-benchmarks/kairo/mux.bench.ts new file mode 100644 index 0000000..27fd75b --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/kairo/mux.bench.ts @@ -0,0 +1,37 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/kairo/mux.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../../src'; +import {setup} from '../../gc'; +import {batch, effect} from '../../effect'; + +const heads = new Array(100).fill(null).map(() => new Signal.State(0)); +const mux = new Signal.Computed(() => { + return Object.fromEntries(heads.map((h) => h.get()).entries()); +}); +const splited = heads + .map((_, index) => new Signal.Computed(() => mux.get()[index])) + .map((x) => new Signal.Computed(() => x.get() + 1)); + +splited.forEach((x) => { + effect(() => x.get()); +}); + +bench( + 'mux', + () => { + for (let i = 0; i < 10; i++) { + batch(() => { + heads[i].set(i); + }); + expect(splited[i].get()).toBe(i + 1); + } + for (let i = 0; i < 10; i++) { + batch(() => { + heads[i].set(i * 2); + }); + expect(splited[i].get()).toBe(i * 2 + 1); + } + }, + {throws: true, setup}, +); diff --git a/benchmarks/js-reactivity-benchmarks/kairo/repeated.bench.ts b/benchmarks/js-reactivity-benchmarks/kairo/repeated.bench.ts new file mode 100644 index 0000000..ce078d6 --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/kairo/repeated.bench.ts @@ -0,0 +1,44 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/kairo/repeated.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../../src'; +import {setup} from '../../gc'; +import {batch, effect} from '../../effect'; + +const size = 30; + +const head = new Signal.State(0); +const current = new Signal.Computed(() => { + let result = 0; + for (let i = 0; i < size; i++) { + // tbh I think it's meanigless to be this big... + result += head.get(); + } + return result; +}); + +let callCounter = 0; +effect(() => { + current.get(); + callCounter++; +}); + +bench( + 'repeated', + () => { + batch(() => { + head.set(1); + }); + expect(current.get()).toBe(size); + const atleast = 100; + callCounter = 0; + for (let i = 0; i < 100; i++) { + batch(() => { + head.set(i); + }); + expect(current.get()).toBe(i * size); + } + expect(callCounter).toBe(atleast); + }, + {throws: true, setup}, +); diff --git a/benchmarks/js-reactivity-benchmarks/kairo/triangle.bench.ts b/benchmarks/js-reactivity-benchmarks/kairo/triangle.bench.ts new file mode 100644 index 0000000..01a03a6 --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/kairo/triangle.bench.ts @@ -0,0 +1,57 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/kairo/triangle.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../../src'; +import {setup} from '../../gc'; +import {batch, effect} from '../../effect'; + +const width = 10; + +const head = new Signal.State(0); +let current: Signal.State | Signal.Computed = head; +const list: (Signal.State | Signal.Computed)[] = []; +for (let i = 0; i < width; i++) { + const c = current; + list.push(current); + current = new Signal.Computed(() => { + return c.get() + 1; + }); +} +const sum = new Signal.Computed(() => { + return list.map((x) => x.get()).reduce((a, b) => a + b, 0); +}); + +let callCounter = 0; + +effect(() => { + sum.get(); + callCounter++; +}); + +bench( + 'triangle', + () => { + const constant = count(width); + batch(() => { + head.set(1); + }); + expect(sum.get()).toBe(constant); + const atleast = 100; + callCounter = 0; + for (let i = 0; i < 100; i++) { + batch(() => { + head.set(i); + }); + expect(sum.get()).toBe(constant - width + i * width); + } + expect(callCounter).toBe(atleast); + }, + {throws: true, setup}, +); + +function count(number: number) { + return new Array(number) + .fill(0) + .map((_, i) => i + 1) + .reduce((x, y) => x + y, 0); +} diff --git a/benchmarks/js-reactivity-benchmarks/kairo/unstable.bench.ts b/benchmarks/js-reactivity-benchmarks/kairo/unstable.bench.ts new file mode 100644 index 0000000..e8b6df4 --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/kairo/unstable.bench.ts @@ -0,0 +1,43 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/kairo/unstable.ts + +import {bench, expect} from 'vitest'; +import {Signal} from '../../../src'; +import {setup} from '../../gc'; +import {batch, effect} from '../../effect'; + +const head = new Signal.State(0); +const double = new Signal.Computed(() => head.get() * 2); +const inverse = new Signal.Computed(() => -head.get()); +const current = new Signal.Computed(() => { + let result = 0; + for (let i = 0; i < 20; i++) { + result += head.get() % 2 ? double.get() : inverse.get(); + } + return result; +}); + +let callCounter = 0; +effect(() => { + current.get(); + callCounter++; +}); + +bench( + 'unstable', + () => { + batch(() => { + head.set(1); + }); + expect(current.get()).toBe(40); + const atleast = 100; + callCounter = 0; + for (let i = 0; i < 100; i++) { + batch(() => { + head.set(i); + }); + // expect(current()).toBe(i % 2 ? i * 2 * 10 : i * -10); + } + expect(callCounter).toBe(atleast); + }, + {throws: true, setup}, +); diff --git a/benchmarks/js-reactivity-benchmarks/molBench.bench.ts b/benchmarks/js-reactivity-benchmarks/molBench.bench.ts new file mode 100644 index 0000000..f725ee4 --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/molBench.bench.ts @@ -0,0 +1,48 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/molBench.ts + +import {bench} from 'vitest'; +import {Signal} from '../../src'; +import {setup} from '../gc'; +import {batch, effect} from '../effect'; + +function fib(n: number): number { + if (n < 2) return 1; + return fib(n - 1) + fib(n - 2); +} + +function hard(n: number) { + return n + fib(16); +} + +const numbers = Array.from({length: 5}, (_, i) => i); + +const res: number[] = []; + +const A = new Signal.State(0); +const B = new Signal.State(0); +const C = new Signal.Computed(() => (A.get() % 2) + (B.get() % 2)); +const D = new Signal.Computed(() => numbers.map((i) => ({x: i + (A.get() % 2) - (B.get() % 2)}))); +const E = new Signal.Computed(() => hard(C.get() + A.get() + D.get()[0].x /*, 'E'*/)); +const F = new Signal.Computed(() => hard(D.get()[2].x || B.get() /*, 'F'*/)); +const G = new Signal.Computed(() => C.get() + (C.get() || E.get() % 2) + D.get()[4].x + F.get()); +effect(() => res.push(hard(G.get() /*, 'H'*/))); +effect(() => res.push(G.get())); +effect(() => res.push(hard(F.get() /*, 'J'*/))); + +bench( + 'molBench', + () => { + for (let i = 0; i < 1e4; i++) { + res.length = 0; + batch(() => { + B.set(1); + A.set(1 + i * 2); + }); + batch(() => { + A.set(2 + i * 2); + B.set(2); + }); + } + }, + {throws: true, setup}, +); diff --git a/benchmarks/js-reactivity-benchmarks/sBench.bench.ts b/benchmarks/js-reactivity-benchmarks/sBench.bench.ts new file mode 100644 index 0000000..eef7c64 --- /dev/null +++ b/benchmarks/js-reactivity-benchmarks/sBench.bench.ts @@ -0,0 +1,260 @@ +// adapted from https://github.com/milomg/js-reactivity-benchmark/blob/main/src/sBench.ts + +import {bench} from 'vitest'; +import {Signal} from '../../src'; +import {setup} from '../gc'; +import {batch, effect} from '../effect'; + +// Inspired by https://github.com/solidjs/solid/blob/main/packages/solid/bench/bench.cjs + +const COUNT = 1e4; + +type Reader = Signal.Computed | Signal.State; + +defineBench(onlyCreateDataSignals, COUNT, COUNT); +defineBench(createComputations0to1, COUNT, 0); +defineBench(createComputations1to1, COUNT, COUNT); +defineBench(createComputations2to1, COUNT / 2, COUNT); +defineBench(createComputations4to1, COUNT / 4, COUNT); +defineBench(createComputations1000to1, COUNT / 1000, COUNT); +// createTotal += bench(createComputations8to1, COUNT, 8 * COUNT); +defineBench(createComputations1to2, COUNT, COUNT / 2); +defineBench(createComputations1to4, COUNT, COUNT / 4); +defineBench(createComputations1to8, COUNT, COUNT / 8); +defineBench(createComputations1to1000, COUNT, COUNT / 1000); +defineBench(updateComputations1to1, COUNT * 4, 1); +defineBench(updateComputations2to1, COUNT * 2, 2); +defineBench(updateComputations4to1, COUNT, 4); +defineBench(updateComputations1000to1, COUNT / 100, 1000); +defineBench(updateComputations1to2, COUNT * 4, 1); +defineBench(updateComputations1to4, COUNT * 4, 1); +defineBench(updateComputations1to1000, COUNT * 4, 1); + +function defineBench(fn: (n: number, sources: any[]) => void, n: number, scount: number) { + bench(fn.name, () => fn(n, createDataSignals(scount, [])), {throws: true, setup}); +} + +function onlyCreateDataSignals() { + // createDataSignals is already called before +} + +function createDataSignals(n: number, sources: Signal.State[]) { + for (let i = 0; i < n; i++) { + sources[i] = new Signal.State(i); + } + return sources; +} + +function createComputations0to1(n: number /*, _sources: Signal.State[]*/) { + for (let i = 0; i < n; i++) { + createComputation0(i); + } +} + +function createComputations1to1000(n: number, sources: Signal.State[]) { + for (let i = 0; i < n / 1000; i++) { + const get = sources[i]; + for (let j = 0; j < 1000; j++) { + createComputation1(get); + } + } +} + +function createComputations1to8(n: number, sources: Signal.State[]) { + for (let i = 0; i < n / 8; i++) { + const get = sources[i]; + createComputation1(get); + createComputation1(get); + createComputation1(get); + createComputation1(get); + createComputation1(get); + createComputation1(get); + createComputation1(get); + createComputation1(get); + } +} + +function createComputations1to4(n: number, sources: Signal.State[]) { + for (let i = 0; i < n / 4; i++) { + const get = sources[i]; + createComputation1(get); + createComputation1(get); + createComputation1(get); + createComputation1(get); + } +} + +function createComputations1to2(n: number, sources: Signal.State[]) { + for (let i = 0; i < n / 2; i++) { + const get = sources[i]; + createComputation1(get); + createComputation1(get); + } +} + +function createComputations1to1(n: number, sources: Signal.State[]) { + for (let i = 0; i < n; i++) { + const get = sources[i]; + createComputation1(get); + } +} + +function createComputations2to1(n: number, sources: Signal.State[]) { + for (let i = 0; i < n; i++) { + createComputation2(sources[i * 2], sources[i * 2 + 1]); + } +} + +function createComputations4to1(n: number, sources: Signal.State[]) { + for (let i = 0; i < n; i++) { + createComputation4(sources[i * 4], sources[i * 4 + 1], sources[i * 4 + 2], sources[i * 4 + 3]); + } +} + +// function createComputations8to1(n: number, sources: Signal.State[]) { +// for (let i = 0; i < n; i++) { +// createComputation8( +// sources[i * 8], +// sources[i * 8 + 1], +// sources[i * 8 + 2], +// sources[i * 8 + 3], +// sources[i * 8 + 4], +// sources[i * 8 + 5], +// sources[i * 8 + 6], +// sources[i * 8 + 7] +// ); +// } +// } + +// only create n / 100 computations, as otherwise takes too long +function createComputations1000to1(n: number, sources: Signal.State[]) { + for (let i = 0; i < n; i++) { + createComputation1000(sources, i * 1000); + } +} + +function createComputation0(i: number) { + effect(() => i); +} + +function createComputation1(s1: Reader) { + effect(() => s1.get()); +} +function createComputation2(s1: Reader, s2: Reader) { + effect(() => s1.get() + s2.get()); +} + +function createComputation4(s1: Reader, s2: Reader, s3: Reader, s4: Reader) { + effect(() => s1.get() + s2.get() + s3.get() + s4.get()); +} + +// function createComputation8( +// s1: Reader, +// s2: Reader, +// s3: Reader, +// s4: Reader, +// s5: Reader, +// s6: Reader, +// s7: Reader, +// s8: Reader +// ) { +// computed( +// () => s1() + s2() + s3() + s4() + s5() + s6() + s7() + s8() +// ); +// } + +function createComputation1000(ss: Signal.State[], offset: number) { + effect(() => { + let sum = 0; + for (let i = 0; i < 1000; i++) { + sum += ss[offset + i].get(); + } + return sum; + }); +} + +function updateComputations1to1(n: number, sources: Signal.State[]) { + const s1 = sources[0]; + effect(() => s1.get()); + for (let i = 0; i < n; i++) { + batch(() => { + s1.set(i); + }); + } +} + +function updateComputations2to1(n: number, sources: Signal.State[]) { + const s1 = sources[0], + s2 = sources[1]; + effect(() => s1.get() + s2.get()); + for (let i = 0; i < n; i++) { + batch(() => { + s1.set(i); + }); + } +} + +function updateComputations4to1(n: number, sources: Signal.State[]) { + const s1 = sources[0], + s2 = sources[1], + s3 = sources[2], + s4 = sources[3]; + effect(() => s1.get() + s2.get() + s3.get() + s4.get()); + for (let i = 0; i < n; i++) { + batch(() => { + s1.set(i); + }); + } +} + +function updateComputations1000to1(n: number, sources: Signal.State[]) { + const s1 = sources[0]; + effect(() => { + let sum = 0; + for (let i = 0; i < 1000; i++) { + sum += sources[i].get(); + } + return sum; + }); + for (let i = 0; i < n; i++) { + batch(() => { + s1.set(i); + }); + } +} + +function updateComputations1to2(n: number, sources: Signal.State[]) { + const s1 = sources[0]; + effect(() => s1.get()); + effect(() => s1.get()); + for (let i = 0; i < n / 2; i++) { + batch(() => { + s1.set(i); + }); + } +} + +function updateComputations1to4(n: number, sources: Signal.State[]) { + const s1 = sources[0]; + effect(() => s1.get()); + effect(() => s1.get()); + effect(() => s1.get()); + effect(() => s1.get()); + for (let i = 0; i < n / 4; i++) { + batch(() => { + s1.set(i); + }); + } +} + +function updateComputations1to1000(n: number, sources: Signal.State[]) { + const s1 = sources[0]; + for (let i = 0; i < 1000; i++) { + effect(() => s1.get()); + } + for (let i = 0; i < n / 1000; i++) { + batch(() => { + s1.set(i); + }); + } +} diff --git a/benchmarks/jsonArrayReporter.ts b/benchmarks/jsonArrayReporter.ts new file mode 100644 index 0000000..5ca4f69 --- /dev/null +++ b/benchmarks/jsonArrayReporter.ts @@ -0,0 +1,38 @@ +import type {RunnerTestFile} from 'vitest'; +import type {Reporter} from 'vitest/reporters'; +import {writeFile} from 'fs/promises'; + +class JsonArrayReporter implements Reporter { + async onFinished(files: RunnerTestFile[]): Promise { + const results: { + name: string; + unit: string; + value: number; + }[] = []; + + function processTasks(tasks: RunnerTestFile['tasks'], name: string) { + for (const task of tasks) { + if (task.type === 'suite') { + processTasks(task.tasks, `${name} > ${task.name}`); + } else { + const value = task.result?.benchmark?.hz; + if (value) { + results.push({ + name: `${name} > ${task.name}`, + unit: 'Hz', + value, + }); + } + } + } + } + + for (const file of files) { + processTasks(file.tasks, file.name); + } + + await writeFile('benchmarks.json', JSON.stringify(results, null, ' ')); + } +} + +export default JsonArrayReporter; diff --git a/package.json b/package.json index 137cfd7..724c190 100644 --- a/package.json +++ b/package.json @@ -26,17 +26,17 @@ }, "devDependencies": { "@types/node": "^20.11.25", - "@vitest/browser": "^1.5.3", + "@vitest/browser": "^2.1.4", "prettier": "^3.2.5", "release-plan": "^0.9.0", "typescript": "latest", "vite": "^5.2.6", "vite-plugin-dts": "^3.7.3", - "vitest": "^1.4.0", + "vitest": "^2.1.4", "webdriverio": "^8.36.1" }, "volta": { - "node": "22.0.0", + "node": "22.11.0", "pnpm": "9.0.6" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 87e3f01..e1edf5f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^20.11.25 version: 20.12.6 '@vitest/browser': - specifier: ^1.5.3 - version: 1.5.3(vitest@1.4.0)(webdriverio@8.36.1(encoding@0.1.13)(typescript@5.4.4)) + specifier: ^2.1.4 + version: 2.1.4(@types/node@20.12.6)(typescript@5.4.4)(vite@5.2.8(@types/node@20.12.6))(vitest@2.1.4)(webdriverio@8.36.1(encoding@0.1.13)(typescript@5.4.4)) prettier: specifier: ^3.2.5 version: 3.2.5 @@ -30,14 +30,18 @@ importers: specifier: ^3.7.3 version: 3.8.1(@types/node@20.12.6)(rollup@4.14.1)(typescript@5.4.4)(vite@5.2.8(@types/node@20.12.6)) vitest: - specifier: ^1.4.0 - version: 1.4.0(@types/node@20.12.6)(@vitest/browser@1.5.3) + specifier: ^2.1.4 + version: 2.1.4(@types/node@20.12.6)(@vitest/browser@2.1.4)(msw@2.6.4(@types/node@20.12.6)(typescript@5.4.4)) webdriverio: specifier: ^8.36.1 version: 8.36.1(encoding@0.1.13)(typescript@5.4.4) packages: + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.24.1': resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} engines: {node: '>=6.9.0'} @@ -46,15 +50,32 @@ packages: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.24.4': resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + '@babel/types@7.24.0': resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} + '@bundled-es-modules/cookie@2.0.1': + resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} + + '@bundled-es-modules/statuses@1.0.1': + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + + '@bundled-es-modules/tough-cookie@0.1.6': + resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + '@esbuild/aix-ppc64@0.20.2': resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} engines: {node: '>=12'} @@ -196,17 +217,36 @@ packages: '@gar/promisify@1.1.3': resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + '@inquirer/confirm@5.0.2': + resolution: {integrity: sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + + '@inquirer/core@10.1.0': + resolution: {integrity: sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.8': + resolution: {integrity: sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==} + engines: {node: '>=18'} + + '@inquirer/type@3.0.1': + resolution: {integrity: sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@manypkg/find-root@2.2.1': resolution: {integrity: sha512-34NlypD5mmTY65cFAK7QPgY5Tzt0qXR4ZRXdg97xAlkiLuwXUPBEXy5Hsqzd+7S2acsLxUz6Cs50rlDZQr4xUA==} engines: {node: '>=14.18.0'} @@ -232,6 +272,10 @@ packages: '@microsoft/tsdoc@0.14.2': resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + '@mswjs/interceptors@0.36.10': + resolution: {integrity: sha512-GXrJgakgJW3DWKueebkvtYgGKkxA7s0u5B0P5syJM5rvQUnrpLPigvci8Hukl7yEM+sU06l+er2Fgvx/gmiRgg==} + engines: {node: '>=18'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -321,6 +365,15 @@ packages: '@octokit/types@9.3.2': resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -452,9 +505,6 @@ packages: '@rushstack/ts-command-line@4.19.1': resolution: {integrity: sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==} - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@sindresorhus/is@0.14.0': resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} engines: {node: '>=6'} @@ -471,6 +521,16 @@ packages: resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/user-event@14.5.2': + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + '@tootallnate/once@1.1.2': resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} @@ -481,6 +541,12 @@ packages: '@types/argparse@1.0.38': resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -505,6 +571,12 @@ packages: '@types/semver@7.5.8': resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + '@types/statuses@2.0.5': + resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/which@2.0.2': resolution: {integrity: sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==} @@ -520,12 +592,12 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@vitest/browser@1.5.3': - resolution: {integrity: sha512-75XHo+qzbTqvb7kvOCZt4EAphugo8HbeepqcXLWqQiNCYd/PkBWzPu5pSptGVt86WDd8DUVybyq/nGVY1XfWZA==} + '@vitest/browser@2.1.4': + resolution: {integrity: sha512-89SrvShW6kWzmEYtBj5k1gBq88emoC2qrngw5hE1vNpRFteQ5/1URbKIVww391rIALTpzhhCt5yJt5tjLPZxYw==} peerDependencies: playwright: '*' safaridriver: '*' - vitest: 1.5.3 + vitest: 2.1.4 webdriverio: '*' peerDependenciesMeta: playwright: @@ -535,23 +607,34 @@ packages: webdriverio: optional: true - '@vitest/expect@1.4.0': - resolution: {integrity: sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==} + '@vitest/expect@2.1.4': + resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} + + '@vitest/mocker@2.1.4': + resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true - '@vitest/runner@1.4.0': - resolution: {integrity: sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==} + '@vitest/pretty-format@2.1.4': + resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} - '@vitest/snapshot@1.4.0': - resolution: {integrity: sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==} + '@vitest/runner@2.1.4': + resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} - '@vitest/spy@1.4.0': - resolution: {integrity: sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==} + '@vitest/snapshot@2.1.4': + resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} - '@vitest/utils@1.4.0': - resolution: {integrity: sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==} + '@vitest/spy@2.1.4': + resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} - '@vitest/utils@1.5.3': - resolution: {integrity: sha512-rE9DTN1BRhzkzqNQO+kw8ZgfeEBCLXiHJwetk668shmNBpSagQxneT5eSqEBLP+cqSiAeecvQmbpFfdMyLcIQA==} + '@vitest/utils@2.1.4': + resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} '@volar/language-core@1.11.1': resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} @@ -606,15 +689,6 @@ packages: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -634,6 +708,10 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -681,8 +759,9 @@ packages: assert-never@1.2.1: resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} ast-types@0.13.4: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} @@ -772,9 +851,9 @@ packages: resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} engines: {node: '>=8'} - chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} - engines: {node: '>=4'} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -784,8 +863,9 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} @@ -805,6 +885,10 @@ packages: engines: {node: '>=8.0.0', npm: '>=5.0.0'} hasBin: true + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -836,6 +920,10 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -881,6 +969,15 @@ packages: supports-color: optional: true + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize@6.0.0: resolution: {integrity: sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -893,8 +990,8 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} - deep-eql@4.1.3: - resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} deep-extend@0.6.0: @@ -929,14 +1026,13 @@ packages: devtools-protocol@0.0.1282316: resolution: {integrity: sha512-i7eIqWdVxeXBY/M+v83yRkOV1sTHnr3XYiC0YNBivLIE6hBfE2H0c2o8VC5ynT44yjy+Ei0kLrBQFK/RUKaAHQ==} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + duplexer2@0.1.4: resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} @@ -1022,9 +1118,9 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} @@ -1121,9 +1217,6 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - get-port@7.1.0: resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} engines: {node: '>=16'} @@ -1140,10 +1233,6 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - get-uri@6.0.3: resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} engines: {node: '>= 14'} @@ -1183,6 +1272,10 @@ packages: grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + graphql@16.9.0: + resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1195,6 +1288,9 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} @@ -1237,10 +1333,6 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} @@ -1304,6 +1396,9 @@ packages: is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -1320,10 +1415,6 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -1341,8 +1432,8 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - js-tokens@9.0.0: - resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} @@ -1368,9 +1459,6 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - jsonc-parser@3.2.1: - resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} - jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -1398,10 +1486,6 @@ packages: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} engines: {node: '>= 0.6.3'} - local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} - locate-app@2.4.11: resolution: {integrity: sha512-PS3s33TwvMte9SEWAMtZglr7hrgnEqivajB/zaaQ4u0xOYVtzerPSjSZqNsyMPycJyfJG30c5lpjoJsxvo835g==} @@ -1431,8 +1515,8 @@ packages: resolution: {integrity: sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==} engines: {node: '>= 0.6.0'} - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} lowercase-keys@1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} @@ -1458,6 +1542,13 @@ packages: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + magic-string@0.30.9: resolution: {integrity: sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==} engines: {node: '>=12'} @@ -1481,10 +1572,6 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -1565,9 +1652,6 @@ packages: engines: {node: '>=10'} hasBin: true - mlly@1.6.1: - resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} - moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} @@ -1578,9 +1662,26 @@ packages: ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msw@2.6.4: + resolution: {integrity: sha512-Pm4LmWQeytDsNCR+A7gt39XAdtH6zQb6jnIKRig0FlvYOn8eksn3s1nXxUfz5KYUjbckof7Z4p2ewzgffPoCbg==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + muggle-string@0.3.1: resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -1650,10 +1751,6 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1665,9 +1762,8 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} p-cancelable@1.1.0: resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} @@ -1681,10 +1777,6 @@ packages: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} - p-limit@5.0.0: - resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} - engines: {node: '>=18'} - p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -1740,10 +1832,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -1751,6 +1839,9 @@ packages: resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} engines: {node: '>=16 || 14 >=14.17'} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -1758,8 +1849,9 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} @@ -1775,9 +1867,6 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pkg-types@1.0.3: - resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} - postcss@8.4.38: resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} engines: {node: ^10 || ^12 || >=14} @@ -1796,9 +1885,9 @@ packages: engines: {node: '>=14'} hasBin: true - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} proc-log@4.2.0: resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} @@ -1838,6 +1927,9 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + psl@1.10.0: + resolution: {integrity: sha512-KSKHEbjAnpUuAUserOq0FxGXCUrzC3WniuSJhvdbs102rL55266ZcHBqLWOsG30spQMlPdpy7icATiAQehg/iA==} + pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -1857,6 +1949,9 @@ packages: query-selector-shadow-dom@1.0.1: resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -1871,8 +1966,8 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} @@ -1888,6 +1983,9 @@ packages: readdir-glob@1.1.3: resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + registry-auth-token@4.2.2: resolution: {integrity: sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==} engines: {node: '>=6.0.0'} @@ -1904,6 +2002,9 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -1999,9 +2100,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - sirv@2.0.4: - resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} - engines: {node: '>= 10'} + sirv@3.0.0: + resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} + engines: {node: '>=18'} slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} @@ -2063,12 +2164,19 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} streamx@2.16.1: resolution: {integrity: sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==} + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -2103,10 +2211,6 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -2115,9 +2219,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@2.1.0: - resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2153,15 +2254,22 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - tinybench@2.6.0: - resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinypool@0.8.3: - resolution: {integrity: sha512-Ud7uepAklqRH1bvwy22ynrliC7Dljz7Tm8M/0RBUW+YRa4YHhZ6e4PpgE+fu1zr/WqB1kbeuVrdfeuyIBpy4tw==} + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinypool@1.0.1: + resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} engines: {node: '>=14.0.0'} - tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} to-fast-properties@2.0.0: @@ -2180,15 +2288,19 @@ packages: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} type-fest@2.13.0: resolution: {integrity: sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==} @@ -2198,6 +2310,10 @@ packages: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} + type-fest@4.26.1: + resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} + engines: {node: '>=16'} + typescript@5.4.2: resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} engines: {node: '>=14.17'} @@ -2208,9 +2324,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - ufo@1.5.3: - resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} @@ -2230,6 +2343,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -2244,6 +2361,9 @@ packages: resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} engines: {node: '>=4'} + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + userhome@1.0.0: resolution: {integrity: sha512-ayFKY3H+Pwfy4W98yPdtH1VqH4psDeyW8lYYFzfecR9d6hqLpqhecktvYR3SEEXt7vG0S1JEpciI3g94pMErig==} engines: {node: '>= 0.8.0'} @@ -2262,8 +2382,8 @@ packages: resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} engines: {node: '>= 0.10'} - vite-node@1.4.0: - resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} + vite-node@2.1.4: + resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -2305,15 +2425,15 @@ packages: terser: optional: true - vitest@1.4.0: - resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==} + vitest@2.1.4: + resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 1.4.0 - '@vitest/ui': 1.4.0 + '@vitest/browser': 2.1.4 + '@vitest/ui': 2.1.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -2377,11 +2497,15 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true - why-is-node-running@2.2.2: - resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} hasBin: true + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2417,6 +2541,18 @@ packages: utf-8-validate: optional: true + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -2447,9 +2583,9 @@ packages: yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} z-schema@5.0.5: resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} @@ -2462,20 +2598,45 @@ packages: snapshots: + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.0.0 + '@babel/helper-string-parser@7.24.1': {} '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/parser@7.24.4': dependencies: '@babel/types': 7.24.0 + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/types@7.24.0': dependencies: '@babel/helper-string-parser': 7.24.1 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + '@bundled-es-modules/cookie@2.0.1': + dependencies: + cookie: 0.7.2 + + '@bundled-es-modules/statuses@1.0.1': + dependencies: + statuses: 2.0.1 + + '@bundled-es-modules/tough-cookie@0.1.6': + dependencies: + '@types/tough-cookie': 4.0.5 + tough-cookie: 4.1.4 + '@esbuild/aix-ppc64@0.20.2': optional: true @@ -2547,6 +2708,32 @@ snapshots: '@gar/promisify@1.1.3': {} + '@inquirer/confirm@5.0.2(@types/node@20.12.6)': + dependencies: + '@inquirer/core': 10.1.0(@types/node@20.12.6) + '@inquirer/type': 3.0.1(@types/node@20.12.6) + '@types/node': 20.12.6 + + '@inquirer/core@10.1.0(@types/node@20.12.6)': + dependencies: + '@inquirer/figures': 1.0.8 + '@inquirer/type': 3.0.1(@types/node@20.12.6) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + transitivePeerDependencies: + - '@types/node' + + '@inquirer/figures@1.0.8': {} + + '@inquirer/type@3.0.1(@types/node@20.12.6)': + dependencies: + '@types/node': 20.12.6 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -2556,12 +2743,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@manypkg/find-root@2.2.1': dependencies: '@manypkg/tools': 1.1.0 @@ -2615,6 +2800,15 @@ snapshots: '@microsoft/tsdoc@0.14.2': {} + '@mswjs/interceptors@0.36.10': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2747,6 +2941,15 @@ snapshots: dependencies: '@octokit/openapi-types': 18.1.1 + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + '@pkgjs/parseargs@0.11.0': optional: true @@ -2869,8 +3072,6 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@sinclair/typebox@0.27.8': {} - '@sindresorhus/is@0.14.0': {} '@sindresorhus/is@5.6.0': {} @@ -2883,12 +3084,31 @@ snapshots: dependencies: defer-to-connect: 2.0.1 + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.26.0 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + '@tootallnate/once@1.1.2': {} '@tootallnate/quickjs-emscripten@0.23.0': {} '@types/argparse@1.0.38': {} + '@types/aria-query@5.0.4': {} + + '@types/cookie@0.6.0': {} + '@types/estree@1.0.5': {} '@types/fs-extra@9.0.13': @@ -2913,6 +3133,10 @@ snapshots: '@types/semver@7.5.8': {} + '@types/statuses@2.0.5': {} + + '@types/tough-cookie@4.0.5': {} + '@types/which@2.0.2': {} '@types/ws@8.5.10': @@ -2930,50 +3154,67 @@ snapshots: '@types/node': 20.12.6 optional: true - '@vitest/browser@1.5.3(vitest@1.4.0)(webdriverio@8.36.1(encoding@0.1.13)(typescript@5.4.4))': - dependencies: - '@vitest/utils': 1.5.3 - magic-string: 0.30.9 - sirv: 2.0.4 - vitest: 1.4.0(@types/node@20.12.6)(@vitest/browser@1.5.3) + '@vitest/browser@2.1.4(@types/node@20.12.6)(typescript@5.4.4)(vite@5.2.8(@types/node@20.12.6))(vitest@2.1.4)(webdriverio@8.36.1(encoding@0.1.13)(typescript@5.4.4))': + dependencies: + '@testing-library/dom': 10.4.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/mocker': 2.1.4(msw@2.6.4(@types/node@20.12.6)(typescript@5.4.4))(vite@5.2.8(@types/node@20.12.6)) + '@vitest/utils': 2.1.4 + magic-string: 0.30.12 + msw: 2.6.4(@types/node@20.12.6)(typescript@5.4.4) + sirv: 3.0.0 + tinyrainbow: 1.2.0 + vitest: 2.1.4(@types/node@20.12.6)(@vitest/browser@2.1.4)(msw@2.6.4(@types/node@20.12.6)(typescript@5.4.4)) + ws: 8.18.0 optionalDependencies: webdriverio: 8.36.1(encoding@0.1.13)(typescript@5.4.4) + transitivePeerDependencies: + - '@types/node' + - bufferutil + - typescript + - utf-8-validate + - vite - '@vitest/expect@1.4.0': + '@vitest/expect@2.1.4': dependencies: - '@vitest/spy': 1.4.0 - '@vitest/utils': 1.4.0 - chai: 4.4.1 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + tinyrainbow: 1.2.0 - '@vitest/runner@1.4.0': + '@vitest/mocker@2.1.4(msw@2.6.4(@types/node@20.12.6)(typescript@5.4.4))(vite@5.2.8(@types/node@20.12.6))': dependencies: - '@vitest/utils': 1.4.0 - p-limit: 5.0.0 - pathe: 1.1.2 + '@vitest/spy': 2.1.4 + estree-walker: 3.0.3 + magic-string: 0.30.12 + optionalDependencies: + msw: 2.6.4(@types/node@20.12.6)(typescript@5.4.4) + vite: 5.2.8(@types/node@20.12.6) - '@vitest/snapshot@1.4.0': + '@vitest/pretty-format@2.1.4': dependencies: - magic-string: 0.30.9 + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.4': + dependencies: + '@vitest/utils': 2.1.4 pathe: 1.1.2 - pretty-format: 29.7.0 - '@vitest/spy@1.4.0': + '@vitest/snapshot@2.1.4': dependencies: - tinyspy: 2.2.1 + '@vitest/pretty-format': 2.1.4 + magic-string: 0.30.12 + pathe: 1.1.2 - '@vitest/utils@1.4.0': + '@vitest/spy@2.1.4': dependencies: - diff-sequences: 29.6.3 - estree-walker: 3.0.3 - loupe: 2.3.7 - pretty-format: 29.7.0 + tinyspy: 3.0.2 - '@vitest/utils@1.5.3': + '@vitest/utils@2.1.4': dependencies: - diff-sequences: 29.6.3 - estree-walker: 3.0.3 - loupe: 2.3.7 - pretty-format: 29.7.0 + '@vitest/pretty-format': 2.1.4 + loupe: 3.1.2 + tinyrainbow: 1.2.0 '@volar/language-core@1.11.1': dependencies: @@ -3068,10 +3309,6 @@ snapshots: dependencies: event-target-shim: 5.0.1 - acorn-walk@8.3.2: {} - - acorn@8.11.3: {} - agent-base@6.0.2: dependencies: debug: 4.3.4 @@ -3100,6 +3337,10 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + ansi-regex@5.0.1: {} ansi-regex@6.0.1: {} @@ -3148,7 +3389,7 @@ snapshots: assert-never@1.2.1: {} - assertion-error@1.1.0: {} + assertion-error@2.0.1: {} ast-types@0.13.4: dependencies: @@ -3267,15 +3508,13 @@ snapshots: normalize-url: 4.5.1 responselike: 1.0.2 - chai@4.4.1: + chai@5.1.2: dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 chalk@4.1.2: dependencies: @@ -3284,9 +3523,7 @@ snapshots: chalk@5.3.0: {} - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 + check-error@2.1.1: {} chownr@2.0.0: {} @@ -3306,6 +3543,8 @@ snapshots: parse5-htmlparser2-tree-adapter: 6.0.1 yargs: 16.2.0 + cli-width@4.1.0: {} + cliui@7.0.4: dependencies: string-width: 4.2.3 @@ -3342,6 +3581,8 @@ snapshots: concat-map@0.0.1: {} + cookie@0.7.2: {} + core-util-is@1.0.3: {} crc-32@1.2.2: {} @@ -3377,6 +3618,10 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.3.7: + dependencies: + ms: 2.1.3 + decamelize@6.0.0: {} decompress-response@3.3.0: @@ -3387,9 +3632,7 @@ snapshots: dependencies: mimic-response: 3.1.0 - deep-eql@4.1.3: - dependencies: - type-detect: 4.0.8 + deep-eql@5.0.2: {} deep-extend@0.6.0: {} @@ -3413,12 +3656,12 @@ snapshots: devtools-protocol@0.0.1282316: {} - diff-sequences@29.6.3: {} - dir-glob@3.0.1: dependencies: path-type: 4.0.0 + dom-accessibility-api@0.5.16: {} + duplexer2@0.1.4: dependencies: readable-stream: 2.3.8 @@ -3534,17 +3777,7 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - execa@8.0.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 + expect-type@1.1.0: {} extract-zip@2.0.1: dependencies: @@ -3662,8 +3895,6 @@ snapshots: get-caller-file@2.0.5: {} - get-func-name@2.0.2: {} - get-port@7.1.0: {} get-stream@4.1.0: @@ -3676,8 +3907,6 @@ snapshots: get-stream@6.0.1: {} - get-stream@8.0.1: {} - get-uri@6.0.3: dependencies: basic-ftp: 5.0.5 @@ -3766,6 +3995,8 @@ snapshots: grapheme-splitter@1.0.4: {} + graphql@16.9.0: {} + has-flag@4.0.0: {} hasown@2.0.2: @@ -3774,6 +4005,8 @@ snapshots: he@1.2.0: {} + headers-polyfill@4.0.3: {} + highlight.js@10.7.3: {} hosted-git-info@4.1.0: @@ -3824,8 +4057,6 @@ snapshots: human-signals@2.1.0: {} - human-signals@5.0.0: {} - humanize-ms@1.2.1: dependencies: ms: 2.1.2 @@ -3877,6 +4108,8 @@ snapshots: is-lambda@1.0.1: {} + is-node-process@1.2.0: {} + is-number@7.0.0: {} is-plain-obj@4.1.0: {} @@ -3885,8 +4118,6 @@ snapshots: is-stream@2.0.1: {} - is-stream@3.0.0: {} - isarray@1.0.0: {} isexe@2.0.0: {} @@ -3901,7 +4132,7 @@ snapshots: jju@1.4.0: {} - js-tokens@9.0.0: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: dependencies: @@ -3922,8 +4153,6 @@ snapshots: json-schema-traverse@0.4.1: {} - jsonc-parser@3.2.1: {} - jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -3954,11 +4183,6 @@ snapshots: dependencies: readable-stream: 2.3.8 - local-pkg@0.5.0: - dependencies: - mlly: 1.6.1 - pkg-types: 1.0.3 - locate-app@2.4.11: dependencies: '@promptbook/utils': 0.45.0 @@ -3983,9 +4207,7 @@ snapshots: loglevel@1.9.1: {} - loupe@2.3.7: - dependencies: - get-func-name: 2.0.2 + loupe@3.1.2: {} lowercase-keys@1.0.1: {} @@ -4001,6 +4223,12 @@ snapshots: lru-cache@7.18.3: {} + lz-string@1.5.0: {} + + magic-string@0.30.12: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + magic-string@0.30.9: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -4038,8 +4266,6 @@ snapshots: mimic-fn@2.1.0: {} - mimic-fn@4.0.0: {} - mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -4111,21 +4337,43 @@ snapshots: mkdirp@1.0.4: {} - mlly@1.6.1: - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.0.3 - ufo: 1.5.3 - moment@2.30.1: {} mrmime@2.0.0: {} ms@2.1.2: {} + ms@2.1.3: {} + + msw@2.6.4(@types/node@20.12.6)(typescript@5.4.4): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.0.2(@types/node@20.12.6) + '@mswjs/interceptors': 0.36.10 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + chalk: 4.1.2 + graphql: 16.9.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + strict-event-emitter: 0.5.1 + type-fest: 4.26.1 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.4.4 + transitivePeerDependencies: + - '@types/node' + muggle-string@0.3.1: {} + mute-stream@2.0.0: {} + mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -4189,10 +4437,6 @@ snapshots: dependencies: path-key: 3.1.1 - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - object-assign@4.1.1: {} once@1.4.0: @@ -4203,9 +4447,7 @@ snapshots: dependencies: mimic-fn: 2.1.0 - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 + outvariant@1.4.3: {} p-cancelable@1.1.0: {} @@ -4215,10 +4457,6 @@ snapshots: dependencies: p-try: 2.2.0 - p-limit@5.0.0: - dependencies: - yocto-queue: 1.0.0 - p-locate@4.1.0: dependencies: p-limit: 2.3.0 @@ -4276,8 +4514,6 @@ snapshots: path-key@3.1.1: {} - path-key@4.0.0: {} - path-parse@1.0.7: {} path-scurry@1.10.2: @@ -4285,11 +4521,13 @@ snapshots: lru-cache: 10.2.2 minipass: 7.0.4 + path-to-regexp@6.3.0: {} + path-type@4.0.0: {} pathe@1.1.2: {} - pathval@1.1.1: {} + pathval@2.0.0: {} pend@1.2.0: {} @@ -4299,12 +4537,6 @@ snapshots: pify@4.0.1: {} - pkg-types@1.0.3: - dependencies: - jsonc-parser: 3.2.1 - mlly: 1.6.1 - pathe: 1.1.2 - postcss@8.4.38: dependencies: nanoid: 3.3.7 @@ -4317,11 +4549,11 @@ snapshots: prettier@3.2.5: {} - pretty-format@29.7.0: + pretty-format@27.5.1: dependencies: - '@jest/schemas': 29.6.3 + ansi-regex: 5.0.1 ansi-styles: 5.2.0 - react-is: 18.2.0 + react-is: 17.0.2 proc-log@4.2.0: {} @@ -4366,6 +4598,10 @@ snapshots: proxy-from-env@1.1.0: {} + psl@1.10.0: + dependencies: + punycode: 2.3.1 + pump@3.0.0: dependencies: end-of-stream: 1.4.4 @@ -4391,6 +4627,8 @@ snapshots: query-selector-shadow-dom@1.0.1: {} + querystringify@2.2.0: {} + queue-microtask@1.2.3: {} queue-tick@1.0.1: {} @@ -4404,7 +4642,7 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-is@18.2.0: {} + react-is@17.0.2: {} read-yaml-file@1.1.0: dependencies: @@ -4435,6 +4673,8 @@ snapshots: dependencies: minimatch: 5.1.6 + regenerator-runtime@0.14.1: {} + registry-auth-token@4.2.2: dependencies: rc: 1.2.8 @@ -4470,6 +4710,8 @@ snapshots: require-directory@2.1.1: {} + requires-port@1.0.0: {} + resolve-alpn@1.2.1: {} resolve@1.19.0: @@ -4569,7 +4811,7 @@ snapshots: signal-exit@4.1.0: {} - sirv@2.0.4: + sirv@3.0.0: dependencies: '@polka/url': 1.0.0-next.25 mrmime: 2.0.0 @@ -4632,6 +4874,8 @@ snapshots: stackback@0.0.2: {} + statuses@2.0.1: {} + std-env@3.7.0: {} streamx@2.16.1: @@ -4641,6 +4885,8 @@ snapshots: optionalDependencies: bare-events: 2.2.2 + strict-event-emitter@0.5.1: {} + string-argv@0.3.2: {} string-width@4.2.3: @@ -4675,16 +4921,10 @@ snapshots: strip-final-newline@2.0.0: {} - strip-final-newline@3.0.0: {} - strip-json-comments@2.0.1: {} strip-json-comments@3.1.1: {} - strip-literal@2.1.0: - dependencies: - js-tokens: 9.0.0 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -4734,11 +4974,15 @@ snapshots: through@2.3.8: {} - tinybench@2.6.0: {} + tinybench@2.9.0: {} - tinypool@0.8.3: {} + tinyexec@0.3.1: {} - tinyspy@2.2.1: {} + tinypool@1.0.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} to-fast-properties@2.0.0: {} @@ -4750,22 +4994,29 @@ snapshots: totalist@3.0.1: {} + tough-cookie@4.1.4: + dependencies: + psl: 1.10.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + tr46@0.0.3: {} tslib@2.6.2: {} - type-detect@4.0.8: {} + type-fest@0.21.3: {} type-fest@2.13.0: {} type-fest@2.19.0: {} + type-fest@4.26.1: {} + typescript@5.4.2: {} typescript@5.4.4: {} - ufo@1.5.3: {} - unbzip2-stream@1.4.3: dependencies: buffer: 5.7.1 @@ -4785,6 +5036,8 @@ snapshots: universalify@0.1.2: {} + universalify@0.2.0: {} + universalify@2.0.1: {} unzipper@0.11.4: @@ -4803,6 +5056,11 @@ snapshots: dependencies: prepend-http: 2.0.0 + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + userhome@1.0.0: {} util-deprecate@1.0.2: {} @@ -4816,12 +5074,11 @@ snapshots: validator@13.11.0: {} - vite-node@1.4.0(@types/node@20.12.6): + vite-node@2.1.4(@types/node@20.12.6): dependencies: cac: 6.7.14 - debug: 4.3.4 + debug: 4.3.7 pathe: 1.1.2 - picocolors: 1.0.0 vite: 5.2.8(@types/node@20.12.6) transitivePeerDependencies: - '@types/node' @@ -4859,34 +5116,35 @@ snapshots: '@types/node': 20.12.6 fsevents: 2.3.3 - vitest@1.4.0(@types/node@20.12.6)(@vitest/browser@1.5.3): - dependencies: - '@vitest/expect': 1.4.0 - '@vitest/runner': 1.4.0 - '@vitest/snapshot': 1.4.0 - '@vitest/spy': 1.4.0 - '@vitest/utils': 1.4.0 - acorn-walk: 8.3.2 - chai: 4.4.1 - debug: 4.3.4 - execa: 8.0.1 - local-pkg: 0.5.0 - magic-string: 0.30.9 + vitest@2.1.4(@types/node@20.12.6)(@vitest/browser@2.1.4)(msw@2.6.4(@types/node@20.12.6)(typescript@5.4.4)): + dependencies: + '@vitest/expect': 2.1.4 + '@vitest/mocker': 2.1.4(msw@2.6.4(@types/node@20.12.6)(typescript@5.4.4))(vite@5.2.8(@types/node@20.12.6)) + '@vitest/pretty-format': 2.1.4 + '@vitest/runner': 2.1.4 + '@vitest/snapshot': 2.1.4 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.12 pathe: 1.1.2 - picocolors: 1.0.0 std-env: 3.7.0 - strip-literal: 2.1.0 - tinybench: 2.6.0 - tinypool: 0.8.3 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 vite: 5.2.8(@types/node@20.12.6) - vite-node: 1.4.0(@types/node@20.12.6) - why-is-node-running: 2.2.2 + vite-node: 2.1.4(@types/node@20.12.6) + why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 20.12.6 - '@vitest/browser': 1.5.3(vitest@1.4.0)(webdriverio@8.36.1(encoding@0.1.13)(typescript@5.4.4)) + '@vitest/browser': 2.1.4(@types/node@20.12.6)(typescript@5.4.4)(vite@5.2.8(@types/node@20.12.6))(vitest@2.1.4)(webdriverio@8.36.1(encoding@0.1.13)(typescript@5.4.4)) transitivePeerDependencies: - less - lightningcss + - msw - sass - stylus - sugarss @@ -4981,11 +5239,17 @@ snapshots: dependencies: isexe: 3.1.1 - why-is-node-running@2.2.2: + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 stackback: 0.0.2 + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -5004,6 +5268,8 @@ snapshots: ws@8.17.0: {} + ws@8.18.0: {} + y18n@5.0.8: {} yallist@4.0.0: {} @@ -5047,7 +5313,7 @@ snapshots: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 - yocto-queue@1.0.0: {} + yoctocolors-cjs@2.1.2: {} z-schema@5.0.5: dependencies: diff --git a/vite.config.ts b/vite.config.ts index fea5e8c..91fd0a9 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,11 @@ import {dirname, join} from 'node:path'; import {fileURLToPath} from 'node:url'; import {defineConfig} from 'vite'; +import JsonArrayReporter from './benchmarks/jsonArrayReporter'; import dts from 'vite-plugin-dts'; +process.env.NODE_OPTIONS = `${process.env.NODE_OPTIONS ?? ''} --expose-gc`; + const entry = join(dirname(fileURLToPath(import.meta.url)), './src/index.ts'); export default defineConfig({ @@ -15,4 +18,10 @@ export default defineConfig({ fileName: 'index', }, }, + test: { + benchmark: { + include: ['benchmarks/**/*.bench.ts'], + reporters: ['default', new JsonArrayReporter()], + }, + }, });