diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..efc3bf7 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,7 @@ +**/node_modules/** +**/dist/** +**/coverage/** +**/build/** +**/.git/** +**/public/** +**/__deprecated__/** diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..722d01f --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,2 @@ +module.exports = { +}; diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 8360b0e..a319cae 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - node: [16] + node: [20] os: [ubuntu-latest] steps: @@ -19,8 +19,9 @@ jobs: - uses: actions/setup-node@v1 with: node-version: ${{ matrix.node }} - - run: npm i - - run: npm run test -- --coverage - - uses: coverallsapp/github-action@master + - run: npm install -g yarn + - run: yarn + - run: yarn run test:all --coverage + - uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 441fc82..800f3a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,24 @@ -# OS -.DS_Store +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js -# VS Code files for those working on multiple tools -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -*.code-workspace +# testing +/coverage -# packages -node_modules +# production +/build +/dist -# TS -dist +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local -# Jest -coverage \ No newline at end of file +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..8996736 --- /dev/null +++ b/.npmignore @@ -0,0 +1,20 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index cf784ee..87a4dd2 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -1,19 +1,13 @@ -# Ya Signals +# Signals _React application architecture on MobX._ -## Installation - -```bash -npm install ya-signals -``` - -- [Ya Signals](#ya-signals) +- [Signals](#signals) - [Installation](#installation) - [React Integration](#react-integration) - [Guide / API](#guide--api) - [`signal(initialValue)`](#signalinitialvalue) - - [`wrap(fn)`](#wrapfn) + - [`wrapSignal(fn)`](#wrapsignalfn) - [`autorun(fn)`](#autorunfn) - [`reaction(fn,fn)`](#reactionfnfn) - [`sync(fn,fn)`](#syncfnfn) @@ -24,7 +18,6 @@ npm install ya-signals - [Simple and fast events abstraction](#simple-and-fast-events-abstraction) - [Automatic unsubscription control](#automatic-unsubscription-control) - [On demand services](#on-demand-services) - - [Isolated services scope for SSR support](#isolated-services-scope-for-ssr-support) - [Describe component logic in OOP-style](#describe-component-logic-in-oop-style) - [License](#license) @@ -33,7 +26,7 @@ npm install ya-signals React adapter allows you to access signals directly inside your components and will automatically subscribe to them. ```typescript -import { observer, signal } from "ya-signals"; +import { observer, signal } from "@volga/signals"; const count = signal(0); @@ -55,7 +48,7 @@ In practice this makes MobX applications very well optimized out of the box and The `signal` function creates a new signal. A signal is a container for a value that can change over time. You can read a signal's value or subscribe to value updates by accessing its `.value` property. ```js -import { signal } from "ya-signals"; +import { signal } from '@volga/signals'; const counter = signal(0); @@ -68,57 +61,57 @@ counter(1); Writing to a signal is done by calling as a function. Changing a signal's value synchronously updates every [computed](#computedfn) and [autorun](#autorunfn) that depends on that signal, ensuring your app state is always consistent. -### `wrap(fn)` +### `wrapSignal(fn)` -Data is often derived from other pieces of existing data. The `wrap` function lets you combine the values of multiple signals into a new signal that can be reacted to, or even used by additional computeds. When the signals accessed from within a computed callback change, the computed callback is re-executed and its new return value becomes the computed signal's value. +Data is often derived from other pieces of existing data. The `wrapSignal` function lets you combine the values of multiple signals into a new signal that can be reacted to, or even used by additional computeds. When the signals accessed from within a computed callback change, the computed callback is re-executed and its new return value becomes the computed signal's value. ```js -import { signal, wrap } from "ya-signals"; +import { signal, wrapSignal } from '@volga/signals'; -const name = signal("Jane"); -const surname = signal("Doe"); +const name = signal('Jane'); +const surname = signal('Doe'); -const fullName = wrap(() => name.value + " " + surname.value); +const fullName = wrapSignal(() => name.value + ' ' + surname.value); // Logs: "Jane Doe" console.log(fullName.value); -// Updates flow through wrap, but only if someone +// Updates flow through wrapSignal, but only if someone // subscribes to it. More on that later. -name("John"); +name('John'); // Logs: "John Doe" console.log(fullName.value); ``` -Any signal that is accessed inside the `wrap`'s callback function will be automatically subscribed to and tracked as a dependency of the struct computed signal. +Any signal that is accessed inside the `wrapSignal`'s callback function will be automatically subscribed to and tracked as a dependency of the struct computed signal. ### `autorun(fn)` -The `autorun` function is the last piece that makes everything reactive. When you access a signal inside its callback function, that signal and every dependency of said signal will be activated and subscribed to. In that regard it is very similar to [`wrap(fn)`](#wrapfn). By default all updates are lazy, so nothing will update until you access a signal inside `autorun`. +The `autorun` function is the last piece that makes everything reactive. When you access a signal inside its callback function, that signal and every dependency of said signal will be activated and subscribed to. In that regard it is very similar to [`wrapSignal(fn)`](#wrapsignalfn). By default all updates are lazy, so nothing will update until you access a signal inside `autorun`. ```js -import { signal, wrap, autorun } from "ya-signals"; +import { signal, wrapSignal, autorun } from '@volga/signals'; -const name = signal("Jane"); -const surname = signal("Doe"); -const fullName = wrap(() => name.value + " " + surname.value); +const name = signal('Jane'); +const surname = signal('Doe'); +const fullName = wrapSignal(() => name.value + ' ' + surname.value); // Logs: "Jane Doe" autorun(() => console.log(fullName.value)); // Updating one of its dependencies will automatically trigger // the autorun above, and will print "John Doe" to the console. -name("John"); +name('John'); ``` You can destroy an autorun and unsubscribe from all signals it was subscribed to, by calling the returned function. ```js -import { signal, wrap, autorun } from "ya-signals"; +import { signal, wrapSignal, autorun } from '@volga/signals'; -const name = signal("Jane"); -const surname = signal("Doe"); -const fullName = wrap(() => name.value + " " + surname.value); +const name = signal('Jane'); +const surname = signal('Doe'); +const fullName = wrapSignal(() => name.value + ' ' + surname.value); // Logs: "Jane Doe" const dispose = autorun(() => console.log(fullName.value)); @@ -129,7 +122,7 @@ dispose(); // Update does nothing, because no one is subscribed anymore. // Even the computed `fullName` signal won't change, because it knows // that no one listens to it. -surname("Doe 2"); +surname('Doe 2'); ``` ### `reaction(fn,fn)` @@ -139,43 +132,43 @@ surname("Doe 2"); The typical pattern is that you produce the things you need in your side effect in the data function, and in that way control more precisely when the effect triggers. By default, the result of the data function has to change in order for the effect function to be triggered. ```typescript -import { signal, reaction } from "ya-signals" +import { signal, reaction } from '@volga/signals'; class Animal { - name = signal(0) - energyLevel = signal(0) + name = signal(0); + energyLevel = signal(0); constructor(name) { - this.name(name) - this.energyLevel(100) + this.name(name); + this.energyLevel(100); } reduceEnergy() { - this.energyLevel.update(v => v - 10) + this.energyLevel.update(v => v - 10); } get isHungry() { - return this.energyLevel.value < 50 + return this.energyLevel.value < 50; } } -const giraffe = new Animal("Gary") +const giraffe = new Animal('Gary'); reaction( () => giraffe.isHungry, isHungry => { if (isHungry) { - console.log("Now I'm hungry!") + console.log("Now I'm hungry!"); } else { - console.log("I'm not hungry!") + console.log("I'm not hungry!"); } - console.log("Energy level:", giraffe.energyLevel.value) - } -) + console.log('Energy level:', giraffe.energyLevel.value); + }, +); -console.log("Now let's change state!") +console.log("Now let's change state!"); for (let i = 0; i < 10; i++) { - giraffe.reduceEnergy() + giraffe.reduceEnergy(); } ``` @@ -184,20 +177,21 @@ for (let i = 0; i < 10; i++) { `sync` is like [`reaction`](#reactionfnfn), but the effect function should immediately be triggered after the first run of the data function. ```typescript -import { sync } from "ya-signals" +import { sync } from '@volga/signals'; class List { constructor(authService) { sync( () => authService.isLoggedIn, // data function - (loggedIn) => { // effect function + loggedIn => { + // effect function if (loggedIn) { - this.initUserData() + this.initUserData(); } else { - this.clearUserData() + this.clearUserData(); } - } - ) + }, + ); } initUserData() {} clearUserData() {} @@ -213,7 +207,7 @@ The `when` function returns a `Promise` with `cancel` method allowing you to can This combines nicely with `async / await` to let you wait for changes in reactive state. ```typescript -import { when } from "ya-signals" +import { when } from "@volga/signals" async function() { await when(() => that.isVisible) @@ -235,9 +229,11 @@ autorun(() => { console.log(counter.value); // Whenever this effect is triggered, run function that gives new value - effectCount(untracked(() => { - return effectCount.value + 1; - })); + effectCount( + untracked(() => { + return effectCount.value + 1; + }), + ); }); ``` @@ -246,11 +242,11 @@ autorun(() => { The `transaction` function allows you to combine multiple signal writes into one single update that is triggered at the end when the callback completes. ```js -import { signal, wrap, autorun, transaction } from "ya-signals"; +import { signal, wrapSignal, autorun, transaction } from '@volga/signals'; -const name = signal("Jane"); -const surname = signal("Doe"); -const fullName = wrap(() => name.value + " " + surname.value); +const name = signal('Jane'); +const surname = signal('Doe'); +const fullName = wrapSignal(() => name.value + ' ' + surname.value); // Logs: "Jane Doe" autorun(() => console.log(fullName.value)); @@ -258,19 +254,19 @@ autorun(() => console.log(fullName.value)); // Combines both signal writes into one update. Once the callback // returns the `autorun` will trigger and we'll log "Foo Bar" transaction(() => { - name("Foo"); - surname("Bar"); + name('Foo'); + surname('Bar'); }); ``` When you access a signal that you wrote to earlier inside the callback, or access a computed signal that was invalidated by another signal, we'll only update the necessary dependencies to get the current value for the signal you read from. All other invalidated signals will update at the end of the callback function. ```js -import { signal, wrap, autorun, transaction } from "ya-signals"; +import { signal, wrapSignal, autorun, transaction } from '@volga/signals'; const counter = signal(0); -const double = wrap(() => counter.value * 2); -const triple = wrap(() => counter.value * 3); +const double = wrapSignal(() => counter.value * 2); +const triple = wrapSignal(() => counter.value * 3); autorun(() => console.log(double.value, triple.value)); @@ -286,7 +282,7 @@ transaction(() => { Transactions can be nested and updates will be flushed when the outermost transaction call completes. ```js -import { signal, wrap, autorun, transaction } from "ya-signals"; +import { signal, wrapSignal, autorun, transaction } from '@volga/signals'; const counter = signal(0); autorun(() => console.log(counter.value)); @@ -303,21 +299,20 @@ transaction(() => { // Now the callback completed and we'll trigger the autorun. ``` - ## Extra API ### Simple and fast events abstraction ```typescript -import { event } from "ya-signals" +import { event } from '@volga/signals'; -const userLoggedIn = event() +const onUserLoggedIn = event(); // subscribe to the event -userLoggedIn.subscribe(listener) +onUserLoggedIn(listener); // call the event -userLoggedIn() +onUserLoggedIn.fire(); ``` ### Automatic unsubscription control @@ -325,15 +320,13 @@ userLoggedIn() ```typescript un(() => { // unsubscribe your event listeners here -}) +}); ``` ### On demand services -[![Edit example in Codesandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/sleepy-field-79wqfh?file=%2Fsrc%2FApp.tsx%3A25%2C1-25%2C11) - ```typescript -import { service, makeObservable, observable } from "ya-signals"; +import { service, makeObservable, observable } from '@volga/signals'; // AppService.ts @@ -341,7 +334,7 @@ class AppService { public lang: string; constructor() { - this.lang = "ru"; + this.lang = 'ru'; makeObservable(this, { lang: observable.ref, // immutable value @@ -356,7 +349,7 @@ export const appService = service(AppService); If you run `appService.user` in your code anywhere it's get app property for **on demand** created service ```typescript -import { observer } from "ya-signals"; +import { observer } from "@volga/signals"; import { appService } from "./AppService.ts" // App.tsx @@ -382,51 +375,30 @@ In rare case when it's necessary to destroy a service manually. service.destroy(appService); ``` -### Isolated services scope for SSR support - -Isolation of async scopes (only in node environment) - -Run your app in isolated Service Provider scope. All instances cached for this will be isolated from all cached instances in other scopes. Useful for implementing SSR. - -```typescript -import { isolate } from "provi/ssr" - -const html = await isolate(async () => { - // Isolated instance of appService created on demand here, - // by calling run method contains state initialization requests - await appService.run(); - // ... - return ReactDOMServer.renderToString(); -}); -``` - -Each isolated instance will be destroyed at the end of the isolated asynchronous function. - ### Describe component logic in OOP-style ```typescript -import { hook, un } from "ya-signals"; +import { hook, un } from '@volga/signals'; class RecipeForm { - constructor() { + constructor() {} + init() { un(() => { // destroy - }) + }); } } -export const useRecipeForm = hook(RecipeForm) +export const useRecipeForm = hook(RecipeForm); // Somewhere in React component -const form = useRecipeForm() +const form = useRecipeForm(); ``` **And it can be with params of course** -[![Edit example in Codesandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/nostalgic-galileo-p8ylnf?file=%2Fsrc%2FApp.tsx%3A20%2C1) - ```typescript -import { hook, type SignalReadonly } from "ya-signals"; +import { reaction, hook, type StructSignalReadonly } from '@volga/signals'; // Can be object struct with named fields type Params = { @@ -435,19 +407,23 @@ type Params = { }; class LocalLogic { - constructor($params: SignalReadonly) { - console.log("constructor with params", $params.value); - - $params.subscribe((params) => { - console.log("updated params", params); - }); + constructor(private params: StructSignalReadonly) { + console.log('Count from params', params.count); + } + init() { + reaction( + () => this.params.text, + text => { + console.log('Text updated', text); + }, + ); } } const useLocalLogic = hook(LocalLogic); ``` -The `signal` documentation see [here](/DOCUMENTATION.md#signalinitialvalue). +The `signal` documentation see [here](#signalinitialvalue). And using it somewhere inside React component function @@ -463,6 +439,3 @@ function Form() { // ... } ``` - -## License -ISC diff --git a/README.md b/README.md index 120e4c5..759efe4 100644 --- a/README.md +++ b/README.md @@ -10,49 +10,62 @@ _React application architecture on MobX._ npm install ya-signals ``` -- [Ya Signals](#ya-signals) - - [Installation](#installation) - - [Logic](#logic) - - [On demand services](#on-demand-services) - - [Describe component logic in OOP-style](#describe-component-logic-in-oop-style) - - [API Reference](#api-reference) - - [License](#license) +## Общие положения -## Logic +Необходимые методы MobX рекомендовано подключать через эту библиотеку. -### On demand services +```typescript +reaction; +autorun; + +observable; +computed; +makeObservable; +makeAutoObservable; +action; +transaction; + +observer; // из mobx-react-lite +``` -[![Edit example in Codesandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/sleepy-field-79wqfh?file=%2Fsrc%2FApp.tsx%3A25%2C1-25%2C11) +Например: ```typescript -import { service, makeObservable, observable } from "ya-signals"; +import { makeAutoObservable, observer } from "@volga/signals" + +class Some { + constructor() { + makeAutoObservable(this, {}, { deep: false }); + } +} -// AppService.ts +const App = observer(() => { + return <> +}); +``` + +## Сервисы + +```typescript +import { service, makeAutoObservable, observable } from '@volga/signals'; class AppService { public lang: string; constructor() { - this.lang = "ru"; - - makeObservable(this, { - lang: observable.ref, // immutable value - }); + makeAutoObservable(this, {}, { deep: false }); } } -// Only Proxy for create class on demand in future export const appService = service(AppService); ``` -If you run `appService.lang` in your code anywhere it's get app property for **on demand** created service +Функция `service` вернет прокси, который инициализирует класс `AppService` при первом использовании, например, когда будет использован `appService.lang`. ```typescript -import { observer } from "ya-signals"; +import { observer } from "@volga/signals"; import { appService } from "./AppService.ts" -// App.tsx - export const App = observer(() => { return (
@@ -62,69 +75,179 @@ export const App = observer(() => { }); ``` -In rare cases when it's necessary to initialize a service without invoking any method. +Иногда нужно инициализировать сервис без его явного использования: ```typescript service.instantiate(appService); ``` -In rare case when it's necessary to destroy a service manually. +## Dependency Injection в Сервисах + +Для переопределения класса сервиса в продуктовых пакетах необходимо использовать метод `override`. + +```typescript +//./services/customCommandManager.ts + +class CustomCommandManager extends CommandManager { + // override parent + send() {} + fetch() {} + + // implement new + customMethod() {} +} + +// customCommandManager will be full feature service +// with types defined from class CustomCommandManager +export const customCommandManager = service.override(commandManager, CustomCommandManager); +``` + +Если новый сервис расширяет возможности предыдущего (базового), то одназначно имеет смысл размещать его файл рядом с другими сервисами и использовать именно его в данном пакете. Так как функционально он будет идентичным, а тип его будет новым, расширенным. ```typescript -service.destroy(appService); +import { customCommandManager } from './services/customCommandManager'; + +function bootstrap() { + // ... + service.instantiate(customCommandManager); +} ``` -### Describe component logic in OOP-style +Если же сервис должен только переопределить некий базовый сервис, не внося какой-либо новой логики, то можно вызывать фазу `override` и в `bootstrap` функции. Такое решение выглядет приемлено, но я бы рекомендовал подумать над этим решением, всё-таки хотелось бы оставить фазу `override` на том же уровне где и вызов функции создания сервисов `service`, но это не требование, нужно глядеть как смотрится. + +## Side-эффекты + +Сайд-эффекты необходимо создавать внутри отдельного метода `init` внутри класса сервиса. В контексте выполнения этого метода доступна функция `un` для регистрации отписчиков. Именно внутри `init` нужно описывать реакции и реактивные синхронизации через `reaction` и `autorun`. ```typescript -import { hook, un } from "ya-signals"; +import { makeAutoObservable, reaction } from '@volga/signals'; + +class AppService { + public lang: string; + + constructor() { + makeAutoObservable(this, {}, { deep: false }); + } + + init() { + reaction( + () => this.lang, + lang => { + console.log('Lang updated', lang); + }, + ); + } +} +``` + +При _сложной_ композиции классов нужно организовывать `init` фазу в ручную. + +```typescript +class ComplexService { + logicA = new LogicA(); + logicB = new LogicB(); + + init() { + this.logicA.init(); + this.logicB.init(); + } +} +``` + +## Моки сервисов (тестирование) + +Так же удобно определять моки для сервисов: + +```typescript +service.mock(appService, { + lang: 'en', +}); +``` + +Такой вызов работает очень просто. Инстанция для сервиса задаётся явно в виде объекта и при обращении к сервису, будет просходить обращение к указанному объекту. + +А **освобождать моки**, как и сервисы созданные в штатном порядке, можно через `service.destroy(appService)`. +А если вызвать без аргументов, то будут уничтожены все созданные на данный момент сервисы и моки `service.destroy()`. + +## Логика компонентов + +Логика компонентов должна быть описана в том же стиле, что и логика сервисов. Это классы, которые инстанциируются по требованию к компоненте React, и уничтожаются со смертью компонента. Сайд эффекты инициализируются так же как и в сервисах в методе `init`. + +```typescript +import { hook, un } from '@volga/signals'; class RecipeForm { + title = ''; + constructor() { + makeAutoObservable(this, {}, { deep: false }); + } + + init() { + // Сайд-эффекты + un(() => { - // destroy - }) + // unmount phase + }); } -} -export const useRecipeForm = hook(RecipeForm) + titleInputHander = (event: any) => { + this.title = event.target.value; + }; +} -// Somewhere in React component -const form = useRecipeForm() +export const useRecipeForm = hook(RecipeForm); ``` -**And it can be with params of course** +Описываются они эквивалентным образом как сервисы, для единства стиля и управления реактивными взаимодействиями. Только используется метод `hook`, который возвращает хук для подключения в React компонент. + +```typescript +import { useRecipeForm } from "./useRecipeForm.ts"; + +const Form = () => { + const form = useRecipeForm(); // Somewhere in React component + + return ( +
+ +
+ ) +} +``` -[![Edit example in Codesandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/nostalgic-galileo-p8ylnf?file=%2Fsrc%2FApp.tsx%3A20%2C1) +### Если нужны параметры ```typescript -import { hook, type SignalReadonly } from "ya-signals"; +import { reaction, hook, type StructSignalReadonly } from '@volga/signals'; -// Can be object struct with named fields +// Can be object struct with named fields or tuple type Params = { count: number; text: string; }; class LocalLogic { - constructor($params: SignalReadonly) { - console.log("constructor with params", $params.value); + constructor(private params: StructSignalReadonly) { + console.log('Count from params', params.count); + } - $params.subscribe((params) => { - console.log("updated params", params); - }); + init() { + reaction( + () => this.params.text, + text => { + console.log('Text updated', text); + }, + ); } } const useLocalLogic = hook(LocalLogic); ``` -The `signal` documentation see [here](/DOCUMENTATION.md#signalinitialvalue). - -And using it somewhere inside React component function +И используем хук с параметрами в любом React компоненте ```typescript -import { useRecipeForm } from './recipe-form.ts'; +import { useRecipeForm } from "./recipe-form.ts"; function Form() { const [count, setCount] = useState(() => 1); @@ -136,9 +259,142 @@ function Form() { } ``` -## API Reference +Для передачи параметров используется `signal`. Документацию по нему можно найти [здесь](DOCUMENTATION.md#signalinitialvalue). + +## Сигналы-структуры + +**Этот кейс, для больших и сложных (complex) Реакт компонентов с ожидаемой глубокой вложенностью.** - - [Documentation](/DOCUMENTATION.md) +> Если значение не используется в дочернем компоненте, а используется в его потомках (дочерний дочернего), то оборачиваем в сигналы (useStructSignal, useSignal), что бы исключить неожиданный ререндер родителей. + +С помощью сигналов хотелось бы иметь возможность удобно передавать конкретные свойства в общие компоненты без утери контроля над обновлениями реакт компонентов и потери контекса подписки в сервисах. + +> **Это подход должен быть использован только как оптимизация. +> А оптимизация как известно должна быть только там где она нужна, лучше используйте более простые возможности когда оптимизация преждевремена.** + +```typescript +import { useStructSignal, useSignal, observer, hook } from "@volga/signals" + +const ParentComponent = () => { + const [value, setValue] = useState(); + + // variant 1 + const props1 = useStructSignal(() => ({ + scroll: viewportState.scroll, // scroll это Observable getter + height: viewportState.y.viewportSize, // y это Observable + width: viewportState.x.viewportSize, // y это Observable + zoom: viewportState.zoom, // zoom это Observable + })); // => StructSignalReadonly<{...}> + + // variant 2 + const props2 = useMemo( + () => ({ + get zoom() { + return viewportState.zoom; + }, + get scroll() { + return viewportState.scroll; + }, + get height() { + return viewportState.y.viewportSize; + }, + get width() { + return viewportState.x.viewportSize; + }, + }), + [], + ); // => {...} + +// variant 1 + const scroll1 = useSignal(() => canvasProps.scroll); // SignalReadonly + +// variant 2 + const scroll2 = useMemo( + () => ({ + get value() { + return canvasProps.scroll; + }, + }), + [], + ); // { value: XY } + + return ; +}; + + +// rerenders only when zoom changes! +const Child = observer(({ commonProps, scroll }) => { + return ( + <> +

{commonProps.zoom}

// subscribe only to zoom property + + + ); +}); + +class LocalLogic { + constructor(private params: StructSignalReadonly<{ scroll: SignalReadonly }>) { + makeAutoObservable(this, {}, { deep: false }); + } + + get strangeDiff() { + return this.params.scroll.value.x - this.params.scroll.value.y; + } +} + +const useLocalLogic = hook(LocalLogic); + +const ChildOfChild = observer(({ scroll }) => { + const { strangeDiff } = useLocalLogic({ scroll }); + + return

strange difference is {strangeDiff}

; +}); +``` + +## Модульные события + +При Проектировании систем довольно часто используют паттерн EventEmitter. И бросают через один эмиттер множество типов эвентов. + +В следствии EventEmitter должен при описании типов знать обо всех типах эвентов, а если просто сказать, то он должен включать в себя все эвенты сразу. + +Проблема появляется при модульных системах и расширяемых системах. При появлении плагинов которые тоже хотят реализовать свои евенты в шину. А так как обычно шина это один EventEmitter, то его плагинизация является невозможным по определению в TypeScript. + +В таких случае очень приятно кодировать модули и плагины, которые могут иметь свой собственный набор ивентов, состояний и логики. + +Пример кодирования интерфейса событий такого модуля: + +```typescript +export const onPastToClipboard = event(); +``` + +Либо использование внутри класса: + +```typescript +import { event } from "@volga/signals" + +class ClipboardPlugin { + public onPastToClipboard = event() + + someMethod() { + // fire event + this.onPastToClipboard.fire({ ... }); + } + + constructor() { + // Event subscription + this.onPastToClipboard((clipboard) => { + // ... + }); + } +} +``` + +Обычной практикой канонического ООП является наследование от EventEmitter, что бы иметь возможность бросать события у сущности. +Но это порождает во первых рост цепочки наследования. +А с другой стороны нивелирует преимущества паттерна Композиция. + +Имея такие эвенты, которые предоставляет evemin можно не только отказаться от проблем общей шины и наследования, а ещё и воспользоваться преимуществом и наглядностью паттерна композиция. На примере выше любой плагин сможет поставлять какое угодно количество событий кого-то угодно типа, изолированно от других плагинов и в 2 раза быстрее чем EventEmitter. + +## API Reference -## License -ISC +- [Documentation](DOCUMENTATION.md) diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index b4bc92b..0000000 --- a/jest.config.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', -}; \ No newline at end of file diff --git a/package.json b/package.json index 8cfdc4f..ffc41f4 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,14 @@ { "name": "ya-signals", - "version": "0.9.14", - "description": "React application architecture on MobX.", - "main": "dist/index.js", + "version": "1.0.0", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", "files": [ "dist", "README.md" ], - "scripts": { - "test": "jest", - "build": "tsc" - }, "repository": { "type": "git", "url": "git+https://github.com/betula/ya-signals.git" @@ -26,28 +24,34 @@ "mobx", "signals" ], - "author": "Slava Bereza ", - "license": "ISC", - "bugs": { - "url": "https://github.com/betula/ya-signals/issues" + "scripts": { + "test": "vitest --changed", + "test:ci": "vitest", + "test:all": "vitest", + "lint": "eslint \"./src/**/*.{ts,tsx}\" --format=codeframe", + "lint:fix": "yarn run lint --fix", + "ts-check": "tsc --noEmit", + "type:check": "tsc --noEmit", + "format": "prettier \"./src/**/*.{ts,tsx}\" -w", + "build": "tsup" }, - "homepage": "https://github.com/betula/ya-signals#readme", "dependencies": { - "mobx": "6.12.0", - "mobx-react-lite": "4.0.5", - "unsubscriber": "2.2.0", - "provi": "2.3.3", - "evemin": "2.0.0" + "mobx": "6.12.3", + "mobx-react-lite": "4.0.7", + "mobx-utils": "6.0.8" }, "peerDependencies": { - "react" : "^16.8.0 || ^17.0.0 || ^18.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "devDependencies": { - "@types/jest": "^29.5.3", - "jest": "^29.6.2", - "ts-jest": "^29.1.1", - "typescript": "^5.1.6", + "@types/node": "20.12.7", + "@types/react": "18.2.21", + "@vitest/coverage-v8": "3.0.2", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-test-renderer": "^18.0.0", + "tsup": "^8.3.5", + "typescript": "^5.1.6", + "vitest": "3.0.2" } } diff --git a/src/classes/Destroyable.ts b/src/classes/Destroyable.ts new file mode 100644 index 0000000..a75cd0a --- /dev/null +++ b/src/classes/Destroyable.ts @@ -0,0 +1,73 @@ +import { type Signal, signal } from '..'; +import { collect, run, type Unsubscriber, unsubscriber } from '../unsubscriber'; +import { untracked } from '../untracked'; + +export class Destroyable { + protected _unsubscriber?: Unsubscriber; + + private __sDestroyed?: Signal; + /** + * Признак того, что ноду уничтожили + */ + protected get _sDestroyed(): Signal { + return (this.__sDestroyed ??= signal(undefined)); + } + + get destroyed() { + return Boolean(this._sDestroyed.value); + } + + // just for usability + get active() { + return !this.destroyed; + } + + /** + * Return current unsubscriber. Create it if not exists. + * @returns Unsubscriber + */ + get unsubscriber() { + return (this._unsubscriber ??= unsubscriber()); + } + + /** + * Run any function in self destroy scope + */ + runInDestroyScope(fn: () => T): T { + return collect(this.unsubscriber, fn); + } + + /** + * Add destroy event listener + * @param fn destoy event listener + * @returns unlink destroy event listener + */ + onDestroy(fn: () => void): () => void { + this.unsubscriber.add(fn); + return () => { + this.unsubscriber.delete(fn); + }; + } + + /** + * Safely run all unsubscribers and clearing it. + */ + destroy() { + const destroyed = untracked(() => this._sDestroyed.value); + if (destroyed) { + return; + } + + this._sDestroyed(true); + try { + if (this._unsubscriber) { + untracked(() => { + run(this._unsubscriber!); + }); + } + } catch (error) { + // some global error log + console.error('Destroyable: destroy unknown error', error); + } + } +} diff --git a/src/classes/Initable.ts b/src/classes/Initable.ts new file mode 100644 index 0000000..827b3cc --- /dev/null +++ b/src/classes/Initable.ts @@ -0,0 +1,77 @@ +import { untracked } from 'mobx'; +import { runInAction } from '..'; +import { Destroyable } from './Destroyable'; + +export class Initable extends Destroyable { + get initialized() { + return this._sDestroyed.value === false; + } + + /** + * Разрешает ноде инициализироваться повторно после разрушения + */ + protected get allowReinitializing() { + return false; + } + + /** + * Run init function in self destroy scope. + * All side-effects will run, and it unsubscribers will kept + * and collected to self destroy scope + */ + runInit() { + untracked(() => { + this.runInDestroyScope(() => this.init()); + }); + } + + /** + * Define all your effects here + */ + init() { + if (this.destroyed && !this.allowReinitializing) { + console.warn( + 'Initable: Reinitializing after destroy', + (this as unknown as { _typeName: string })._typeName ?? '', + (this as unknown as { _uid: number })._uid ?? '', + ); + } + if (this.initialized) { + console.error( + 'Initable: Cannot be reinitialized before destroy', + (this as unknown as { _typeName: string })._typeName ?? '', + (this as unknown as { _uid: number })._uid ?? '', + ); + } + runInAction(() => { + this._sDestroyed(false); + }); + } + + /** + * Ensure initialize be done + */ + ensureInit() { + untracked(() => { + if (!this.initialized) { + if (this.destroyed) { + console.warn( + 'Initable: Are you sure you want to reinit destroyed initable instance', + (this as unknown as { _typeName: string })._typeName ?? '', + (this as unknown as { _uid: number })._uid ?? '', + ); + } + + this.runInit(); + + if (!this.initialized) { + console.error( + 'Initable: You are probably forget to call super.init() in your init override', + (this as unknown as { _typeName: string })._typeName ?? '', + (this as unknown as { _uid: number })._uid ?? '', + ); + } + } + }); + } +} diff --git a/src/configure.ts b/src/configure.ts index 897e1c6..ef832a4 100644 --- a/src/configure.ts +++ b/src/configure.ts @@ -1,5 +1,6 @@ import { configure } from 'mobx'; configure({ - enforceActions: "never", + enforceActions: 'never', + safeDescriptors: false, }); diff --git a/src/contextHook.test.tsx b/src/contextHook.test.tsx new file mode 100644 index 0000000..3d58f50 --- /dev/null +++ b/src/contextHook.test.tsx @@ -0,0 +1,176 @@ +import React, { useState } from 'react'; +import { act, create, ReactTestRenderer } from 'react-test-renderer'; +import { expect, it, vi } from 'vitest'; +import { autorun, contextHook, observer, signal, StructSignalReadonly, sync, un } from '.'; + +it('contextHook works', async () => { + const create_spy = vi.fn(); + const destroy_spy = vi.fn(); + const init_spy = vi.fn(); + + class A { + a = signal(0); + b = 0; + constructor() { + create_spy(); + } + init() { + un(destroy_spy); + init_spy(); + autorun(() => { + this.b = (this.a.value || 0) + 10; + }); + } + } + const [useA, Provider] = contextHook(A); + + const render = async () => { + let refresh: (p: {}) => void; + let instance: A; + const B = () => ( + + + + ); + const C = observer(() => { + refresh = useState<{}>()[1]; + instance = useA(); + + return ( + + {instance.a.value},{instance.b} + + ); + }); + + let renderer: ReactTestRenderer; + + await act(() => { + renderer = create(); + }); + + return { + inst: instance!, + renderer: renderer!, + refresh: () => refresh!({}), + }; + }; + + const { inst, renderer, refresh } = await render(); + + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['0', ',', '0'] }); + expect(inst.b).toBe(10); + + await act(() => { + inst.a(10); + refresh(); + }); + expect(inst.b).toBe(20); + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['10', ',', '20'] }); + + expect(create_spy).toBeCalled(); + expect(init_spy).toBeCalled(); + expect(destroy_spy).not.toBeCalled(); + + await act(() => { + renderer.unmount(); + }); + expect(destroy_spy).toBeCalled(); +}); + +it('contextHook struct params works', async () => { + const create_spy = vi.fn(); + const destroy_spy = vi.fn(); + const params_spy = vi.fn(); + const init_spy = vi.fn(); + + type Params = { + a: number; + b: string; + }; + + class A { + constructor(public params: StructSignalReadonly) { + create_spy(); + } + init() { + un(destroy_spy); + init_spy(); + sync(() => { + params_spy(this.params.toJSON()); + }); + } + } + + const [useA, Provider] = contextHook(A); + + const render = async (initial: Params) => { + let setParams: (p: Params) => void; + let instance: A; + const B = () => { + const [params, _setParams] = useState(initial); + setParams = _setParams; + + return ( + + + + ); + }; + const C = observer(() => { + instance = useA(); + + return ( + + {instance.params.a},{instance.params.b} + + ); + }); + + let renderer: ReactTestRenderer; + + await act(() => { + renderer = create(); + }); + + return { + inst: instance!, + renderer: renderer!, + setParams: (params: Params) => { + setParams!(params); + }, + }; + }; + + const { renderer, setParams } = await render({ a: 10, b: 'a' }); + + expect(params_spy).toBeCalledWith({ a: 10, b: 'a' }); + params_spy.mockClear(); + + await act(() => { + setParams({ a: 10, b: 'a' }); + }); + + expect(params_spy).not.toBeCalled(); + + await act(() => { + setParams({ a: 10, b: 'b' }); + }); + + expect(params_spy).toBeCalledWith({ a: 10, b: 'b' }); + params_spy.mockClear(); + + await act(() => { + setParams({ a: 10, b: 'b' }); + }); + expect(params_spy).not.toBeCalled(); + + expect(create_spy).toBeCalled(); + expect(init_spy).toBeCalled(); + expect(destroy_spy).not.toBeCalled(); + + await act(() => { + renderer.unmount(); + }); + expect(destroy_spy).toBeCalled(); +}); diff --git a/src/contextHook.tsx b/src/contextHook.tsx new file mode 100644 index 0000000..3040021 --- /dev/null +++ b/src/contextHook.tsx @@ -0,0 +1,31 @@ +import React, { createContext, PropsWithChildren, useContext } from 'react'; +import type { HookWithoutParams, LogicWithoutParams, LogicWithParams } from './hook'; +import { hook } from './hook'; +import { type LikeStruct } from './structSignal'; + +type ReturnTypeWithParams = readonly [ + HookWithoutParams, + (props: PropsWithChildren) => JSX.Element, + React.Consumer, +]; +type ReturnTypeWithoutParams = readonly [ + HookWithoutParams, + (props: PropsWithChildren) => JSX.Element, + React.Consumer, +]; + +export function contextHook(Class: LogicWithoutParams): ReturnTypeWithoutParams; +export function contextHook(Class: LogicWithParams): ReturnTypeWithParams; +export function contextHook( + Logic: LogicWithoutParams | LogicWithParams, +): ReturnTypeWithoutParams | ReturnTypeWithParams { + const useInstance = hook(Logic as LogicWithParams); + const Context = createContext(undefined as T); + const useStore = () => useContext(Context); + const Provider = ({ children, ...p }: PropsWithChildren) => { + const store = useInstance(p as Params); + return {children}; + }; + + return [useStore, Provider, Context.Consumer] as const; +} diff --git a/src/event.test.ts b/src/event.test.ts new file mode 100644 index 0000000..9eeca03 --- /dev/null +++ b/src/event.test.ts @@ -0,0 +1,50 @@ +import { expect, it, vi } from 'vitest'; +import { event } from './event'; + +it('light event works', () => { + const spy = vi.fn(); + + const a = event(); + a(spy); + + expect(spy).not.toBeCalled(); + a.fire(); + expect(spy).toBeCalled(); + a.fire(); + expect(spy).toBeCalledTimes(2); +}); + +it('params event works', () => { + const spy = vi.fn(); + + const a = event(); + a(spy); + + expect(spy).not.toBeCalled(); + a.fire(1); + expect(spy).toBeCalledWith(1); + a.fire(2); + expect(spy).toBeCalledTimes(2); + expect(spy).toHaveBeenLastCalledWith(2); +}); + +it('connected event works', () => { + const spy = vi.fn(); + + const a = event(); + const b = event(); + const un = b.connect(a); + b(spy); + + a.fire(1); + expect(spy).toBeCalledTimes(1); + expect(spy).toBeCalledWith(1); + + a.fire(2); + expect(spy).toBeCalledTimes(2); + expect(spy).toHaveBeenLastCalledWith(2); + + un(); + a.fire(3); + expect(spy).toBeCalledTimes(2); +}); diff --git a/src/event.ts b/src/event.ts index e246ccf..1f09fe5 100644 --- a/src/event.ts +++ b/src/event.ts @@ -1,18 +1,60 @@ -import { event as originEvent, listen } from 'evemin'; -import { un } from 'unsubscriber'; +import { un } from './unsubscriber'; -export interface Event { - (value: T): void; - subscribe(listener: (value: T) => void): (() => void); +/* +Modern and blazing fast event emitter + +- Zero-cost abstraction +- High performance +- Super small + +🌈 2x times faster standard node.js event emitter + */ + +const LISTENERS = Symbol('listeners'); + +interface EventParametrized { + [LISTENERS]: ((value: T) => void)[]; + (listener: (value: T) => void): () => void; + fire(value: T): void; + connect(source: Event): () => void; + clear(): void; } -export interface LightEvent extends Event { - (): void; - subscribe(listener: () => void): (() => void); +interface EventLite extends EventParametrized { + [LISTENERS]: (() => void)[]; + (listener: () => void): () => void; + fire(): void; } -export const event = (): T extends void ? LightEvent : Event => { - const fn = originEvent() as any; - fn.subscribe = (listener) => un(listen(fn, listener)); - return fn; -} \ No newline at end of file +export type Event = [T] extends [void] ? EventLite : EventParametrized; + +const subscribe = (ev: Event, fn: (value?: T) => void) => { + if (!ev[LISTENERS].includes(fn)) { + ev[LISTENERS] = ev[LISTENERS].concat(fn); + } + return () => { + ev[LISTENERS] = ev[LISTENERS].filter(f => f !== fn); + }; +}; + +export const event = (): Event => { + const ev = ((listener: (value?: T) => void) => un(subscribe(ev, listener))) as Event; + const fire = (data: T) => { + const listeners = ev[LISTENERS]; + // eslint-disable-next-line unicorn/no-for-loop + for (let i = 0; i < listeners.length; i++) { + listeners[i]?.(data); + } + }; + const connect = (source: Event) => { + return source(fire as () => void); + }; + const clear = () => { + ev[LISTENERS] = []; + }; + ev[LISTENERS] = []; + ev.fire = fire; + ev.connect = connect; + ev.clear = clear; + return ev; +}; diff --git a/src/hook.test.tsx b/src/hook.test.tsx new file mode 100644 index 0000000..bfae83a --- /dev/null +++ b/src/hook.test.tsx @@ -0,0 +1,208 @@ +import { useState } from 'react'; +import React from 'react'; +import { act, create, ReactTestRenderer } from 'react-test-renderer'; +import { expect, it, vi } from 'vitest'; +import { autorun, hook, observer, signal, StructSignal, structSignal, StructSignalReadonly, sync, un } from '.'; + +it('hook works', async () => { + const create_spy = vi.fn(); + const destroy_spy = vi.fn(); + const init_spy = vi.fn(); + + class A { + a = signal(0); + b = 0; + constructor() { + create_spy(); + } + init() { + un(destroy_spy); + init_spy(); + autorun(() => { + this.b = (this.a.value || 0) + 10; + }); + } + } + const useA = hook(A); + + const render = async () => { + let refresh: (p: {}) => void; + let instance: A; + const C = observer(() => { + refresh = useState<{}>()[1]; + instance = useA(); + + return ( + + {instance.a.value},{instance.b} + + ); + }); + + let renderer: ReactTestRenderer; + + await act(() => { + renderer = create(); + }); + + return { + inst: instance!, + renderer: renderer!, + refresh: () => refresh!({}), + }; + }; + + const { inst, renderer, refresh } = await render(); + + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['0', ',', '0'] }); + expect(inst.b).toBe(10); + + await act(() => { + inst.a(10); + refresh(); + }); + expect(inst.b).toBe(20); + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['10', ',', '20'] }); + + expect(create_spy).toBeCalled(); + expect(init_spy).toBeCalled(); + expect(destroy_spy).not.toBeCalled(); + + await act(() => { + renderer.unmount(); + }); + expect(destroy_spy).toBeCalled(); +}); + +it('hook struct params works', async () => { + const create_spy = vi.fn(); + const destroy_spy = vi.fn(); + const params_spy = vi.fn(); + const init_spy = vi.fn(); + + type Params = { + a: number; + b: string; + }; + + class A { + constructor(public params: StructSignalReadonly) { + create_spy(); + } + init() { + un(destroy_spy); + init_spy(); + sync(() => { + params_spy(this.params.toJSON()); + }); + } + } + + const useA = hook(A); + + const render = async (initial: Params) => { + let setParams: (p: Params) => void; + let instance: A; + const C = observer(() => { + const [params, _setParams] = useState(initial); + setParams = _setParams; + instance = useA(params); + + return ( + + {instance.params.a},{instance.params.b} + + ); + }); + + let renderer: ReactTestRenderer; + + await act(() => { + renderer = create(); + }); + + return { + inst: instance!, + renderer: renderer!, + setParams: (params: Params) => { + setParams!(params); + }, + }; + }; + + const { renderer, setParams } = await render({ a: 10, b: 'a' }); + + expect(params_spy).toBeCalledWith({ a: 10, b: 'a' }); + params_spy.mockClear(); + + await act(() => { + setParams({ a: 10, b: 'a' }); + }); + + expect(params_spy).not.toBeCalled(); + + await act(() => { + setParams({ a: 10, b: 'b' }); + }); + + expect(params_spy).toBeCalledWith({ a: 10, b: 'b' }); + params_spy.mockClear(); + + await act(() => { + setParams({ a: 10, b: 'b' }); + }); + expect(params_spy).not.toBeCalled(); + + expect(create_spy).toBeCalled(); + expect(init_spy).toBeCalled(); + expect(destroy_spy).not.toBeCalled(); + + await act(() => { + renderer.unmount(); + }); + expect(destroy_spy).toBeCalled(); +}); + +it('hook struct params as struct works', async () => { + const params_spy = vi.fn(); + + type Params = { + a: number; + b: string; + }; + + class A { + constructor(public params: StructSignalReadonly) {} + init() { + sync(() => { + params_spy(this.params.toJSON()); + }); + } + } + + const useA = hook(A); + + const render = async (structParams: StructSignal) => { + const C = () => { + useA(structParams); + return null; + }; + + await act(() => { + create(); + }); + }; + + const structParams = structSignal({ + a: 10, + b: 'a', + }); + + await render(structParams); + + expect(params_spy).toBeCalledWith({ a: 10, b: 'a' }); + params_spy.mockClear(); + + structParams({ a: 11, b: 'a' }); + expect(params_spy).toBeCalledWith({ a: 11, b: 'a' }); +}); diff --git a/src/hook.ts b/src/hook.ts index 6b6e749..e1affff 100644 --- a/src/hook.ts +++ b/src/hook.ts @@ -1,39 +1,89 @@ -import React from 'react'; -import { collect, unsubscriber, run } from 'unsubscriber'; -import { signal, wrap, SignalReadonly } from './signal'; +import React, { useEffect } from 'react'; +import { isStructSignal } from './isSignal'; +import { runInstanceInit } from './runInstanceInit'; +import { type LikeStruct, StructSignal, structSignal, StructSignalReadonly } from './structSignal'; +import { collect, run, unsubscriber } from './unsubscriber'; import { untracked } from './untracked'; -export function hook(Class: (() => T) | (new () => T)): (() => T); -export function hook(Class: ((params: SignalReadonly) => T) | (new (params: SignalReadonly) => T)): ((params: M) => T); -export function hook(Class: ((params?: SignalReadonly) => T) | (new (params?: SignalReadonly) => T)): ((params?: M) => T) { - return (params: M) => { +type ClassLogic = new (params: P) => T; +type FunctionLogic = (params: P) => T; + +export type LogicWithoutParams = ClassLogic | FunctionLogic; +export type LogicWithParams = ClassLogic> | FunctionLogic>; + +function instantiateLogic(Logic: LogicWithoutParams): T; +function instantiateLogic(Logic: LogicWithParams, params: P): T; +function instantiateLogic(Logic: LogicWithParams | LogicWithoutParams, params?: P): T { + // It's very challenging to differentiate a function from a class + // the type-check below only ensures that we won't call a new on an arrow function + // it still can fire `new` on the plain function. + // But it should be okay for us here, because we're always waiting an object from the functions + if (Logic.prototype === undefined) { + // The function overloading ensures that param would be `undefined` if Logic is LogicWithoutParams + // but, still, we pass param as undefined, which is not absolutely the same as not passing param at all + // keeping that in mind + return (Logic as FunctionLogic)(params!); + } + return new (Logic as ClassLogic)(params!); +} + +type HookParams = M | StructSignalReadonly; +export type HookWithParams = (params: HookParams) => T; +export type HookWithoutParams = () => T; + +export function hook(Class: LogicWithoutParams): HookWithoutParams; +export function hook(Class: LogicWithParams): HookWithParams; +export function hook( + Logic: LogicWithoutParams | LogicWithParams, +): HookWithoutParams | HookWithParams { + return (params?: HookParams) => { + const isWithParams = params !== undefined; + const isParamsStructSignal = isStructSignal(params); + const [instance, unsubs, signalParams] = React.useMemo(() => { - const signalParams = signal(params); - const wrapped = wrap(signalParams.get); + let signalParams: StructSignal | StructSignalReadonly | null = isParamsStructSignal + ? params + : null; + if (signalParams === null && isWithParams) { + signalParams = structSignal(params); + } + const unsubs = unsubscriber(); return [ - collect(unsubs, untracked.func(() => ( - Class.prototype === void 0 - ? (Class as (params?: SignalReadonly) => T)(wrapped) - : new (Class as new (params?: SignalReadonly) => T)(wrapped) - ))), + collect( + unsubs, + untracked.func(() => { + if (signalParams) { + return instantiateLogic(Logic as LogicWithParams, signalParams); + } + return instantiateLogic(Logic as LogicWithoutParams); + }), + ), unsubs, - signalParams - ] + signalParams, + ]; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - React.useEffect(() => () => run(unsubs), [unsubs]); - + useEffect(() => { + runInstanceInit(instance, unsubs); + return () => run(unsubs); + }, [unsubs, instance]); - // For prevent the error + // For prevent the error // Error: Cannot update a component (`Unknown`) while rendering a different component (`Unknown`). // We should add time for render phase finished before update params, // that can initiate next update sycle inside current. We use Promise microtask queue for prevent it. // (I believe one time MobX will implement "Unit of Work" pattern for observer updating) - Promise.resolve().then(() => { - signalParams(params); - }); + const deps = isWithParams && !isParamsStructSignal ? Object.values(params) : []; + useEffect(() => { + if (!isParamsStructSignal && isWithParams && typeof signalParams === 'function') { + signalParams(params); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, deps); + return instance; - } -} \ No newline at end of file + }; +} diff --git a/test/works.test.ts b/src/index.test.ts similarity index 73% rename from test/works.test.ts rename to src/index.test.ts index e5fc5b5..16ad7a0 100644 --- a/test/works.test.ts +++ b/src/index.test.ts @@ -1,9 +1,13 @@ -import { wrap, reaction, signal, transaction, sync, when } from "../src"; +import { expect, it, vi } from 'vitest'; +import { reaction, signal, sync, transaction, when, wrapSignal } from '.'; it('signal works', () => { - const spy = jest.fn(); + const spy = vi.fn(); const s = signal(0); - sync(() => s.value, (v) => spy(v)); + sync( + () => s.value, + v => spy(v), + ); s(1); s(s.value + 1); @@ -14,11 +18,14 @@ it('signal works', () => { }); it('wrap works', () => { - const spy = jest.fn(); + const spy = vi.fn(); const a = signal(0); const b = signal(0); - const c = wrap(() => a.value + b.value); - sync(() => c.value, (v) => spy(v)); + const c = wrapSignal(() => a.value + b.value); + sync( + () => c.value, + v => spy(v), + ); a(1); transaction(() => { @@ -38,9 +45,12 @@ it('wrap works', () => { }); it('reaction works', () => { - const spy = jest.fn(); + const spy = vi.fn(); const s = signal(0); - reaction(() => s.value, (v) => spy(v)); + reaction( + () => s.value, + v => spy(v), + ); expect(spy).not.toBeCalled(); s(s.value + 1); @@ -53,9 +63,12 @@ it('reaction works', () => { }); it('sync works', () => { - const spy = jest.fn(); + const spy = vi.fn(); const s = signal(0); - sync(() => s.value, (v) => spy(v)); + sync( + () => s.value, + v => spy(v), + ); expect(spy).toBeCalled(); s(s.value + 1); @@ -69,7 +82,7 @@ it('sync works', () => { }); it('when works', async () => { - const spy = jest.fn(); + const spy = vi.fn(); const s = signal(0); when(() => s.value > 0).then(() => spy()); await new Promise(r => setTimeout(() => r(0), 0)); @@ -80,14 +93,13 @@ it('when works', async () => { }); it('when rejected works', async () => { - const spy = jest.fn(); + const spy = vi.fn(); try { await when(() => { throw 0; - }) - } - catch { - spy() + }); + } catch { + spy(); } expect(spy).toBeCalled(); -}); \ No newline at end of file +}); diff --git a/src/index.ts b/src/index.ts index 2484a70..153667c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,27 +1,47 @@ +export { type Signal, type SignalReadonly, signal, wrapSignal, useSignal } from './signal'; export { - type Signal, - type SignalReadonly, - signal, - wrap -} from './signal'; + type StructSignal, + type StructSignalReadonly, + structSignal, + wrapStructSignal, + useStructSignal, +} from './structSignal'; +export { isSignal, isStructSignal } from './isSignal'; -export { observer } from 'mobx-react-lite'; +export { observer, useObserver } from 'mobx-react-lite'; export { transaction, makeAutoObservable, makeObservable, + createAtom, computed, observable, - action + action, + comparer, + toJS, + type IAtom, + type IObservableValue, } from 'mobx'; +export { runInAction, type IReactionPublic, trace } from 'mobx'; +export { computedFn } from 'mobx-utils'; import './configure'; -export { un } from 'unsubscriber'; +export { un } from './unsubscriber'; +export { Destroyable } from './classes/Destroyable'; +export { Initable } from './classes/Initable'; export { autorun, reaction, sync, when } from './reaction'; -export { event, type Event, type LightEvent } from './event'; -export { service } from './service'; -export { hook } from './hook'; -export { untracked } from './untracked'; \ No newline at end of file +export { contextHook } from './contextHook'; +export { event, type Event } from './event'; +export { service, isolate, isolated, initAsyncHooksZonator } from './service'; +export { hook, type HookWithParams, type HookWithoutParams } from './hook'; +export { untracked } from './untracked'; + +/** + * just for subscription to properties + * */ +export function subscribe(...args: unknown[]) { + return args; +} diff --git a/src/isSignal.ts b/src/isSignal.ts new file mode 100644 index 0000000..4c6f822 --- /dev/null +++ b/src/isSignal.ts @@ -0,0 +1,11 @@ +import { SIGNAL } from './signal'; +import { STRUCT_SIGNAL, StructSignal, StructSignalReadonly } from './structSignal'; + +export function isSignal | StructSignalReadonly>(reactive: S | unknown): reactive is S { + return reactive instanceof Object && SIGNAL in reactive; +} +export function isStructSignal | StructSignalReadonly>( + reactive: S | unknown, +): reactive is S { + return reactive instanceof Object && STRUCT_SIGNAL in reactive; +} diff --git a/src/logger/logger.ts b/src/logger/logger.ts new file mode 100644 index 0000000..46d5be3 --- /dev/null +++ b/src/logger/logger.ts @@ -0,0 +1,16 @@ +export class NamedLogger { + constructor(private name: string) {}; + + log(...args: any[]) { + console.log(this.name + ': ' + args.join(' ')); + } + info(...args: any[]) { + console.info(this.name + ': ' + args.join(' ')); + } + error(...args: any[]) { + console.error(this.name + ': ' + args.join(' ')); + } + warn(...args: any[]) { + console.warn(this.name + ': ' + args.join(' ')); + } +} \ No newline at end of file diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/reaction.ts b/src/reaction.ts index 94a981f..7979add 100644 --- a/src/reaction.ts +++ b/src/reaction.ts @@ -1,24 +1,32 @@ -import { un } from 'unsubscriber'; -import { - autorun as autorunOrigin, - reaction as reactionOrigin, - when as whenOrigin -} from 'mobx'; +import type { IAutorunOptions, IReactionOptions } from 'mobx'; +import type { IReactionPublic } from 'mobx'; +import { autorun as autorunOrigin, reaction as reactionOrigin, when as whenOrigin } from 'mobx'; +import { un } from './unsubscriber'; -export const autorun = (expression: () => void) => ( - un(autorunOrigin(expression)) -); +export const autorun = (expression: (r: IReactionPublic) => void, opts?: IAutorunOptions) => + un(autorunOrigin(expression, opts)); -export const reaction = (expression: () => T, listener: (value: T, prev: T) => void) => ( - un(reactionOrigin(expression, listener)) -); +export const reaction = ( + expression: (r: IReactionPublic) => T, + listener: (value: T, prev: FireImmediately extends true ? T | undefined : T, r: IReactionPublic) => void, + opts?: IReactionOptions, +) => un(reactionOrigin(expression, listener, opts)); -export const sync = (expression: () => T, listener: (value: T, prev: T | undefined) => void) => ( - un(reactionOrigin(expression, listener, { fireImmediately: true })) -); +export const sync = (expression: (r: IReactionPublic) => T, listener?: (value: T, prev: T | undefined) => void) => + listener ? un(reactionOrigin(expression, listener, { fireImmediately: true })) : un(autorunOrigin(expression)); -export const when = (expression: () => boolean): Promise & { cancel(): void } => { - const promise = whenOrigin(expression); - un(promise.cancel); - return promise; -} \ No newline at end of file +// TODO: remove ts errors +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-expect-error +export const when: typeof whenOrigin = (...args) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + const result = whenOrigin(...args); + + if (result instanceof Promise) { + un(result.cancel); + return result; + } + + return un(result); +}; diff --git a/src/runInstanceInit.ts b/src/runInstanceInit.ts new file mode 100644 index 0000000..c1ba8d3 --- /dev/null +++ b/src/runInstanceInit.ts @@ -0,0 +1,19 @@ +import { Initable } from './classes/Initable'; +import { collect, Unsubscriber } from './unsubscriber/index'; +import { untracked } from './untracked'; + +export function runInstanceInit(instance: unknown, unsubs: Unsubscriber) { + collect( + unsubs, + untracked.func(() => { + if (instance instanceof Initable) { + instance.runInit(); + return; + } + if (instance instanceof Object && 'init' in instance && typeof instance.init === 'function') { + instance.init(); + return; + } + }), + ); +} diff --git a/src/service.ts b/src/service.ts deleted file mode 100644 index 63b73ea..0000000 --- a/src/service.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { untracked } from 'mobx'; -import { provide, destroy } from 'provi/client' - -const INSTANTIATE_KEY = Symbol('instantiate'); -const DESTROY_KEY = Symbol('destroy'); - -interface ServiceFactory { - (Class: (() => T) | (new () => T)): T; - instantiate(instance: object); - destroy(instance: object); -} - -export const service: ServiceFactory = ((Class: (() => T) | (new () => T)) => { - let instance; - - return new Proxy({}, { - get(_target, prop) { - if (prop === DESTROY_KEY) { - if (instance) { - destroy(Class); - instance = void 0; - } - return; - } - if (!instance) { - instance = untracked(() => provide(Class)); - }; - if (prop !== INSTANTIATE_KEY) { - return instance[prop]; - } - }, - set(_target, prop, value) { - if (!instance) { - instance = untracked(() => provide(Class)); - } - instance[prop] = value; - return true; - } - }); -}) as any; - -service.instantiate = (instance: object) => instance[INSTANTIATE_KEY]; -service.destroy = (instance: object) => instance[DESTROY_KEY]; diff --git a/src/service/ServiceHandler.ts b/src/service/ServiceHandler.ts new file mode 100644 index 0000000..223eb42 --- /dev/null +++ b/src/service/ServiceHandler.ts @@ -0,0 +1,276 @@ +import { Initable } from '../classes/Initable'; +import { attach, collect, run, unsubscriber } from '../unsubscriber'; +import { untracked } from '../untracked'; +import { getZoneId, type ZoneId } from './zones'; + +export type Ctor = new () => T; + +export type DeepPartial = T extends object + ? { + [P in keyof T]?: DeepPartial; + } + : T; + +export const SERVICE_KEY = Symbol('service'); + +export interface ServiceInternal { + [SERVICE_KEY]: ServiceHandler; +} + +export const getGlobalServicesRegistry = () => { + const zoneId = getZoneId(); + if (!globalServicesRegistryByZones.has(zoneId)) { + const registry = new Set(); + globalServicesRegistryByZones.set(zoneId, registry); + return registry; + } + return globalServicesRegistryByZones.get(zoneId)!; +}; + +/** + * Registry of all currently active services + * Necessary for destroy all machanism + */ +const globalServicesRegistryByZones = new Map>(); + +class ServiceState { + /** + * Instance of service + */ + public rawInstance?: T; + + /** + * Set of destroy listeners + */ + public unsubs = unsubscriber(); +} + +/** + * Service implementation + */ +export class ServiceHandler { + /** + * Service state splitted by zones + */ + private stateByZones = new Map>(); + + /** + * Service class can be overrided in child packages + */ + private FinalClass: Ctor; + + /** + * List of configures functions + */ + private configures: ((instance: T & ServiceInternal) => void)[] = []; + + /** + * Proxy of service + */ + public proxy: T & ServiceInternal; + + /** + * Service handler constructor + */ + constructor(Class: Ctor) { + this.FinalClass = Class; + this.proxy = this.createProxy(); + } + + /** + * run all configure functions for all overrided constructors + */ + private runConfigures() { + this.configures.forEach(fn => fn(this.proxy)); + } + + /** + * Clear service artifacts + */ + private clearing() { + // Delete info about service existance in global service registry + getGlobalServicesRegistry().delete(this.proxy); + + // Delete state for current zone in service handler + this.stateByZones.delete(getZoneId()); + } + + /** + * Register function who clearing service after destroy, and + * register service in global registry + */ + private register() { + getGlobalServicesRegistry().add(this.proxy); + this.unsubs.add(this.clearing.bind(this)); + } + + /** + * run service init + */ + private init() { + const { rawInstance } = this; + + if (rawInstance instanceof Initable) { + rawInstance.runInit(); + + // Add Initable destroy to scoped unsubscribers + attach(rawInstance.destroy.bind(rawInstance)); + return; + } + if (rawInstance instanceof Object && 'init' in rawInstance && typeof rawInstance.init === 'function') { + rawInstance.init(); + return; + } + } + + /** + * run service init, and collect all unsubscribers during init phase + */ + private runInit() { + collect(this.unsubs, this.init.bind(this)); + } + + /** + * Create the proxy for service + */ + private createProxy() { + // eslint-disable-next-line @typescript-eslint/no-this-alias, unicorn/no-this-assignment + const handler = this; + + const getRawInstance = this.getRawInstance.bind(this) as () => { [prop: string | symbol]: unknown }; + const ensureInstantiate = this.ensureInstantiate.bind(this); + + // Create the proxy for service + return new Proxy({} as T & ServiceInternal, { + get(_target, prop) { + if (prop === SERVICE_KEY) { + return handler; + } + ensureInstantiate(); + return getRawInstance()[prop]; + }, + set(_target, prop, value) { + ensureInstantiate(); + getRawInstance()[prop] = value; + return true; + }, + ownKeys(_target) { + ensureInstantiate(); + return Object.keys(getRawInstance()); + }, + has(_target, key) { + ensureInstantiate(); + return key in getRawInstance(); + }, + getOwnPropertyDescriptor(_target, prop) { + ensureInstantiate(); + const descriptor = Object.getOwnPropertyDescriptor(getRawInstance(), prop); + if (!descriptor) { + return descriptor; + } + return Object.assign(descriptor, { configurable: true }); + }, + defineProperty(_target, prop, attributes) { + ensureInstantiate(); + Object.defineProperty(getRawInstance(), prop, attributes); + return true; + }, + deleteProperty(_target, prop) { + ensureInstantiate(); + delete getRawInstance()[prop]; + return true; + }, + }); + } + + /** + * Return state only for current zone + */ + private getStateByCurrentZone() { + const zoneId = getZoneId(); + let state = this.stateByZones.get(zoneId); + if (!state) { + state = new ServiceState(); + this.stateByZones.set(zoneId, state); + } + return state; + } + + /** + * Zoned get raw instance + */ + private get rawInstance(): T | undefined { + return this.getStateByCurrentZone().rawInstance; + } + + /** + * Zoned set raw instance + */ + private set rawInstance(value: T | undefined) { + this.getStateByCurrentZone().rawInstance = value; + } + + /** + * Zoned get unsubs + */ + private get unsubs() { + return this.getStateByCurrentZone().unsubs; + } + + // Public: + + /** + * Get raw instance + */ + public getRawInstance() { + return this.rawInstance; + } + + /** + * We should create instance of service class if it doesnot exists yet + */ + public ensureInstantiate() { + if (!this.rawInstance) { + untracked(() => { + this.rawInstance = new this.FinalClass(); + this.register(); + this.runConfigures(); + this.runInit(); + }); + } + } + + /** + * Set overrided class for service + */ + public override(OverridedClass: Ctor) { + if (this.rawInstance) { + throw new Error('You should override service before its instantiate'); + } + this.FinalClass = OverridedClass; + } + + /** + * Destroy service, run unsubscribers, and cleaning from global service registry + */ + public destroy() { + if (this.rawInstance && this.unsubs) { + run(this.unsubs); + } + } + + /** + * Add configure function for service + */ + public configure(config: (instance: T & ServiceInternal) => void) { + this.configures.push(config); + } + + /** + * Add mock for service + */ + public mock(impl: DeepPartial) { + this.rawInstance = impl as T; + this.register(); + } +} diff --git a/src/service/index.ts b/src/service/index.ts new file mode 100644 index 0000000..a5581f9 --- /dev/null +++ b/src/service/index.ts @@ -0,0 +1,3 @@ +export { service } from './service'; +export { isolate, isolated } from './isolate'; +export { initAsyncHooksZonator } from './zones'; diff --git a/src/service/isolate.test.ts b/src/service/isolate.test.ts new file mode 100644 index 0000000..1ab84c6 --- /dev/null +++ b/src/service/isolate.test.ts @@ -0,0 +1,150 @@ +import * as fs from 'node:fs'; +import { beforeAll, expect, it, vi } from 'vitest'; +import { service, un } from '..'; +import { getZoneId } from './zones'; +import { initAsyncHooksZonator, isolate } from '.'; + +beforeAll(async () => { + await initAsyncHooksZonator(); +}); + +it('isolate works', async () => { + const destroy_spy = vi.fn(); + class A { + value = 0; + + init() { + un(() => destroy_spy(this.value)); + } + } + + const a = service(A); + + a.value = 10; + + const zone_id_0 = getZoneId(); + expect(zone_id_0).toBe(0); + + // Serial isolate scope + await isolate(async () => { + const zone_id_1 = getZoneId(); + expect(zone_id_1).not.toBe(zone_id_0); + + expect(a.value).toBe(0); + + a.value = 11; + + // Nested isolate scope + await isolate(async () => { + const zone_id_2 = getZoneId(); + expect(zone_id_2).not.toBe(zone_id_0); + expect(zone_id_2).not.toBe(zone_id_1); + + let timeoutPromiseResolve: () => void; + const timeoutPromise = new Promise(resolve => (timeoutPromiseResolve = resolve)); + + expect(a.value).toBe(0); + a.value = 12; + expect(a.value).toBe(12); + + // Test that timeout operation not change current zone + setTimeout(() => { + const zone_id_timeout_2 = getZoneId(); + expect(zone_id_timeout_2).toBe(zone_id_2); + expect(a.value).toBe(12); + a.value = 121; + expect(a.value).toBe(121); + timeoutPromiseResolve(); + }, 10); + await timeoutPromise; + + let intervalPromiseResolve: () => void; + const intervalPromise = new Promise(resolve => (intervalPromiseResolve = resolve)); + + expect(a.value).toBe(121); + a.value = 122; + expect(a.value).toBe(122); + + let intervalsCount = 3; + // Test that interval operation not change current zone + const int = setInterval(() => { + intervalsCount--; + const zone_id_interval_2 = getZoneId(); + expect(zone_id_interval_2).toBe(zone_id_2); + a.value += 1; + if (intervalsCount === 0) { + clearInterval(int); + intervalPromiseResolve(); + } + }, 10); + await intervalPromise; + + expect(a.value).toBe(125); + + // Test that nested async operation not change current zone + await (async () => { + const zone_id_async_2 = getZoneId(); + expect(zone_id_async_2).toBe(zone_id_2); + expect(a.value).toBe(125); + a.value = 126; + expect(a.value).toBe(126); + // Test nested nested async operation + await (async () => { + const zone_id_async_2_1 = getZoneId(); + expect(zone_id_async_2_1).toBe(zone_id_2); + expect(a.value).toBe(126); + a.value = 127; + expect(a.value).toBe(127); + })(); + })(); + + expect(a.value).toBe(127); + + expect(destroy_spy).not.toBeCalled(); + }); + expect(destroy_spy).toBeCalledWith(127); + destroy_spy.mockClear(); + + expect(zone_id_1).toBe(getZoneId()); + + expect(a.value).toBe(11); + expect(destroy_spy).not.toBeCalled(); + }); + expect(destroy_spy).toBeCalledWith(11); + destroy_spy.mockClear(); + + expect(zone_id_0).toBe(getZoneId()); + + expect(a.value).toBe(10); + + // Next serial isolated scope + await isolate(async () => { + expect(a.value).toBe(0); + a.value = 9; + + expect(destroy_spy).not.toBeCalled(); + }); + expect(destroy_spy).toBeCalledWith(9); + destroy_spy.mockClear(); + + expect(a.value).toBe(10); +}); + +vi.mock('node:fs'); + +it('isolate log not destroyed nested resource', async () => { + const consoleMock = vi.spyOn(console, 'warn'); + + let timeout: NodeJS.Timeout; + await isolate(async () => { + timeout = setTimeout(() => {}, 100); + }); + clearTimeout(timeout!); + expect(consoleMock).toBeCalledWith('zones: Isolation destroyed but zone has not fulfilled async resources'); +}); + +it('reinit zonator warning', async () => { + const consoleMock = vi.spyOn(console, 'warn'); + initAsyncHooksZonator(); + expect(consoleMock).toBeCalledWith('zones: Attempt reinit zonator for current process'); +}); diff --git a/src/service/isolate.ts b/src/service/isolate.ts new file mode 100644 index 0000000..f312568 --- /dev/null +++ b/src/service/isolate.ts @@ -0,0 +1,8 @@ +import { service } from './service'; +import { createIsolate } from './zones'; + +export const isolate = createIsolate(() => service.destroy()); +export const isolated = + (fn: (...args: Args) => Promise) => + (...args: Args) => + isolate(() => fn(...args)); diff --git a/src/service/service.test.ts b/src/service/service.test.ts new file mode 100644 index 0000000..deb2960 --- /dev/null +++ b/src/service/service.test.ts @@ -0,0 +1,249 @@ +import { expect, it, vi } from 'vitest'; +import { Initable, signal, un, wrapSignal } from '..'; +import { service } from './service'; +import { getGlobalServicesRegistry } from './ServiceHandler'; + +it('service works', () => { + const create_spy = vi.fn(); + const destroy_spy = vi.fn(); + + class A { + m = signal(1); + c = wrapSignal(() => this.m.value + 1); + + constructor() { + create_spy(); + } + init() { + un(destroy_spy); + } + + a() { + return 1; + } + } + + const s = service(A); + + expect(create_spy).not.toBeCalled(); + expect(s.a()).toBe(1); + expect(create_spy).toBeCalled(); + + expect(s.c.value).toBe(2); + s.m.update(v => v + 1); + expect(s.c.value).toBe(3); + + expect(destroy_spy).not.toBeCalled(); + service.destroy(s); + expect(destroy_spy).toBeCalled(); + + create_spy.mockReset(); + destroy_spy.mockReset(); + + s.m(2); + expect(s.c.value).toBe(3); + expect(create_spy).toBeCalled(); + + expect(destroy_spy).not.toBeCalled(); + service.destroy(s); + expect(destroy_spy).toBeCalled(); +}); + +it('service instantiate works', () => { + const create_spy = vi.fn(); + + const s = service( + class { + constructor() { + create_spy(); + } + }, + ); + expect(create_spy).not.toBeCalled(); + + service.instantiate(s); + expect(create_spy).toBeCalled(); +}); + +it('service mock works', () => { + const create_spy = vi.fn(); + class A { + a = 10; + constructor() { + create_spy(); + } + } + + const s = service(A); + service.mock(s, { a: 12 }); + expect(create_spy).not.toBeCalled(); + + expect(s.a).toBe(12); + + service.instantiate(s); + expect(create_spy).not.toBeCalled(); +}); + +it('two services should be independent each other', () => { + class A { + a = 10; + } + const a1 = service(A); + const a2 = service(A); + + a1.a = 11; + a2.a = 12; + expect(a1.a).toBe(11); + expect(a2.a).toBe(12); + + service.destroy(a1); + expect(a1.a).toBe(10); + + expect(a2.a).toBe(12); + service.destroy(a2); + expect(a2.a).toBe(10); +}); + +it('service configure works', () => { + const configureSpy = vi.fn(); + + class A { + a = 10; + } + + const a = service(A); + + service.configure(a, instance => { + instance.a = 20; + + configureSpy(); + }); + + service.instantiate(a); + + expect(configureSpy).toBeCalled(); + + expect(a.a).toBe(20); +}); + +it('service override works', () => { + class A { + a = 10; + action() {} + } + + const a = service(A); + + class B extends A { + action() { + this.a++; + } + act() { + this.action(); + } + } + + const b = service.override(a, B); + b.act(); + + expect(a.a).toBe(11); + expect(b.a).toBe(11); + + expect((a as unknown as B).act).toBeTruthy(); +}); + +it('service overrides this configures works', () => { + const spy = vi.fn(); + + class A { + action(a: string) { + spy(a); + } + } + + const a = service(A); + + service.configure(a, inst => { + inst.action('a_configure'); + }); + + class B extends A { + bAction(a: string) { + this.action(a); + } + } + + const b = service.override(a, B); + + service.configure(b, inst => { + inst.bAction('b_configure'); + }); + + class C extends B { + cAction(a: string) { + this.bAction(a); + } + } + + const c = service.override(b, C); + + service.configure(c, inst => { + inst.cAction('c_configure'); + }); + + expect(spy).toBeCalledTimes(0); + + // make the service and call action + c.cAction('c_action'); + + expect(a).toBe(c); + expect(spy).toHaveBeenNthCalledWith(1, 'a_configure'); + expect(spy).toHaveBeenNthCalledWith(2, 'b_configure'); + expect(spy).toHaveBeenNthCalledWith(3, 'c_configure'); + expect(spy).toHaveBeenNthCalledWith(4, 'c_action'); +}); + +it('destroy all should works', () => { + service.destroy(); + + const spy_a = vi.fn(); + const spy_b = vi.fn(); + const spy_c = vi.fn(); + + class A { + init() { + un(spy_a); + } + } + + service.instantiate(service(A)); + + class B { + init() { + un(spy_b); + } + } + + service.instantiate(service(B)); + + class C extends Initable { + init() { + un(spy_c); + } + } + + service.instantiate(service(C)); + + expect(spy_a).not.toBeCalled(); + expect(spy_b).not.toBeCalled(); + expect(spy_c).not.toBeCalled(); + + expect(getGlobalServicesRegistry().size).toBe(3); + service.destroy(); + + expect(spy_a).toBeCalled(); + expect(spy_b).toBeCalled(); + expect(spy_c).toBeCalled(); + + expect(getGlobalServicesRegistry().size).toBe(0); +}); diff --git a/src/service/service.ts b/src/service/service.ts new file mode 100644 index 0000000..3ea2ea0 --- /dev/null +++ b/src/service/service.ts @@ -0,0 +1,60 @@ +import { + Ctor, + DeepPartial, + getGlobalServicesRegistry, + SERVICE_KEY, + ServiceHandler, + ServiceInternal, +} from './ServiceHandler'; + +interface ServiceFactory { + (Class: Ctor): T & ServiceInternal; + mock(serviceInstance: ServiceInternal, impl: DeepPartial): T; + instantiate(...serviceInstances: ServiceInternal[]): void; + destroy(...serviceInstances: ServiceInternal[]): void; + isService(instance: T): instance is T & ServiceInternal; + configure(instance: ServiceInternal, config: (instance: T & ServiceInternal) => void): void; + override

(instance: ServiceInternal

, Class: Ctor): T & ServiceInternal; +} + +export const service: ServiceFactory = (Class: Ctor): T & ServiceInternal => { + const handler = new ServiceHandler(Class); + return handler.proxy; +}; + +service.instantiate = (...instances: ServiceInternal[]) => { + instances.forEach(instance => instance[SERVICE_KEY].ensureInstantiate()); +}; + +service.destroy = (...instances: ServiceInternal[]) => { + if (instances.length === 0) { + instances = [...getGlobalServicesRegistry()] as ServiceInternal[]; + } + + instances.forEach(instance => instance[SERVICE_KEY].destroy()); +}; + +service.configure = ( + instance: ServiceInternal, + config: (instance: T & ServiceInternal) => void, +): void => { + instance[SERVICE_KEY].configure(config); +}; + +service.mock = >(instance: ServiceInternal, impl: M): T => { + const obj = impl as unknown as T; + instance[SERVICE_KEY].mock(obj as DeepPartial); + return obj; +}; + +service.isService = (instance: T): instance is T & ServiceInternal => { + return !!instance && !!(instance as ServiceInternal)[SERVICE_KEY]; +}; + +service.override =

( + instance: ServiceInternal

, + Class: Ctor, +): T & ServiceInternal => { + instance[SERVICE_KEY].override(Class); + return instance as T & ServiceInternal; +}; diff --git a/src/service/zones.ts b/src/service/zones.ts new file mode 100644 index 0000000..1418950 --- /dev/null +++ b/src/service/zones.ts @@ -0,0 +1,88 @@ +import type * as AsyncHooksModule from 'node:async_hooks'; +import { NamedLogger } from '../logger/logger'; + +const logger = new NamedLogger('zones'); + +type AsyncHooks = typeof AsyncHooksModule; + +export type ZoneId = number; + +const isNode = () => typeof window === 'undefined'; + +let nodeAsyncHooksModulePromise: Promise | undefined; +export const asyncHooksZonator = async () => { + const asyncHooks = await (nodeAsyncHooksModulePromise ??= import('node:async_hooks')); + const zoneIndex = new Map(); + let zoneId: ZoneId = 0; + asyncHooks + .createHook({ + init(asyncId, _type, triggerAsyncId) { + zoneIndex.set(asyncId, zoneIndex.get(triggerAsyncId) ?? 0); + }, + before(asyncId) { + zoneId = zoneIndex.get(asyncId) ?? 0; // root zone + }, + destroy(asyncId) { + zoneIndex.delete(asyncId); + }, + }) + .enable(); + return { + getZoneId: () => zoneId, + ensureZone: () => { + zoneId = asyncHooks.executionAsyncId(); + zoneIndex.set(zoneId, zoneId); + }, + createCheckDestroy: () => { + const keepZoneId = zoneId; + return () => { + if (zoneIndex.has(keepZoneId)) { + logger.warn('Isolation destroyed but zone has not fulfilled async resources'); + } + }; + }, + } satisfies Zonator; +}; + +let asyncHooksZonatorPromise: Promise; +export const initAsyncHooksZonator = async () => { + if (!isNode()) { + throw new Error('AsyncHooks zonator is not available in current environment'); + } + if (zonator) { + logger.warn('Attempt reinit zonator for current process'); + } + zonator = await (asyncHooksZonatorPromise ??= asyncHooksZonator()); +}; + +export interface Zonator { + getZoneId(): ZoneId; + ensureZone(): void; // Function for set current zone_id when new isolate starts + createCheckDestroy(): () => void; +} + +let zonator: Zonator | undefined; + +export const getZoneId = () => zonator?.getZoneId() ?? 0; + +export const createIsolate = + (destroy: () => void) => + (fn: () => Promise): Promise => { + if (!zonator) { + throw new Error('initAsyncHooksZonator should be called for isolate usage'); + } + + let checkZoneDestroy: () => void; + const zonePromise = new Promise((resolve, reject) => { + process.nextTick(() => { + zonator!.ensureZone(); + checkZoneDestroy = zonator!.createCheckDestroy(); + fn() + .finally(() => destroy()) + .then(resolve) + .catch(reject); + }); + }); + zonePromise.finally(() => checkZoneDestroy()); + return zonePromise; + }; diff --git a/src/signal.test.tsx b/src/signal.test.tsx new file mode 100644 index 0000000..505b94e --- /dev/null +++ b/src/signal.test.tsx @@ -0,0 +1,69 @@ +import React, { useState } from 'react'; +import { act, create } from 'react-test-renderer'; +import { describe, expect, it } from 'vitest'; +import { useSignal } from './signal'; +import { observer, signal } from '.'; + +describe('Signal hook', () => { + const render = () => { + const s = signal(1); + + let setA: (value: number) => void = () => void 0; + let setB: (value: number) => void = () => void 0; + + const A = () => { + const [a, sA] = useState(2); + const [b, sB] = useState(3); + + setA = sA; + setB = sB; + + return ; + }; + + const C: React.FC<{ a: number; b: number }> = observer(({ a, b }) => { + const st = useSignal(() => { + return { + s: s.value, + a, + b, + }; + }, [a, b]); + + return ( + + {st.value.s},{st.value.a},{st.value.b} + + ); + }); + + const renderer = create(); + + return { + renderer, + s, + setA, + setB, + }; + }; + + it('should be rendered', async () => { + const { renderer, s, setA, setB } = render(); + + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['1', ',', '2', ',', '3'] }); + await act(() => { + setA(10); + }); + + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['1', ',', '10', ',', '3'] }); + await act(() => { + setB(11); + }); + + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['1', ',', '10', ',', '11'] }); + await act(() => { + s(12); + }); + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['12', ',', '10', ',', '11'] }); + }); +}); diff --git a/src/signal.ts b/src/signal.ts index a3c455d..c110cd1 100644 --- a/src/signal.ts +++ b/src/signal.ts @@ -1,49 +1,79 @@ -import { observable, untracked, computed as mobxComputed, comparer } from 'mobx'; -import { reaction, sync } from './reaction'; +import { comparer, computed as mobxComputed, observable, untracked } from 'mobx'; +import { useEffect, useMemo } from 'react'; + +export const SIGNAL = Symbol('Signal'); + +export interface SignalOptions { + shallow?: boolean; +} export interface SignalReadonly { + [SIGNAL]: true; get value(): T; get(): T; - subscribe(listener: (current: T, prev: T) =>void): () => void; - sync(listener: (current: T, prev: T | undefined) =>void): () => void; } export interface Signal extends SignalReadonly { - (value: T): T, - update(fn: (value: T) => T); + (value: T): void; + update(fn: (value: T) => T): void; } -export function signal(value: T): Signal { - const box = observable.box(value, { equals: comparer.default, deep: false }); - const get = box.get.bind(box); - const set = box.set.bind(box); - return make(get, set); +export function signal(value: T, options?: SignalOptions): Signal { + const box = observable.box(value, { + equals: options?.shallow ? comparer.shallow : comparer.default, + deep: false, + }); + return makeSignal(box.get.bind(box), box.set.bind(box)); } -export function wrap(readfn: () => T): SignalReadonly; -export function wrap(readfn: () => T, writefn: (value: T) => void): Signal; -export function wrap(readfn: () => T, writefn?: (value: T) => void): (SignalReadonly | Signal) { - const box = mobxComputed(readfn, { equals: comparer.shallow }); - const get = box.get.bind(box); - return make(get, writefn); +export function wrapSignal(get: () => T): SignalReadonly; +export function wrapSignal(get: () => T, set: (value: T) => void): Signal; +export function wrapSignal(get: () => T, set?: (value: T) => void): SignalReadonly | Signal { + const box = mobxComputed(get, { equals: comparer.shallow }); + return makeSignal(box.get.bind(box), set!); } -function make(readfn: () => T): SignalReadonly; -function make(readfn: () => T, writefn: (value: T) => void): Signal; -function make(readfn: () => T, writefn?: (value: T) => void): (SignalReadonly | Signal) { - const get = readfn; - const h = writefn || {}; - Object.defineProperty(h, 'value', { get }) - Object.assign(h, { - get, - subscribe: (listener) => reaction(get, listener), - sync: (listener) => sync(get, listener) +function makeSignal(get: () => T): SignalReadonly; +function makeSignal(get: () => T, set: (value: T) => void): Signal; +function makeSignal(get: () => T, set?: (value: T) => void): SignalReadonly | Signal { + const sig = (set as Signal) || ({} as SignalReadonly); + Object.defineProperty(sig, 'value', { get }); + Object.defineProperty(sig, SIGNAL, { enumerable: false, value: true }); + Object.assign(sig, { + get, + }); + if (set) { + Object.assign(sig, { + update: (fn: (value: T) => T) => set(fn(untracked(get))), }); - if (writefn) { - Object.assign(h, { - update: (fn: (value: T) => T) => writefn(fn(untracked(get))), - }) - } - - return h as any; -} \ No newline at end of file + } + + return sig; +} + +export function useSignal(fn: () => T, deps?: D) { + const [instance, signalFn] = useMemo(() => { + const signalFn = signal(fn); + + const instance = wrapSignal(() => { + const fn = signalFn.value; + return fn(); + }); + + return [instance, signalFn]; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // For prevent the error + // Error: Cannot update a component (`Unknown`) while rendering a different component (`Unknown`). + // We should add time for render phase finished before update params, + // that can initiate next update sycle inside current. We use Promise microtask queue for prevent it. + // (I believe one time MobX will implement "Unit of Work" pattern for observer updating) + + useEffect(() => { + signalFn(fn); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, deps || []); + + return instance; +} diff --git a/src/structSignal.test.tsx b/src/structSignal.test.tsx new file mode 100644 index 0000000..0caad46 --- /dev/null +++ b/src/structSignal.test.tsx @@ -0,0 +1,138 @@ +import React, { useState } from 'react'; +import { act, create } from 'react-test-renderer'; +import { describe, expect, it, vi } from 'vitest'; +import { structSignal, useStructSignal } from './structSignal'; +import { reaction, sync } from '.'; +import { observer, signal } from '.'; + +describe('Struct signal', () => { + it('should works', () => { + const a_watch = vi.fn(); + const b_watch = vi.fn(); + + const s = structSignal({ a: 10, b: 11 }); + + reaction( + () => s.a, + val => a_watch(val), + ); + reaction( + () => s.b, + val => b_watch(val), + ); + + expect(a_watch).not.toBeCalled(); + expect(b_watch).not.toBeCalled(); + + s({ a: 10, b: 11 }); + expect(a_watch).not.toBeCalled(); + expect(b_watch).not.toBeCalled(); + s({ a: 10, b: 12 }); + expect(a_watch).not.toBeCalled(); + expect(b_watch).toBeCalled(); + s({ a: 11, b: 12 }); + expect(a_watch).toBeCalled(); + }); + + it('should works with undefined', () => { + const a_watch = vi.fn(); + const b_watch = vi.fn(); + + const s = structSignal(undefined as any); + + sync( + () => s.a, + val => a_watch(val), + ); + sync( + () => 'b' in s, + val => b_watch(val), + ); + + expect(a_watch).toBeCalledWith(undefined); + expect(b_watch).toBeCalledWith(false); + + a_watch.mockClear(); + b_watch.mockClear(); + + s({ a: 10 }); + expect(a_watch).toBeCalledWith(10); + expect(b_watch).not.toBeCalled(); + + a_watch.mockClear(); + + s({ a: 10, b: 'b' }); + expect(a_watch).not.toBeCalled(); + expect(b_watch).toBeCalledWith(true); + + b_watch.mockClear(); + + s(undefined as any); + expect(a_watch).toBeCalledWith(undefined); + expect(b_watch).toBeCalledWith(false); + }); +}); + +describe('Struct signal hook', () => { + const render = () => { + const s = signal(1); + + let setA: (value: number) => void = () => void 0; + let setB: (value: number) => void = () => void 0; + + const A = () => { + const [a, sA] = useState(2); + const [b, sB] = useState(3); + + setA = sA; + setB = sB; + + return ; + }; + + const C: React.FC<{ a: number; b: number }> = observer(({ a, b }) => { + const st = useStructSignal(() => { + return { + s: s.value, + a, + b, + }; + }, [a, b]); + + return ( + + {st.s},{st.a},{st.b} + + ); + }); + + const renderer = create(); + + return { + renderer, + s, + setA, + setB, + }; + }; + + it('should be rendered', async () => { + const { renderer, s, setA, setB } = render(); + + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['1', ',', '2', ',', '3'] }); + await act(() => { + setA(10); + }); + + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['1', ',', '10', ',', '3'] }); + await act(() => { + setB(11); + }); + + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['1', ',', '10', ',', '11'] }); + await act(() => { + s(12); + }); + expect(renderer.toJSON()).toStrictEqual({ type: 'i', props: {}, children: ['12', ',', '10', ',', '11'] }); + }); +}); diff --git a/src/structSignal.ts b/src/structSignal.ts new file mode 100644 index 0000000..c4ff91f --- /dev/null +++ b/src/structSignal.ts @@ -0,0 +1,136 @@ +import type { IComputedValue } from 'mobx'; +import { comparer, computed as mobxComputed, observable } from 'mobx'; +import { useEffect, useMemo } from 'react'; +import { signal } from './signal'; +import { un } from './unsubscriber'; + +export const STRUCT_SIGNAL = Symbol('StructSignal'); + +export type LikeStruct = { [index: string | symbol]: unknown }; + +interface StructSignalInternal { + [STRUCT_SIGNAL]: true; + toJSON(): T; +} + +export type StructSignalReadonly = Readonly & StructSignalInternal; +export type StructSignal = Readonly & StructSignalInternal & ((value: M) => void); + +export function structSignal(value: T): StructSignal { + const box = observable.box(value, { + equals: comparer.shallow, + deep: false, + }); + return makeWriteOptimizer(box.get.bind(box), box.set.bind(box)); +} + +export function wrapStructSignal(get: () => T): StructSignalReadonly; +export function wrapStructSignal( + get: () => T, + set: (value: M) => void, +): StructSignal; +export function wrapStructSignal( + get: () => T, + set?: (value: T) => void, +): StructSignal | StructSignalReadonly { + const box = mobxComputed(get, { equals: comparer.shallow }); + + if (set) { + return makeWriteOptimizer(box.get.bind(box), set) as StructSignal; + } else { + return makeReadOptimizer(box.get.bind(box)) as StructSignalReadonly; + } +} + +function makeWriteOptimizer(get: () => T, set: (value: T) => void): StructSignal { + return makeReadOptimizer(get, { + apply(_target, _thisArg, argArray) { + set(argArray[0]); + }, + }) as StructSignal; +} + +function makeReadOptimizer( + get: () => T, + extraProxyHandler?: ProxyHandler>, +): StructSignalReadonly { + const cacheGet = new Map>(); + const cacheHas = new Map>(); + un(() => { + cacheGet.clear(); + cacheHas.clear(); + }); + + const target = extraProxyHandler && 'apply' in extraProxyHandler ? () => {} : {}; + + return new Proxy(target as StructSignalReadonly, { + ...extraProxyHandler, + get(_target, prop) { + if (prop === STRUCT_SIGNAL) { + return true; + } + if (prop === 'toJSON') { + return get; + } + + let ret; + if (cacheGet.has(prop)) { + ret = cacheGet.get(prop); + } else { + ret = mobxComputed(() => get()?.[prop], { equals: comparer.default }); + cacheGet.set(prop, ret); + } + return ret?.get(); + }, + has(_target, prop) { + if (prop === STRUCT_SIGNAL) { + return true; + } + + let ret; + if (cacheHas.has(prop)) { + ret = cacheHas.get(prop); + } else { + ret = mobxComputed( + () => { + const obj = get(); + return obj instanceof Object && prop in obj; + }, + { equals: comparer.identity }, + ); + cacheHas.set(prop, ret); + } + return !!ret?.get(); + }, + }); +} + +export function useStructSignal( + fn: () => T, + deps?: D, +) { + const [instance, signalFn] = useMemo(() => { + const signalFn = signal(fn); + + const instance = wrapStructSignal(() => { + const fn = signalFn.value; + return fn(); + }); + + return [instance, signalFn]; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // For prevent the error + // Error: Cannot update a component (`Unknown`) while rendering a different component (`Unknown`). + // We should add time for render phase finished before update params, + // that can initiate next update sycle inside current. We use Promise microtask queue for prevent it. + // (I believe one time MobX will implement "Unit of Work" pattern for observer updating) + + useEffect(() => { + signalFn(fn); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, deps || []); + + return instance; +} diff --git a/src/testUtils.ts b/src/testUtils.ts new file mode 100644 index 0000000..01d1c58 --- /dev/null +++ b/src/testUtils.ts @@ -0,0 +1,21 @@ +import { observable } from 'mobx'; +import { LikeStruct, structSignal, StructSignalReadonly } from './structSignal'; + +interface HasInit { + init?: () => void; +} + +export const createHookInstance = ( + Class: new (params: StructSignalReadonly) => M, + params: T, +): M => { + const classInstance = new Class(structSignal(params)) as M & HasInit; + + if (classInstance.init) { + classInstance.init(); + } + + return classInstance; +}; + +export const observableStruct = (value: T) => observable(value, {}, { deep: false }); diff --git a/src/unsubscriber/README.md b/src/unsubscriber/README.md new file mode 100644 index 0000000..4770f28 --- /dev/null +++ b/src/unsubscriber/README.md @@ -0,0 +1,35 @@ +# unsubscriber + +> Originally from [github.com/re-js/unsubscriber](https://github.com/re-js/unsubscriber). + +How to easy collect unsubscribe functions from several sources. + +```javascript +import { unsubscriber, collect, attach, run, scope, un } from '.'; + +const unsubs = unsubscriber(); + +// Run code and collect unsubscribers +const app = collect(usubs, () => { + un(() => { + console.log('unsubscribe'); + }); + + attach(scope(), () => {}); + return new App(); +}); + +const detach = attach(usubs, () => {}); + +run(usubs); +``` + +Context dependent functions who available into the function body: + +```javascript +const app = collect(usubs, () => { + const detach = un(unsubscriber); +}); +``` + +Enjoy your code! diff --git a/src/unsubscriber/index.test.ts b/src/unsubscriber/index.test.ts new file mode 100644 index 0000000..0e3168f --- /dev/null +++ b/src/unsubscriber/index.test.ts @@ -0,0 +1,109 @@ +import { expect, it, vi } from 'vitest'; +import { attach, collect, run, scope, un, Unsubscriber, unsubscriber } from '.'; + +it('unsubscriber works', () => { + const spy1 = vi.fn(); + + const unsubs = unsubscriber(); + expect(unsubs.size).toBe(0); + + attach(unsubs, spy1); + + expect(unsubs.size).toBe(1); + expect(spy1).toBeCalledTimes(0); + run(unsubs); + + expect(spy1).toBeCalledTimes(1); + expect(unsubs.size).toBe(0); +}); + +it('un should return argument function', () => { + const fn = () => {}; + expect(un(fn)).toBe(fn); + expect(attach(fn)).not.toBe(fn); +}); + +it('attach should works', () => { + const spy1 = vi.fn(); + const spy2 = vi.fn(); + const spy3 = vi.fn(); + const spy4 = vi.fn(); + const spy5 = vi.fn(); + const spy6 = vi.fn(); + const spy7 = vi.fn(); + + let detach2: () => void; + + const unsubs = unsubscriber(); + + // Run code and collect "un" calls. + collect(unsubs, () => { + attach(spy1); + detach2 = attach(spy2); + un(spy3); + }); + + const detach5 = attach(unsubs, spy4); + attach(unsubs, spy5); + + // no unsubscribe scope, no error, nothing to do + un(spy6); + attach(spy7)(); // no error if detach out of scope + + expect(unsubs.size).toBe(5); + + detach2!(); + detach5(); + + expect(unsubs.size).toBe(3); + + expect(spy1).toBeCalledTimes(0); + expect(spy3).toBeCalledTimes(0); + expect(spy5).toBeCalledTimes(0); + + run(unsubs); + + expect(unsubs.size).toBe(0); + expect(spy1).toBeCalledTimes(1); + expect(spy3).toBeCalledTimes(1); + expect(spy5).toBeCalledTimes(1); + + expect(spy2).toBeCalledTimes(0); + expect(spy4).toBeCalledTimes(0); + expect(spy6).toBeCalledTimes(0); + expect(spy7).toBeCalledTimes(0); +}); + +it('collect should works', () => { + const spy1 = vi.fn(); + const spy2 = vi.fn(); + let detach2: () => void; + let inner_scope: Unsubscriber; + + const unsubs = unsubscriber(); + + // Run code and collect "un" unsubscribers. + const ret = collect(unsubs, () => { + // each function will be added only one times + un(spy1); + un(spy1); + attach(spy1); + + detach2 = attach(spy2); + inner_scope = scope()!; + return 'foo'; + }); + expect(ret).toBe('foo'); + expect(inner_scope!).toBe(unsubs); + + expect(unsubs.size).toBe(2); + detach2!(); + expect(unsubs.size).toBe(1); + + expect(spy1).toBeCalledTimes(0); + run(unsubs); + + expect(spy1).toBeCalledTimes(1); + expect(unsubs.size).toBe(0); + expect(spy2).toBeCalledTimes(0); +}); diff --git a/src/unsubscriber/index.ts b/src/unsubscriber/index.ts new file mode 100644 index 0000000..9c0c7d4 --- /dev/null +++ b/src/unsubscriber/index.ts @@ -0,0 +1,65 @@ +import { NamedLogger } from '../logger/logger'; + +const logger = new NamedLogger('unsubscriber'); + +export type Unsubscriber = Set<() => void>; + +let context_unsubs: Unsubscriber | void; + +export function unsubscriber(): Unsubscriber { + return new Set(); +} + +export function collect(unsubs: Unsubscriber, fn: () => T): T { + const stack = context_unsubs; + context_unsubs = unsubs; + try { + return fn(); + } finally { + context_unsubs = stack; + } +} + +export function attach(unsubscriber: Unsubscriber, fn: () => void): () => void; +export function attach(fn: () => void): () => void; +export function attach(unsubs: Unsubscriber | (() => void), fn?: () => void): () => void { + if (!fn) { + fn = unsubs as unknown as () => void; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + unsubs = context_unsubs!; + } + if (unsubs) { + (unsubs as Unsubscriber).add(fn); + } + + return () => { + if (unsubs) { + (unsubs as Unsubscriber).delete(fn!); + } + }; +} + +export function un(fn: () => void): () => void { + attach(fn); + return fn; +} + +export function run(unsubs: Unsubscriber): void { + unsubs.forEach(fn => { + try { + if (fn) { + fn(); + } else { + logger.warn('Unexpected undefined unsubscriber'); + } + } catch (e) { + logger.error('Error during unsubscribing', e); + } + }); + unsubs.clear(); +} + +export function scope() { + return context_unsubs; +} diff --git a/src/untracked.test.ts b/src/untracked.test.ts new file mode 100644 index 0000000..e03edd3 --- /dev/null +++ b/src/untracked.test.ts @@ -0,0 +1,32 @@ +import { expect, it, vi } from 'vitest'; +import { autorun, signal, untracked } from '.'; + +it('untracked should work', () => { + const spy = vi.fn(); + + const s = signal(0); + autorun(() => { + spy(untracked(s.get)); + }); + + expect(spy).toBeCalledWith(0); + spy.mockClear(); + s(1); + expect(spy).not.toBeCalled(); +}); + +it('untracked func should work', () => { + const spy = vi.fn(); + + const s = signal(0); + autorun( + untracked.func(() => { + spy(s.value); + }), + ); + + expect(spy).toBeCalledWith(0); + spy.mockClear(); + s(1); + expect(spy).not.toBeCalled(); +}); diff --git a/src/untracked.ts b/src/untracked.ts index 0c762a4..fe9f47a 100644 --- a/src/untracked.ts +++ b/src/untracked.ts @@ -2,15 +2,15 @@ import { untracked as untrackedOrigin } from 'mobx'; interface Untracked { (action: () => T): T; - func: (fn: (...args: T) => R) => ((...args: T) => R); + func: (fn: (...args: T) => R) => (...args: T) => R; } -export const untracked: Untracked = (action) => { +export const untracked: Untracked = action => { return untrackedOrigin(action); -} +}; -untracked.func = (fn) => { - return function handle() { - return untracked(() => fn.apply(this, arguments)); - } -} \ No newline at end of file +untracked.func = fn => { + return function handle(this: unknown, ...args) { + return untracked(() => fn.apply(this, args)); + }; +}; diff --git a/test/event.test.ts b/test/event.test.ts deleted file mode 100644 index 92bf852..0000000 --- a/test/event.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { event } from "../src"; - -it('light event works', () => { - const spy = jest.fn(); - - const a = event(); - a.subscribe(spy); - - expect(spy).not.toBeCalled(); - a(); - expect(spy).toBeCalled(); - a(); - expect(spy).toBeCalledTimes(2); -}); - -it('params event works', () => { - const spy = jest.fn(); - - const a = event(); - a.subscribe(spy); - - expect(spy).not.toBeCalled(); - a(1); - expect(spy).toBeCalledWith(1); - a(2); - expect(spy).toBeCalledTimes(2); - expect(spy).toHaveBeenLastCalledWith(2); -}); \ No newline at end of file diff --git a/test/hook.test.ts b/test/hook.test.ts deleted file mode 100644 index f5ff187..0000000 --- a/test/hook.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -import React from 'react'; -import { scope } from 'unsubscriber'; -import { SignalReadonly, autorun, hook, signal, un } from "../src"; - -const waitNextTick = () => new Promise(resolve => setTimeout(resolve, 0)); - -let useMemoCache; -let unmount; -let unsubs; - -beforeAll(() => { - jest.spyOn(React, 'useMemo') - .mockImplementation((fn, deps) => { - expect(deps).toStrictEqual([]); - - if (useMemoCache) return useMemoCache; - return useMemoCache = fn(); - }); - - jest.spyOn(React, 'useEffect') - .mockImplementation((fn, deps) => { - expect(deps).toStrictEqual([unsubs]); - unmount = fn(); - }); -}); - -afterEach(() => { - useMemoCache = void 0; -}); - -afterAll(() => { - jest.restoreAllMocks() -}) - - -it('hook works', () => { - const create_spy = jest.fn(); - const destroy_spy = jest.fn(); - - class A { - a = signal(0); - b = 0; - constructor() { - unsubs = scope(); - create_spy(); - un(destroy_spy); - - autorun(() => { - this.b = (this.a.value || 0) + 10; - }); - } - } - - const useA = hook(A); - const inst = useA(); - - expect(inst.b).toBe(10); - inst.a(10); - expect(inst.b).toBe(20); - - expect(create_spy).toBeCalled(); - expect(destroy_spy).not.toBeCalled(); - - unmount(); - expect(destroy_spy).toBeCalled(); -}); - -it('hook array params works', async () => { - const create_spy = jest.fn(); - const destroy_spy = jest.fn(); - const params_spy = jest.fn(); - - class A { - constructor(params: SignalReadonly<[number, string]>) { - unsubs = scope(); - create_spy(); - un(destroy_spy); - - params.sync((state) => { - params_spy(state); - }); - } - } - - const useA = hook(A); - const inst = useA([10, 'a']); - - expect(params_spy).toBeCalledWith([10, 'a']); params_spy.mockClear(); - expect(inst).toBe(useA([10, 'a'])); - await waitNextTick(); - expect(params_spy).not.toBeCalled(); - - expect(inst).toBe(useA([10, 'b'])); - await waitNextTick(); - expect(params_spy).toBeCalledWith([10, 'b']); params_spy.mockClear(); - - expect(inst).toBe(useA([10, 'b'])); - await waitNextTick(); - expect(params_spy).not.toBeCalled(); - - expect(create_spy).toBeCalled(); - expect(destroy_spy).not.toBeCalled(); - - unmount(); - expect(destroy_spy).toBeCalled(); -}); - -it('hook struct params works', async () => { - const create_spy = jest.fn(); - const destroy_spy = jest.fn(); - const params_spy = jest.fn(); - - class A { - constructor(params: SignalReadonly<{ a: number; b: string }>) { - unsubs = scope(); - create_spy(); - un(destroy_spy); - - params.sync((state) => { - params_spy(state); - }); - } - } - - const useA = hook(A); - const inst = useA({a: 10, b: 'a'}); - - expect(params_spy).toBeCalledWith({a: 10, b: 'a'}); params_spy.mockClear(); - expect(inst).toBe(useA({a: 10, b: 'a'})); - await waitNextTick(); - expect(params_spy).not.toBeCalled(); - - expect(inst).toBe(useA({a: 10, b: 'b'})); - await waitNextTick(); - expect(params_spy).toBeCalledWith({a: 10, b: 'b'}); params_spy.mockClear(); - - expect(inst).toBe(useA({a: 10, b: 'b'})); - await waitNextTick(); - expect(params_spy).not.toBeCalled(); - - expect(create_spy).toBeCalled(); - expect(destroy_spy).not.toBeCalled(); - - unmount(); - expect(destroy_spy).toBeCalled(); -}); \ No newline at end of file diff --git a/test/service.test.ts b/test/service.test.ts deleted file mode 100644 index 0d8dcc8..0000000 --- a/test/service.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { service, un, signal, wrap } from "../src"; - -it('service works', () => { - const create_spy = jest.fn(); - const destroy_spy = jest.fn(); - - class A { - m = signal(1); - c = wrap(() => this.m.value + 1); - - constructor() { - create_spy(); - un(destroy_spy) - } - - a() { - return 1; - } - } - - const s = service(A); - - expect(create_spy).not.toBeCalled(); - expect(s.a()).toBe(1); - expect(create_spy).toBeCalled(); - - expect(s.c.value).toBe(2); - s.m.update(v => v + 1); - expect(s.c.value).toBe(3); - - expect(destroy_spy).not.toBeCalled(); - service.destroy(s); - expect(destroy_spy).toBeCalled(); - - create_spy.mockReset(); - destroy_spy.mockReset(); - - s.m(2); - expect(s.c.value).toBe(3); - expect(create_spy).toBeCalled(); - - expect(destroy_spy).not.toBeCalled(); - service.destroy(s); - expect(destroy_spy).toBeCalled(); -}); - -it('service instantiate works', () => { - const create_spy = jest.fn(); - - const s = service(class { - constructor() { - create_spy(); - } - }); - expect(create_spy).not.toBeCalled(); - - service.instantiate(s); - expect(create_spy).toBeCalled(); -}); \ No newline at end of file diff --git a/test/untracked.test.ts b/test/untracked.test.ts deleted file mode 100644 index 5a5db43..0000000 --- a/test/untracked.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { untracked, signal, autorun } from "../src"; - -it('untracked should work', () => { - const spy = jest.fn(); - - const s = signal(0); - autorun(() => { - spy(untracked(s.get)); - }) - - expect(spy).toBeCalledWith(0); spy.mockClear(); - s(1); - expect(spy).not.toBeCalled(); -}); - -it('untracked func should work', () => { - const spy = jest.fn(); - - const s = signal(0); - autorun(untracked.func(() => { - spy(s.value); - })) - - expect(spy).toBeCalledWith(0); spy.mockClear(); - s(1); - expect(spy).not.toBeCalled(); -}); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index bbc880a..e4f1650 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,30 @@ { - "compilerOptions": { - "target": "es2018", - "module": "esnext", - "outDir": "./dist", - "moduleResolution": "node", - "declaration": true, - "esModuleInterop": true, - "skipLibCheck": true - }, - "include": ["src"] + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "outDir": "./dist", + "skipLibCheck": true, + /********************* Bundler mode *********************/ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "noImplicitAny": true, + "strictNullChecks": true, + /********************* Linting *********************/ + "strict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noUncheckedIndexedAccess": true, + "noFallthroughCasesInSwitch": true, + "esModuleInterop": true, + "baseUrl": ".", + "types": ["node", "vite/client"], + }, + "include": ["./src/**/*.ts", "./src/**/*.tsx", "./index.ts"], + "exclude": ["node_modules", "../**/src/**/*.test.ts", "../**/src/**/*.test.tsx", "**/setupTests.ts"] } \ No newline at end of file diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 0000000..ed40cc6 --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["./index.ts"], + format: ["cjs", "esm"], // Build for commonJS and ESmodules + dts: true, // Generate declaration file (.d.ts) + splitting: false, + sourcemap: true, + clean: true, +}); \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..5941bb1 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + coverage: { + reporter: ['text', 'json', 'html', 'lcov'], + }, + }, +}) \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 6bc3ddf..b7b0559 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,509 +2,187 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" - integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== - dependencies: - "@babel/highlight" "^7.22.5" - -"@babel/compat-data@^7.22.9": - version "7.22.9" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" - integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== - -"@babel/core@^7.11.6", "@babel/core@^7.12.3": - version "7.22.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" - integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.9" - "@babel/helper-compilation-targets" "^7.22.9" - "@babel/helper-module-transforms" "^7.22.9" - "@babel/helpers" "^7.22.6" - "@babel/parser" "^7.22.7" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.8" - "@babel/types" "^7.22.5" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.1" - -"@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": - version "7.22.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" - integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== - dependencies: - "@babel/types" "^7.22.5" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/helper-compilation-targets@^7.22.9": - version "7.22.9" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" - integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== - dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.5" - browserslist "^4.21.9" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-environment-visitor@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" - integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== - -"@babel/helper-function-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" - integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== - dependencies: - "@babel/template" "^7.22.5" - "@babel/types" "^7.22.5" - -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-module-imports@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" - integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-module-transforms@^7.22.9": - version "7.22.9" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" - integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-module-imports" "^7.22.5" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.5" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - -"@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - -"@babel/helper-validator-identifier@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" - integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== - -"@babel/helper-validator-option@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" - integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== - -"@babel/helpers@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" - integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== - dependencies: - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.6" - "@babel/types" "^7.22.5" - -"@babel/highlight@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" - integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== - dependencies: - "@babel/helper-validator-identifier" "^7.22.5" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.5", "@babel/parser@^7.22.7": - version "7.22.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" - integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" - integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== +"@ampproject/remapping@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== dependencies: - "@babel/helper-plugin-utils" "^7.8.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" - integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/template@^7.22.5", "@babel/template@^7.3.3": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" - integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== - dependencies: - "@babel/code-frame" "^7.22.5" - "@babel/parser" "^7.22.5" - "@babel/types" "^7.22.5" +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== -"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": - version "7.22.8" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" - integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== +"@babel/parser@^7.25.4": + version "7.26.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.5.tgz#6fec9aebddef25ca57a935c86dbb915ae2da3e1f" + integrity sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw== dependencies: - "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.7" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.22.7" - "@babel/types" "^7.22.5" - debug "^4.1.0" - globals "^11.1.0" + "@babel/types" "^7.26.5" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.5", "@babel/types@^7.3.3": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" - integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== +"@babel/types@^7.25.4", "@babel/types@^7.26.5": + version "7.26.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.5.tgz#7a1e1c01d28e26d1fe7f8ec9567b3b92b9d07747" + integrity sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg== dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.5" - to-fast-properties "^2.0.0" + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" +"@bcoe/v8-coverage@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz#bbe12dca5b4ef983a0d0af4b07b9bc90ea0ababa" + integrity sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA== + +"@esbuild/aix-ppc64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz#38848d3e25afe842a7943643cbcd387cc6e13461" + integrity sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA== + +"@esbuild/android-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz#f592957ae8b5643129fa889c79e69cd8669bb894" + integrity sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg== + +"@esbuild/android-arm@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz#72d8a2063aa630308af486a7e5cbcd1e134335b3" + integrity sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q== + +"@esbuild/android-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz#9a7713504d5f04792f33be9c197a882b2d88febb" + integrity sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw== + +"@esbuild/darwin-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz#02ae04ad8ebffd6e2ea096181b3366816b2b5936" + integrity sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA== + +"@esbuild/darwin-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz#9ec312bc29c60e1b6cecadc82bd504d8adaa19e9" + integrity sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA== + +"@esbuild/freebsd-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz#5e82f44cb4906d6aebf24497d6a068cfc152fa00" + integrity sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg== + +"@esbuild/freebsd-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz#3fb1ce92f276168b75074b4e51aa0d8141ecce7f" + integrity sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q== + +"@esbuild/linux-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz#856b632d79eb80aec0864381efd29de8fd0b1f43" + integrity sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg== + +"@esbuild/linux-arm@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz#c846b4694dc5a75d1444f52257ccc5659021b736" + integrity sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA== + +"@esbuild/linux-ia32@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz#f8a16615a78826ccbb6566fab9a9606cfd4a37d5" + integrity sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw== + +"@esbuild/linux-loong64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz#1c451538c765bf14913512c76ed8a351e18b09fc" + integrity sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ== + +"@esbuild/linux-mips64el@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz#0846edeefbc3d8d50645c51869cc64401d9239cb" + integrity sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw== + +"@esbuild/linux-ppc64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz#8e3fc54505671d193337a36dfd4c1a23b8a41412" + integrity sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw== + +"@esbuild/linux-riscv64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz#6a1e92096d5e68f7bb10a0d64bb5b6d1daf9a694" + integrity sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q== + +"@esbuild/linux-s390x@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz#ab18e56e66f7a3c49cb97d337cd0a6fea28a8577" + integrity sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw== + +"@esbuild/linux-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz#8140c9b40da634d380b0b29c837a0b4267aff38f" + integrity sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q== + +"@esbuild/netbsd-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz#65f19161432bafb3981f5f20a7ff45abb2e708e6" + integrity sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw== + +"@esbuild/netbsd-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz#7a3a97d77abfd11765a72f1c6f9b18f5396bcc40" + integrity sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw== + +"@esbuild/openbsd-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz#58b00238dd8f123bfff68d3acc53a6ee369af89f" + integrity sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A== + +"@esbuild/openbsd-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz#0ac843fda0feb85a93e288842936c21a00a8a205" + integrity sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA== + +"@esbuild/sunos-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz#8b7aa895e07828d36c422a4404cc2ecf27fb15c6" + integrity sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig== + +"@esbuild/win32-arm64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz#c023afb647cabf0c3ed13f0eddfc4f1d61c66a85" + integrity sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ== + +"@esbuild/win32-ia32@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz#96c356132d2dda990098c8b8b951209c3cd743c2" + integrity sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA== + +"@esbuild/win32-x64@0.24.2": + version "0.24.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz#34aa0b52d0fbb1a654b596acfa595f0c7b77a77b" + integrity sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" "@istanbuljs/schema@^0.1.2": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.6.2.tgz#bf1d4101347c23e07c029a1b1ae07d550f5cc541" - integrity sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w== - dependencies: - "@jest/types" "^29.6.1" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^29.6.2" - jest-util "^29.6.2" - slash "^3.0.0" - -"@jest/core@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.6.2.tgz#6f2d1dbe8aa0265fcd4fb8082ae1952f148209c8" - integrity sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg== - dependencies: - "@jest/console" "^29.6.2" - "@jest/reporters" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^29.5.0" - jest-config "^29.6.2" - jest-haste-map "^29.6.2" - jest-message-util "^29.6.2" - jest-regex-util "^29.4.3" - jest-resolve "^29.6.2" - jest-resolve-dependencies "^29.6.2" - jest-runner "^29.6.2" - jest-runtime "^29.6.2" - jest-snapshot "^29.6.2" - jest-util "^29.6.2" - jest-validate "^29.6.2" - jest-watcher "^29.6.2" - micromatch "^4.0.4" - pretty-format "^29.6.2" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.6.2.tgz#794c0f769d85e7553439d107d3f43186dc6874a9" - integrity sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q== - dependencies: - "@jest/fake-timers" "^29.6.2" - "@jest/types" "^29.6.1" - "@types/node" "*" - jest-mock "^29.6.2" - -"@jest/expect-utils@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.2.tgz#1b97f290d0185d264dd9fdec7567a14a38a90534" - integrity sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg== - dependencies: - jest-get-type "^29.4.3" - -"@jest/expect@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.6.2.tgz#5a2ad58bb345165d9ce0a1845bbf873c480a4b28" - integrity sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg== - dependencies: - expect "^29.6.2" - jest-snapshot "^29.6.2" - -"@jest/fake-timers@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.6.2.tgz#fe9d43c5e4b1b901168fe6f46f861b3e652a2df4" - integrity sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA== - dependencies: - "@jest/types" "^29.6.1" - "@sinonjs/fake-timers" "^10.0.2" - "@types/node" "*" - jest-message-util "^29.6.2" - jest-mock "^29.6.2" - jest-util "^29.6.2" - -"@jest/globals@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.6.2.tgz#74af81b9249122cc46f1eb25793617eec69bf21a" - integrity sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw== - dependencies: - "@jest/environment" "^29.6.2" - "@jest/expect" "^29.6.2" - "@jest/types" "^29.6.1" - jest-mock "^29.6.2" - -"@jest/reporters@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.6.2.tgz#524afe1d76da33d31309c2c4a2c8062d0c48780a" - integrity sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" - "@jridgewell/trace-mapping" "^0.3.18" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^29.6.2" - jest-util "^29.6.2" - jest-worker "^29.6.2" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - v8-to-istanbul "^9.0.1" - -"@jest/schemas@^29.6.0": - version "29.6.0" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.0.tgz#0f4cb2c8e3dca80c135507ba5635a4fd755b0040" - integrity sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ== - dependencies: - "@sinclair/typebox" "^0.27.8" - -"@jest/source-map@^29.6.0": - version "29.6.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.0.tgz#bd34a05b5737cb1a99d43e1957020ac8e5b9ddb1" - integrity sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.18" - callsites "^3.0.0" - graceful-fs "^4.2.9" - -"@jest/test-result@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.6.2.tgz#fdd11583cd1608e4db3114e8f0cce277bf7a32ed" - integrity sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw== - dependencies: - "@jest/console" "^29.6.2" - "@jest/types" "^29.6.1" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.6.2.tgz#585eff07a68dd75225a7eacf319780cb9f6b9bf4" - integrity sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw== - dependencies: - "@jest/test-result" "^29.6.2" - graceful-fs "^4.2.9" - jest-haste-map "^29.6.2" - slash "^3.0.0" - -"@jest/transform@^29.6.2": - version "29.6.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.6.2.tgz#522901ebbb211af08835bc3bcdf765ab778094e3" - integrity sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^29.6.1" - "@jridgewell/trace-mapping" "^0.3.18" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.6.2" - jest-regex-util "^29.4.3" - jest-util "^29.6.2" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.2" - -"@jest/types@^29.6.1": - version "29.6.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.1.tgz#ae79080278acff0a6af5eb49d063385aaa897bf2" - integrity sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw== - dependencies: - "@jest/schemas" "^29.6.0" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": +"@jridgewell/gen-mapping@^0.3.2": version "0.3.3" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== @@ -513,16 +191,35 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" + integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + "@jridgewell/sourcemap-codec@1.4.14": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" @@ -533,7 +230,20 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": version "0.3.18" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== @@ -541,346 +251,292 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - -"@sinonjs/commons@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" - integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== - dependencies: - type-detect "4.0.8" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@rollup/rollup-android-arm-eabi@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.31.0.tgz#d4dd60da0075a6ce9a6c76d71b8204f3e1822285" + integrity sha512-9NrR4033uCbUBRgvLcBrJofa2KY9DzxL2UKZ1/4xA/mnTNyhZCWBuD8X3tPm1n4KxcgaraOYgrFKSgwjASfmlA== + +"@rollup/rollup-android-arm64@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.31.0.tgz#25c4d33259a7a2ccd2f52a5ffcc0bb3ab3f0729d" + integrity sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g== + +"@rollup/rollup-darwin-arm64@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.31.0.tgz#d137dff254b19163a6b52ac083a71cd055dae844" + integrity sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g== + +"@rollup/rollup-darwin-x64@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.31.0.tgz#58ff20b5dacb797d3adca19f02a21c532f9d55bf" + integrity sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ== + +"@rollup/rollup-freebsd-arm64@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.31.0.tgz#96ce1a241c591ec3e068f4af765d94eddb24e60c" + integrity sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew== + +"@rollup/rollup-freebsd-x64@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.31.0.tgz#e59e7ede505be41f0b4311b0b943f8eb44938467" + integrity sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA== + +"@rollup/rollup-linux-arm-gnueabihf@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.31.0.tgz#e455ca6e4ff35bd46d62201c153352e717000a7b" + integrity sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw== + +"@rollup/rollup-linux-arm-musleabihf@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.31.0.tgz#bc1a93d807d19e70b1e343a5bfea43723bcd6327" + integrity sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg== + +"@rollup/rollup-linux-arm64-gnu@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.31.0.tgz#f38bf843f1dc3d5de680caf31084008846e3efae" + integrity sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA== + +"@rollup/rollup-linux-arm64-musl@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.31.0.tgz#b3987a96c18b7287129cf735be2dbf83e94d9d05" + integrity sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g== + +"@rollup/rollup-linux-loongarch64-gnu@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.31.0.tgz#0f0324044e71c4f02e9f49e7ec4e347b655b34ee" + integrity sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ== + +"@rollup/rollup-linux-powerpc64le-gnu@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.31.0.tgz#809479f27f1fd5b4eecd2aa732132ad952d454ba" + integrity sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ== + +"@rollup/rollup-linux-riscv64-gnu@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.31.0.tgz#7bc75c4f22db04d3c972f83431739cfa41c6a36e" + integrity sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw== + +"@rollup/rollup-linux-s390x-gnu@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.31.0.tgz#cfe8052345c55864d83ae343362cf1912480170e" + integrity sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ== + +"@rollup/rollup-linux-x64-gnu@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.31.0.tgz#c6b048f1e25f3fea5b4bd246232f4d07a159c5a0" + integrity sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g== + +"@rollup/rollup-linux-x64-musl@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.31.0.tgz#615273ac52d1a201f4de191cbd3389016a9d7d80" + integrity sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA== + +"@rollup/rollup-win32-arm64-msvc@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.31.0.tgz#32ed85810c1b831c648eca999d68f01255b30691" + integrity sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw== + +"@rollup/rollup-win32-ia32-msvc@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.31.0.tgz#d47effada68bcbfdccd30c4a788d42e4542ff4d3" + integrity sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ== + +"@rollup/rollup-win32-x64-msvc@4.31.0": + version "4.31.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.31.0.tgz#7a2d89a82cf0388d60304964217dd7beac6de645" + integrity sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw== + +"@types/estree@1.0.6", "@types/estree@^1.0.0": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== -"@sinonjs/fake-timers@^10.0.2": - version "10.3.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" - integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== +"@types/node@20.12.7": + version "20.12.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.7.tgz#04080362fa3dd6c5822061aa3124f5c152cff384" + integrity sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg== dependencies: - "@sinonjs/commons" "^3.0.0" + undici-types "~5.26.4" -"@types/babel__core@^7.1.14": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b" - integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" +"@types/prop-types@*": + version "15.7.14" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.14.tgz#1433419d73b2a7ebfc6918dcefd2ec0d5cd698f2" + integrity sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ== -"@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== +"@types/react@18.2.21": + version "18.2.21" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.21.tgz#774c37fd01b522d0b91aed04811b58e4e0514ed9" + integrity sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA== dependencies: - "@babel/types" "^7.0.0" + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" -"@types/babel__template@*": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" +"@types/scheduler@*": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.23.0.tgz#0a6655b3e2708eaabca00b7372fafd7a792a7b09" + integrity sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw== -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.1.tgz#dd6f1d2411ae677dcb2db008c962598be31d6acf" - integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== +"@vitest/coverage-v8@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-3.0.2.tgz#7d1f8e27fb0ebbc0c3133161e32883fc89244004" + integrity sha512-U+hZYb0FtgNDb6B3E9piAHzXXIuxuBw2cd6Lvepc9sYYY4KjgiwCBmo3Sird9ZRu3ggLpLBTfw1ZRr77ipiSfw== + dependencies: + "@ampproject/remapping" "^2.3.0" + "@bcoe/v8-coverage" "^1.0.2" + debug "^4.4.0" + istanbul-lib-coverage "^3.2.2" + istanbul-lib-report "^3.0.1" + istanbul-lib-source-maps "^5.0.6" + istanbul-reports "^3.1.7" + magic-string "^0.30.17" + magicast "^0.3.5" + std-env "^3.8.0" + test-exclude "^7.0.1" + tinyrainbow "^2.0.0" + +"@vitest/expect@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.0.2.tgz#26a480597a80402f972b1ac8478071b5fd66a698" + integrity sha512-dKSHLBcoZI+3pmP5hiZ7I5grNru2HRtEW8Z5Zp4IXog8QYcxhlox7JUPyIIFWfN53+3HW3KPLIl6nSzUGgKSuQ== dependencies: - "@babel/types" "^7.20.7" + "@vitest/spy" "3.0.2" + "@vitest/utils" "3.0.2" + chai "^5.1.2" + tinyrainbow "^2.0.0" -"@types/graceful-fs@^4.1.3": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" - integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== +"@vitest/mocker@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-3.0.2.tgz#b49987b7293fdca74bb859f45ad84dbe521171d8" + integrity sha512-Hr09FoBf0jlwwSyzIF4Xw31OntpO3XtZjkccpcBf8FeVW3tpiyKlkeUzxS/txzHqpUCNIX157NaTySxedyZLvA== dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + "@vitest/spy" "3.0.2" + estree-walker "^3.0.3" + magic-string "^0.30.17" -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== +"@vitest/pretty-format@3.0.2", "@vitest/pretty-format@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-3.0.2.tgz#d1d0ac72a7b9ed6e8421aa54686b925b72a91fab" + integrity sha512-yBohcBw/T/p0/JRgYD+IYcjCmuHzjC3WLAKsVE4/LwiubzZkE8N49/xIQ/KGQwDRA8PaviF8IRO8JMWMngdVVQ== dependencies: - "@types/istanbul-lib-coverage" "*" + tinyrainbow "^2.0.0" -"@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== +"@vitest/runner@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-3.0.2.tgz#bea5a177e8ca278c9eaaa68a80dda038a33a0081" + integrity sha512-GHEsWoncrGxWuW8s405fVoDfSLk6RF2LCXp6XhevbtDjdDme1WV/eNmUueDfpY1IX3MJaCRelVCEXsT9cArfEg== dependencies: - "@types/istanbul-lib-report" "*" + "@vitest/utils" "3.0.2" + pathe "^2.0.1" -"@types/jest@^29.5.3": - version "29.5.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.3.tgz#7a35dc0044ffb8b56325c6802a4781a626b05777" - integrity sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA== +"@vitest/snapshot@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-3.0.2.tgz#c3029d298c905f40ec3f238cab1130c87175a47e" + integrity sha512-h9s67yD4+g+JoYG0zPCo/cLTabpDqzqNdzMawmNPzDStTiwxwkyYM1v5lWE8gmGv3SVJ2DcxA2NpQJZJv9ym3g== dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" + "@vitest/pretty-format" "3.0.2" + magic-string "^0.30.17" + pathe "^2.0.1" -"@types/node@*": - version "20.4.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.7.tgz#74d323a93f1391a63477b27b9aec56669c98b2ab" - integrity sha512-bUBrPjEry2QUTsnuEjzjbS7voGWCc30W0qzgMf90GPeDGFRakvrz47ju+oqDAKCXLUCe39u57/ORMl/O/04/9g== - -"@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== - -"@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== - -"@types/yargs@^17.0.8": - version "17.0.24" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" - integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== +"@vitest/spy@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-3.0.2.tgz#0e306746cc56943db75b69449747483ba466f74a" + integrity sha512-8mI2iUn+PJFMT44e3ISA1R+K6ALVs47W6eriDTfXe6lFqlflID05MB4+rIFhmDSLBj8iBsZkzBYlgSkinxLzSQ== dependencies: - "@types/yargs-parser" "*" + tinyspy "^3.0.2" -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== +"@vitest/utils@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-3.0.2.tgz#dff19c1d05890c93a2c4d0ff861e65fb81224d52" + integrity sha512-Qu01ZYZlgHvDP02JnMBRpX43nRaZtNpIzw3C1clDXmn8eakgX6iQVGzTQ/NjkIr64WD8ioqOjkaYRVvHQI5qiw== dependencies: - type-fest "^0.21.3" + "@vitest/pretty-format" "3.0.2" + loupe "^3.1.2" + tinyrainbow "^2.0.0" ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" +ansi-regex@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== -anymatch@^3.0.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -babel-jest@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.6.2.tgz#cada0a59e07f5acaeb11cbae7e3ba92aec9c1126" - integrity sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A== - dependencies: - "@jest/transform" "^29.6.2" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.5.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== -babel-plugin-jest-hoist@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz#a97db437936f441ec196990c9738d4b88538618a" - integrity sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - -babel-preset-jest@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz#57bc8cc88097af7ff6a5ab59d1cd29d52a5916e2" - integrity sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg== - dependencies: - babel-plugin-jest-hoist "^29.5.0" - babel-preset-current-node-syntax "^1.0.0" +assertion-error@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: balanced-match "^1.0.0" - concat-map "0.0.1" -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +bundle-require@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-5.1.0.tgz#8db66f41950da3d77af1ef3322f4c3e04009faee" + integrity sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA== dependencies: - fill-range "^7.0.1" + load-tsconfig "^0.2.3" -browserslist@^4.21.9: - version "4.21.10" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0" - integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== - dependencies: - caniuse-lite "^1.0.30001517" - electron-to-chromium "^1.4.477" - node-releases "^2.0.13" - update-browserslist-db "^1.0.11" +cac@^6.7.14: + version "6.7.14" + resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" + integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== +chai@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.2.tgz#3afbc340b994ae3610ca519a6c70ace77ad4378d" + integrity sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw== dependencies: - fast-json-stable-stringify "2.x" + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" -bser@2.1.1: +check-error@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001517: - version "1.0.30001519" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" - integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -ci-info@^3.2.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" + integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== -cjs-module-lexer@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" - integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== +chokidar@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" + integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -collect-v8-coverage@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" - integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" + readdirp "^4.0.1" color-convert@^2.0.1: version "2.0.1" @@ -889,337 +545,166 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +consola@^3.2.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.4.0.tgz#4cfc9348fd85ed16a17940b3032765e31061ab88" + integrity sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA== -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +cross-spawn@^7.0.0: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" which "^2.0.1" -debug@^4.1.0, debug@^4.1.1: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -dedent@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" - integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== - -deepmerge@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== -diff-sequences@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" - integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== +debug@^4.1.1, debug@^4.3.7, debug@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" -electron-to-chromium@^1.4.477: - version "1.4.484" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.484.tgz#770358eba089471c5dae5719db3a5a4fbf02bfb2" - integrity sha512-nO3ZEomTK2PO/3TUXgEx0A97xZTpKVf4p427lABHuCpT1IQ2N+njVh29DkQkCk6Q4m2wjU+faK4xAcfFndwjvw== +deep-eql@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" - integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +es-module-lexer@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.6.0.tgz#da49f587fd9e68ee2404fe4e256c0c7d3a81be21" + integrity sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ== -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== +esbuild@^0.24.0, esbuild@^0.24.2: + version "0.24.2" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.2.tgz#b5b55bee7de017bff5fb8a4e3e44f2ebe2c3567d" + integrity sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA== + optionalDependencies: + "@esbuild/aix-ppc64" "0.24.2" + "@esbuild/android-arm" "0.24.2" + "@esbuild/android-arm64" "0.24.2" + "@esbuild/android-x64" "0.24.2" + "@esbuild/darwin-arm64" "0.24.2" + "@esbuild/darwin-x64" "0.24.2" + "@esbuild/freebsd-arm64" "0.24.2" + "@esbuild/freebsd-x64" "0.24.2" + "@esbuild/linux-arm" "0.24.2" + "@esbuild/linux-arm64" "0.24.2" + "@esbuild/linux-ia32" "0.24.2" + "@esbuild/linux-loong64" "0.24.2" + "@esbuild/linux-mips64el" "0.24.2" + "@esbuild/linux-ppc64" "0.24.2" + "@esbuild/linux-riscv64" "0.24.2" + "@esbuild/linux-s390x" "0.24.2" + "@esbuild/linux-x64" "0.24.2" + "@esbuild/netbsd-arm64" "0.24.2" + "@esbuild/netbsd-x64" "0.24.2" + "@esbuild/openbsd-arm64" "0.24.2" + "@esbuild/openbsd-x64" "0.24.2" + "@esbuild/sunos-x64" "0.24.2" + "@esbuild/win32-arm64" "0.24.2" + "@esbuild/win32-ia32" "0.24.2" + "@esbuild/win32-x64" "0.24.2" + +estree-walker@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +expect-type@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.1.0.tgz#a146e414250d13dfc49eafcfd1344a4060fa4c75" + integrity sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA== -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +fdir@^6.4.2: + version "6.4.3" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72" + integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw== -evemin@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/evemin/-/evemin-2.0.0.tgz#3461e2947d5546046d8e79242ed6dc9af3b9adfb" - integrity sha512-lvrn9j5pKVRsHuLPmpgz3FEfZFiaR11GFw+DAcrwtt1NdykfalNDQhDauAV+6pqW5Sxj2tS0u053i+9QJ5aICA== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expect@^29.0.0, expect@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.2.tgz#7b08e83eba18ddc4a2cf62b5f2d1918f5cd84521" - integrity sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA== - dependencies: - "@jest/expect-utils" "^29.6.2" - "@types/node" "*" - jest-get-type "^29.4.3" - jest-matcher-utils "^29.6.2" - jest-message-util "^29.6.2" - jest-util "^29.6.2" - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== +foreground-child@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== dependencies: - bser "2.1.1" + cross-spawn "^7.0.0" + signal-exit "^4.0.1" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== +glob@^10.3.10, glob@^10.4.1: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-core-module@^2.11.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" - integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== - dependencies: - has "^1.0.3" - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== - -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== -istanbul-lib-report@^3.0.0: +istanbul-lib-report@^3.0.0, istanbul-lib-report@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== @@ -1228,435 +713,61 @@ istanbul-lib-report@^3.0.0: make-dir "^4.0.0" supports-color "^7.1.0" -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== +istanbul-lib-source-maps@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz#acaef948df7747c8eb5fbf1265cb980f6353a441" + integrity sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A== dependencies: + "@jridgewell/trace-mapping" "^0.3.23" debug "^4.1.1" istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" -istanbul-reports@^3.1.3: - version "3.1.6" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" - integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== +istanbul-reports@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.5.0.tgz#e88786dca8bf2aa899ec4af7644e16d9dcf9b23e" - integrity sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag== - dependencies: - execa "^5.0.0" - p-limit "^3.1.0" - -jest-circus@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.6.2.tgz#1e6ffca60151ac66cad63fce34f443f6b5bb4258" - integrity sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw== - dependencies: - "@jest/environment" "^29.6.2" - "@jest/expect" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/types" "^29.6.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^1.0.0" - is-generator-fn "^2.0.0" - jest-each "^29.6.2" - jest-matcher-utils "^29.6.2" - jest-message-util "^29.6.2" - jest-runtime "^29.6.2" - jest-snapshot "^29.6.2" - jest-util "^29.6.2" - p-limit "^3.1.0" - pretty-format "^29.6.2" - pure-rand "^6.0.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-cli@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.6.2.tgz#edb381763398d1a292cd1b636a98bfa5644b8fda" - integrity sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q== - dependencies: - "@jest/core" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/types" "^29.6.1" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^29.6.2" - jest-util "^29.6.2" - jest-validate "^29.6.2" - prompts "^2.0.1" - yargs "^17.3.1" - -jest-config@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.6.2.tgz#c68723f06b31ca5e63030686e604727d406cd7c3" - integrity sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.6.2" - "@jest/types" "^29.6.1" - babel-jest "^29.6.2" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^29.6.2" - jest-environment-node "^29.6.2" - jest-get-type "^29.4.3" - jest-regex-util "^29.4.3" - jest-resolve "^29.6.2" - jest-runner "^29.6.2" - jest-util "^29.6.2" - jest-validate "^29.6.2" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^29.6.2" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.2.tgz#c36001e5543e82a0805051d3ceac32e6825c1c46" - integrity sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.4.3" - jest-get-type "^29.4.3" - pretty-format "^29.6.2" - -jest-docblock@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" - integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== - dependencies: - detect-newline "^3.0.0" - -jest-each@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.6.2.tgz#c9e4b340bcbe838c73adf46b76817b15712d02ce" - integrity sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw== - dependencies: - "@jest/types" "^29.6.1" - chalk "^4.0.0" - jest-get-type "^29.4.3" - jest-util "^29.6.2" - pretty-format "^29.6.2" - -jest-environment-node@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.6.2.tgz#a9ea2cabff39b08eca14ccb32c8ceb924c8bb1ad" - integrity sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ== - dependencies: - "@jest/environment" "^29.6.2" - "@jest/fake-timers" "^29.6.2" - "@jest/types" "^29.6.1" - "@types/node" "*" - jest-mock "^29.6.2" - jest-util "^29.6.2" - -jest-get-type@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" - integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== - -jest-haste-map@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.6.2.tgz#298c25ea5255cfad8b723179d4295cf3a50a70d1" - integrity sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA== - dependencies: - "@jest/types" "^29.6.1" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^29.4.3" - jest-util "^29.6.2" - jest-worker "^29.6.2" - micromatch "^4.0.4" - walker "^1.0.8" +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" optionalDependencies: - fsevents "^2.3.2" - -jest-leak-detector@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.6.2.tgz#e2b307fee78cab091c37858a98c7e1d73cdf5b38" - integrity sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ== - dependencies: - jest-get-type "^29.4.3" - pretty-format "^29.6.2" - -jest-matcher-utils@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.2.tgz#39de0be2baca7a64eacb27291f0bd834fea3a535" - integrity sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ== - dependencies: - chalk "^4.0.0" - jest-diff "^29.6.2" - jest-get-type "^29.4.3" - pretty-format "^29.6.2" - -jest-message-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.2.tgz#af7adc2209c552f3f5ae31e77cf0a261f23dc2bb" - integrity sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.1" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.6.2" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.6.2.tgz#ef9c9b4d38c34a2ad61010a021866dad41ce5e00" - integrity sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg== - dependencies: - "@jest/types" "^29.6.1" - "@types/node" "*" - jest-util "^29.6.2" - -jest-pnp-resolver@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" - integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== - -jest-resolve-dependencies@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.2.tgz#36435269b6672c256bcc85fb384872c134cc4cf2" - integrity sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w== - dependencies: - jest-regex-util "^29.4.3" - jest-snapshot "^29.6.2" - -jest-resolve@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.6.2.tgz#f18405fe4b50159b7b6d85e81f6a524d22afb838" - integrity sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.6.2" - jest-pnp-resolver "^1.2.2" - jest-util "^29.6.2" - jest-validate "^29.6.2" - resolve "^1.20.0" - resolve.exports "^2.0.0" - slash "^3.0.0" - -jest-runner@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.6.2.tgz#89e8e32a8fef24781a7c4c49cd1cb6358ac7fc01" - integrity sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w== - dependencies: - "@jest/console" "^29.6.2" - "@jest/environment" "^29.6.2" - "@jest/test-result" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.13.1" - graceful-fs "^4.2.9" - jest-docblock "^29.4.3" - jest-environment-node "^29.6.2" - jest-haste-map "^29.6.2" - jest-leak-detector "^29.6.2" - jest-message-util "^29.6.2" - jest-resolve "^29.6.2" - jest-runtime "^29.6.2" - jest-util "^29.6.2" - jest-watcher "^29.6.2" - jest-worker "^29.6.2" - p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runtime@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.6.2.tgz#692f25e387f982e89ab83270e684a9786248e545" - integrity sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg== - dependencies: - "@jest/environment" "^29.6.2" - "@jest/fake-timers" "^29.6.2" - "@jest/globals" "^29.6.2" - "@jest/source-map" "^29.6.0" - "@jest/test-result" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" - "@types/node" "*" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^29.6.2" - jest-message-util "^29.6.2" - jest-mock "^29.6.2" - jest-regex-util "^29.4.3" - jest-resolve "^29.6.2" - jest-snapshot "^29.6.2" - jest-util "^29.6.2" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-snapshot@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.6.2.tgz#9b431b561a83f2bdfe041e1cab8a6becdb01af9c" - integrity sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-jsx" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.6.2" - "@jest/transform" "^29.6.2" - "@jest/types" "^29.6.1" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^29.6.2" - graceful-fs "^4.2.9" - jest-diff "^29.6.2" - jest-get-type "^29.4.3" - jest-matcher-utils "^29.6.2" - jest-message-util "^29.6.2" - jest-util "^29.6.2" - natural-compare "^1.4.0" - pretty-format "^29.6.2" - semver "^7.5.3" + "@pkgjs/parseargs" "^0.11.0" + +joycon@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" + integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== -jest-util@^29.0.0, jest-util@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.2.tgz#8a052df8fff2eebe446769fd88814521a517664d" - integrity sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w== - dependencies: - "@jest/types" "^29.6.1" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.6.2.tgz#25d972af35b2415b83b1373baf1a47bb266c1082" - integrity sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg== - dependencies: - "@jest/types" "^29.6.1" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^29.4.3" - leven "^3.1.0" - pretty-format "^29.6.2" - -jest-watcher@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.6.2.tgz#77c224674f0620d9f6643c4cfca186d8893ca088" - integrity sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA== - dependencies: - "@jest/test-result" "^29.6.2" - "@jest/types" "^29.6.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.13.1" - jest-util "^29.6.2" - string-length "^4.0.1" - -jest-worker@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.6.2.tgz#682fbc4b6856ad0aa122a5403c6d048b83f3fb44" - integrity sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ== - dependencies: - "@types/node" "*" - jest-util "^29.6.2" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.6.2.tgz#3bd55b9fd46a161b2edbdf5f1d1bd0d1eab76c42" - integrity sha512-8eQg2mqFbaP7CwfsTpCxQ+sHzw1WuNWL5UUvjnWP4hx2riGz9fPSzYOaU5q8/GqWn1TfgZIVTqYJygbGbWAANg== - dependencies: - "@jest/core" "^29.6.2" - "@jest/types" "^29.6.1" - import-local "^3.0.2" - jest-cli "^29.6.2" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: +"js-tokens@^3.0.0 || ^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json5@^2.2.2, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +lilconfig@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" + integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" +load-tsconfig@^0.2.3: + version "0.2.5" + resolved "https://registry.yarnpkg.com/load-tsconfig/-/load-tsconfig-0.2.5.tgz#453b8cd8961bfb912dea77eb6c168fe8cca3d3a1" + integrity sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg== -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== loose-envify@^1.1.0: version "1.4.0" @@ -1665,19 +776,31 @@ loose-envify@^1.1.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== +loupe@^3.1.0, loupe@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" + integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== + +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +magic-string@^0.30.17: + version "0.30.17" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== dependencies: - yallist "^3.0.2" + "@jridgewell/sourcemap-codec" "^1.5.0" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== +magicast@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" + integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== dependencies: - yallist "^4.0.0" + "@babel/parser" "^7.25.4" + "@babel/types" "^7.25.4" + source-map-js "^1.2.0" make-dir@^4.0.0: version "4.0.0" @@ -1686,207 +809,122 @@ make-dir@^4.0.0: dependencies: semver "^7.5.3" -make-error@1.x: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== dependencies: - braces "^3.0.2" - picomatch "^2.3.1" + brace-expansion "^2.0.1" -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -minimatch@^3.0.4, minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -mobx-react-lite@4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-4.0.5.tgz#e2cb98f813e118917bcc463638f5bf6ea053a67b" - integrity sha512-StfB2wxE8imKj1f6T8WWPf4lVMx3cYH9Iy60bbKXEs21+HQ4tvvfIBZfSmMXgQAefi8xYEwQIz4GN9s0d2h7dg== +mobx-react-lite@4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-4.0.7.tgz#f4e21e18d05c811010dcb1d3007e797924c4d90b" + integrity sha512-RjwdseshK9Mg8On5tyJZHtGD+J78ZnCnRaxeQDSiciKVQDUbfZcXhmld0VMxAwvcTnPEHZySGGewm467Fcpreg== dependencies: use-sync-external-store "^1.2.0" -mobx@6.12.0: - version "6.12.0" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.12.0.tgz#72b2685ca5af031aaa49e77a4d76ed67fcbf9135" - integrity sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: +mobx-utils@6.0.8: + version "6.0.8" + resolved "https://registry.yarnpkg.com/mobx-utils/-/mobx-utils-6.0.8.tgz#843e222c7694050c2e42842682fd24a84fdb7024" + integrity sha512-fPNt0vJnHwbQx9MojJFEnJLfM3EMGTtpy4/qOOW6xueh1mPofMajrbYAUvByMYAvCJnpy1A5L0t+ZVB5niKO4g== + +mobx@6.12.3: + version "6.12.3" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.12.3.tgz#b6a0fde4268116be602d50bffb32f1b90a8fb077" + integrity sha512-c8NKkO4R2lShkSXZ2Ongj1ycjugjzFFo/UswHBnS62y07DMcTc9Rvo03/3nRyszIvwPNljlkd4S828zIBv/piw== + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.8: + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== + +object-assign@^4.0.1, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +package-json-from-dist@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== -path-key@^3.0.0, path-key@^3.1.0: +path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +pathe@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.2.tgz#5ed86644376915b3c7ee4d00ac8c348d671da3a5" + integrity sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w== -picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pathval@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" + integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== + +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== -pirates@^4.0.4: +pirates@^4.0.1: version "4.0.6" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pretty-format@^29.0.0, pretty-format@^29.6.2: - version "29.6.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.2.tgz#3d5829261a8a4d89d8b9769064b29c50ed486a47" - integrity sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg== +postcss-load-config@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-6.0.1.tgz#6fd7dcd8ae89badcf1b2d644489cbabf83aa8096" + integrity sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g== dependencies: - "@jest/schemas" "^29.6.0" - ansi-styles "^5.0.0" - react-is "^18.0.0" + lilconfig "^3.1.1" -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== +postcss@^8.4.49: + version "8.5.1" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214" + integrity sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ== dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" + nanoid "^3.3.8" + picocolors "^1.1.1" + source-map-js "^1.2.1" -provi@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/provi/-/provi-2.3.3.tgz#6862513c005517c7a3020cda579d629ec6de4d50" - integrity sha512-OK9KTRScUWkFuqHOF2gcYp2srmmU4vK0R8//918b5Jd8hilvwHhe/yKzy+hpPMg9u+QxZBGA7h2HyfF3k5m53Q== - dependencies: - unsubscriber ">=2.2.0 && <3.0.0" - -pure-rand@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" - integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== react-dom@^18.2.0: version "18.2.0" @@ -1896,10 +934,27 @@ react-dom@^18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" -react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +react-shallow-renderer@^16.15.0: + version "16.15.0" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" + integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== + dependencies: + object-assign "^4.1.1" + react-is "^16.12.0 || ^17.0.0 || ^18.0.0" + +react-test-renderer@^18.0.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.3.1.tgz#e693608a1f96283400d4a3afead6893f958b80b4" + integrity sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA== + dependencies: + react-is "^18.3.1" + react-shallow-renderer "^16.15.0" + scheduler "^0.23.2" react@^18.2.0: version "18.2.0" @@ -1908,36 +963,43 @@ react@^18.2.0: dependencies: loose-envify "^1.1.0" -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" +readdirp@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.1.tgz#bd115327129672dc47f87408f05df9bd9ca3ef55" + integrity sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw== resolve-from@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve.exports@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" - integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== - -resolve@^1.20.0: - version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== +rollup@^4.23.0, rollup@^4.24.0: + version "4.31.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.31.0.tgz#b84af969a0292cb047dce2c0ec5413a9457597a4" + integrity sha512-9cCE8P4rZLx9+PjoyqHLs31V9a9Vpvfo4qNcs6JCiGWYhw2gijSetFbH6SSy1whnkgcefnUwr8sad7tgqsGvnw== dependencies: - is-core-module "^2.11.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" + "@types/estree" "1.0.6" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.31.0" + "@rollup/rollup-android-arm64" "4.31.0" + "@rollup/rollup-darwin-arm64" "4.31.0" + "@rollup/rollup-darwin-x64" "4.31.0" + "@rollup/rollup-freebsd-arm64" "4.31.0" + "@rollup/rollup-freebsd-x64" "4.31.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.31.0" + "@rollup/rollup-linux-arm-musleabihf" "4.31.0" + "@rollup/rollup-linux-arm64-gnu" "4.31.0" + "@rollup/rollup-linux-arm64-musl" "4.31.0" + "@rollup/rollup-linux-loongarch64-gnu" "4.31.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.31.0" + "@rollup/rollup-linux-riscv64-gnu" "4.31.0" + "@rollup/rollup-linux-s390x-gnu" "4.31.0" + "@rollup/rollup-linux-x64-gnu" "4.31.0" + "@rollup/rollup-linux-x64-musl" "4.31.0" + "@rollup/rollup-win32-arm64-msvc" "4.31.0" + "@rollup/rollup-win32-ia32-msvc" "4.31.0" + "@rollup/rollup-win32-x64-msvc" "4.31.0" + fsevents "~2.3.2" scheduler@^0.23.0: version "0.23.0" @@ -1946,17 +1008,17 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" -semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" semver@^7.5.3: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== shebang-command@^2.0.0: version "2.0.0" @@ -1970,55 +1032,48 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +siginfo@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" + integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +source-map-js@^1.2.0, source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== +source-map@0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" + whatwg-url "^7.0.0" -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +stackback@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" + integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -stack-utils@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" - integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== - dependencies: - escape-string-regexp "^2.0.0" +std-env@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.8.0.tgz#b56ffc1baf1a29dcc80a3bdf11d7fca7c315e7d5" + integrity sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w== -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -2027,34 +1082,48 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== +sucrase@^3.35.0: + version "3.35.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" + integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== dependencies: - has-flag "^3.0.0" + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "^10.3.10" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" supports-color@^7.1.0: version "7.2.0" @@ -2063,106 +1132,177 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== +test-exclude@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-7.0.1.tgz#20b3ba4906ac20994e275bbcafd68d510264c2a2" + integrity sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg== dependencies: - has-flag "^4.0.0" + "@istanbuljs/schema" "^0.1.2" + glob "^10.4.1" + minimatch "^9.0.4" -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" + any-promise "^1.0.0" -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== +tinybench@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" + integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== +tinyexec@^0.3.1, tinyexec@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.2.tgz#941794e657a85e496577995c6eef66f53f42b3d2" + integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA== -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -ts-jest@^29.1.1: - version "29.1.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" - integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^29.0.0" - json5 "^2.2.3" - lodash.memoize "4.x" - make-error "1.x" - semver "^7.5.3" - yargs-parser "^21.0.1" +tinyglobby@^0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.10.tgz#e712cf2dc9b95a1f5c5bbd159720e15833977a0f" + integrity sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew== + dependencies: + fdir "^6.4.2" + picomatch "^4.0.2" + +tinypool@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.2.tgz#706193cc532f4c100f66aa00b01c42173d9051b2" + integrity sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA== -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +tinyrainbow@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-2.0.0.tgz#9509b2162436315e80e3eee0fcce4474d2444294" + integrity sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw== + +tinyspy@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" + integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +tsup@^8.3.5: + version "8.3.5" + resolved "https://registry.yarnpkg.com/tsup/-/tsup-8.3.5.tgz#d55344e4756e924bf6f442e54e7d324b4471eee0" + integrity sha512-Tunf6r6m6tnZsG9GYWndg0z8dEV7fD733VBFzFJ5Vcm1FtlXB8xBD/rtrBi2a3YKEV7hHtxiZtW5EAVADoe1pA== + dependencies: + bundle-require "^5.0.0" + cac "^6.7.14" + chokidar "^4.0.1" + consola "^3.2.3" + debug "^4.3.7" + esbuild "^0.24.0" + joycon "^3.1.1" + picocolors "^1.1.1" + postcss-load-config "^6.0.1" + resolve-from "^5.0.0" + rollup "^4.24.0" + source-map "0.8.0-beta.0" + sucrase "^3.35.0" + tinyexec "^0.3.1" + tinyglobby "^0.2.9" + tree-kill "^1.2.2" typescript@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== -unsubscriber@2.2.0, "unsubscriber@>=2.2.0 && <3.0.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/unsubscriber/-/unsubscriber-2.2.0.tgz#cdc8fe9351987d38f68afbc7363eede0c797d1ff" - integrity sha512-HFpU13+ShfP4i+KiCyehBloTFHYtOWF4E3t4p3ZVA+ImCBKsMgqPzpLVdQTtSGUhPgxdm/Rhyl/Yy+CEM6xHVA== - -update-browserslist-db@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" - integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== use-sync-external-store@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== -v8-to-istanbul@^9.0.1: - version "9.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" - integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" +vite-node@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-3.0.2.tgz#0839794dfc9bcc847d8be5529cb6a240ae7a067c" + integrity sha512-hsEQerBAHvVAbv40m3TFQe/lTEbOp7yDpyqMJqr2Tnd+W58+DEYOt+fluQgekOePcsNBmR77lpVAnIU2Xu4SvQ== + dependencies: + cac "^6.7.14" + debug "^4.4.0" + es-module-lexer "^1.6.0" + pathe "^2.0.1" + vite "^5.0.0 || ^6.0.0" + +"vite@^5.0.0 || ^6.0.0": + version "6.0.11" + resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.11.tgz#224497e93e940b34c3357c9ebf2ec20803091ed8" + integrity sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg== + dependencies: + esbuild "^0.24.2" + postcss "^8.4.49" + rollup "^4.23.0" + optionalDependencies: + fsevents "~2.3.3" -walker@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== +vitest@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-3.0.2.tgz#2ec1f9a2515b13bbfc810cc8e53ab1aa13472823" + integrity sha512-5bzaHakQ0hmVVKLhfh/jXf6oETDBtgPo8tQCHYB+wftNgFJ+Hah67IsWc8ivx4vFL025Ow8UiuTf4W57z4izvQ== + dependencies: + "@vitest/expect" "3.0.2" + "@vitest/mocker" "3.0.2" + "@vitest/pretty-format" "^3.0.2" + "@vitest/runner" "3.0.2" + "@vitest/snapshot" "3.0.2" + "@vitest/spy" "3.0.2" + "@vitest/utils" "3.0.2" + chai "^5.1.2" + debug "^4.4.0" + expect-type "^1.1.0" + magic-string "^0.30.17" + pathe "^2.0.1" + std-env "^3.8.0" + tinybench "^2.9.0" + tinyexec "^0.3.2" + tinypool "^1.0.2" + tinyrainbow "^2.0.0" + vite "^5.0.0 || ^6.0.0" + vite-node "3.0.2" + why-is-node-running "^2.3.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== dependencies: - makeerror "1.0.12" + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" which@^2.0.1: version "2.0.2" @@ -2171,7 +1311,15 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wrap-ansi@^7.0.0: +why-is-node-running@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04" + integrity sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w== + dependencies: + siginfo "^2.0.0" + stackback "0.0.2" + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -2180,53 +1328,11 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^21.0.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs@^17.3.1: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1"