From 338edb68bf9d1825d146782996703b2f94721dac Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Sun, 12 Nov 2023 08:39:14 +0100 Subject: [PATCH 01/21] copied react runtime --- packages/react/CHANGELOG.md | 179 ++++ packages/react/README.md | 102 +++ packages/react/package.json | 71 ++ packages/react/runtime/package.json | 27 + packages/react/runtime/src/auto.ts | 362 ++++++++ packages/react/runtime/src/index.ts | 181 ++++ .../react/runtime/test/useSignals.test.tsx | 422 +++++++++ packages/react/src/index.ts | 33 + packages/react/test/browser/exports.test.tsx | 18 + packages/react/test/browser/mounts.test.tsx | 32 + .../react/test/browser/react-router.test.tsx | 63 ++ packages/react/test/browser/updates.test.tsx | 842 ++++++++++++++++++ .../test/node/renderToStaticMarkup.test.tsx | 22 + packages/react/test/shared/mounting.tsx | 184 ++++ packages/react/test/shared/utils.ts | 127 +++ 15 files changed, 2665 insertions(+) create mode 100644 packages/react/CHANGELOG.md create mode 100644 packages/react/README.md create mode 100644 packages/react/package.json create mode 100644 packages/react/runtime/package.json create mode 100644 packages/react/runtime/src/auto.ts create mode 100644 packages/react/runtime/src/index.ts create mode 100644 packages/react/runtime/test/useSignals.test.tsx create mode 100644 packages/react/src/index.ts create mode 100644 packages/react/test/browser/exports.test.tsx create mode 100644 packages/react/test/browser/mounts.test.tsx create mode 100644 packages/react/test/browser/react-router.test.tsx create mode 100644 packages/react/test/browser/updates.test.tsx create mode 100644 packages/react/test/node/renderToStaticMarkup.test.tsx create mode 100644 packages/react/test/shared/mounting.tsx create mode 100644 packages/react/test/shared/utils.ts diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md new file mode 100644 index 00000000..9225ddc2 --- /dev/null +++ b/packages/react/CHANGELOG.md @@ -0,0 +1,179 @@ +# @preact/signals-react + +## 1.3.6 + +### Patch Changes + +- [#399](https://github.com/preactjs/signals/pull/399) [`24fa9f7`](https://github.com/preactjs/signals/commit/24fa9f791d70baba35bdce722f71ce63ac091a4d) Thanks [@rschristian](https://github.com/rschristian)! - Fixes UMD builds of `@preact/signals` and `@preact/signals-react` + +## 1.3.5 + +### Patch Changes + +- [#375](https://github.com/preactjs/signals/pull/375) [`cd3a22d`](https://github.com/preactjs/signals/commit/cd3a22d628c3a535108bc45b8151505dd6fc51c8) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Clean up effect store reference after finishing it + +* [#375](https://github.com/preactjs/signals/pull/375) [`59115d9`](https://github.com/preactjs/signals/commit/59115d9ea6dfa073255f9803dd7e8a09892d2acc) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Update internal useSignals API + +* Updated dependencies [[`256a331`](https://github.com/preactjs/signals/commit/256a331b5335e54f7e918b3f1068fb9d92d1c613)]: + - @preact/signals-core@1.4.0 + +## 1.3.4 + +### Patch Changes + +- [#377](https://github.com/preactjs/signals/pull/377) [`f4ff0ab`](https://github.com/preactjs/signals/commit/f4ff0abc55c83198e5ff7557f3d6663bac4b5149) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Fix internal property names + +## 1.3.3 + +### Patch Changes + +- [#373](https://github.com/preactjs/signals/pull/373) [`8c12a0d`](https://github.com/preactjs/signals/commit/8c12a0df74f00e9cab04e999fc443889b3528c04) Thanks [@rschristian](https://github.com/rschristian)! - Removes package.json#exports.umd, which had invalid paths if they were ever to be consumed + +* [#372](https://github.com/preactjs/signals/pull/372) [`6717601`](https://github.com/preactjs/signals/commit/6717601a34449080617033d93a87cc9c441a7567) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Reorganize signals-react package + +* Updated dependencies [[`8c12a0d`](https://github.com/preactjs/signals/commit/8c12a0df74f00e9cab04e999fc443889b3528c04), [`26f6526`](https://github.com/preactjs/signals/commit/26f6526875ef0968621c4113594ac95b93de5163)]: + - @preact/signals-core@1.3.1 + +## 1.3.2 + +### Patch Changes + +- [#358](https://github.com/preactjs/signals/pull/358) [`08ed3a0`](https://github.com/preactjs/signals/commit/08ed3a02a2291ad1e18389674d8ac20678064723) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Add note to Readme about tradeoffs in current React integration + +* [#355](https://github.com/preactjs/signals/pull/355) [`21c8ee9`](https://github.com/preactjs/signals/commit/21c8ee98070a8bda05095dc91b64d2fe54042fb3) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Fix React adapter in SSR and when rerendering + +- [#352](https://github.com/preactjs/signals/pull/352) [`a2b7320`](https://github.com/preactjs/signals/commit/a2b7320ee5829f58efaee5f7b20d993f35f09d2a) Thanks [@rschristian](https://github.com/rschristian)! - Uses full file path on useSyncExternalStore import, fixing a possible resolution issue in some build tools. + +## 1.3.1 + +### Patch Changes + +- [#344](https://github.com/preactjs/signals/pull/344) [`acdead6`](https://github.com/preactjs/signals/commit/acdead6a8631d7198d8a55d6cbde7713b5776d6b) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Allow React ^16.14.0 as a peer dependency + +## 1.3.0 + +### Minor Changes + +- [#335](https://github.com/preactjs/signals/pull/335) [`5fd438d`](https://github.com/preactjs/signals/commit/5fd438db9793d73343403e8926b9b69b03fb26f9) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Revert react integration to tracking current dispatcher + +### Patch Changes + +- [#271](https://github.com/preactjs/signals/pull/271) [`0135d60`](https://github.com/preactjs/signals/commit/0135d60b6de1325ee2b027a25cd60cc379f9c198) Thanks [@billybimbob](https://github.com/billybimbob)! - type Signal as a React Element + +* [#334](https://github.com/preactjs/signals/pull/334) [`0a58566`](https://github.com/preactjs/signals/commit/0a585660e141f3d92fb8789c234e69d5a1da8a86) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Run test suite agains React's production build + +- [#246](https://github.com/preactjs/signals/pull/246) [`ad5a485`](https://github.com/preactjs/signals/commit/ad5a485e4fe3cfc1d1f60a57a30e50e88f7b1281) Thanks [@Shu-Ji](https://github.com/Shu-Ji)! - Support forwardRef in @preact/signals-react + +- Updated dependencies [[`862d9d6`](https://github.com/preactjs/signals/commit/862d9d6538b94e0a110213e98f2a0cabb14b8ad8), [`8b70764`](https://github.com/preactjs/signals/commit/8b7076436ce6d912f17d57da8ecd1bdfca852183), [`8e726ed`](https://github.com/preactjs/signals/commit/8e726ed1df6c90b85a93484f275baa7f013c799a)]: + - @preact/signals-core@1.3.0 + +## 1.2.2 + +### Patch Changes + +- [#243](https://github.com/preactjs/signals/pull/243) [`e41b8b1`](https://github.com/preactjs/signals/commit/e41b8b16bf68da7004a3174912fe95a109a453ed) Thanks [@melnikov-s](https://github.com/melnikov-s)! - Replace `Map` useage with `WeakMap` + +* [#282](https://github.com/preactjs/signals/pull/282) [`cafbdaa`](https://github.com/preactjs/signals/commit/cafbdaabd525a034e38da10b04eee0688c026152) Thanks [@developit](https://github.com/developit)! - Fix a bug that caused cleanup functions returned from a `useSignalEffect()` callback not to be called. + +* Updated dependencies [[`7e15d3c`](https://github.com/preactjs/signals/commit/7e15d3cf5f5e66258105e6f27cd7838b52fbbf9f)]: + - @preact/signals-core@1.2.3 + +## 1.2.1 + +### Patch Changes + +- [#238](https://github.com/preactjs/signals/pull/238) [`bcf4b0b`](https://github.com/preactjs/signals/commit/bcf4b0b25d774483ddafa29c2fa133c467668b8c) Thanks [@eddyw](https://github.com/eddyw)! - Fix ERR_UNSUPPORTED_DIR_IMPORT error when importing `use-sync-external-store/shim` from ESM build + +## 1.2.0 + +### Minor Changes + +- [#219](https://github.com/preactjs/signals/pull/219) [`0621526`](https://github.com/preactjs/signals/commit/0621526dd59187f674557e6df42c71980b32efab) Thanks [@eddyw](https://github.com/eddyw)! - Replace useReducer with useSyncExternalStore + +### Patch Changes + +- [#226](https://github.com/preactjs/signals/pull/226) [`ad29826`](https://github.com/preactjs/signals/commit/ad2982606a8894ea8562a0726d7777185987ad60) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - Fix hook names being mangled + +- Updated dependencies [[`aa4cb7b`](https://github.com/preactjs/signals/commit/aa4cb7bfad744e78952cacc37af5bd4a713f0d3f), [`3f652a7`](https://github.com/preactjs/signals/commit/3f652a77d2a125a02a0cfc29fe661c81beeda16d)]: + - @preact/signals-core@1.2.2 + +## 1.1.1 + +### Patch Changes + +- [#221](https://github.com/preactjs/signals/pull/221) [`7e8d4c2`](https://github.com/preactjs/signals/commit/7e8d4c25dfdc7fa9434b6c2af4aa0e495b9fae55) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - Fix signal not updated in React production build + +- Updated dependencies [[`4b73164`](https://github.com/preactjs/signals/commit/4b7316497aee03413f91e9f714cdcf9f553e39d9), [`57fd2e7`](https://github.com/preactjs/signals/commit/57fd2e723528a36cc5d4ebf09ba34178aa84c879), [`49756ae`](https://github.com/preactjs/signals/commit/49756aef28fe12c6ae6b801224bf5ae608ddf562)]: + - @preact/signals-core@1.2.1 + +## 1.1.0 + +### Minor Changes + +- [#91](https://github.com/preactjs/signals/pull/91) [`fb74bb9`](https://github.com/preactjs/signals/commit/fb74bb9ce4e44192e1ee7d3d041274cc985db767) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - add the `useSignalEffect` hook + +* [#183](https://github.com/preactjs/signals/pull/183) [`79ff1e7`](https://github.com/preactjs/signals/commit/79ff1e794dde9952db2d6d43b22cebfb2accc770) Thanks [@jviide](https://github.com/jviide)! - Add ability to run custom cleanup logic when an effect is disposed. + + ```js + effect(() => { + console.log("This runs whenever a dependency changes"); + return () => { + console.log("This runs when the effect is disposed"); + }); + }); + ``` + +### Patch Changes + +- [#161](https://github.com/preactjs/signals/pull/161) [`6ac6923`](https://github.com/preactjs/signals/commit/6ac6923e5294f8a31ee1a009550b9891c3996cb4) Thanks [@jviide](https://github.com/jviide)! - Remove all usages of `Set`, `Map` and other allocation heavy objects in signals-core. This substaintially increases performance across all measurements. + +- Updated dependencies [[`b4611cc`](https://github.com/preactjs/signals/commit/b4611cc9dee0ae09f4b378ba293c3203edc32be4), [`9802da5`](https://github.com/preactjs/signals/commit/9802da5274bb45c3cc28dda961b9b2d18535729a), [`6ac6923`](https://github.com/preactjs/signals/commit/6ac6923e5294f8a31ee1a009550b9891c3996cb4), [`79ff1e7`](https://github.com/preactjs/signals/commit/79ff1e794dde9952db2d6d43b22cebfb2accc770), [`3e31aab`](https://github.com/preactjs/signals/commit/3e31aabb812ddb0f7451deba38267f8384eff9d1)]: + - @preact/signals-core@1.2.0 + +## 1.0.2 + +### Patch Changes + +- [#147](https://github.com/preactjs/signals/pull/147) [`3556499`](https://github.com/preactjs/signals/commit/355649903b766630b62cdd0f90a35d3eafa99fa9) Thanks [@developit](https://github.com/developit)! - Improve performance when rendering Signals as Text in Preact. + +* [#148](https://github.com/preactjs/signals/pull/148) [`b948745`](https://github.com/preactjs/signals/commit/b948745de7b5b60a20ce3bdc5ee72d47d47f38ec) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - Move `types` field in `package.json` to the top of the entry list to ensure that TypeScript always finds it. + +- [#146](https://github.com/preactjs/signals/pull/146) [`9e798fd`](https://github.com/preactjs/signals/commit/9e798fdaf419566530696f850ea7fc1fc649d3cd) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - fix(react): track owners separately, mutate updaters with dispatcher + +- Updated dependencies [[`f2ba3d6`](https://github.com/preactjs/signals/commit/f2ba3d657bf8169c6ba1d47c0827aa18cfe1c947), [`160ea77`](https://github.com/preactjs/signals/commit/160ea7791f3adb55c562f5990e0b4848d8491a38), [`4385ea8`](https://github.com/preactjs/signals/commit/4385ea8c8358a154d8b789685bb061658ce1153f), [`b948745`](https://github.com/preactjs/signals/commit/b948745de7b5b60a20ce3bdc5ee72d47d47f38ec), [`00a59c6`](https://github.com/preactjs/signals/commit/00a59c6475bd4542fb934474d82d1e242b2ac870)]: + - @preact/signals-core@1.1.1 + +## 1.0.1 + +### Patch Changes + +- 62439c9: Fixes invalid React peer dependency range for environments with strict peerDeps +- Updated dependencies [336bb34] +- Updated dependencies [bc0080c] +- Updated dependencies [7228418] +- Updated dependencies [32abe07] +- Updated dependencies [4782b41] +- Updated dependencies [bf6af3b] + - @preact/signals-core@1.1.0 + +## 1.0.0 + +### Major Changes + +- 2ee8489: The v1 release for the signals package, we'd to see the uses you all + come up with and are eager to see performance improvements in your + applications. + +### Patch Changes + +- Updated dependencies [ab22ec7] +- Updated dependencies [2ee8489] +- Updated dependencies [b56abf3] + - @preact/signals-core@1.0.0 + +## 0.0.2 + +### Patch Changes + +- Updated dependencies [702a9c5] + - @preact/signals-core@0.0.5 diff --git a/packages/react/README.md b/packages/react/README.md new file mode 100644 index 00000000..c9ad4791 --- /dev/null +++ b/packages/react/README.md @@ -0,0 +1,102 @@ +# Signals + +Signals is a performant state management library with two primary goals: + +1. Make it as easy as possible to write business logic for small up to complex apps. No matter how complex your logic is, your app updates should stay fast without you needing to think about it. Signals automatically optimize state updates behind the scenes to trigger the fewest updates necessary. They are lazy by default and automatically skip signals that no one listens to. +2. Integrate into frameworks as if they were native built-in primitives. You don't need any selectors, wrapper functions, or anything else. Signals can be accessed directly and your component will automatically re-render when the signal's value changes. + +Read the [announcement post](https://preactjs.com/blog/introducing-signals/) to learn more about which problems signals solves and how it came to be. + +## Installation: + +```sh +npm install @preact/signals-react +``` + +- [Guide / API](../../README.md#guide--api) + - [`signal(initialValue)`](../../README.md#signalinitialvalue) + - [`signal.peek()`](../../README.md#signalpeek) + - [`computed(fn)`](../../README.md#computedfn) + - [`effect(fn)`](../../README.md#effectfn) + - [`batch(fn)`](../../README.md#batchfn) + - [`untracked(fn)`](../../README.md#untrackedfn) +- [React Integration](#react-integration) + - [Hooks](#hooks) +- [License](#license) + +## React Integration + +> Note: The React integration plugs into some React internals and may break unexpectedly in future versions of React. If you are using Signals with React and encounter errors such as "Rendered more hooks than during previous render", "Should have a queue. This is likely a bug in React." or "Cannot redefine property: createElement" please open an issue here. + +The React integration can be installed via: + +```sh +npm install @preact/signals-react +``` + +Similar to the Preact integration, the React adapter allows you to access signals directly inside your components and will automatically subscribe to them. + +```js +import { signal } from "@preact/signals-react"; + +const count = signal(0); + +function CounterValue() { + // Whenever the `count` signal is updated, we'll + // re-render this component automatically for you + return

Value: {count.value}

; +} +``` + +### Hooks + +If you need to instantiate new signals inside your components, you can use the `useSignal` or `useComputed` hook. + +```js +import { useSignal, useComputed } from "@preact/signals-react"; + +function Counter() { + const count = useSignal(0); + const double = useComputed(() => count.value * 2); + + return ( + + ); +} +``` + +### Rendering optimizations + +The React adapter ships with several optimizations it can apply out of the box to skip virtual-dom rendering entirely. If you pass a signal directly into JSX, it will bind directly to the DOM `Text` node that is created and update that whenever the signal changes. + +```js +import { signal } from "@preact/signals-react"; + +const count = signal(0); + +// Unoptimized: Will trigger the surrounding +// component to re-render +function Counter() { + return

Value: {count.value}

; +} + +// Optimized: Will update the text node directly +function Counter() { + return ( +

+ <>Value: {count} +

+ ); +} +``` + +To opt into this optimization, simply pass the signal directly instead of accessing the `.value` property. + +> **Note** +> The content is wrapped in a React Fragment due to React 18's newer, more strict children types. + +## License + +`MIT`, see the [LICENSE](../../LICENSE) file. diff --git a/packages/react/package.json b/packages/react/package.json new file mode 100644 index 00000000..969c881b --- /dev/null +++ b/packages/react/package.json @@ -0,0 +1,71 @@ +{ + "name": "@preact/signals-react", + "version": "1.3.6", + "license": "MIT", + "description": "Manage state with style in React", + "keywords": [], + "authors": [ + "The Preact Authors (https://github.com/preactjs/signals/contributors)" + ], + "repository": { + "type": "git", + "url": "https://github.com/preactjs/signals", + "directory": "packages/react" + }, + "bugs": "https://github.com/preactjs/signals/issues", + "homepage": "https://preactjs.com", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + }, + "amdName": "reactSignals", + "main": "dist/signals.js", + "module": "dist/signals.module.js", + "unpkg": "dist/signals.min.js", + "types": "dist/signals.d.ts", + "source": "src/index.ts", + "exports": { + ".": { + "types": "./dist/signals.d.ts", + "browser": "./dist/signals.module.js", + "import": "./dist/signals.mjs", + "require": "./dist/signals.js" + }, + "./runtime": { + "types": "./runtime/dist/index.d.ts", + "browser": "./runtime/dist/runtime.module.js", + "import": "./runtime/dist/runtime.mjs", + "require": "./runtime/dist/runtime.js" + }, + "./runtime/package.json": "./runtime/package.json" + }, + "mangle": "../../mangle.json", + "files": [ + "src", + "dist", + "runtime/dist", + "runtime/src", + "runtime/package.json", + "CHANGELOG.md", + "LICENSE", + "README.md" + ], + "scripts": { + "prepublishOnly": "cd ../.. && pnpm build:react-runtime && pnpm build:react" + }, + "dependencies": { + "@preact/signals-core": "workspace:^1.4.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.14.0 || 17.x || 18.x" + }, + "devDependencies": { + "@types/react": "^18.0.18", + "@types/react-dom": "^18.0.6", + "@types/use-sync-external-store": "^0.0.3", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.9.0" + } +} diff --git a/packages/react/runtime/package.json b/packages/react/runtime/package.json new file mode 100644 index 00000000..de98164a --- /dev/null +++ b/packages/react/runtime/package.json @@ -0,0 +1,27 @@ +{ + "name": "@preact/signals-react-runtime", + "description": "Sub package for @preact/signals-react that contains the pure runtime functions", + "private": true, + "amdName": "reactSignalsRuntime", + "main": "dist/runtime.js", + "module": "dist/runtime.module.js", + "unpkg": "dist/runtime.min.js", + "types": "dist/index.d.ts", + "source": "src/index.ts", + "mangle": "../../../mangle.json", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "browser": "./dist/runtime.module.js", + "import": "./dist/runtime.mjs", + "require": "./dist/runtime.js" + } + }, + "dependencies": { + "@preact/signals-core": "workspace:^1.3.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.14.0 || 17.x || 18.x" + } +} diff --git a/packages/react/runtime/src/auto.ts b/packages/react/runtime/src/auto.ts new file mode 100644 index 00000000..b5d505ec --- /dev/null +++ b/packages/react/runtime/src/auto.ts @@ -0,0 +1,362 @@ +import { + // @ts-ignore-next-line + // eslint-disable-next-line @typescript-eslint/no-unused-vars + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as ReactInternals, +} from "react"; +import React from "react"; +import jsxRuntime from "react/jsx-runtime"; +import jsxRuntimeDev from "react/jsx-dev-runtime"; +import { EffectStore, useSignals, wrapJsx } from "./index"; + +export interface ReactDispatcher { + useRef: typeof React.useRef; + useCallback: typeof React.useCallback; + useReducer: typeof React.useReducer; + useSyncExternalStore: typeof React.useSyncExternalStore; + useEffect: typeof React.useEffect; + useImperativeHandle: typeof React.useImperativeHandle; +} + +// In order for signals to work in React, we need to observe what signals a +// component uses while rendering. To do this, we need to know when a component +// is rendering. To do this, we watch the transition of the +// ReactCurrentDispatcher to know when a component is rerendering. +// +// To track when we are entering and exiting a component render (i.e. before and +// after React renders a component), we track how the dispatcher changes. +// Outside of a component rendering, the dispatcher is set to an instance that +// errors or warns when any hooks are called. This behavior is prevents hooks +// from being used outside of components. Right before React renders a +// component, the dispatcher is set to an instance that doesn't warn or error +// and contains the implementations of all hooks. Right after React finishes +// rendering a component, the dispatcher is set to the erroring one again. This +// erroring dispatcher is called the `ContextOnlyDispatcher` in React's source. +// +// So, we watch the getter and setter on `ReactCurrentDispatcher.current` to +// monitor the changes to the current ReactDispatcher. When the dispatcher +// changes from the ContextOnlyDispatcher to a "valid" dispatcher, we assume we +// are entering a component render. At this point, we setup our +// auto-subscriptions for any signals used in the component. We do this by +// creating an Signal effect and manually starting the Signal effect. We use +// `useSyncExternalStore` to trigger rerenders on the component when any signals +// it uses changes. +// +// When the dispatcher changes from a valid dispatcher back to the +// ContextOnlyDispatcher, we assume we are exiting a component render. At this +// point we stop the effect. +// +// Some additional complexities to be aware of: +// - If a component calls `setState` while rendering, React will re-render the +// component immediately. Before triggering the re-render, React will change +// the dispatcher to the HooksDispatcherOnRerender. When we transition to this +// rerendering adapter, we need to re-trigger our hooks to keep the order of +// hooks the same for every render of a component. +// +// - In development, useReducer, useState, and useMemo change the dispatcher to +// a different warning dispatcher (not ContextOnlyDispatcher) before invoking +// the reducer and resets it right after. +// +// The useSyncExternalStore shim will use some of these hooks when we invoke +// it while entering a component render. We need to prevent this dispatcher +// change caused by these hooks from re-triggering our entering logic (it +// would cause an infinite loop if we did not). We do this by using a lock to +// prevent the setter from running while we are in the setter. +// +// When a Component's function body invokes useReducer, useState, or useMemo, +// this change in dispatcher should not signal that we are entering or exiting +// a component render. We ignore this change by detecting these dispatchers as +// different from ContextOnlyDispatcher and other valid dispatchers. +// +// - The `use` hook will change the dispatcher to from a valid update dispatcher +// to a valid mount dispatcher in some cases. Similarly to useReducer +// mentioned above, we should not signal that we are exiting a component +// during this change. Because these other valid dispatchers do not pass the +// ContextOnlyDispatcher check, they do not affect our logic. +// +// - When server rendering, React does not change the dispatcher before and +// after each component render. It sets it once for before the first render +// and once for after the last render. This means that we will not be able to +// detect when we are entering or exiting a component render. This is fine +// because we don't need to detect this for server rendering. A component +// can't trigger async rerenders in SSR so we don't need to track signals. +// +// If a component updates a signal value while rendering during SSR, we will +// not rerender the component because the signal value will synchronously +// change so all reads of the signal further down the tree will see the new +// value. + +/* +Below is a state machine definition for transitions between the various +dispatchers in React's prod build. (It does not include dev time warning +dispatchers which are just always ignored). + +ENTER and EXIT suffixes indicates whether this ReactCurrentDispatcher transition +signals we are entering or exiting a component render, or if it doesn't signal a +change in the component rendering lifecyle (NOOP). + +```js +// Paste this into https://stately.ai/viz to visualize the state machine. +import { createMachine } from "xstate"; + +// ENTER, EXIT, NOOP suffixes indicates whether this ReactCurrentDispatcher +// transition signals we are entering or exiting a component render, or +// if it doesn't signal a change in the component rendering lifecyle (NOOP). + +const dispatcherMachinePROD = createMachine({ + id: "ReactCurrentDispatcher_PROD", + initial: "null", + states: { + null: { + on: { + pushDispatcher: "ContextOnlyDispatcher", + }, + }, + ContextOnlyDispatcher: { + on: { + renderWithHooks_Mount_ENTER: "HooksDispatcherOnMount", + renderWithHooks_Update_ENTER: "HooksDispatcherOnUpdate", + pushDispatcher_NOOP: "ContextOnlyDispatcher", + popDispatcher_NOOP: "ContextOnlyDispatcher", + }, + }, + HooksDispatcherOnMount: { + on: { + renderWithHooksAgain_ENTER: "HooksDispatcherOnRerender", + resetHooksAfterThrow_EXIT: "ContextOnlyDispatcher", + finishRenderingHooks_EXIT: "ContextOnlyDispatcher", + }, + }, + HooksDispatcherOnUpdate: { + on: { + renderWithHooksAgain_ENTER: "HooksDispatcherOnRerender", + resetHooksAfterThrow_EXIT: "ContextOnlyDispatcher", + finishRenderingHooks_EXIT: "ContextOnlyDispatcher", + use_ResumeSuspensedMount_NOOP: "HooksDispatcherOnMount", + }, + }, + HooksDispatcherOnRerender: { + on: { + renderWithHooksAgain_ENTER: "HooksDispatcherOnRerender", + resetHooksAfterThrow_EXIT: "ContextOnlyDispatcher", + finishRenderingHooks_EXIT: "ContextOnlyDispatcher", + }, + }, + }, +}); +``` +*/ + +let store: EffectStore | null = null; +let lock = false; +let currentDispatcher: ReactDispatcher | null = null; + +function installCurrentDispatcherHook() { + Object.defineProperty(ReactInternals.ReactCurrentDispatcher, "current", { + get() { + return currentDispatcher; + }, + set(nextDispatcher: ReactDispatcher) { + if (lock) { + currentDispatcher = nextDispatcher; + return; + } + + const currentDispatcherType = getDispatcherType(currentDispatcher); + const nextDispatcherType = getDispatcherType(nextDispatcher); + + // Update the current dispatcher now so the hooks inside of the + // useSyncExternalStore shim get the right dispatcher. + currentDispatcher = nextDispatcher; + if ( + isEnteringComponentRender(currentDispatcherType, nextDispatcherType) + ) { + lock = true; + store = useSignals(); + lock = false; + } else if ( + isExitingComponentRender(currentDispatcherType, nextDispatcherType) + ) { + store?.f(); + store = null; + } + }, + }); +} + +type DispatcherType = number; +const ContextOnlyDispatcherType = 1 << 0; +const WarningDispatcherType = 1 << 1; +const MountDispatcherType = 1 << 2; +const UpdateDispatcherType = 1 << 3; +const RerenderDispatcherType = 1 << 4; +const ServerDispatcherType = 1 << 5; +const BrowserClientDispatcherType = + MountDispatcherType | UpdateDispatcherType | RerenderDispatcherType; + +const dispatcherTypeCache = new Map(); +function getDispatcherType(dispatcher: ReactDispatcher | null): DispatcherType { + // Treat null the same as the ContextOnlyDispatcher. + if (!dispatcher) return ContextOnlyDispatcherType; + + const cached = dispatcherTypeCache.get(dispatcher); + if (cached !== undefined) return cached; + + // The ContextOnlyDispatcher sets all the hook implementations to a function + // that takes no arguments and throws and error. This dispatcher is the only + // dispatcher where useReducer and useEffect will have the same + // implementation. + let type: DispatcherType; + const useCallbackImpl = dispatcher.useCallback.toString(); + if (dispatcher.useReducer === dispatcher.useEffect) { + type = ContextOnlyDispatcherType; + + // @ts-expect-error When server rendering, useEffect and useImperativeHandle + // are both set to noop functions and so have the same implementation. + } else if (dispatcher.useEffect === dispatcher.useImperativeHandle) { + type = ServerDispatcherType; + } else if (/Invalid/.test(useCallbackImpl)) { + // We first check for warning dispatchers because they would also pass some + // of the checks below. + type = WarningDispatcherType; + } else if ( + // The development mount dispatcher invokes a function called + // `mountCallback` whereas the development update/re-render dispatcher + // invokes a function called `updateCallback`. Use that difference to + // determine if we are in a mount or update-like dispatcher in development. + // The production mount dispatcher defines an array of the form [callback, + // deps] whereas update/re-render dispatchers read the array using array + // indices (e.g. `[0]` and `[1]`). Use those differences to determine if we + // are in a mount or update-like dispatcher in production. + /updateCallback/.test(useCallbackImpl) || + (/\[0\]/.test(useCallbackImpl) && /\[1\]/.test(useCallbackImpl)) + ) { + // The update and rerender dispatchers have different implementations for + // useReducer. We'll check it's implementation to determine if this is the + // rerender or update dispatcher. + let useReducerImpl = dispatcher.useReducer.toString(); + if ( + // The development rerender dispatcher invokes a function called + // `rerenderReducer` whereas the update dispatcher invokes a function + // called `updateReducer`. The production rerender dispatcher returns an + // array of the form `[state, dispatch]` whereas the update dispatcher + // returns an array of `[fiber.memoizedState, dispatch]` so we check the + // return statement in the implementation of useReducer to differentiate + // between the two. + /rerenderReducer/.test(useReducerImpl) || + /return\s*\[\w+,/.test(useReducerImpl) + ) { + type = RerenderDispatcherType; + } else { + type = UpdateDispatcherType; + } + } else { + type = MountDispatcherType; + } + + dispatcherTypeCache.set(dispatcher, type); + return type; +} + +function isEnteringComponentRender( + currentDispatcherType: DispatcherType, + nextDispatcherType: DispatcherType +): boolean { + if ( + currentDispatcherType & ContextOnlyDispatcherType && + nextDispatcherType & BrowserClientDispatcherType + ) { + // ## Mount or update (ContextOnlyDispatcher -> ValidDispatcher (Mount or Update)) + // + // If the current dispatcher is the ContextOnlyDispatcher and the next + // dispatcher is a valid dispatcher, we are entering a component render. + return true; + } else if ( + currentDispatcherType & WarningDispatcherType || + nextDispatcherType & WarningDispatcherType + ) { + // ## Warning dispatcher + // + // If the current dispatcher or next dispatcher is an warning dispatcher, + // we are not entering a component render. The current warning dispatchers + // are used to warn when hooks are nested improperly and do not indicate + // entering a new component render. + return false; + } else if (nextDispatcherType & RerenderDispatcherType) { + // Any transition into the rerender dispatcher is the beginning of a + // component render, so we should invoke our hooks. Details below. + // + // ## In-place rerendering (e.g. Mount -> Rerender) + // + // If we are transitioning from the mount, update, or rerender dispatcher to + // the rerender dispatcher (e.g. HooksDispatcherOnMount to + // HooksDispatcherOnRerender), then this component is rerendering due to + // calling setState inside of its function body. We are re-entering a + // component's render method and so we should re-invoke our hooks. + return true; + } else { + // ## Resuming suspended mount edge case (Update -> Mount) + // + // If we are transitioning from the update dispatcher to the mount + // dispatcher, then this component is using the `use` hook and is resuming + // from a mount. We should not re-invoke our hooks in this situation since + // we are not entering a new component render, but instead continuing a + // previous render. + // + // ## Other transitions + // + // For example, Mount -> Mount, Update -> Update, Mount -> Update, any + // transition in and out of invalid dispatchers. + // + // There is no known transition for the following transitions so we default + // to not triggering a re-enter of the component. + // - HooksDispatcherOnMount -> HooksDispatcherOnMount + // - HooksDispatcherOnMount -> HooksDispatcherOnUpdate + // - HooksDispatcherOnUpdate -> HooksDispatcherOnUpdate + return false; + } +} + +/** + * We are exiting a component render if the current dispatcher is a valid + * dispatcher and the next dispatcher is the ContextOnlyDispatcher. + */ +function isExitingComponentRender( + currentDispatcherType: DispatcherType, + nextDispatcherType: DispatcherType +): boolean { + return Boolean( + currentDispatcherType & BrowserClientDispatcherType && + nextDispatcherType & ContextOnlyDispatcherType + ); +} + +interface JsxRuntimeModule { + jsx?(type: any, ...rest: any[]): unknown; + jsxs?(type: any, ...rest: any[]): unknown; + jsxDEV?(type: any, ...rest: any[]): unknown; +} + +export function installJSXHooks() { + const JsxPro: JsxRuntimeModule = jsxRuntime; + const JsxDev: JsxRuntimeModule = jsxRuntimeDev; + + /** + * createElement _may_ be called by jsx runtime as a fallback in certain cases, + * so we need to wrap it regardless. + * + * The jsx exports depend on the `NODE_ENV` var to ensure the users' bundler doesn't + * include both, so one of them will be set with `undefined` values. + */ + React.createElement = wrapJsx(React.createElement); + JsxDev.jsx && /* */ (JsxDev.jsx = wrapJsx(JsxDev.jsx)); + JsxPro.jsx && /* */ (JsxPro.jsx = wrapJsx(JsxPro.jsx)); + JsxDev.jsxs && /* */ (JsxDev.jsxs = wrapJsx(JsxDev.jsxs)); + JsxPro.jsxs && /* */ (JsxPro.jsxs = wrapJsx(JsxPro.jsxs)); + JsxDev.jsxDEV && /**/ (JsxDev.jsxDEV = wrapJsx(JsxDev.jsxDEV)); + JsxPro.jsxDEV && /**/ (JsxPro.jsxDEV = wrapJsx(JsxPro.jsxDEV)); +} + +export function installAutoSignalTracking() { + installCurrentDispatcherHook(); + installJSXHooks(); +} diff --git a/packages/react/runtime/src/index.ts b/packages/react/runtime/src/index.ts new file mode 100644 index 00000000..8a81cdb8 --- /dev/null +++ b/packages/react/runtime/src/index.ts @@ -0,0 +1,181 @@ +import { signal, computed, effect, Signal } from "@preact/signals-core"; +import { useRef, useMemo, useEffect } from "react"; +import { useSyncExternalStore } from "use-sync-external-store/shim/index.js"; + +export { installAutoSignalTracking } from "./auto"; + +const Empty = [] as const; +const ReactElemType = Symbol.for("react.element"); // https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15 + +export function wrapJsx(jsx: T): T { + if (typeof jsx !== "function") return jsx; + + return function (type: any, props: any, ...rest: any[]) { + if (typeof type === "string" && props) { + for (let i in props) { + let v = props[i]; + if (i !== "children" && v instanceof Signal) { + props[i] = v.value; + } + } + } + + return jsx.call(jsx, type, props, ...rest); + } as any as T; +} + +const symDispose: unique symbol = + (Symbol as any).dispose || Symbol.for("Symbol.dispose"); + +interface Effect { + _sources: object | undefined; + _start(): () => void; + _callback(): void; + _dispose(): void; +} + +export interface EffectStore { + effect: Effect; + subscribe(onStoreChange: () => void): () => void; + getSnapshot(): number; + /** finishEffect - stop tracking the signals used in this component */ + f(): void; + [symDispose](): void; +} + +let finishUpdate: (() => void) | undefined; + +function setCurrentStore(store?: EffectStore) { + // end tracking for the current update: + if (finishUpdate) finishUpdate(); + // start tracking the new update: + finishUpdate = store && store.effect._start(); +} + +const clearCurrentStore = () => setCurrentStore(); + +/** + * A redux-like store whose store value is a positive 32bit integer (a 'version'). + * + * React subscribes to this store and gets a snapshot of the current 'version', + * whenever the 'version' changes, we tell React it's time to update the component (call 'onStoreChange'). + * + * How we achieve this is by creating a binding with an 'effect', when the `effect._callback' is called, + * we update our store version and tell React to re-render the component ([1] We don't really care when/how React does it). + * + * [1] + * @see https://react.dev/reference/react/useSyncExternalStore + * @see https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md + */ +function createEffectStore(): EffectStore { + let effectInstance!: Effect; + let version = 0; + let onChangeNotifyReact: (() => void) | undefined; + + let unsubscribe = effect(function (this: Effect) { + effectInstance = this; + }); + effectInstance._callback = function () { + version = (version + 1) | 0; + if (onChangeNotifyReact) onChangeNotifyReact(); + }; + + return { + effect: effectInstance, + subscribe(onStoreChange) { + onChangeNotifyReact = onStoreChange; + + return function () { + /** + * Rotate to next version when unsubscribing to ensure that components are re-run + * when subscribing again. + * + * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so + * don't re-run after subscribing again if the version is the same as last time. + * + * Because we unsubscribe from the effect, the version may not change. We simply + * set a new initial version in case of stale snapshots here. + */ + version = (version + 1) | 0; + onChangeNotifyReact = undefined; + unsubscribe(); + }; + }, + getSnapshot() { + return version; + }, + f() { + clearCurrentStore(); + }, + [symDispose]() { + clearCurrentStore(); + }, + }; +} + +let finalCleanup: Promise | undefined; +const _queueMicroTask = Promise.prototype.then.bind(Promise.resolve()); + +/** + * Custom hook to create the effect to track signals used during render and + * subscribe to changes to rerender the component when the signals change. + */ +export function useSignals(): EffectStore { + clearCurrentStore(); + if (!finalCleanup) { + finalCleanup = _queueMicroTask(() => { + finalCleanup = undefined; + clearCurrentStore(); + }); + } + + const storeRef = useRef(); + if (storeRef.current == null) { + storeRef.current = createEffectStore(); + } + + const store = storeRef.current; + useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot); + setCurrentStore(store); + + return store; +} + +/** + * A wrapper component that renders a Signal's value directly as a Text node or JSX. + */ +function SignalValue({ data }: { data: Signal }) { + return data.value; +} + +// Decorate Signals so React renders them as components. +Object.defineProperties(Signal.prototype, { + $$typeof: { configurable: true, value: ReactElemType }, + type: { configurable: true, value: SignalValue }, + props: { + configurable: true, + get() { + return { data: this }; + }, + }, + ref: { configurable: true, value: null }, +}); + +export function useSignal(value: T) { + return useMemo(() => signal(value), Empty); +} + +export function useComputed(compute: () => T) { + const $compute = useRef(compute); + $compute.current = compute; + return useMemo(() => computed(() => $compute.current()), Empty); +} + +export function useSignalEffect(cb: () => void | (() => void)) { + const callback = useRef(cb); + callback.current = cb; + + useEffect(() => { + return effect(() => callback.current()); + }, Empty); +} diff --git a/packages/react/runtime/test/useSignals.test.tsx b/packages/react/runtime/test/useSignals.test.tsx new file mode 100644 index 00000000..c941e27d --- /dev/null +++ b/packages/react/runtime/test/useSignals.test.tsx @@ -0,0 +1,422 @@ +import { createElement, Fragment } from "react"; +import { Signal, signal, batch } from "@preact/signals-core"; +import { useSignals } from "@preact/signals-react/runtime"; +import { + Root, + createRoot, + act, + checkHangingAct, + getConsoleErrorSpy, + checkConsoleErrorLogs, +} from "../../test/shared/utils"; + +describe("useSignals", () => { + let scratch: HTMLDivElement; + let root: Root; + + async function render(element: Parameters[0]) { + await act(() => root.render(element)); + } + + beforeEach(async () => { + scratch = document.createElement("div"); + document.body.appendChild(scratch); + root = await createRoot(scratch); + getConsoleErrorSpy().resetHistory(); + }); + + afterEach(async () => { + await act(() => root.unmount()); + scratch.remove(); + + checkConsoleErrorLogs(); + checkHangingAct(); + }); + + it("should rerender components when signals they use change", async () => { + const signal1 = signal(0); + function Child1() { + useSignals(); + return

{signal1.value}

; + } + + const signal2 = signal(0); + function Child2() { + useSignals(); + return

{signal2.value}

; + } + + function Parent() { + return ( + + + + + ); + } + + await render(); + expect(scratch.innerHTML).to.equal("

0

0

"); + + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

0

"); + + await act(() => { + signal2.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

1

"); + }); + + it("should correctly invoke rerenders if useSignals is called multiple times in the same component", async () => { + const signal1 = signal(0); + const signal2 = signal(0); + const signal3 = signal(0); + function App() { + useSignals(); + const sig1 = signal1.value; + useSignals(); + const sig2 = signal2.value; + const sig3 = signal3.value; + useSignals(); + return ( +

+ {sig1} + {sig2} + {sig3} +

+ ); + } + + await render(); + expect(scratch.innerHTML).to.equal("

000

"); + + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("

100

"); + + await act(() => { + signal2.value += 1; + }); + expect(scratch.innerHTML).to.equal("

110

"); + + await act(() => { + signal3.value += 1; + }); + expect(scratch.innerHTML).to.equal("

111

"); + }); + + it("should not rerender components when signals they use do not change", async () => { + const child1Spy = sinon.spy(); + const signal1 = signal(0); + function Child1() { + child1Spy(); + useSignals(); + return

{signal1.value}

; + } + + const child2Spy = sinon.spy(); + const signal2 = signal(0); + function Child2() { + child2Spy(); + useSignals(); + return

{signal2.value}

; + } + + const parentSpy = sinon.spy(); + function Parent() { + parentSpy(); + return ( + + + + + ); + } + + function resetSpies() { + child1Spy.resetHistory(); + child2Spy.resetHistory(); + parentSpy.resetHistory(); + } + + resetSpies(); + await render(); + expect(scratch.innerHTML).to.equal("

0

0

"); + expect(child1Spy).to.have.been.calledOnce; + expect(child2Spy).to.have.been.calledOnce; + expect(parentSpy).to.have.been.calledOnce; + + resetSpies(); + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

0

"); + expect(child1Spy).to.have.been.calledOnce; + expect(child2Spy).to.not.have.been.called; + expect(parentSpy).to.not.have.been.called; + + resetSpies(); + await act(() => { + signal2.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

1

"); + expect(child1Spy).to.not.have.been.called; + expect(child2Spy).to.have.been.calledOnce; + expect(parentSpy).to.not.have.been.called; + }); + + it("should not rerender components when signals they use change but they are not mounted", async () => { + const child1Spy = sinon.spy(); + const signal1 = signal(0); + function Child() { + child1Spy(); + useSignals(); + const sig1 = signal1.value; + return

{sig1}

; + } + + function Parent({ show }: { show: boolean }) { + return {show && }; + } + + await render(); + expect(scratch.innerHTML).to.equal("

0

"); + + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

"); + + await act(() => { + render(); + }); + expect(scratch.innerHTML).to.equal(""); + + await act(() => { + signal1.value += 1; + }); + expect(child1Spy).to.have.been.calledTwice; + }); + + it("should not rerender components that only update signals in event handlers", async () => { + const buttonSpy = sinon.spy(); + function AddOneButton({ num }: { num: Signal }) { + useSignals(); + buttonSpy(); + return ( + + ); + } + + const displaySpy = sinon.spy(); + function DisplayNumber({ num }: { num: Signal }) { + useSignals(); + displaySpy(); + return

{num.value}

; + } + + const number = signal(0); + function App() { + return ( + + + + + ); + } + + await render(); + expect(scratch.innerHTML).to.equal("

0

"); + expect(buttonSpy).to.have.been.calledOnce; + expect(displaySpy).to.have.been.calledOnce; + + await act(() => { + scratch.querySelector("button")!.click(); + }); + + expect(scratch.innerHTML).to.equal("

1

"); + expect(buttonSpy).to.have.been.calledOnce; + expect(displaySpy).to.have.been.calledTwice; + }); + + it("should not rerender components that only read signals in event handlers", async () => { + const buttonSpy = sinon.spy(); + function AddOneButton({ num }: { num: Signal }) { + useSignals(); + buttonSpy(); + return ( + + ); + } + + const displaySpy = sinon.spy(); + function DisplayNumber({ num }: { num: Signal }) { + useSignals(); + displaySpy(); + return

{num.value}

; + } + + const adder = signal(2); + const number = signal(0); + function App() { + return ( + + + + + ); + } + + function resetSpies() { + buttonSpy.resetHistory(); + displaySpy.resetHistory(); + } + + resetSpies(); + await render(); + expect(scratch.innerHTML).to.equal("

0

"); + expect(buttonSpy).to.have.been.calledOnce; + expect(displaySpy).to.have.been.calledOnce; + + resetSpies(); + await act(() => { + scratch.querySelector("button")!.click(); + }); + + expect(scratch.innerHTML).to.equal("

2

"); + expect(buttonSpy).to.not.have.been.called; + expect(displaySpy).to.have.been.calledOnce; + + resetSpies(); + await act(() => { + adder.value += 1; + }); + + expect(scratch.innerHTML).to.equal("

2

"); + expect(buttonSpy).to.not.have.been.called; + expect(displaySpy).to.not.have.been.called; + + resetSpies(); + await act(() => { + scratch.querySelector("button")!.click(); + }); + + expect(scratch.innerHTML).to.equal("

5

"); + expect(buttonSpy).to.not.have.been.called; + expect(displaySpy).to.have.been.calledOnce; + }); + + it("should properly rerender components that use custom hooks", async () => { + const greeting = signal("Hello"); + function useGreeting() { + useSignals(); + return greeting.value; + } + + const name = signal("John"); + function useName() { + useSignals(); + return name.value; + } + + function App() { + const greeting = useGreeting(); + const name = useName(); + return ( +
+ {greeting} {name}! +
+ ); + } + + await render(); + expect(scratch.innerHTML).to.equal("
Hello John!
"); + + await act(() => { + greeting.value = "Hi"; + }); + expect(scratch.innerHTML).to.equal("
Hi John!
"); + + await act(() => { + name.value = "Jane"; + }); + expect(scratch.innerHTML).to.equal("
Hi Jane!
"); + + await act(() => { + batch(() => { + greeting.value = "Hello"; + name.value = "John"; + }); + }); + expect(scratch.innerHTML).to.equal("
Hello John!
"); + }); + + it("should properly rerender components that use custom hooks and signals", async () => { + const greeting = signal("Hello"); + function useGreeting() { + useSignals(); + return greeting.value; + } + + const name = signal("John"); + function useName() { + useSignals(); + return name.value; + } + + const punctuation = signal("!"); + function App() { + useSignals(); + const greeting = useGreeting(); + const name = useName(); + return ( +
+ {greeting} {name} + {punctuation.value} +
+ ); + } + + await render(); + expect(scratch.innerHTML).to.equal("
Hello John!
"); + + await act(() => { + greeting.value = "Hi"; + }); + expect(scratch.innerHTML).to.equal("
Hi John!
"); + + await act(() => { + name.value = "Jane"; + }); + expect(scratch.innerHTML).to.equal("
Hi Jane!
"); + + await act(() => { + punctuation.value = "?"; + }); + expect(scratch.innerHTML).to.equal("
Hi Jane?
"); + + await act(() => { + batch(() => { + greeting.value = "Hello"; + name.value = "John"; + punctuation.value = "!"; + }); + }); + expect(scratch.innerHTML).to.equal("
Hello John!
"); + }); +}); diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts new file mode 100644 index 00000000..b2c03f14 --- /dev/null +++ b/packages/react/src/index.ts @@ -0,0 +1,33 @@ +import { + signal, + computed, + batch, + effect, + Signal, + type ReadonlySignal, + untracked, +} from "@preact/signals-core"; +import type { ReactElement } from "react"; +import { useSignal, useComputed, useSignalEffect } from "../runtime"; +import { installAutoSignalTracking } from "../runtime/src/auto"; + +export { + signal, + computed, + batch, + effect, + Signal, + type ReadonlySignal, + useSignal, + useComputed, + useSignalEffect, + untracked, +}; + +declare module "@preact/signals-core" { + // @ts-ignore internal Signal is viewed as function + // eslint-disable-next-line @typescript-eslint/no-empty-interface + interface Signal extends ReactElement {} +} + +installAutoSignalTracking(); diff --git a/packages/react/test/browser/exports.test.tsx b/packages/react/test/browser/exports.test.tsx new file mode 100644 index 00000000..a36d0241 --- /dev/null +++ b/packages/react/test/browser/exports.test.tsx @@ -0,0 +1,18 @@ +import * as core from "@preact/signals-core"; +import * as adapter from "@preact/signals-react"; + +describe("@preact/signals-react", () => { + describe("exports", () => { + it("should re-export core", () => { + const keys = Object.keys(core); + + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + expect(key in adapter).to.equal( + true, + `"${key}" is not exported from react adapter` + ); + } + }); + }); +}); diff --git a/packages/react/test/browser/mounts.test.tsx b/packages/react/test/browser/mounts.test.tsx new file mode 100644 index 00000000..af132cac --- /dev/null +++ b/packages/react/test/browser/mounts.test.tsx @@ -0,0 +1,32 @@ +import { mountSignalsTests } from "../shared/mounting"; +import { + Root, + createRoot, + act, + getConsoleErrorSpy, + checkConsoleErrorLogs, +} from "../shared/utils"; + +describe("@preact/signals-react mounting", () => { + let scratch: HTMLDivElement; + let root: Root; + + async function render(element: JSX.Element | null): Promise { + await act(() => root.render(element)); + return scratch.innerHTML; + } + + beforeEach(async () => { + scratch = document.createElement("div"); + document.body.appendChild(scratch); + root = await createRoot(scratch); + getConsoleErrorSpy().resetHistory(); + }); + + afterEach(async () => { + scratch.remove(); + checkConsoleErrorLogs(); + }); + + mountSignalsTests(render); +}); diff --git a/packages/react/test/browser/react-router.test.tsx b/packages/react/test/browser/react-router.test.tsx new file mode 100644 index 00000000..eaa1dd8d --- /dev/null +++ b/packages/react/test/browser/react-router.test.tsx @@ -0,0 +1,63 @@ +// @ts-ignore-next-line +globalThis.IS_REACT_ACT_ENVIRONMENT = true; + +import { signal } from "@preact/signals-react"; +import { createElement } from "react"; +import * as ReactRouter from "react-router-dom"; + +import { act, checkHangingAct, createRoot, Root } from "../shared/utils"; + +const MemoryRouter = ReactRouter.MemoryRouter; +const Routes = ReactRouter.Routes + ? ReactRouter.Routes + : (ReactRouter as any).Switch; // react-router-dom v5 + +// @ts-expect-error We are doing a check for react-router-dom v5 vs v6 here, so +// while TS thinks ReactRouter.Routes will always be here, it isn't in v5. +const Route = ReactRouter.Routes + ? ReactRouter.Route + : // react-router-dom v5 requires the element prop to be passed as children. + ({ element, ...props }: any) => ( + {element} + ); + +describe("@preact/signals-react", () => { + let scratch: HTMLDivElement; + let root: Root; + async function render(element: Parameters[0]) { + await act(() => root.render(element)); + } + + beforeEach(async () => { + scratch = document.createElement("div"); + document.body.appendChild(scratch); + root = await createRoot(scratch); + }); + + afterEach(async () => { + checkHangingAct(); + await act(() => root.unmount()); + scratch.remove(); + }); + + describe("react-router-dom", () => { + it("Route component should render", async () => { + const name = signal("World")!; + + function App() { + return ( + + + Page 1}> + Hello {name}!}> + + + ); + } + + await render(); + + expect(scratch.innerHTML).to.equal("
Hello World!
"); + }); + }); +}); diff --git a/packages/react/test/browser/updates.test.tsx b/packages/react/test/browser/updates.test.tsx new file mode 100644 index 00000000..dec3fe8e --- /dev/null +++ b/packages/react/test/browser/updates.test.tsx @@ -0,0 +1,842 @@ +// @ts-ignore-next-line +globalThis.IS_REACT_ACT_ENVIRONMENT = true; + +import { + signal, + computed, + useComputed, + useSignalEffect, + useSignal, +} from "@preact/signals-react"; +import type { Signal, ReadonlySignal } from "@preact/signals-react"; +import { + createElement, + Fragment, + forwardRef, + useMemo, + useReducer, + memo, + StrictMode, + createRef, + useState, + useContext, + createContext, + useRef, +} from "react"; +import type { FunctionComponent } from "react"; + +import { renderToStaticMarkup } from "react-dom/server"; +import { + createRoot, + Root, + act, + checkHangingAct, + isReact16, + isProd, + getConsoleErrorSpy, + checkConsoleErrorLogs, +} from "../shared/utils"; + +describe("@preact/signals-react updating", () => { + let scratch: HTMLDivElement; + let root: Root; + + async function render(element: Parameters[0]) { + await act(() => root.render(element)); + } + + beforeEach(async () => { + scratch = document.createElement("div"); + document.body.appendChild(scratch); + root = await createRoot(scratch); + getConsoleErrorSpy().resetHistory(); + }); + + afterEach(async () => { + await act(() => root.unmount()); + scratch.remove(); + + checkConsoleErrorLogs(); + checkHangingAct(); + }); + + describe("SignalValue bindings", () => { + it("should render text without signals", async () => { + await render(test); + const span = scratch.firstChild; + const text = span?.firstChild; + expect(text).to.have.property("data", "test"); + }); + + it("should render Signals as SignalValue", async () => { + const sig = signal("test"); + await render({sig}); + const span = scratch.firstChild; + expect(span).to.have.property("firstChild").that.is.an.instanceOf(Text); + const text = span?.firstChild; + expect(text).to.have.property("data", "test"); + }); + + it("should render computed as SignalValue", async () => { + const sig = signal("test"); + const comp = computed(() => `${sig} ${sig}`); + await render({comp}); + const span = scratch.firstChild; + expect(span).to.have.property("firstChild").that.is.an.instanceOf(Text); + const text = span?.firstChild; + expect(text).to.have.property("data", "test test"); + }); + + it("should update Signal-based SignalValue (no parent component)", async () => { + const sig = signal("test"); + await render({sig}); + + const text = scratch.firstChild!.firstChild!; + expect(text).to.have.property("data", "test"); + + await act(() => { + sig.value = "changed"; + }); + + // should not remount/replace SignalValue + expect(scratch.firstChild!.firstChild!).to.equal(text); + // should update the text in-place + expect(text).to.have.property("data", "changed"); + }); + + it("should update Signal-based SignalValue (in a parent component)", async () => { + const sig = signal("test"); + function App({ x }: { x: typeof sig }) { + return {x}; + } + await render(); + + const text = scratch.firstChild!.firstChild!; + expect(text).to.have.property("data", "test"); + + await act(() => { + sig.value = "changed"; + }); + + // should not remount/replace SignalValue + expect(scratch.firstChild!.firstChild!).to.equal(text); + // should update the text in-place + expect(text).to.have.property("data", "changed"); + }); + + it("should work with JSX inside signal", async () => { + const sig = signal(test); + function App({ x }: { x: typeof sig }) { + return {x}; + } + await render(); + + let text = scratch.firstChild!.firstChild!; + expect(text).to.be.instanceOf(HTMLElement); + expect(text.firstChild).to.have.property("data", "test"); + + await act(() => { + sig.value =
changed
; + }); + + text = scratch.firstChild!.firstChild!; + expect(text).to.be.instanceOf(HTMLDivElement); + expect(text.firstChild).to.have.property("data", "changed"); + }); + }); + + describe("Component bindings", () => { + it("should subscribe to signals", async () => { + const sig = signal("foo"); + + function App() { + const value = sig.value; + return

{value}

; + } + + await render(); + expect(scratch.textContent).to.equal("foo"); + + await act(() => { + sig.value = "bar"; + }); + expect(scratch.textContent).to.equal("bar"); + }); + + it("should rerender components when signals they use change", async () => { + const signal1 = signal(0); + function Child1() { + return
{signal1}
; + } + + const signal2 = signal(0); + function Child2() { + return
{signal2}
; + } + + function Parent() { + return ( + + + + + ); + } + + await render(); + expect(scratch.innerHTML).to.equal("
0
0
"); + + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("
1
0
"); + + await act(() => { + signal2.value += 1; + }); + expect(scratch.innerHTML).to.equal("
1
1
"); + }); + + it("should subscribe to signals passed as props to DOM elements", async () => { + const className = signal("foo"); + function App() { + // @ts-expect-error React types don't allow signals on DOM elements :/ + return
; + } + + await render(); + + expect(scratch.innerHTML).to.equal('
'); + + await act(() => { + className.value = "bar"; + }); + + expect(scratch.innerHTML).to.equal('
'); + }); + + it("should activate signal accessed in render", async () => { + const sig = signal(null); + + function App() { + const arr = useComputed(() => { + // trigger read + sig.value; + + return []; + }); + + const str = arr.value.join(", "); + return

{str}

; + } + + try { + await render(); + } catch (e: any) { + expect.fail(e.stack); + } + }); + + it("should not subscribe to child signals", async () => { + const sig = signal("foo"); + + function Child() { + const value = sig.value; + return

{value}

; + } + + const spy = sinon.spy(); + function App() { + spy(); + return ; + } + + await render(); + expect(scratch.textContent).to.equal("foo"); + + await act(() => { + sig.value = "bar"; + }); + expect(spy).to.be.calledOnce; + }); + + it("should update memo'ed component via signals", async () => { + const sig = signal("foo"); + + function Inner() { + const value = sig.value; + return

{value}

; + } + + function App() { + sig.value; + return useMemo(() => , []); + } + + await render(); + expect(scratch.textContent).to.equal("foo"); + + await act(() => { + sig.value = "bar"; + }); + expect(scratch.textContent).to.equal("bar"); + }); + + it("should update forwardRef'ed component via signals", async () => { + const sig = signal("foo"); + + const Inner = forwardRef(() => { + return

{sig.value}

; + }); + + function App() { + return ; + } + + await render(); + expect(scratch.textContent).to.equal("foo"); + + await act(() => { + sig.value = "bar"; + }); + expect(scratch.textContent).to.equal("bar"); + }); + + it("should consistently rerender in strict mode", async () => { + const sig = signal(-1); + + const Test = () =>

{sig.value}

; + const App = () => ( + + + + ); + + await render(); + expect(scratch.textContent).to.equal("-1"); + + for (let i = 0; i < 3; i++) { + await act(async () => { + sig.value = i; + }); + expect(scratch.textContent).to.equal("" + i); + } + }); + + it("should consistently rerender in strict mode (with memo)", async () => { + const sig = signal(-1); + + const Test = memo(() =>

{sig.value}

); + const App = () => ( + + + + ); + + await render(); + expect(scratch.textContent).to.equal("-1"); + + for (let i = 0; i < 3; i++) { + await act(async () => { + sig.value = i; + }); + expect(scratch.textContent).to.equal("" + i); + } + }); + + it("should render static markup of a component", async () => { + const count = signal(0); + + const Test = () => { + return ( +
+						{renderToStaticMarkup({count})}
+						{renderToStaticMarkup({count.value})}
+					
+ ); + }; + + await render(); + expect(scratch.textContent).to.equal("00"); + + for (let i = 0; i < 3; i++) { + await act(async () => { + count.value += 1; + }); + expect(scratch.textContent).to.equal( + `${count.value}${count.value}` + ); + } + }); + + it("should correctly render components that have useReducer()", async () => { + const count = signal(0); + + let increment: () => void; + const Test = () => { + const [state, dispatch] = useReducer( + (state: number, action: number) => { + return state + action; + }, + -2 + ); + + increment = () => dispatch(1); + + const doubled = count.value * 2; + + return ( +
+						{state}
+						{doubled}
+					
+ ); + }; + + await render(); + expect(scratch.innerHTML).to.equal( + "
-20
" + ); + + for (let i = 0; i < 3; i++) { + await act(async () => { + count.value += 1; + }); + expect(scratch.innerHTML).to.equal( + `
-2${count.value * 2}
` + ); + } + + await act(() => { + increment(); + }); + expect(scratch.innerHTML).to.equal( + `
-1${count.value * 2}
` + ); + }); + + it("should not fail when a component calls setState while rendering", async () => { + let increment: () => void; + function App() { + const [state, setState] = useState(0); + increment = () => setState(state + 1); + + if (state > 0 && state < 2) { + setState(state + 1); + } + + return
{state}
; + } + + await render(); + expect(scratch.innerHTML).to.equal("
0
"); + + await act(() => { + increment(); + }); + expect(scratch.innerHTML).to.equal("
2
"); + }); + + it("should not fail when a component calls setState multiple times while rendering", async () => { + let increment: () => void; + function App() { + const [state, setState] = useState(0); + increment = () => setState(state + 1); + + if (state > 0 && state < 5) { + setState(state + 1); + } + + return
{state}
; + } + + await render(); + expect(scratch.innerHTML).to.equal("
0
"); + + await act(() => { + increment(); + }); + expect(scratch.innerHTML).to.equal("
5
"); + }); + + it("should not fail when a component only uses state-less hooks", async () => { + // This test is suppose to trigger a condition in React where the + // HooksDispatcherOnMountWithHookTypesInDEV is used. This dispatcher is + // used in the development build of React if a component has hook types + // defined but no memoizedState, meaning no stateful hooks (e.g. useState) + // are used. `useContext` is an example of a state-less hook because it + // does not mount any hook state onto the fiber's memoizedState field. + // + // However, as of writing, because our react adapter inserts a + // useSyncExternalStore into all components, all components have memoized + // state and so this condition is never hit. However, I'm leaving the test + // to capture this unique behavior to hopefully catch any errors caused by + // not understanding or handling this in the future. + + const sig = signal(0); + const MyContext = createContext(0); + + function Child() { + const value = useContext(MyContext); + return ( +
+ {sig} {value} +
+ ); + } + + let updateContext: () => void; + function App() { + const [value, setValue] = useState(0); + updateContext = () => setValue(value + 1); + + return ( + + + + ); + } + + await render(); + expect(scratch.innerHTML).to.equal("
0 0
"); + + await act(() => { + sig.value++; + }); + expect(scratch.innerHTML).to.equal("
1 0
"); + + await act(() => { + updateContext(); + }); + expect(scratch.innerHTML).to.equal("
1 1
"); + }); + + it("should minimize rerenders when passing signals through context", async () => { + function spyOn

( + c: FunctionComponent

+ ) { + return sinon.spy(c); + } + + // Manually read signal value below so we can watch whether components rerender + const Origin = spyOn(function Origin() { + const origin = useContext(URLModelContext).origin; + return {origin.value}; + }); + + const Pathname = spyOn(function Pathname() { + const pathname = useContext(URLModelContext).pathname; + return {pathname.value}; + }); + + const Search = spyOn(function Search() { + const search = useContext(URLModelContext).search; + return {search.value}; + }); + + // Never reads signal value during render so should never rerender + const UpdateURL = spyOn(function UpdateURL() { + const update = useContext(URLModelContext).update; + return ( + + ); + }); + + interface URLModel { + origin: ReadonlySignal; + pathname: ReadonlySignal; + search: ReadonlySignal; + update(updater: (newURL: URL) => void): void; + } + + // Also never reads signal value during render so should never rerender + const URLModelContext = createContext(null as any); + const URLModelProvider = spyOn(function SignalProvider({ children }) { + const url = useSignal(new URL("https://domain.com/test?a=1")); + const modelRef = useRef(null); + + if (modelRef.current == null) { + modelRef.current = { + origin: computed(() => url.value.origin), + pathname: computed(() => url.value.pathname), + search: computed(() => url.value.search), + update(updater) { + const newURL = new URL(url.value); + updater(newURL); + url.value = newURL; + }, + }; + } + + return ( + + {children} + + ); + }); + + function App() { + return ( + +

+ + + +

+ + + ); + } + + await render(); + + const url = scratch.querySelector("p")!; + expect(url.textContent).to.equal("https://domain.com/test?a=1"); + expect(URLModelProvider).to.be.calledOnce; + expect(Origin).to.be.calledOnce; + expect(Pathname).to.be.calledOnce; + expect(Search).to.be.calledOnce; + + await act(() => { + scratch.querySelector("button")!.click(); + }); + + expect(url.textContent).to.equal("https://domain.com/test?a=2"); + expect(URLModelProvider).to.be.calledOnce; + expect(Origin).to.be.calledOnce; + expect(Pathname).to.be.calledOnce; + expect(Search).to.be.calledTwice; + }); + + it("should not subscribe to computed signals only created and not used", async () => { + const sig = signal(0); + const childSpy = sinon.spy(); + const parentSpy = sinon.spy(); + + function Child({ num }: { num: Signal }) { + childSpy(); + return

{num.value}

; + } + + function Parent({ num }: { num: Signal }) { + parentSpy(); + const sig2 = useComputed(() => num.value + 1); + return ; + } + + await render(); + expect(scratch.innerHTML).to.equal("

1

"); + expect(parentSpy).to.be.calledOnce; + expect(childSpy).to.be.calledOnce; + + await act(() => { + sig.value += 1; + }); + expect(scratch.innerHTML).to.equal("

2

"); + expect(parentSpy).to.be.calledOnce; + expect(childSpy).to.be.calledTwice; + }); + + it("should properly subscribe and unsubscribe to conditionally rendered computed signals ", async () => { + const computedDep = signal(0); + const renderComputed = signal(true); + const renderSpy = sinon.spy(); + + function App() { + renderSpy(); + const computed = useComputed(() => computedDep.value + 1); + return renderComputed.value ?

{computed.value}

: null; + } + + await render(); + expect(scratch.innerHTML).to.equal("

1

"); + expect(renderSpy).to.be.calledOnce; + + await act(() => { + computedDep.value += 1; + }); + expect(scratch.innerHTML).to.equal("

2

"); + expect(renderSpy).to.be.calledTwice; + + await act(() => { + renderComputed.value = false; + }); + expect(scratch.innerHTML).to.equal(""); + expect(renderSpy).to.be.calledThrice; + + await act(() => { + computedDep.value += 1; + }); + expect(scratch.innerHTML).to.equal(""); + expect(renderSpy).to.be.calledThrice; // Should not be called again + }); + }); + + describe("useSignal()", () => { + it("should create a signal from a primitive value", async () => { + function App() { + const count = useSignal(1); + return ( +
+ {count} + +
+ ); + } + + await render(); + expect(scratch.textContent).to.equal("1Increment"); + + await act(() => { + scratch.querySelector("button")!.click(); + }); + expect(scratch.textContent).to.equal("2Increment"); + }); + }); + + describe("useSignalEffect()", () => { + it("should be invoked after commit", async () => { + const ref = createRef(); + const sig = signal("foo"); + const spy = sinon.spy(); + let count = 0; + + function App() { + useSignalEffect(() => + spy( + sig.value, + ref.current, + ref.current!.getAttribute("data-render-id") + ) + ); + return ( +

+ {sig.value} +

+ ); + } + + await render(); + expect(scratch.textContent).to.equal("foo"); + + expect(spy).to.have.been.calledOnceWith( + "foo", + scratch.firstElementChild, + "0" + ); + + spy.resetHistory(); + + await act(() => { + sig.value = "bar"; + }); + + expect(scratch.textContent).to.equal("bar"); + + // NOTE: Ideally, call should receive "1" as its third argument! The "0" + // indicates that React's DOM mutations hadn't yet been performed when the + // callback ran. This happens because we do signal-based effect runs after + // the first, not VDOM. Perhaps we could find a way to defer the callback + // when it coincides with a render? In React 16 when running in production + // however, we do see "1" as expected, likely because we are using a fake + // act() implementation which completes after the DOM has been updated. + expect(spy).to.have.been.calledOnceWith( + "bar", + scratch.firstElementChild, + isReact16 && isProd ? "1" : "0" // ideally always "1" - update if we find a nice way to do so! + ); + }); + + it("should invoke any returned cleanup function for updates", async () => { + const ref = createRef(); + const sig = signal("foo"); + const spy = sinon.spy(); + const cleanup = sinon.spy(); + let count = 0; + + function App() { + useSignalEffect(() => { + const id = ref.current!.getAttribute("data-render-id"); + const value = sig.value; + spy(value, ref.current, id); + return () => cleanup(value, ref.current, id); + }); + return ( +

+ {sig.value} +

+ ); + } + + await render(); + + expect(cleanup).not.to.have.been.called; + expect(spy).to.have.been.calledOnceWith( + "foo", + scratch.firstElementChild, + "0" + ); + spy.resetHistory(); + + await act(() => { + sig.value = "bar"; + }); + + expect(scratch.textContent).to.equal("bar"); + + const child = scratch.firstElementChild; + + expect(cleanup).to.have.been.calledOnceWith("foo", child, "0"); + + expect(spy).to.have.been.calledOnceWith( + "bar", + child, + isReact16 && isProd ? "1" : "0" // ideally always "1" - update if we find a nice way to do so! + ); + }); + + it("should invoke any returned cleanup function for unmounts", async () => { + const ref = createRef(); + const sig = signal("foo"); + const spy = sinon.spy(); + const cleanup = sinon.spy(); + + function App() { + useSignalEffect(() => { + const value = sig.value; + spy(value, ref.current); + return () => cleanup(value, ref.current); + }); + return

{sig.value}

; + } + + await render(); + + const child = scratch.firstElementChild; + + expect(scratch.innerHTML).to.equal("

foo

"); + expect(cleanup).not.to.have.been.called; + expect(spy).to.have.been.calledOnceWith("foo", child); + spy.resetHistory(); + + await act(() => { + root.unmount(); + }); + + expect(scratch.innerHTML).to.equal(""); + expect(spy).not.to.have.been.called; + expect(cleanup).to.have.been.calledOnce; + // @note: React v18 cleans up the ref eagerly, so it's already null by the + // time the callback runs. this is probably worth fixing at some point. + expect(cleanup).to.have.been.calledWith("foo", isReact16 ? child : null); + }); + }); +}); diff --git a/packages/react/test/node/renderToStaticMarkup.test.tsx b/packages/react/test/node/renderToStaticMarkup.test.tsx new file mode 100644 index 00000000..08ad99be --- /dev/null +++ b/packages/react/test/node/renderToStaticMarkup.test.tsx @@ -0,0 +1,22 @@ +import { signal, useSignalEffect } from "@preact/signals-react"; +import { createElement } from "react"; +import { renderToStaticMarkup } from "react-dom/server"; +import { mountSignalsTests } from "../shared/mounting"; + +describe("renderToStaticMarkup", () => { + mountSignalsTests(renderToStaticMarkup); + + it("should not invoke useSignalEffect", async () => { + const spy = sinon.spy(); + const sig = signal("foo"); + + function App() { + useSignalEffect(() => spy(sig.value)); + return

{sig.value}

; + } + + const html = await renderToStaticMarkup(); + expect(html).to.equal("

foo

"); + expect(spy.called).to.be.false; + }); +}); diff --git a/packages/react/test/shared/mounting.tsx b/packages/react/test/shared/mounting.tsx new file mode 100644 index 00000000..cef29aca --- /dev/null +++ b/packages/react/test/shared/mounting.tsx @@ -0,0 +1,184 @@ +// @ts-ignore-next-line +globalThis.IS_REACT_ACT_ENVIRONMENT = true; + +import { + signal, + computed, + useComputed, + useSignal, +} from "@preact/signals-react"; +import { expect } from "chai"; +import { createElement, useReducer, StrictMode, useState } from "react"; + +import { getConsoleErrorSpy, checkConsoleErrorLogs } from "./utils"; + +export function mountSignalsTests( + render: (element: JSX.Element) => string | Promise +) { + beforeEach(async () => { + getConsoleErrorSpy().resetHistory(); + }); + + afterEach(async () => { + checkConsoleErrorLogs(); + }); + + describe("mount text bindings", () => { + it("should render text without signals", async () => { + const html = await render(test); + expect(html).to.equal("test"); + }); + + it("should render Signals as SignalValue", async () => { + const sig = signal("test"); + const html = await render({sig}); + expect(html).to.equal("test"); + }); + + it("should render computed as SignalValue", async () => { + const sig = signal("test"); + const comp = computed(() => `${sig} ${sig}`); + const html = await render({comp}); + expect(html).to.equal("test test"); + }); + }); + + describe("mount component bindings", () => { + it("should mount component with signals as text", async () => { + const sig = signal("foo"); + + function App() { + const value = sig.value; + return

{value}

; + } + + const html = await render(); + expect(html).to.equal("

foo

"); + }); + + it("should activate signal accessed in render", async () => { + const sig = signal(null); + + function App() { + const arr = useComputed(() => { + // trigger read + sig.value; + + return []; + }); + + const str = arr.value.join(", "); + return

{str}

; + } + + try { + await render(); + } catch (e: any) { + expect.fail(e.stack); + } + }); + + it("should properly mount in strict mode", async () => { + const sig = signal(-1); + + const Test = () =>

{sig.value}

; + const App = () => ( + + + + ); + + const html = await render(); + expect(html).to.equal("

-1

"); + }); + + it("should correctly mount components that have useReducer()", async () => { + const count = signal(0); + + const Test = () => { + const [state] = useReducer((state: number, action: number) => { + return state + action; + }, -2); + + const doubled = count.value * 2; + + return ( +
+						{state}
+						{doubled}
+					
+ ); + }; + + const html = await render(); + expect(html).to.equal("
-20
"); + }); + + it("should not fail when a component calls setState while mounting", async () => { + function App() { + const [state, setState] = useState(0); + if (state == 0) { + setState(1); + } + + return
{state}
; + } + + const html = await render(); + expect(html).to.equal("
1
"); + }); + + it("should not fail when a component calls setState multiple times while mounting", async () => { + function App() { + const [state, setState] = useState(0); + if (state < 5) { + setState(state + 1); + } + + return
{state}
; + } + + const html = await render(); + expect(html).to.equal("
5
"); + }); + }); + + describe("useSignal()", () => { + it("should create a signal from a primitive value", async () => { + function App() { + const count = useSignal(1); + return ( +
+ {count} + +
+ ); + } + + const html = await render(); + expect(html).to.equal("
1
"); + }); + + it("should properly update signal values changed during mount", async () => { + function App() { + const count = useSignal(0); + if (count.value == 0) { + count.value++; + } + + return ( +
+ {count} + +
+ ); + } + + const html = await render(); + expect(html).to.equal("
1
"); + + const html2 = await render(); + expect(html2).to.equal("
1
"); + }); + }); +} diff --git a/packages/react/test/shared/utils.ts b/packages/react/test/shared/utils.ts new file mode 100644 index 00000000..2d561b93 --- /dev/null +++ b/packages/react/test/shared/utils.ts @@ -0,0 +1,127 @@ +import React from "react"; +import sinon from "sinon"; +import { act as realAct } from "react-dom/test-utils"; + +export interface Root { + render(element: JSX.Element | null): void; + unmount(): void; +} + +export const isProd = process.env.NODE_ENV === "production"; +export const isReact16 = React.version.startsWith("16."); + +// We need to use createRoot() if it's available, but it's only available in +// React 18. To enable local testing with React 16 & 17, we'll create a fake +// createRoot() that uses render() and unmountComponentAtNode() instead. +let createRootCache: ((container: Element) => Root) | undefined; +export async function createRoot(container: Element): Promise { + if (!createRootCache) { + try { + // @ts-expect-error ESBuild will replace this import with a require() call + // if it resolves react-dom/client. If it doesn't, it will leave the + // import untouched causing a runtime error we'll handle below. + const { createRoot } = await import("react-dom/client"); + createRootCache = createRoot; + } catch (e) { + // @ts-expect-error ESBuild will replace this import with a require() call + // if it resolves react-dom. + const { render, unmountComponentAtNode } = await import("react-dom"); + createRootCache = (container: Element) => ({ + render(element: JSX.Element) { + render(element, container); + }, + unmount() { + unmountComponentAtNode(container); + }, + }); + } + } + + return createRootCache(container); +} + +// When testing using react's production build, we can't use act (React +// explicitly throws an error in this situation). So instead we'll fake act by +// waiting for a requestAnimationFrame and then 10ms for React's concurrent +// rerendering and any effects to flush. We'll make a best effort to throw a +// helpful error in afterEach if we detect that act() was called but not +// awaited. +const afterFrame = (ms: number) => + new Promise(r => requestAnimationFrame(() => setTimeout(r, ms))); + +let acting = 0; +async function prodActShim(cb: () => void | Promise): Promise { + acting++; + try { + await cb(); + await afterFrame(10); + } finally { + acting--; + } +} + +export function checkHangingAct() { + if (acting > 0) { + throw new Error( + `It appears act() was called but not awaited. This could happen if a test threw an Error or if a test forgot to await a call to act. Make sure to await act() calls in tests.` + ); + } +} + +export const act = + process.env.NODE_ENV === "production" + ? (prodActShim as typeof realAct) + : realAct; + +/** + * `console.log` supports formatting strings with `%s` for string substitutions. + * This function accepts a string and additional arguments of values and returns + * a string with the values substituted in. + */ +export function consoleFormat(str: string, ...values: unknown[]): string { + let idx = 0; + return str.replace(/%s/g, () => String(values[idx++])); +} + +declare global { + let errorSpy: sinon.SinonSpy | undefined; +} + +// Only one spy can be active on an object at a time and since all tests share +// the same console object we need to make sure we're only spying on it once. +// We'll use this method to share the spy across all tests. +export function getConsoleErrorSpy(): sinon.SinonSpy { + if (typeof errorSpy === "undefined") { + (globalThis as any).errorSpy = sinon.spy(console, "error"); + } + + return errorSpy!; +} + +const messagesToIgnore = [ + // Ignore errors for timeouts of tests that often happen while debugging + /async tests and hooks,/, + // Ignore React 16 warnings about awaiting `act` calls (warning removed in React 18) + /Do not await the result of calling act/, + // Ignore how chai or mocha uses `console.error` to print out errors + /AssertionError/, +]; + +export function checkConsoleErrorLogs(): void { + const errorSpy = getConsoleErrorSpy(); + if (errorSpy.called) { + let message: string; + if (errorSpy.firstCall.args[0].toString().includes("%s")) { + const firstArg = errorSpy.firstCall.args[0]; + message = consoleFormat(firstArg, ...errorSpy.firstCall.args.slice(1)); + } else { + message = errorSpy.firstCall.args.join(" "); + } + + if (messagesToIgnore.every(re => re.test(message) === false)) { + expect.fail( + `Console.error was unexpectedly called with this message: \n${message}` + ); + } + } +} From 84e2583a38a527046e2181618fa51d006cd3af2c Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Sun, 12 Nov 2023 10:12:23 +0100 Subject: [PATCH 02/21] tests env updated --- packages/query/vitest-setup.ts | 3 + packages/utils/setupVitest.ts | 89 ++++++++++--------- .../src/__tests__/store/integration.test.tsx | 38 ++++---- packages/utils/src/__tests__/utils.ts | 5 +- 4 files changed, 75 insertions(+), 60 deletions(-) diff --git a/packages/query/vitest-setup.ts b/packages/query/vitest-setup.ts index 481b073e..9c901bbc 100644 --- a/packages/query/vitest-setup.ts +++ b/packages/query/vitest-setup.ts @@ -4,6 +4,9 @@ import matchers from "@testing-library/jest-dom/matchers"; import { act } from "@testing-library/react"; import { expect } from "vitest"; +// @ts-ignore-next-line +globalThis.IS_REACT_ACT_ENVIRONMENT = true; + expect.extend(matchers); notifyManager.setNotifyFunction((batch) => { diff --git a/packages/utils/setupVitest.ts b/packages/utils/setupVitest.ts index 782a005b..6476bec2 100644 --- a/packages/utils/setupVitest.ts +++ b/packages/utils/setupVitest.ts @@ -1,94 +1,97 @@ -import { afterEach, beforeEach, expect, vi, type SpyInstance, } from 'vitest' +import { afterEach, beforeEach, expect, vi, type SpyInstance } from "vitest"; + +// @ts-ignore-next-line +globalThis.IS_REACT_ACT_ENVIRONMENT = true; expect.extend({ toHaveBeenWarned(received: string) { - asserted.add(received) - const passed = warn.mock.calls.some(args => args[0].includes(received)) + asserted.add(received); + const passed = warn.mock.calls.some((args) => args[0].includes(received)); if (passed) { return { pass: true, - message: () => `expected "${received}" not to have been warned.` - } + message: () => `expected "${received}" not to have been warned.`, + }; } else { - const msgs = warn.mock.calls.map(args => args[0]).join('\n - ') + const msgs = warn.mock.calls.map((args) => args[0]).join("\n - "); return { pass: false, message: () => `expected "${received}" to have been warned` + (msgs.length ? `.\n\nActual messages:\n\n - ${msgs}` - : ` but no warning was recorded.`) - } + : ` but no warning was recorded.`), + }; } }, toHaveBeenWarnedLast(received: string) { - asserted.add(received) + asserted.add(received); const passed = - warn.mock.calls[warn.mock.calls.length - 1]![0].includes(received) + warn.mock.calls[warn.mock.calls.length - 1]![0].includes(received); if (passed) { return { pass: true, - message: () => `expected "${received}" not to have been warned last.` - } + message: () => `expected "${received}" not to have been warned last.`, + }; } else { - const msgs = warn.mock.calls.map(args => args[0]).join('\n - ') + const msgs = warn.mock.calls.map((args) => args[0]).join("\n - "); return { pass: false, message: () => - `expected "${received}" to have been warned last.\n\nActual messages:\n\n - ${msgs}` - } + `expected "${received}" to have been warned last.\n\nActual messages:\n\n - ${msgs}`, + }; } }, toHaveBeenWarnedTimes(received: string, n: number) { - asserted.add(received) - let found = 0 - warn.mock.calls.forEach(args => { + asserted.add(received); + let found = 0; + warn.mock.calls.forEach((args) => { if (args[0].includes(received)) { - found++ + found++; } - }) + }); if (found === n) { return { pass: true, - message: () => `expected "${received}" to have been warned ${n} times.` - } + message: () => `expected "${received}" to have been warned ${n} times.`, + }; } else { return { pass: false, message: () => - `expected "${received}" to have been warned ${n} times but got ${found}.` - } + `expected "${received}" to have been warned ${n} times but got ${found}.`, + }; } - } -}) + }, +}); -let warn: SpyInstance -const asserted: Set = new Set() +let warn: SpyInstance; +const asserted: Set = new Set(); beforeEach(() => { - asserted.clear() - warn = vi.spyOn(console, 'warn') - warn.mockImplementation(() => {}) -}) + asserted.clear(); + warn = vi.spyOn(console, "warn"); + warn.mockImplementation(() => {}); +}); afterEach(() => { - const assertedArray = Array.from(asserted) + const assertedArray = Array.from(asserted); const nonAssertedWarnings = warn.mock.calls - .map(args => args[0]) - .filter(received => { - return !assertedArray.some(assertedMsg => { - return received.includes(assertedMsg) - }) - }) - warn.mockRestore() + .map((args) => args[0]) + .filter((received) => { + return !assertedArray.some((assertedMsg) => { + return received.includes(assertedMsg); + }); + }); + warn.mockRestore(); if (nonAssertedWarnings.length) { throw new Error( `test case threw unexpected warnings:\n - ${nonAssertedWarnings.join( - '\n - ' + "\n - " )}` - ) + ); } -}) \ No newline at end of file +}); diff --git a/packages/utils/src/__tests__/store/integration.test.tsx b/packages/utils/src/__tests__/store/integration.test.tsx index dd07f3ec..ccda1c33 100644 --- a/packages/utils/src/__tests__/store/integration.test.tsx +++ b/packages/utils/src/__tests__/store/integration.test.tsx @@ -1,4 +1,9 @@ -import { batch, computed, effect, untracked } from "@preact-signals/unified-signals"; +import { + batch, + computed, + effect, + untracked, +} from "@preact-signals/unified-signals"; import React from "react"; import { describe, expect, it, vi } from "vitest"; import { $ } from "../.."; @@ -26,20 +31,21 @@ describe("store", () => { expect(fn).toHaveBeenCalledTimes(4); }); - itRenderer("should work with react", async ({ expect, reactRoot, root }) => { - const store = Store.deepReactive({ - count: 0, - }); - reactRoot().render(
{$(() => store.count)}
); + itRenderer( + "should work with react", + async ({ expect, reactRoot, root, act }) => { + const store = Store.deepReactive({ + count: 0, + }); + await reactRoot().render(
{$(() => store.count)}
); - expect(root.innerHTML).toBe("
0
"); - - store.count++; + expect(root.innerHTML).toBe("
0
"); - await sleep(10); + await act(() => store.count++); - expect(root.innerHTML).toBe("
1
"); - }); + expect(root.innerHTML).toBe("
1
"); + } + ); it("custom class tracking", () => { class CustomClass { @@ -74,14 +80,14 @@ describe("store", () => { state.count++; } }); - + expect(state.count).toBe(10); - + effect(() => { untracked(() => { state.count++; - }) - }) + }); + }); expect(state.count).toBe(11); }); diff --git a/packages/utils/src/__tests__/utils.ts b/packages/utils/src/__tests__/utils.ts index 7b2dfce2..c388d8c1 100644 --- a/packages/utils/src/__tests__/utils.ts +++ b/packages/utils/src/__tests__/utils.ts @@ -6,13 +6,16 @@ import { TestFunction, afterEach, it } from "vitest"; const raf = (): Promise => new Promise((resolve) => requestAnimationFrame(() => resolve())); -const act = async (callback: () => unknown): Promise => { +let prevAct = Promise.resolve(); +const _act = async (callback: () => unknown): Promise => { const res = reactAct(callback); await res; await raf(); await res; }; +const act = (callback: () => unknown): Promise => + (prevAct = prevAct.finally(() => _act(callback))); export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); From 824c64745e1edfe69ed5eb4453ba68a1e2af17e4 Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Sun, 12 Nov 2023 12:29:59 +0100 Subject: [PATCH 03/21] passes tests --- .eslintignore | 3 + .eslintrc | 16 + apps/react-test/.eslintrc.cjs | 14 - apps/react-test/package.json | 5 - package.json | 4 + .../react-query/reactBatchedUpdates.native.ts | 5 +- packages/react/CHANGELOG.md | 179 -- packages/react/package.json | 8 +- packages/react/runtime/package.json | 2 +- packages/react/runtime/src/index.ts | 234 +-- .../react/runtime/test/useSignals.test.tsx | 832 ++++----- packages/react/setupVitest.ts | 2 + packages/react/src/index.ts | 42 +- packages/react/test/browser/exports.test.tsx | 28 +- packages/react/test/browser/mounts.test.tsx | 45 +- .../react/test/browser/react-router.test.tsx | 98 +- packages/react/test/browser/updates.test.tsx | 1642 ++++++++--------- .../test/node/renderToStaticMarkup.test.tsx | 29 +- packages/react/test/shared/mounting.tsx | 348 ++-- packages/react/test/shared/utils.ts | 138 +- packages/react/vitest.config.ts | 11 + packages/type/src/codegen.ts | 2 +- packages/utils/src/__tests__/$.test.tsx | 4 +- packages/utils/src/__tests__/hoc.test.tsx | 26 +- packages/utils/src/__tests__/utils.ts | 24 +- packages/utils/src/resource/resource.test.ts | 10 +- pnpm-lock.yaml | 336 ++-- tsconfig.json | 1 - 28 files changed, 1958 insertions(+), 2130 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc delete mode 100644 apps/react-test/.eslintrc.cjs create mode 100644 packages/react/setupVitest.ts create mode 100644 packages/react/vitest.config.ts diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..59980e46 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +packages/query/src/__tests__/standart-query +node_modules +dist \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..a575b4f4 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,16 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "parserOptions": { + "project": ["./tsconfig.json"] // Specify it only for TypeScript files + }, + "rules": { + "@typescript-eslint/no-floating-promises": [ + "error", + { + "ignoreVoid": true + } + ] + }, + "root": true +} diff --git a/apps/react-test/.eslintrc.cjs b/apps/react-test/.eslintrc.cjs deleted file mode 100644 index 4020bcbf..00000000 --- a/apps/react-test/.eslintrc.cjs +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - env: { browser: true, es2020: true }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', - ], - parser: '@typescript-eslint/parser', - parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': 'warn', - }, -} diff --git a/apps/react-test/package.json b/apps/react-test/package.json index 222e1ba8..ad8de6b5 100644 --- a/apps/react-test/package.json +++ b/apps/react-test/package.json @@ -19,14 +19,9 @@ "devDependencies": { "@types/react": "^18.0.37", "@types/react-dom": "^18.0.11", - "@typescript-eslint/eslint-plugin": "^5.59.0", - "@typescript-eslint/parser": "^5.59.0", "@vitejs/plugin-react-swc": "^3.0.0", "autoprefixer": "^10.4.14", "daisyui": "^3.5.1", - "eslint": "^8.38.0", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.3.4", "postcss": "^8.4.27", "tailwindcss": "^3.3.3", "vite": "^4.3.9" diff --git a/package.json b/package.json index 8abed608..93fa469f 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,9 @@ "version": "0.0.1", "devDependencies": { "@changesets/cli": "^2.26.2", + "@typescript-eslint/eslint-plugin": "^6.10.0", + "@typescript-eslint/parser": "^6.10.0", + "eslint": "^8.53.0", "rimraf": "^5.0.1", "turbo": "^1.10.12", "typescript": "^5.1.6", @@ -14,6 +17,7 @@ "build:with-apps": "turbo run build", "watch": "turbo run watch --parallel", "test": "turbo run test --parallel", + "eslint": "eslint --ext .ts,.tsx . --cache --cache-location=node_modules/.eslintcache", "lint": "turbo run lint", "changeset": "changeset", "release": "pnpm build && changeset publish" diff --git a/packages/query/src/react-query/reactBatchedUpdates.native.ts b/packages/query/src/react-query/reactBatchedUpdates.native.ts index 7ca91f79..f510e28c 100644 --- a/packages/query/src/react-query/reactBatchedUpdates.native.ts +++ b/packages/query/src/react-query/reactBatchedUpdates.native.ts @@ -1,4 +1,3 @@ // @ts-ignore -// eslint-disable-next-line import/no-unresolved -import { unstable_batchedUpdates } from 'react-native' -export { unstable_batchedUpdates } +import { unstable_batchedUpdates } from "react-native"; +export { unstable_batchedUpdates }; diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 9225ddc2..e69de29b 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,179 +0,0 @@ -# @preact/signals-react - -## 1.3.6 - -### Patch Changes - -- [#399](https://github.com/preactjs/signals/pull/399) [`24fa9f7`](https://github.com/preactjs/signals/commit/24fa9f791d70baba35bdce722f71ce63ac091a4d) Thanks [@rschristian](https://github.com/rschristian)! - Fixes UMD builds of `@preact/signals` and `@preact/signals-react` - -## 1.3.5 - -### Patch Changes - -- [#375](https://github.com/preactjs/signals/pull/375) [`cd3a22d`](https://github.com/preactjs/signals/commit/cd3a22d628c3a535108bc45b8151505dd6fc51c8) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Clean up effect store reference after finishing it - -* [#375](https://github.com/preactjs/signals/pull/375) [`59115d9`](https://github.com/preactjs/signals/commit/59115d9ea6dfa073255f9803dd7e8a09892d2acc) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Update internal useSignals API - -* Updated dependencies [[`256a331`](https://github.com/preactjs/signals/commit/256a331b5335e54f7e918b3f1068fb9d92d1c613)]: - - @preact/signals-core@1.4.0 - -## 1.3.4 - -### Patch Changes - -- [#377](https://github.com/preactjs/signals/pull/377) [`f4ff0ab`](https://github.com/preactjs/signals/commit/f4ff0abc55c83198e5ff7557f3d6663bac4b5149) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Fix internal property names - -## 1.3.3 - -### Patch Changes - -- [#373](https://github.com/preactjs/signals/pull/373) [`8c12a0d`](https://github.com/preactjs/signals/commit/8c12a0df74f00e9cab04e999fc443889b3528c04) Thanks [@rschristian](https://github.com/rschristian)! - Removes package.json#exports.umd, which had invalid paths if they were ever to be consumed - -* [#372](https://github.com/preactjs/signals/pull/372) [`6717601`](https://github.com/preactjs/signals/commit/6717601a34449080617033d93a87cc9c441a7567) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Reorganize signals-react package - -* Updated dependencies [[`8c12a0d`](https://github.com/preactjs/signals/commit/8c12a0df74f00e9cab04e999fc443889b3528c04), [`26f6526`](https://github.com/preactjs/signals/commit/26f6526875ef0968621c4113594ac95b93de5163)]: - - @preact/signals-core@1.3.1 - -## 1.3.2 - -### Patch Changes - -- [#358](https://github.com/preactjs/signals/pull/358) [`08ed3a0`](https://github.com/preactjs/signals/commit/08ed3a02a2291ad1e18389674d8ac20678064723) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Add note to Readme about tradeoffs in current React integration - -* [#355](https://github.com/preactjs/signals/pull/355) [`21c8ee9`](https://github.com/preactjs/signals/commit/21c8ee98070a8bda05095dc91b64d2fe54042fb3) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Fix React adapter in SSR and when rerendering - -- [#352](https://github.com/preactjs/signals/pull/352) [`a2b7320`](https://github.com/preactjs/signals/commit/a2b7320ee5829f58efaee5f7b20d993f35f09d2a) Thanks [@rschristian](https://github.com/rschristian)! - Uses full file path on useSyncExternalStore import, fixing a possible resolution issue in some build tools. - -## 1.3.1 - -### Patch Changes - -- [#344](https://github.com/preactjs/signals/pull/344) [`acdead6`](https://github.com/preactjs/signals/commit/acdead6a8631d7198d8a55d6cbde7713b5776d6b) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Allow React ^16.14.0 as a peer dependency - -## 1.3.0 - -### Minor Changes - -- [#335](https://github.com/preactjs/signals/pull/335) [`5fd438d`](https://github.com/preactjs/signals/commit/5fd438db9793d73343403e8926b9b69b03fb26f9) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Revert react integration to tracking current dispatcher - -### Patch Changes - -- [#271](https://github.com/preactjs/signals/pull/271) [`0135d60`](https://github.com/preactjs/signals/commit/0135d60b6de1325ee2b027a25cd60cc379f9c198) Thanks [@billybimbob](https://github.com/billybimbob)! - type Signal as a React Element - -* [#334](https://github.com/preactjs/signals/pull/334) [`0a58566`](https://github.com/preactjs/signals/commit/0a585660e141f3d92fb8789c234e69d5a1da8a86) Thanks [@andrewiggins](https://github.com/andrewiggins)! - Run test suite agains React's production build - -- [#246](https://github.com/preactjs/signals/pull/246) [`ad5a485`](https://github.com/preactjs/signals/commit/ad5a485e4fe3cfc1d1f60a57a30e50e88f7b1281) Thanks [@Shu-Ji](https://github.com/Shu-Ji)! - Support forwardRef in @preact/signals-react - -- Updated dependencies [[`862d9d6`](https://github.com/preactjs/signals/commit/862d9d6538b94e0a110213e98f2a0cabb14b8ad8), [`8b70764`](https://github.com/preactjs/signals/commit/8b7076436ce6d912f17d57da8ecd1bdfca852183), [`8e726ed`](https://github.com/preactjs/signals/commit/8e726ed1df6c90b85a93484f275baa7f013c799a)]: - - @preact/signals-core@1.3.0 - -## 1.2.2 - -### Patch Changes - -- [#243](https://github.com/preactjs/signals/pull/243) [`e41b8b1`](https://github.com/preactjs/signals/commit/e41b8b16bf68da7004a3174912fe95a109a453ed) Thanks [@melnikov-s](https://github.com/melnikov-s)! - Replace `Map` useage with `WeakMap` - -* [#282](https://github.com/preactjs/signals/pull/282) [`cafbdaa`](https://github.com/preactjs/signals/commit/cafbdaabd525a034e38da10b04eee0688c026152) Thanks [@developit](https://github.com/developit)! - Fix a bug that caused cleanup functions returned from a `useSignalEffect()` callback not to be called. - -* Updated dependencies [[`7e15d3c`](https://github.com/preactjs/signals/commit/7e15d3cf5f5e66258105e6f27cd7838b52fbbf9f)]: - - @preact/signals-core@1.2.3 - -## 1.2.1 - -### Patch Changes - -- [#238](https://github.com/preactjs/signals/pull/238) [`bcf4b0b`](https://github.com/preactjs/signals/commit/bcf4b0b25d774483ddafa29c2fa133c467668b8c) Thanks [@eddyw](https://github.com/eddyw)! - Fix ERR_UNSUPPORTED_DIR_IMPORT error when importing `use-sync-external-store/shim` from ESM build - -## 1.2.0 - -### Minor Changes - -- [#219](https://github.com/preactjs/signals/pull/219) [`0621526`](https://github.com/preactjs/signals/commit/0621526dd59187f674557e6df42c71980b32efab) Thanks [@eddyw](https://github.com/eddyw)! - Replace useReducer with useSyncExternalStore - -### Patch Changes - -- [#226](https://github.com/preactjs/signals/pull/226) [`ad29826`](https://github.com/preactjs/signals/commit/ad2982606a8894ea8562a0726d7777185987ad60) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - Fix hook names being mangled - -- Updated dependencies [[`aa4cb7b`](https://github.com/preactjs/signals/commit/aa4cb7bfad744e78952cacc37af5bd4a713f0d3f), [`3f652a7`](https://github.com/preactjs/signals/commit/3f652a77d2a125a02a0cfc29fe661c81beeda16d)]: - - @preact/signals-core@1.2.2 - -## 1.1.1 - -### Patch Changes - -- [#221](https://github.com/preactjs/signals/pull/221) [`7e8d4c2`](https://github.com/preactjs/signals/commit/7e8d4c25dfdc7fa9434b6c2af4aa0e495b9fae55) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - Fix signal not updated in React production build - -- Updated dependencies [[`4b73164`](https://github.com/preactjs/signals/commit/4b7316497aee03413f91e9f714cdcf9f553e39d9), [`57fd2e7`](https://github.com/preactjs/signals/commit/57fd2e723528a36cc5d4ebf09ba34178aa84c879), [`49756ae`](https://github.com/preactjs/signals/commit/49756aef28fe12c6ae6b801224bf5ae608ddf562)]: - - @preact/signals-core@1.2.1 - -## 1.1.0 - -### Minor Changes - -- [#91](https://github.com/preactjs/signals/pull/91) [`fb74bb9`](https://github.com/preactjs/signals/commit/fb74bb9ce4e44192e1ee7d3d041274cc985db767) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - add the `useSignalEffect` hook - -* [#183](https://github.com/preactjs/signals/pull/183) [`79ff1e7`](https://github.com/preactjs/signals/commit/79ff1e794dde9952db2d6d43b22cebfb2accc770) Thanks [@jviide](https://github.com/jviide)! - Add ability to run custom cleanup logic when an effect is disposed. - - ```js - effect(() => { - console.log("This runs whenever a dependency changes"); - return () => { - console.log("This runs when the effect is disposed"); - }); - }); - ``` - -### Patch Changes - -- [#161](https://github.com/preactjs/signals/pull/161) [`6ac6923`](https://github.com/preactjs/signals/commit/6ac6923e5294f8a31ee1a009550b9891c3996cb4) Thanks [@jviide](https://github.com/jviide)! - Remove all usages of `Set`, `Map` and other allocation heavy objects in signals-core. This substaintially increases performance across all measurements. - -- Updated dependencies [[`b4611cc`](https://github.com/preactjs/signals/commit/b4611cc9dee0ae09f4b378ba293c3203edc32be4), [`9802da5`](https://github.com/preactjs/signals/commit/9802da5274bb45c3cc28dda961b9b2d18535729a), [`6ac6923`](https://github.com/preactjs/signals/commit/6ac6923e5294f8a31ee1a009550b9891c3996cb4), [`79ff1e7`](https://github.com/preactjs/signals/commit/79ff1e794dde9952db2d6d43b22cebfb2accc770), [`3e31aab`](https://github.com/preactjs/signals/commit/3e31aabb812ddb0f7451deba38267f8384eff9d1)]: - - @preact/signals-core@1.2.0 - -## 1.0.2 - -### Patch Changes - -- [#147](https://github.com/preactjs/signals/pull/147) [`3556499`](https://github.com/preactjs/signals/commit/355649903b766630b62cdd0f90a35d3eafa99fa9) Thanks [@developit](https://github.com/developit)! - Improve performance when rendering Signals as Text in Preact. - -* [#148](https://github.com/preactjs/signals/pull/148) [`b948745`](https://github.com/preactjs/signals/commit/b948745de7b5b60a20ce3bdc5ee72d47d47f38ec) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - Move `types` field in `package.json` to the top of the entry list to ensure that TypeScript always finds it. - -- [#146](https://github.com/preactjs/signals/pull/146) [`9e798fd`](https://github.com/preactjs/signals/commit/9e798fdaf419566530696f850ea7fc1fc649d3cd) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - fix(react): track owners separately, mutate updaters with dispatcher - -- Updated dependencies [[`f2ba3d6`](https://github.com/preactjs/signals/commit/f2ba3d657bf8169c6ba1d47c0827aa18cfe1c947), [`160ea77`](https://github.com/preactjs/signals/commit/160ea7791f3adb55c562f5990e0b4848d8491a38), [`4385ea8`](https://github.com/preactjs/signals/commit/4385ea8c8358a154d8b789685bb061658ce1153f), [`b948745`](https://github.com/preactjs/signals/commit/b948745de7b5b60a20ce3bdc5ee72d47d47f38ec), [`00a59c6`](https://github.com/preactjs/signals/commit/00a59c6475bd4542fb934474d82d1e242b2ac870)]: - - @preact/signals-core@1.1.1 - -## 1.0.1 - -### Patch Changes - -- 62439c9: Fixes invalid React peer dependency range for environments with strict peerDeps -- Updated dependencies [336bb34] -- Updated dependencies [bc0080c] -- Updated dependencies [7228418] -- Updated dependencies [32abe07] -- Updated dependencies [4782b41] -- Updated dependencies [bf6af3b] - - @preact/signals-core@1.1.0 - -## 1.0.0 - -### Major Changes - -- 2ee8489: The v1 release for the signals package, we'd to see the uses you all - come up with and are eager to see performance improvements in your - applications. - -### Patch Changes - -- Updated dependencies [ab22ec7] -- Updated dependencies [2ee8489] -- Updated dependencies [b56abf3] - - @preact/signals-core@1.0.0 - -## 0.0.2 - -### Patch Changes - -- Updated dependencies [702a9c5] - - @preact/signals-core@0.0.5 diff --git a/packages/react/package.json b/packages/react/package.json index 969c881b..722b5fe2 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { - "name": "@preact/signals-react", - "version": "1.3.6", + "name": "@preact-signals/react", + "version": "0.0.1", "license": "MIT", "description": "Manage state with style in React", "keywords": [], @@ -51,10 +51,10 @@ "README.md" ], "scripts": { - "prepublishOnly": "cd ../.. && pnpm build:react-runtime && pnpm build:react" + "test": "vitest" }, "dependencies": { - "@preact/signals-core": "workspace:^1.4.0", + "@preact/signals-core": "^1.4.0", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { diff --git a/packages/react/runtime/package.json b/packages/react/runtime/package.json index de98164a..a394d186 100644 --- a/packages/react/runtime/package.json +++ b/packages/react/runtime/package.json @@ -1,5 +1,5 @@ { - "name": "@preact/signals-react-runtime", + "name": "@preact-signals/react-runtime", "description": "Sub package for @preact/signals-react that contains the pure runtime functions", "private": true, "amdName": "reactSignalsRuntime", diff --git a/packages/react/runtime/src/index.ts b/packages/react/runtime/src/index.ts index 8a81cdb8..1ba168fb 100644 --- a/packages/react/runtime/src/index.ts +++ b/packages/react/runtime/src/index.ts @@ -8,48 +8,55 @@ const Empty = [] as const; const ReactElemType = Symbol.for("react.element"); // https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15 export function wrapJsx(jsx: T): T { - if (typeof jsx !== "function") return jsx; - - return function (type: any, props: any, ...rest: any[]) { - if (typeof type === "string" && props) { - for (let i in props) { - let v = props[i]; - if (i !== "children" && v instanceof Signal) { - props[i] = v.value; - } - } - } - - return jsx.call(jsx, type, props, ...rest); - } as any as T; + if (typeof jsx !== "function") return jsx; + + return function (type: any, props: any, ...rest: any[]) { + if (typeof type === "string" && props) { + for (let i in props) { + let v = props[i]; + if (i !== "children" && v instanceof Signal) { + props[i] = v.value; + } + } + } + + return jsx.call(jsx, type, props, ...rest); + } as any as T; } const symDispose: unique symbol = - (Symbol as any).dispose || Symbol.for("Symbol.dispose"); - + (Symbol as any).dispose || Symbol.for("Symbol.dispose"); + +// this is effect before mangling, since we are not in preact signals repo, we should use mangled props +// interface Effect { +// _sources: object | undefined; +// _start(): () => void; +// _callback(): void; +// _dispose(): void; +// } interface Effect { - _sources: object | undefined; - _start(): () => void; - _callback(): void; - _dispose(): void; + _sources: object | undefined; + S(): () => void; + c(): void; + d(): void; } export interface EffectStore { - effect: Effect; - subscribe(onStoreChange: () => void): () => void; - getSnapshot(): number; - /** finishEffect - stop tracking the signals used in this component */ - f(): void; - [symDispose](): void; + effect: Effect; + subscribe(onStoreChange: () => void): () => void; + getSnapshot(): number; + /** finishEffect - stop tracking the signals used in this component */ + f(): void; + [symDispose](): void; } let finishUpdate: (() => void) | undefined; function setCurrentStore(store?: EffectStore) { - // end tracking for the current update: - if (finishUpdate) finishUpdate(); - // start tracking the new update: - finishUpdate = store && store.effect._start(); + // end tracking for the current update: + if (finishUpdate) finishUpdate(); + // start tracking the new update: + finishUpdate = store && store.effect.S(); } const clearCurrentStore = () => setCurrentStore(); @@ -68,49 +75,49 @@ const clearCurrentStore = () => setCurrentStore(); * @see https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md */ function createEffectStore(): EffectStore { - let effectInstance!: Effect; - let version = 0; - let onChangeNotifyReact: (() => void) | undefined; - - let unsubscribe = effect(function (this: Effect) { - effectInstance = this; - }); - effectInstance._callback = function () { - version = (version + 1) | 0; - if (onChangeNotifyReact) onChangeNotifyReact(); - }; - - return { - effect: effectInstance, - subscribe(onStoreChange) { - onChangeNotifyReact = onStoreChange; - - return function () { - /** - * Rotate to next version when unsubscribing to ensure that components are re-run - * when subscribing again. - * - * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so - * don't re-run after subscribing again if the version is the same as last time. - * - * Because we unsubscribe from the effect, the version may not change. We simply - * set a new initial version in case of stale snapshots here. - */ - version = (version + 1) | 0; - onChangeNotifyReact = undefined; - unsubscribe(); - }; - }, - getSnapshot() { - return version; - }, - f() { - clearCurrentStore(); - }, - [symDispose]() { - clearCurrentStore(); - }, - }; + let effectInstance!: Effect; + let version = 0; + let onChangeNotifyReact: (() => void) | undefined; + + let unsubscribe = effect(function (this: Effect) { + effectInstance = this; + }); + effectInstance.c = function () { + version = (version + 1) | 0; + if (onChangeNotifyReact) onChangeNotifyReact(); + }; + + return { + effect: effectInstance, + subscribe(onStoreChange) { + onChangeNotifyReact = onStoreChange; + + return function () { + /** + * Rotate to next version when unsubscribing to ensure that components are re-run + * when subscribing again. + * + * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so + * don't re-run after subscribing again if the version is the same as last time. + * + * Because we unsubscribe from the effect, the version may not change. We simply + * set a new initial version in case of stale snapshots here. + */ + version = (version + 1) | 0; + onChangeNotifyReact = undefined; + unsubscribe(); + }; + }, + getSnapshot() { + return version; + }, + f() { + clearCurrentStore(); + }, + [symDispose]() { + clearCurrentStore(); + }, + }; } let finalCleanup: Promise | undefined; @@ -121,61 +128,66 @@ const _queueMicroTask = Promise.prototype.then.bind(Promise.resolve()); * subscribe to changes to rerender the component when the signals change. */ export function useSignals(): EffectStore { - clearCurrentStore(); - if (!finalCleanup) { - finalCleanup = _queueMicroTask(() => { - finalCleanup = undefined; - clearCurrentStore(); - }); - } - - const storeRef = useRef(); - if (storeRef.current == null) { - storeRef.current = createEffectStore(); - } - - const store = storeRef.current; - useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot); - setCurrentStore(store); - - return store; + clearCurrentStore(); + if (!finalCleanup) { + finalCleanup = _queueMicroTask(() => { + finalCleanup = undefined; + clearCurrentStore(); + }); + } + + const storeRef = useRef(); + if (storeRef.current == null) { + storeRef.current = createEffectStore(); + } + + const store = storeRef.current; + useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot); + setCurrentStore(store); + + return store; } /** * A wrapper component that renders a Signal's value directly as a Text node or JSX. */ -function SignalValue({ data }: { data: Signal }) { - return data.value; +function SignalValue(props: { data: Signal }) { + const effectStore = useSignals(); + try { + return props.data.value; + } finally { + effectStore.f(); + } } // Decorate Signals so React renders them as components. Object.defineProperties(Signal.prototype, { - $$typeof: { configurable: true, value: ReactElemType }, - type: { configurable: true, value: SignalValue }, - props: { - configurable: true, - get() { - return { data: this }; - }, - }, - ref: { configurable: true, value: null }, + $$typeof: { configurable: true, value: ReactElemType }, + type: { configurable: true, value: SignalValue }, + props: { + configurable: true, + get() { + return { data: this }; + }, + }, + ref: { configurable: true, value: null }, }); export function useSignal(value: T) { - return useMemo(() => signal(value), Empty); + return useMemo(() => signal(value), Empty); } export function useComputed(compute: () => T) { - const $compute = useRef(compute); - $compute.current = compute; - return useMemo(() => computed(() => $compute.current()), Empty); + const $compute = useRef(compute); + $compute.current = compute; + return useMemo(() => computed(() => $compute.current()), Empty); } export function useSignalEffect(cb: () => void | (() => void)) { - const callback = useRef(cb); - callback.current = cb; + const callback = useRef(cb); + callback.current = cb; - useEffect(() => { - return effect(() => callback.current()); - }, Empty); + useEffect(() => { + return effect(() => callback.current()); + }, Empty); } diff --git a/packages/react/runtime/test/useSignals.test.tsx b/packages/react/runtime/test/useSignals.test.tsx index c941e27d..b8de6c91 100644 --- a/packages/react/runtime/test/useSignals.test.tsx +++ b/packages/react/runtime/test/useSignals.test.tsx @@ -1,422 +1,422 @@ -import { createElement, Fragment } from "react"; +import React, { Fragment } from "react"; import { Signal, signal, batch } from "@preact/signals-core"; -import { useSignals } from "@preact/signals-react/runtime"; +import { useSignals } from "../src"; +import { describe, expect, afterEach, beforeEach, it, vi } from "vitest"; import { - Root, - createRoot, - act, - checkHangingAct, - getConsoleErrorSpy, - checkConsoleErrorLogs, + Root, + createRoot, + act, + checkHangingAct, + getConsoleErrorSpy, + checkConsoleErrorLogs, } from "../../test/shared/utils"; describe("useSignals", () => { - let scratch: HTMLDivElement; - let root: Root; - - async function render(element: Parameters[0]) { - await act(() => root.render(element)); - } - - beforeEach(async () => { - scratch = document.createElement("div"); - document.body.appendChild(scratch); - root = await createRoot(scratch); - getConsoleErrorSpy().resetHistory(); - }); - - afterEach(async () => { - await act(() => root.unmount()); - scratch.remove(); - - checkConsoleErrorLogs(); - checkHangingAct(); - }); - - it("should rerender components when signals they use change", async () => { - const signal1 = signal(0); - function Child1() { - useSignals(); - return

{signal1.value}

; - } - - const signal2 = signal(0); - function Child2() { - useSignals(); - return

{signal2.value}

; - } - - function Parent() { - return ( - - - - - ); - } - - await render(); - expect(scratch.innerHTML).to.equal("

0

0

"); - - await act(() => { - signal1.value += 1; - }); - expect(scratch.innerHTML).to.equal("

1

0

"); - - await act(() => { - signal2.value += 1; - }); - expect(scratch.innerHTML).to.equal("

1

1

"); - }); - - it("should correctly invoke rerenders if useSignals is called multiple times in the same component", async () => { - const signal1 = signal(0); - const signal2 = signal(0); - const signal3 = signal(0); - function App() { - useSignals(); - const sig1 = signal1.value; - useSignals(); - const sig2 = signal2.value; - const sig3 = signal3.value; - useSignals(); - return ( -

- {sig1} - {sig2} - {sig3} -

- ); - } - - await render(); - expect(scratch.innerHTML).to.equal("

000

"); - - await act(() => { - signal1.value += 1; - }); - expect(scratch.innerHTML).to.equal("

100

"); - - await act(() => { - signal2.value += 1; - }); - expect(scratch.innerHTML).to.equal("

110

"); - - await act(() => { - signal3.value += 1; - }); - expect(scratch.innerHTML).to.equal("

111

"); - }); - - it("should not rerender components when signals they use do not change", async () => { - const child1Spy = sinon.spy(); - const signal1 = signal(0); - function Child1() { - child1Spy(); - useSignals(); - return

{signal1.value}

; - } - - const child2Spy = sinon.spy(); - const signal2 = signal(0); - function Child2() { - child2Spy(); - useSignals(); - return

{signal2.value}

; - } - - const parentSpy = sinon.spy(); - function Parent() { - parentSpy(); - return ( - - - - - ); - } - - function resetSpies() { - child1Spy.resetHistory(); - child2Spy.resetHistory(); - parentSpy.resetHistory(); - } - - resetSpies(); - await render(); - expect(scratch.innerHTML).to.equal("

0

0

"); - expect(child1Spy).to.have.been.calledOnce; - expect(child2Spy).to.have.been.calledOnce; - expect(parentSpy).to.have.been.calledOnce; - - resetSpies(); - await act(() => { - signal1.value += 1; - }); - expect(scratch.innerHTML).to.equal("

1

0

"); - expect(child1Spy).to.have.been.calledOnce; - expect(child2Spy).to.not.have.been.called; - expect(parentSpy).to.not.have.been.called; - - resetSpies(); - await act(() => { - signal2.value += 1; - }); - expect(scratch.innerHTML).to.equal("

1

1

"); - expect(child1Spy).to.not.have.been.called; - expect(child2Spy).to.have.been.calledOnce; - expect(parentSpy).to.not.have.been.called; - }); - - it("should not rerender components when signals they use change but they are not mounted", async () => { - const child1Spy = sinon.spy(); - const signal1 = signal(0); - function Child() { - child1Spy(); - useSignals(); - const sig1 = signal1.value; - return

{sig1}

; - } - - function Parent({ show }: { show: boolean }) { - return {show && }; - } - - await render(); - expect(scratch.innerHTML).to.equal("

0

"); - - await act(() => { - signal1.value += 1; - }); - expect(scratch.innerHTML).to.equal("

1

"); - - await act(() => { - render(); - }); - expect(scratch.innerHTML).to.equal(""); - - await act(() => { - signal1.value += 1; - }); - expect(child1Spy).to.have.been.calledTwice; - }); - - it("should not rerender components that only update signals in event handlers", async () => { - const buttonSpy = sinon.spy(); - function AddOneButton({ num }: { num: Signal }) { - useSignals(); - buttonSpy(); - return ( - - ); - } - - const displaySpy = sinon.spy(); - function DisplayNumber({ num }: { num: Signal }) { - useSignals(); - displaySpy(); - return

{num.value}

; - } - - const number = signal(0); - function App() { - return ( - - - - - ); - } - - await render(); - expect(scratch.innerHTML).to.equal("

0

"); - expect(buttonSpy).to.have.been.calledOnce; - expect(displaySpy).to.have.been.calledOnce; - - await act(() => { - scratch.querySelector("button")!.click(); - }); - - expect(scratch.innerHTML).to.equal("

1

"); - expect(buttonSpy).to.have.been.calledOnce; - expect(displaySpy).to.have.been.calledTwice; - }); - - it("should not rerender components that only read signals in event handlers", async () => { - const buttonSpy = sinon.spy(); - function AddOneButton({ num }: { num: Signal }) { - useSignals(); - buttonSpy(); - return ( - - ); - } - - const displaySpy = sinon.spy(); - function DisplayNumber({ num }: { num: Signal }) { - useSignals(); - displaySpy(); - return

{num.value}

; - } - - const adder = signal(2); - const number = signal(0); - function App() { - return ( - - - - - ); - } - - function resetSpies() { - buttonSpy.resetHistory(); - displaySpy.resetHistory(); - } - - resetSpies(); - await render(); - expect(scratch.innerHTML).to.equal("

0

"); - expect(buttonSpy).to.have.been.calledOnce; - expect(displaySpy).to.have.been.calledOnce; - - resetSpies(); - await act(() => { - scratch.querySelector("button")!.click(); - }); - - expect(scratch.innerHTML).to.equal("

2

"); - expect(buttonSpy).to.not.have.been.called; - expect(displaySpy).to.have.been.calledOnce; - - resetSpies(); - await act(() => { - adder.value += 1; - }); - - expect(scratch.innerHTML).to.equal("

2

"); - expect(buttonSpy).to.not.have.been.called; - expect(displaySpy).to.not.have.been.called; - - resetSpies(); - await act(() => { - scratch.querySelector("button")!.click(); - }); - - expect(scratch.innerHTML).to.equal("

5

"); - expect(buttonSpy).to.not.have.been.called; - expect(displaySpy).to.have.been.calledOnce; - }); - - it("should properly rerender components that use custom hooks", async () => { - const greeting = signal("Hello"); - function useGreeting() { - useSignals(); - return greeting.value; - } - - const name = signal("John"); - function useName() { - useSignals(); - return name.value; - } - - function App() { - const greeting = useGreeting(); - const name = useName(); - return ( -
- {greeting} {name}! -
- ); - } - - await render(); - expect(scratch.innerHTML).to.equal("
Hello John!
"); - - await act(() => { - greeting.value = "Hi"; - }); - expect(scratch.innerHTML).to.equal("
Hi John!
"); - - await act(() => { - name.value = "Jane"; - }); - expect(scratch.innerHTML).to.equal("
Hi Jane!
"); - - await act(() => { - batch(() => { - greeting.value = "Hello"; - name.value = "John"; - }); - }); - expect(scratch.innerHTML).to.equal("
Hello John!
"); - }); - - it("should properly rerender components that use custom hooks and signals", async () => { - const greeting = signal("Hello"); - function useGreeting() { - useSignals(); - return greeting.value; - } - - const name = signal("John"); - function useName() { - useSignals(); - return name.value; - } - - const punctuation = signal("!"); - function App() { - useSignals(); - const greeting = useGreeting(); - const name = useName(); - return ( -
- {greeting} {name} - {punctuation.value} -
- ); - } - - await render(); - expect(scratch.innerHTML).to.equal("
Hello John!
"); - - await act(() => { - greeting.value = "Hi"; - }); - expect(scratch.innerHTML).to.equal("
Hi John!
"); - - await act(() => { - name.value = "Jane"; - }); - expect(scratch.innerHTML).to.equal("
Hi Jane!
"); - - await act(() => { - punctuation.value = "?"; - }); - expect(scratch.innerHTML).to.equal("
Hi Jane?
"); - - await act(() => { - batch(() => { - greeting.value = "Hello"; - name.value = "John"; - punctuation.value = "!"; - }); - }); - expect(scratch.innerHTML).to.equal("
Hello John!
"); - }); + let scratch: HTMLDivElement; + let root: Root; + + async function render(element: Parameters[0]) { + await act(() => root.render(element)); + } + + beforeEach(async () => { + scratch = document.createElement("div"); + document.body.appendChild(scratch); + root = await createRoot(scratch); + getConsoleErrorSpy().mockClear(); + }); + + afterEach(async () => { + await act(() => root.unmount()); + scratch.remove(); + + checkConsoleErrorLogs(); + checkHangingAct(); + }); + + it("should rerender components when signals they use change", async () => { + const signal1 = signal(0); + function Child1() { + useSignals(); + return

{signal1.value}

; + } + + const signal2 = signal(0); + function Child2() { + useSignals(); + return

{signal2.value}

; + } + + function Parent() { + return ( + + + + + ); + } + + await render(); + expect(scratch.innerHTML).to.equal("

0

0

"); + + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

0

"); + + await act(() => { + signal2.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

1

"); + }); + + it("should correctly invoke rerenders if useSignals is called multiple times in the same component", async () => { + const signal1 = signal(0); + const signal2 = signal(0); + const signal3 = signal(0); + function App() { + useSignals(); + const sig1 = signal1.value; + useSignals(); + const sig2 = signal2.value; + const sig3 = signal3.value; + useSignals(); + return ( +

+ {sig1} + {sig2} + {sig3} +

+ ); + } + + await render(); + expect(scratch.innerHTML).to.equal("

000

"); + + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("

100

"); + + await act(() => { + signal2.value += 1; + }); + expect(scratch.innerHTML).to.equal("

110

"); + + await act(() => { + signal3.value += 1; + }); + expect(scratch.innerHTML).to.equal("

111

"); + }); + + it("should not rerender components when signals they use do not change", async () => { + const child1Spy = vi.fn(); + const signal1 = signal(0); + function Child1() { + child1Spy(); + useSignals(); + return

{signal1.value}

; + } + + const child2Spy = vi.fn(); + const signal2 = signal(0); + function Child2() { + child2Spy(); + useSignals(); + return

{signal2.value}

; + } + + const parentSpy = vi.fn(); + function Parent() { + parentSpy(); + return ( + + + + + ); + } + + function resetSpies() { + child1Spy.mockClear(); + child2Spy.mockClear(); + parentSpy.mockClear(); + } + + resetSpies(); + await render(); + expect(scratch.innerHTML).to.equal("

0

0

"); + expect(child1Spy).toHaveBeenCalledOnce(); + expect(child2Spy).toHaveBeenCalledOnce(); + expect(parentSpy).toHaveBeenCalledOnce(); + + resetSpies(); + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

0

"); + expect(child1Spy).toHaveBeenCalledOnce(); + expect(child2Spy).not.toHaveBeenCalledOnce(); + expect(parentSpy).not.toHaveBeenCalledOnce(); + resetSpies(); + await act(() => { + signal2.value += 1; + }); + expect(scratch.innerHTML).to.equal("

1

1

"); + expect(child1Spy).not.toHaveBeenCalled(); + expect(child2Spy).toHaveBeenCalledOnce(); + expect(parentSpy).not.toHaveBeenCalled(); + }); + + it("should not rerender components when signals they use change but they are not mounted", async () => { + const child1Spy = vi.fn(); + const signal1 = signal(0); + function Child() { + child1Spy(); + useSignals(); + const sig1 = signal1.value; + return

{sig1}

; + } + + function Parent({ show }: { show: boolean }) { + return {show && }; + } + + await render(); + expect(scratch.innerHTML).toBe("

0

"); + + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).toBe("

1

"); + + await act(async () => { + await render(); + }); + expect(scratch.innerHTML).toBe(""); + + await act(() => { + signal1.value += 1; + }); + expect(child1Spy).toHaveBeenCalledTimes(2); + }); + + it("should not rerender components that only update signals in event handlers", async () => { + const buttonSpy = vi.fn(); + function AddOneButton({ num }: { num: Signal }) { + useSignals(); + buttonSpy(); + return ( + + ); + } + + const displaySpy = vi.fn(); + function DisplayNumber({ num }: { num: Signal }) { + useSignals(); + displaySpy(); + return

{num.value}

; + } + + const number = signal(0); + function App() { + return ( + + + + + ); + } + + await render(); + expect(scratch.innerHTML).toBe("

0

"); + expect(buttonSpy).toHaveBeenCalledTimes(1); + expect(displaySpy).toHaveBeenCalledTimes(1); + + await act(() => { + scratch.querySelector("button")!.click(); + }); + + expect(scratch.innerHTML).toBe("

1

"); + expect(buttonSpy).toHaveBeenCalledTimes(1); + expect(displaySpy).toHaveBeenCalledTimes(2); + }); + + it("should not rerender components that only read signals in event handlers", async () => { + const buttonSpy = vi.fn(); + function AddOneButton({ num }: { num: Signal }) { + useSignals(); + buttonSpy(); + return ( + + ); + } + + const displaySpy = vi.fn(); + function DisplayNumber({ num }: { num: Signal }) { + useSignals(); + displaySpy(); + return

{num.value}

; + } + + const adder = signal(2); + const number = signal(0); + function App() { + return ( + + + + + ); + } + + function resetSpies() { + buttonSpy.mockReset(); + displaySpy.mockReset(); + } + + resetSpies(); + await render(); + expect(scratch.innerHTML).toBe("

0

"); + expect(buttonSpy).toHaveBeenCalledTimes(1); + expect(displaySpy).toHaveBeenCalledTimes(1); + + resetSpies(); + await act(() => { + scratch.querySelector("button")!.click(); + }); + + expect(scratch.innerHTML).toBe("

2

"); + expect(buttonSpy).not.toHaveBeenCalled(); + expect(displaySpy).toHaveBeenCalledTimes(1); + + resetSpies(); + await act(() => { + adder.value += 1; + }); + + expect(scratch.innerHTML).toBe("

2

"); + expect(buttonSpy).not.toHaveBeenCalled(); + expect(displaySpy).not.toHaveBeenCalled(); + + resetSpies(); + await act(() => { + scratch.querySelector("button")!.click(); + }); + + expect(scratch.innerHTML).toBe("

5

"); + expect(buttonSpy).not.toHaveBeenCalled(); + expect(displaySpy).toHaveBeenCalledTimes(1); + }); + + it("should properly rerender components that use custom hooks", async () => { + const greeting = signal("Hello"); + function useGreeting() { + useSignals(); + return greeting.value; + } + + const name = signal("John"); + function useName() { + useSignals(); + return name.value; + } + + function App() { + const greeting = useGreeting(); + const name = useName(); + return ( +
+ {greeting} {name}! +
+ ); + } + + await render(); + expect(scratch.innerHTML).to.equal("
Hello John!
"); + + await act(() => { + greeting.value = "Hi"; + }); + expect(scratch.innerHTML).to.equal("
Hi John!
"); + + await act(() => { + name.value = "Jane"; + }); + expect(scratch.innerHTML).to.equal("
Hi Jane!
"); + + await act(() => { + batch(() => { + greeting.value = "Hello"; + name.value = "John"; + }); + }); + expect(scratch.innerHTML).to.equal("
Hello John!
"); + }); + + it("should properly rerender components that use custom hooks and signals", async () => { + const greeting = signal("Hello"); + function useGreeting() { + useSignals(); + return greeting.value; + } + + const name = signal("John"); + function useName() { + useSignals(); + return name.value; + } + + const punctuation = signal("!"); + function App() { + useSignals(); + const greeting = useGreeting(); + const name = useName(); + return ( +
+ {greeting} {name} + {punctuation.value} +
+ ); + } + + await render(); + expect(scratch.innerHTML).to.equal("
Hello John!
"); + + await act(() => { + greeting.value = "Hi"; + }); + expect(scratch.innerHTML).to.equal("
Hi John!
"); + + await act(() => { + name.value = "Jane"; + }); + expect(scratch.innerHTML).to.equal("
Hi Jane!
"); + + await act(() => { + punctuation.value = "?"; + }); + expect(scratch.innerHTML).to.equal("
Hi Jane?
"); + + await act(() => { + batch(() => { + greeting.value = "Hello"; + name.value = "John"; + punctuation.value = "!"; + }); + }); + expect(scratch.innerHTML).to.equal("
Hello John!
"); + }); }); diff --git a/packages/react/setupVitest.ts b/packages/react/setupVitest.ts new file mode 100644 index 00000000..6912dd4c --- /dev/null +++ b/packages/react/setupVitest.ts @@ -0,0 +1,2 @@ +// @ts-ignore-next-line +globalThis.IS_REACT_ACT_ENVIRONMENT = true; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index b2c03f14..7eb15845 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,33 +1,33 @@ import { - signal, - computed, - batch, - effect, - Signal, - type ReadonlySignal, - untracked, + signal, + computed, + batch, + effect, + Signal, + type ReadonlySignal, + untracked, } from "@preact/signals-core"; import type { ReactElement } from "react"; -import { useSignal, useComputed, useSignalEffect } from "../runtime"; +import { useSignal, useComputed, useSignalEffect } from "../runtime/src"; import { installAutoSignalTracking } from "../runtime/src/auto"; export { - signal, - computed, - batch, - effect, - Signal, - type ReadonlySignal, - useSignal, - useComputed, - useSignalEffect, - untracked, + signal, + computed, + batch, + effect, + Signal, + type ReadonlySignal, + useSignal, + useComputed, + useSignalEffect, + untracked, }; declare module "@preact/signals-core" { - // @ts-ignore internal Signal is viewed as function - // eslint-disable-next-line @typescript-eslint/no-empty-interface - interface Signal extends ReactElement {} + // @ts-ignore internal Signal is viewed as function + // eslint-disable-next-line @typescript-eslint/no-empty-interface + interface Signal extends ReactElement {} } installAutoSignalTracking(); diff --git a/packages/react/test/browser/exports.test.tsx b/packages/react/test/browser/exports.test.tsx index a36d0241..fde42396 100644 --- a/packages/react/test/browser/exports.test.tsx +++ b/packages/react/test/browser/exports.test.tsx @@ -1,18 +1,20 @@ import * as core from "@preact/signals-core"; -import * as adapter from "@preact/signals-react"; +import * as adapter from "../../src"; +import { describe, expect, it } from "vitest"; describe("@preact/signals-react", () => { - describe("exports", () => { - it("should re-export core", () => { - const keys = Object.keys(core); + describe("exports", () => { + it("should re-export core", () => { + const keys = Object.keys(core); - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - expect(key in adapter).to.equal( - true, - `"${key}" is not exported from react adapter` - ); - } - }); - }); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + // @ts-expect-error + expect(key in adapter).to.equal( + true, + `"${key}" is not exported from react adapter` + ); + } + }); + }); }); diff --git a/packages/react/test/browser/mounts.test.tsx b/packages/react/test/browser/mounts.test.tsx index af132cac..94db443d 100644 --- a/packages/react/test/browser/mounts.test.tsx +++ b/packages/react/test/browser/mounts.test.tsx @@ -1,32 +1,33 @@ import { mountSignalsTests } from "../shared/mounting"; import { - Root, - createRoot, - act, - getConsoleErrorSpy, - checkConsoleErrorLogs, + Root, + createRoot, + act, + getConsoleErrorSpy, + checkConsoleErrorLogs, } from "../shared/utils"; +import { afterEach, beforeEach, describe } from "vitest"; describe("@preact/signals-react mounting", () => { - let scratch: HTMLDivElement; - let root: Root; + let scratch: HTMLDivElement; + let root: Root; - async function render(element: JSX.Element | null): Promise { - await act(() => root.render(element)); - return scratch.innerHTML; - } + async function render(element: JSX.Element | null): Promise { + await act(() => root.render(element)); + return scratch.innerHTML; + } - beforeEach(async () => { - scratch = document.createElement("div"); - document.body.appendChild(scratch); - root = await createRoot(scratch); - getConsoleErrorSpy().resetHistory(); - }); + beforeEach(async () => { + scratch = document.createElement("div"); + document.body.appendChild(scratch); + root = await createRoot(scratch); + getConsoleErrorSpy().mockClear(); + }); - afterEach(async () => { - scratch.remove(); - checkConsoleErrorLogs(); - }); + afterEach(async () => { + scratch.remove(); + checkConsoleErrorLogs(); + }); - mountSignalsTests(render); + mountSignalsTests(render); }); diff --git a/packages/react/test/browser/react-router.test.tsx b/packages/react/test/browser/react-router.test.tsx index eaa1dd8d..54873ae5 100644 --- a/packages/react/test/browser/react-router.test.tsx +++ b/packages/react/test/browser/react-router.test.tsx @@ -1,63 +1,61 @@ -// @ts-ignore-next-line -globalThis.IS_REACT_ACT_ENVIRONMENT = true; - -import { signal } from "@preact/signals-react"; -import { createElement } from "react"; +import { signal } from "../../src"; +import React from "react"; import * as ReactRouter from "react-router-dom"; +import { describe, it, beforeEach, afterEach, expect } from "vitest"; import { act, checkHangingAct, createRoot, Root } from "../shared/utils"; const MemoryRouter = ReactRouter.MemoryRouter; const Routes = ReactRouter.Routes - ? ReactRouter.Routes - : (ReactRouter as any).Switch; // react-router-dom v5 + ? ReactRouter.Routes + : (ReactRouter as any).Switch; // react-router-dom v5 // @ts-expect-error We are doing a check for react-router-dom v5 vs v6 here, so // while TS thinks ReactRouter.Routes will always be here, it isn't in v5. const Route = ReactRouter.Routes - ? ReactRouter.Route - : // react-router-dom v5 requires the element prop to be passed as children. - ({ element, ...props }: any) => ( - {element} - ); + ? ReactRouter.Route + : // react-router-dom v5 requires the element prop to be passed as children. + ({ element, ...props }: any) => ( + {element} + ); describe("@preact/signals-react", () => { - let scratch: HTMLDivElement; - let root: Root; - async function render(element: Parameters[0]) { - await act(() => root.render(element)); - } - - beforeEach(async () => { - scratch = document.createElement("div"); - document.body.appendChild(scratch); - root = await createRoot(scratch); - }); - - afterEach(async () => { - checkHangingAct(); - await act(() => root.unmount()); - scratch.remove(); - }); - - describe("react-router-dom", () => { - it("Route component should render", async () => { - const name = signal("World")!; - - function App() { - return ( - - - Page 1
}> - Hello {name}!}> - - - ); - } - - await render(); - - expect(scratch.innerHTML).to.equal("
Hello World!
"); - }); - }); + let scratch: HTMLDivElement; + let root: Root; + async function render(element: Parameters[0]) { + await act(() => root.render(element)); + } + + beforeEach(async () => { + scratch = document.createElement("div"); + document.body.appendChild(scratch); + root = await createRoot(scratch); + }); + + afterEach(async () => { + checkHangingAct(); + await act(() => root.unmount()); + scratch.remove(); + }); + + describe("react-router-dom", () => { + it("Route component should render", async () => { + const name = signal("World")!; + + function App() { + return ( + + + Page 1}> + Hello {name}!}> + + + ); + } + + await render(); + + expect(scratch.innerHTML).to.equal("
Hello World!
"); + }); + }); }); diff --git a/packages/react/test/browser/updates.test.tsx b/packages/react/test/browser/updates.test.tsx index dec3fe8e..e83a3711 100644 --- a/packages/react/test/browser/updates.test.tsx +++ b/packages/react/test/browser/updates.test.tsx @@ -1,842 +1,820 @@ -// @ts-ignore-next-line -globalThis.IS_REACT_ACT_ENVIRONMENT = true; - -import { - signal, - computed, - useComputed, - useSignalEffect, - useSignal, -} from "@preact/signals-react"; -import type { Signal, ReadonlySignal } from "@preact/signals-react"; import { - createElement, - Fragment, - forwardRef, - useMemo, - useReducer, - memo, - StrictMode, - createRef, - useState, - useContext, - createContext, - useRef, + signal, + computed, + useComputed, + useSignalEffect, + useSignal, +} from "../../src"; +import type { Signal, ReadonlySignal } from "../../src"; +import React, { + Fragment, + forwardRef, + useMemo, + useReducer, + memo, + StrictMode, + createRef, + useState, + useContext, + createContext, + useRef, } from "react"; import type { FunctionComponent } from "react"; +import { describe, it, beforeEach, afterEach, expect, vi } from "vitest"; import { renderToStaticMarkup } from "react-dom/server"; import { - createRoot, - Root, - act, - checkHangingAct, - isReact16, - isProd, - getConsoleErrorSpy, - checkConsoleErrorLogs, + createRoot, + Root, + act, + checkHangingAct, + isReact16, + isProd, + getConsoleErrorSpy, + checkConsoleErrorLogs, } from "../shared/utils"; describe("@preact/signals-react updating", () => { - let scratch: HTMLDivElement; - let root: Root; - - async function render(element: Parameters[0]) { - await act(() => root.render(element)); - } - - beforeEach(async () => { - scratch = document.createElement("div"); - document.body.appendChild(scratch); - root = await createRoot(scratch); - getConsoleErrorSpy().resetHistory(); - }); - - afterEach(async () => { - await act(() => root.unmount()); - scratch.remove(); - - checkConsoleErrorLogs(); - checkHangingAct(); - }); - - describe("SignalValue bindings", () => { - it("should render text without signals", async () => { - await render(test); - const span = scratch.firstChild; - const text = span?.firstChild; - expect(text).to.have.property("data", "test"); - }); - - it("should render Signals as SignalValue", async () => { - const sig = signal("test"); - await render({sig}); - const span = scratch.firstChild; - expect(span).to.have.property("firstChild").that.is.an.instanceOf(Text); - const text = span?.firstChild; - expect(text).to.have.property("data", "test"); - }); - - it("should render computed as SignalValue", async () => { - const sig = signal("test"); - const comp = computed(() => `${sig} ${sig}`); - await render({comp}); - const span = scratch.firstChild; - expect(span).to.have.property("firstChild").that.is.an.instanceOf(Text); - const text = span?.firstChild; - expect(text).to.have.property("data", "test test"); - }); - - it("should update Signal-based SignalValue (no parent component)", async () => { - const sig = signal("test"); - await render({sig}); - - const text = scratch.firstChild!.firstChild!; - expect(text).to.have.property("data", "test"); - - await act(() => { - sig.value = "changed"; - }); - - // should not remount/replace SignalValue - expect(scratch.firstChild!.firstChild!).to.equal(text); - // should update the text in-place - expect(text).to.have.property("data", "changed"); - }); - - it("should update Signal-based SignalValue (in a parent component)", async () => { - const sig = signal("test"); - function App({ x }: { x: typeof sig }) { - return {x}; - } - await render(); - - const text = scratch.firstChild!.firstChild!; - expect(text).to.have.property("data", "test"); - - await act(() => { - sig.value = "changed"; - }); - - // should not remount/replace SignalValue - expect(scratch.firstChild!.firstChild!).to.equal(text); - // should update the text in-place - expect(text).to.have.property("data", "changed"); - }); - - it("should work with JSX inside signal", async () => { - const sig = signal(test); - function App({ x }: { x: typeof sig }) { - return {x}; - } - await render(); - - let text = scratch.firstChild!.firstChild!; - expect(text).to.be.instanceOf(HTMLElement); - expect(text.firstChild).to.have.property("data", "test"); - - await act(() => { - sig.value =
changed
; - }); - - text = scratch.firstChild!.firstChild!; - expect(text).to.be.instanceOf(HTMLDivElement); - expect(text.firstChild).to.have.property("data", "changed"); - }); - }); - - describe("Component bindings", () => { - it("should subscribe to signals", async () => { - const sig = signal("foo"); - - function App() { - const value = sig.value; - return

{value}

; - } - - await render(); - expect(scratch.textContent).to.equal("foo"); - - await act(() => { - sig.value = "bar"; - }); - expect(scratch.textContent).to.equal("bar"); - }); - - it("should rerender components when signals they use change", async () => { - const signal1 = signal(0); - function Child1() { - return
{signal1}
; - } - - const signal2 = signal(0); - function Child2() { - return
{signal2}
; - } - - function Parent() { - return ( - - - - - ); - } - - await render(); - expect(scratch.innerHTML).to.equal("
0
0
"); - - await act(() => { - signal1.value += 1; - }); - expect(scratch.innerHTML).to.equal("
1
0
"); - - await act(() => { - signal2.value += 1; - }); - expect(scratch.innerHTML).to.equal("
1
1
"); - }); - - it("should subscribe to signals passed as props to DOM elements", async () => { - const className = signal("foo"); - function App() { - // @ts-expect-error React types don't allow signals on DOM elements :/ - return
; - } - - await render(); - - expect(scratch.innerHTML).to.equal('
'); - - await act(() => { - className.value = "bar"; - }); - - expect(scratch.innerHTML).to.equal('
'); - }); - - it("should activate signal accessed in render", async () => { - const sig = signal(null); - - function App() { - const arr = useComputed(() => { - // trigger read - sig.value; - - return []; - }); - - const str = arr.value.join(", "); - return

{str}

; - } - - try { - await render(); - } catch (e: any) { - expect.fail(e.stack); - } - }); - - it("should not subscribe to child signals", async () => { - const sig = signal("foo"); - - function Child() { - const value = sig.value; - return

{value}

; - } - - const spy = sinon.spy(); - function App() { - spy(); - return ; - } - - await render(); - expect(scratch.textContent).to.equal("foo"); - - await act(() => { - sig.value = "bar"; - }); - expect(spy).to.be.calledOnce; - }); - - it("should update memo'ed component via signals", async () => { - const sig = signal("foo"); - - function Inner() { - const value = sig.value; - return

{value}

; - } - - function App() { - sig.value; - return useMemo(() => , []); - } - - await render(); - expect(scratch.textContent).to.equal("foo"); - - await act(() => { - sig.value = "bar"; - }); - expect(scratch.textContent).to.equal("bar"); - }); - - it("should update forwardRef'ed component via signals", async () => { - const sig = signal("foo"); - - const Inner = forwardRef(() => { - return

{sig.value}

; - }); - - function App() { - return ; - } - - await render(); - expect(scratch.textContent).to.equal("foo"); - - await act(() => { - sig.value = "bar"; - }); - expect(scratch.textContent).to.equal("bar"); - }); - - it("should consistently rerender in strict mode", async () => { - const sig = signal(-1); - - const Test = () =>

{sig.value}

; - const App = () => ( - - - - ); - - await render(); - expect(scratch.textContent).to.equal("-1"); - - for (let i = 0; i < 3; i++) { - await act(async () => { - sig.value = i; - }); - expect(scratch.textContent).to.equal("" + i); - } - }); - - it("should consistently rerender in strict mode (with memo)", async () => { - const sig = signal(-1); - - const Test = memo(() =>

{sig.value}

); - const App = () => ( - - - - ); - - await render(); - expect(scratch.textContent).to.equal("-1"); - - for (let i = 0; i < 3; i++) { - await act(async () => { - sig.value = i; - }); - expect(scratch.textContent).to.equal("" + i); - } - }); - - it("should render static markup of a component", async () => { - const count = signal(0); - - const Test = () => { - return ( -
-						{renderToStaticMarkup({count})}
-						{renderToStaticMarkup({count.value})}
-					
- ); - }; - - await render(); - expect(scratch.textContent).to.equal("00"); - - for (let i = 0; i < 3; i++) { - await act(async () => { - count.value += 1; - }); - expect(scratch.textContent).to.equal( - `${count.value}${count.value}` - ); - } - }); - - it("should correctly render components that have useReducer()", async () => { - const count = signal(0); - - let increment: () => void; - const Test = () => { - const [state, dispatch] = useReducer( - (state: number, action: number) => { - return state + action; - }, - -2 - ); - - increment = () => dispatch(1); - - const doubled = count.value * 2; - - return ( -
-						{state}
-						{doubled}
-					
- ); - }; - - await render(); - expect(scratch.innerHTML).to.equal( - "
-20
" - ); - - for (let i = 0; i < 3; i++) { - await act(async () => { - count.value += 1; - }); - expect(scratch.innerHTML).to.equal( - `
-2${count.value * 2}
` - ); - } - - await act(() => { - increment(); - }); - expect(scratch.innerHTML).to.equal( - `
-1${count.value * 2}
` - ); - }); - - it("should not fail when a component calls setState while rendering", async () => { - let increment: () => void; - function App() { - const [state, setState] = useState(0); - increment = () => setState(state + 1); - - if (state > 0 && state < 2) { - setState(state + 1); - } - - return
{state}
; - } - - await render(); - expect(scratch.innerHTML).to.equal("
0
"); - - await act(() => { - increment(); - }); - expect(scratch.innerHTML).to.equal("
2
"); - }); - - it("should not fail when a component calls setState multiple times while rendering", async () => { - let increment: () => void; - function App() { - const [state, setState] = useState(0); - increment = () => setState(state + 1); - - if (state > 0 && state < 5) { - setState(state + 1); - } - - return
{state}
; - } - - await render(); - expect(scratch.innerHTML).to.equal("
0
"); - - await act(() => { - increment(); - }); - expect(scratch.innerHTML).to.equal("
5
"); - }); - - it("should not fail when a component only uses state-less hooks", async () => { - // This test is suppose to trigger a condition in React where the - // HooksDispatcherOnMountWithHookTypesInDEV is used. This dispatcher is - // used in the development build of React if a component has hook types - // defined but no memoizedState, meaning no stateful hooks (e.g. useState) - // are used. `useContext` is an example of a state-less hook because it - // does not mount any hook state onto the fiber's memoizedState field. - // - // However, as of writing, because our react adapter inserts a - // useSyncExternalStore into all components, all components have memoized - // state and so this condition is never hit. However, I'm leaving the test - // to capture this unique behavior to hopefully catch any errors caused by - // not understanding or handling this in the future. - - const sig = signal(0); - const MyContext = createContext(0); - - function Child() { - const value = useContext(MyContext); - return ( -
- {sig} {value} -
- ); - } - - let updateContext: () => void; - function App() { - const [value, setValue] = useState(0); - updateContext = () => setValue(value + 1); - - return ( - - - - ); - } - - await render(); - expect(scratch.innerHTML).to.equal("
0 0
"); - - await act(() => { - sig.value++; - }); - expect(scratch.innerHTML).to.equal("
1 0
"); - - await act(() => { - updateContext(); - }); - expect(scratch.innerHTML).to.equal("
1 1
"); - }); - - it("should minimize rerenders when passing signals through context", async () => { - function spyOn

( - c: FunctionComponent

- ) { - return sinon.spy(c); - } - - // Manually read signal value below so we can watch whether components rerender - const Origin = spyOn(function Origin() { - const origin = useContext(URLModelContext).origin; - return {origin.value}; - }); - - const Pathname = spyOn(function Pathname() { - const pathname = useContext(URLModelContext).pathname; - return {pathname.value}; - }); - - const Search = spyOn(function Search() { - const search = useContext(URLModelContext).search; - return {search.value}; - }); - - // Never reads signal value during render so should never rerender - const UpdateURL = spyOn(function UpdateURL() { - const update = useContext(URLModelContext).update; - return ( - - ); - }); - - interface URLModel { - origin: ReadonlySignal; - pathname: ReadonlySignal; - search: ReadonlySignal; - update(updater: (newURL: URL) => void): void; - } - - // Also never reads signal value during render so should never rerender - const URLModelContext = createContext(null as any); - const URLModelProvider = spyOn(function SignalProvider({ children }) { - const url = useSignal(new URL("https://domain.com/test?a=1")); - const modelRef = useRef(null); - - if (modelRef.current == null) { - modelRef.current = { - origin: computed(() => url.value.origin), - pathname: computed(() => url.value.pathname), - search: computed(() => url.value.search), - update(updater) { - const newURL = new URL(url.value); - updater(newURL); - url.value = newURL; - }, - }; - } - - return ( - - {children} - - ); - }); - - function App() { - return ( - -

- - - -

- - - ); - } - - await render(); - - const url = scratch.querySelector("p")!; - expect(url.textContent).to.equal("https://domain.com/test?a=1"); - expect(URLModelProvider).to.be.calledOnce; - expect(Origin).to.be.calledOnce; - expect(Pathname).to.be.calledOnce; - expect(Search).to.be.calledOnce; - - await act(() => { - scratch.querySelector("button")!.click(); - }); - - expect(url.textContent).to.equal("https://domain.com/test?a=2"); - expect(URLModelProvider).to.be.calledOnce; - expect(Origin).to.be.calledOnce; - expect(Pathname).to.be.calledOnce; - expect(Search).to.be.calledTwice; - }); - - it("should not subscribe to computed signals only created and not used", async () => { - const sig = signal(0); - const childSpy = sinon.spy(); - const parentSpy = sinon.spy(); - - function Child({ num }: { num: Signal }) { - childSpy(); - return

{num.value}

; - } - - function Parent({ num }: { num: Signal }) { - parentSpy(); - const sig2 = useComputed(() => num.value + 1); - return ; - } - - await render(); - expect(scratch.innerHTML).to.equal("

1

"); - expect(parentSpy).to.be.calledOnce; - expect(childSpy).to.be.calledOnce; - - await act(() => { - sig.value += 1; - }); - expect(scratch.innerHTML).to.equal("

2

"); - expect(parentSpy).to.be.calledOnce; - expect(childSpy).to.be.calledTwice; - }); - - it("should properly subscribe and unsubscribe to conditionally rendered computed signals ", async () => { - const computedDep = signal(0); - const renderComputed = signal(true); - const renderSpy = sinon.spy(); - - function App() { - renderSpy(); - const computed = useComputed(() => computedDep.value + 1); - return renderComputed.value ?

{computed.value}

: null; - } - - await render(); - expect(scratch.innerHTML).to.equal("

1

"); - expect(renderSpy).to.be.calledOnce; - - await act(() => { - computedDep.value += 1; - }); - expect(scratch.innerHTML).to.equal("

2

"); - expect(renderSpy).to.be.calledTwice; - - await act(() => { - renderComputed.value = false; - }); - expect(scratch.innerHTML).to.equal(""); - expect(renderSpy).to.be.calledThrice; - - await act(() => { - computedDep.value += 1; - }); - expect(scratch.innerHTML).to.equal(""); - expect(renderSpy).to.be.calledThrice; // Should not be called again - }); - }); - - describe("useSignal()", () => { - it("should create a signal from a primitive value", async () => { - function App() { - const count = useSignal(1); - return ( -
- {count} - -
- ); - } - - await render(); - expect(scratch.textContent).to.equal("1Increment"); - - await act(() => { - scratch.querySelector("button")!.click(); - }); - expect(scratch.textContent).to.equal("2Increment"); - }); - }); - - describe("useSignalEffect()", () => { - it("should be invoked after commit", async () => { - const ref = createRef(); - const sig = signal("foo"); - const spy = sinon.spy(); - let count = 0; - - function App() { - useSignalEffect(() => - spy( - sig.value, - ref.current, - ref.current!.getAttribute("data-render-id") - ) - ); - return ( -

- {sig.value} -

- ); - } - - await render(); - expect(scratch.textContent).to.equal("foo"); - - expect(spy).to.have.been.calledOnceWith( - "foo", - scratch.firstElementChild, - "0" - ); - - spy.resetHistory(); - - await act(() => { - sig.value = "bar"; - }); - - expect(scratch.textContent).to.equal("bar"); - - // NOTE: Ideally, call should receive "1" as its third argument! The "0" - // indicates that React's DOM mutations hadn't yet been performed when the - // callback ran. This happens because we do signal-based effect runs after - // the first, not VDOM. Perhaps we could find a way to defer the callback - // when it coincides with a render? In React 16 when running in production - // however, we do see "1" as expected, likely because we are using a fake - // act() implementation which completes after the DOM has been updated. - expect(spy).to.have.been.calledOnceWith( - "bar", - scratch.firstElementChild, - isReact16 && isProd ? "1" : "0" // ideally always "1" - update if we find a nice way to do so! - ); - }); - - it("should invoke any returned cleanup function for updates", async () => { - const ref = createRef(); - const sig = signal("foo"); - const spy = sinon.spy(); - const cleanup = sinon.spy(); - let count = 0; - - function App() { - useSignalEffect(() => { - const id = ref.current!.getAttribute("data-render-id"); - const value = sig.value; - spy(value, ref.current, id); - return () => cleanup(value, ref.current, id); - }); - return ( -

- {sig.value} -

- ); - } - - await render(); - - expect(cleanup).not.to.have.been.called; - expect(spy).to.have.been.calledOnceWith( - "foo", - scratch.firstElementChild, - "0" - ); - spy.resetHistory(); - - await act(() => { - sig.value = "bar"; - }); - - expect(scratch.textContent).to.equal("bar"); - - const child = scratch.firstElementChild; - - expect(cleanup).to.have.been.calledOnceWith("foo", child, "0"); - - expect(spy).to.have.been.calledOnceWith( - "bar", - child, - isReact16 && isProd ? "1" : "0" // ideally always "1" - update if we find a nice way to do so! - ); - }); - - it("should invoke any returned cleanup function for unmounts", async () => { - const ref = createRef(); - const sig = signal("foo"); - const spy = sinon.spy(); - const cleanup = sinon.spy(); - - function App() { - useSignalEffect(() => { - const value = sig.value; - spy(value, ref.current); - return () => cleanup(value, ref.current); - }); - return

{sig.value}

; - } - - await render(); - - const child = scratch.firstElementChild; - - expect(scratch.innerHTML).to.equal("

foo

"); - expect(cleanup).not.to.have.been.called; - expect(spy).to.have.been.calledOnceWith("foo", child); - spy.resetHistory(); - - await act(() => { - root.unmount(); - }); - - expect(scratch.innerHTML).to.equal(""); - expect(spy).not.to.have.been.called; - expect(cleanup).to.have.been.calledOnce; - // @note: React v18 cleans up the ref eagerly, so it's already null by the - // time the callback runs. this is probably worth fixing at some point. - expect(cleanup).to.have.been.calledWith("foo", isReact16 ? child : null); - }); - }); + let scratch: HTMLDivElement; + let root: Root; + + async function render(element: Parameters[0]) { + await act(() => root.render(element)); + } + + beforeEach(async () => { + scratch = document.createElement("div"); + document.body.appendChild(scratch); + root = await createRoot(scratch); + getConsoleErrorSpy().mockReset(); + }); + + afterEach(async () => { + await act(() => root.unmount()); + scratch.remove(); + + checkConsoleErrorLogs(); + checkHangingAct(); + }); + + describe("SignalValue bindings", () => { + it("should render text without signals", async () => { + await render(test); + const span = scratch.firstChild; + const text = span?.firstChild; + expect(text).to.have.property("data", "test"); + }); + + it("should render Signals as SignalValue", async () => { + const sig = signal("test"); + await render({sig}); + const span = scratch.firstChild; + expect(span).to.have.property("firstChild").that.is.an.instanceOf(Text); + const text = span?.firstChild; + expect(text).to.have.property("data", "test"); + }); + + it("should render computed as SignalValue", async () => { + const sig = signal("test"); + const comp = computed(() => `${sig} ${sig}`); + await render({comp}); + const span = scratch.firstChild; + expect(span).to.have.property("firstChild").that.is.an.instanceOf(Text); + const text = span?.firstChild; + expect(text).to.have.property("data", "test test"); + }); + + it("should update Signal-based SignalValue (no parent component)", async () => { + const sig = signal("test"); + await render({sig}); + + const text = scratch.firstChild!.firstChild!; + expect(text).to.have.property("data", "test"); + + await act(() => { + sig.value = "changed"; + }); + + // should not remount/replace SignalValue + expect(scratch.firstChild!.firstChild!).to.equal(text); + // should update the text in-place + expect(text).to.have.property("data", "changed"); + }); + + it("should update Signal-based SignalValue (in a parent component)", async () => { + const sig = signal("test"); + function App({ x }: { x: typeof sig }) { + return {x}; + } + await render(); + + const text = scratch.firstChild!.firstChild!; + expect(text).to.have.property("data", "test"); + + await act(() => { + sig.value = "changed"; + }); + + // should not remount/replace SignalValue + expect(scratch.firstChild!.firstChild!).to.equal(text); + // should update the text in-place + expect(text).to.have.property("data", "changed"); + }); + + it("should work with JSX inside signal", async () => { + const sig = signal(test); + function App({ x }: { x: typeof sig }) { + return {x}; + } + await render(); + + let text = scratch.firstChild!.firstChild!; + expect(text).to.be.instanceOf(HTMLElement); + expect(text.firstChild).to.have.property("data", "test"); + + await act(() => { + sig.value =
changed
; + }); + + text = scratch.firstChild!.firstChild!; + expect(text).to.be.instanceOf(HTMLDivElement); + expect(text.firstChild).to.have.property("data", "changed"); + }); + }); + + describe("Component bindings", () => { + it("should subscribe to signals", async () => { + const sig = signal("foo"); + + function App() { + const value = sig.value; + return

{value}

; + } + + await render(); + expect(scratch.textContent).to.equal("foo"); + + await act(() => { + sig.value = "bar"; + }); + expect(scratch.textContent).to.equal("bar"); + }); + + it("should rerender components when signals they use change", async () => { + const signal1 = signal(0); + function Child1() { + return
{signal1}
; + } + + const signal2 = signal(0); + function Child2() { + return
{signal2}
; + } + + function Parent() { + return ( + + + + + ); + } + + await render(); + expect(scratch.innerHTML).to.equal("
0
0
"); + + await act(() => { + signal1.value += 1; + }); + expect(scratch.innerHTML).to.equal("
1
0
"); + + await act(() => { + signal2.value += 1; + }); + expect(scratch.innerHTML).to.equal("
1
1
"); + }); + + it("should subscribe to signals passed as props to DOM elements", async () => { + const className = signal("foo"); + function App() { + // @ts-expect-error React types don't allow signals on DOM elements :/ + return
; + } + + await render(); + + expect(scratch.innerHTML).to.equal('
'); + + await act(() => { + className.value = "bar"; + }); + + expect(scratch.innerHTML).to.equal('
'); + }); + + it("should activate signal accessed in render", async () => { + const sig = signal(null); + + function App() { + const arr = useComputed(() => { + // trigger read + sig.value; + + return []; + }); + + const str = arr.value.join(", "); + return

{str}

; + } + + try { + await render(); + } catch (e: any) { + expect.fail(e.stack); + } + }); + + it("should not subscribe to child signals", async () => { + const sig = signal("foo"); + + function Child() { + const value = sig.value; + return

{value}

; + } + + const spy = vi.fn(); + function App() { + spy(); + return ; + } + + await render(); + expect(scratch.textContent).toBe("foo"); + + await act(() => { + sig.value = "bar"; + }); + expect(spy).toHaveBeenCalledTimes(1); + }); + it("should update memo'ed component via signals", async () => { + const sig = signal("foo"); + + function Inner() { + const value = sig.value; + return

{value}

; + } + + function App() { + sig.value; + return useMemo(() => , []); + } + + await render(); + expect(scratch.textContent).to.equal("foo"); + + await act(() => { + sig.value = "bar"; + }); + expect(scratch.textContent).to.equal("bar"); + }); + + it("should update forwardRef'ed component via signals", async () => { + const sig = signal("foo"); + + const Inner = forwardRef(() => { + return

{sig.value}

; + }); + + function App() { + return ; + } + + await render(); + expect(scratch.textContent).to.equal("foo"); + + await act(() => { + sig.value = "bar"; + }); + expect(scratch.textContent).to.equal("bar"); + }); + + it("should consistently rerender in strict mode", async () => { + const sig = signal(-1); + + const Test = () =>

{sig.value}

; + const App = () => ( + + + + ); + + await render(); + expect(scratch.textContent).to.equal("-1"); + + for (let i = 0; i < 3; i++) { + await act(async () => { + sig.value = i; + }); + expect(scratch.textContent).to.equal("" + i); + } + }); + + it("should consistently rerender in strict mode (with memo)", async () => { + const sig = signal(-1); + + const Test = memo(() =>

{sig.value}

); + const App = () => ( + + + + ); + + await render(); + expect(scratch.textContent).to.equal("-1"); + + for (let i = 0; i < 3; i++) { + await act(async () => { + sig.value = i; + }); + expect(scratch.textContent).to.equal("" + i); + } + }); + + it.fails("should render static markup of a component", async () => { + const count = signal(0); + + const Test = () => { + return ( +
+            {renderToStaticMarkup({count})}
+            {renderToStaticMarkup({count.value})}
+          
+ ); + }; + + await render(); + expect(scratch.textContent).to.equal("00"); + + for (let i = 0; i < 3; i++) { + await act(async () => { + count.value += 1; + }); + expect(scratch.textContent).to.equal( + `${count.value}${count.value}` + ); + } + }); + + it("should correctly render components that have useReducer()", async () => { + const count = signal(0); + + let increment: () => void; + const Test = () => { + const [state, dispatch] = useReducer( + (state: number, action: number) => { + return state + action; + }, + -2 + ); + + increment = () => dispatch(1); + + const doubled = count.value * 2; + + return ( +
+            {state}
+            {doubled}
+          
+ ); + }; + + await render(); + expect(scratch.innerHTML).to.equal( + "
-20
" + ); + + for (let i = 0; i < 3; i++) { + await act(async () => { + count.value += 1; + }); + expect(scratch.innerHTML).to.equal( + `
-2${count.value * 2}
` + ); + } + + await act(() => { + increment(); + }); + expect(scratch.innerHTML).to.equal( + `
-1${count.value * 2}
` + ); + }); + + it("should not fail when a component calls setState while rendering", async () => { + let increment: () => void; + function App() { + const [state, setState] = useState(0); + increment = () => setState(state + 1); + + if (state > 0 && state < 2) { + setState(state + 1); + } + + return
{state}
; + } + + await render(); + expect(scratch.innerHTML).to.equal("
0
"); + + await act(() => { + increment(); + }); + expect(scratch.innerHTML).to.equal("
2
"); + }); + + it("should not fail when a component calls setState multiple times while rendering", async () => { + let increment: () => void; + function App() { + const [state, setState] = useState(0); + increment = () => setState(state + 1); + + if (state > 0 && state < 5) { + setState(state + 1); + } + + return
{state}
; + } + + await render(); + expect(scratch.innerHTML).to.equal("
0
"); + + await act(() => { + increment(); + }); + expect(scratch.innerHTML).to.equal("
5
"); + }); + + it("should not fail when a component only uses state-less hooks", async () => { + // This test is suppose to trigger a condition in React where the + // HooksDispatcherOnMountWithHookTypesInDEV is used. This dispatcher is + // used in the development build of React if a component has hook types + // defined but no memoizedState, meaning no stateful hooks (e.g. useState) + // are used. `useContext` is an example of a state-less hook because it + // does not mount any hook state onto the fiber's memoizedState field. + // + // However, as of writing, because our react adapter inserts a + // useSyncExternalStore into all components, all components have memoized + // state and so this condition is never hit. However, I'm leaving the test + // to capture this unique behavior to hopefully catch any errors caused by + // not understanding or handling this in the future. + + const sig = signal(0); + const MyContext = createContext(0); + + function Child() { + const value = useContext(MyContext); + return ( +
+ {sig} {value} +
+ ); + } + + let updateContext: () => void; + function App() { + const [value, setValue] = useState(0); + updateContext = () => setValue(value + 1); + + return ( + + + + ); + } + + await render(); + expect(scratch.innerHTML).to.equal("
0 0
"); + + await act(() => { + sig.value++; + }); + expect(scratch.innerHTML).to.equal("
1 0
"); + + await act(() => { + updateContext(); + }); + expect(scratch.innerHTML).to.equal("
1 1
"); + }); + + it("should minimize rerenders when passing signals through context", async () => { + function spyOn

( + c: FunctionComponent

+ ) { + return vi.fn(c); + } + + // Manually read signal value below so we can watch whether components rerender + const Origin = spyOn(function Origin() { + const origin = useContext(URLModelContext).origin; + return {origin.value}; + }); + + const Pathname = spyOn(function Pathname() { + const pathname = useContext(URLModelContext).pathname; + return {pathname.value}; + }); + + const Search = spyOn(function Search() { + const search = useContext(URLModelContext).search; + return {search.value}; + }); + + // Never reads signal value during render so should never rerender + const UpdateURL = spyOn(function UpdateURL() { + const update = useContext(URLModelContext).update; + return ( + + ); + }); + + interface URLModel { + origin: ReadonlySignal; + pathname: ReadonlySignal; + search: ReadonlySignal; + update(updater: (newURL: URL) => void): void; + } + + // Also never reads signal value during render so should never rerender + const URLModelContext = createContext(null as any); + const URLModelProvider = spyOn(function SignalProvider({ children }) { + const url = useSignal(new URL("https://domain.com/test?a=1")); + const modelRef = useRef(null); + + if (modelRef.current == null) { + modelRef.current = { + origin: computed(() => url.value.origin), + pathname: computed(() => url.value.pathname), + search: computed(() => url.value.search), + update(updater) { + const newURL = new URL(url.value); + updater(newURL); + url.value = newURL; + }, + }; + } + + return ( + + {children} + + ); + }); + + function App() { + return ( + +

+ + + +

+ + + ); + } + + await render(); + + const url = scratch.querySelector("p")!; + expect(url.textContent).toBe("https://domain.com/test?a=1"); + expect(URLModelProvider).toHaveBeenCalledTimes(1); + expect(Origin).toHaveBeenCalledTimes(1); + expect(Pathname).toHaveBeenCalledTimes(1); + expect(Search).toHaveBeenCalledTimes(1); + + await act(() => { + scratch.querySelector("button")!.click(); + }); + + expect(url.textContent).toBe("https://domain.com/test?a=2"); + expect(URLModelProvider).toHaveBeenCalledTimes(1); + expect(Origin).toHaveBeenCalledTimes(1); + expect(Pathname).toHaveBeenCalledTimes(1); + expect(Search).toHaveBeenCalledTimes(2); + }); + it("should not subscribe to computed signals only created and not used", async () => { + const sig = signal(0); + const childSpy = vi.fn(); + const parentSpy = vi.fn(); + + function Child({ num }: { num: Signal }) { + childSpy(); + return

{num.value}

; + } + + function Parent({ num }: { num: Signal }) { + parentSpy(); + const sig2 = useComputed(() => num.value + 1); + return ; + } + + await render(); + expect(scratch.innerHTML).toBe("

1

"); + expect(parentSpy).toHaveBeenCalledTimes(1); + expect(childSpy).toHaveBeenCalledTimes(1); + + await act(() => { + sig.value += 1; + }); + expect(scratch.innerHTML).toBe("

2

"); + expect(parentSpy).toHaveBeenCalledTimes(1); + expect(childSpy).toHaveBeenCalledTimes(2); + }); + + it("should properly subscribe and unsubscribe to conditionally rendered computed signals ", async () => { + const computedDep = signal(0); + const renderComputed = signal(true); + const renderSpy = vi.fn(); + + function App() { + renderSpy(); + const computed = useComputed(() => computedDep.value + 1); + return renderComputed.value ?

{computed.value}

: null; + } + + await render(); + expect(scratch.innerHTML).toBe("

1

"); + expect(renderSpy).toHaveBeenCalledTimes(1); + + await act(() => { + computedDep.value += 1; + }); + expect(scratch.innerHTML).toBe("

2

"); + expect(renderSpy).toHaveBeenCalledTimes(2); + + await act(() => { + renderComputed.value = false; + }); + expect(scratch.innerHTML).toBe(""); + expect(renderSpy).toHaveBeenCalledTimes(3); + + await act(() => { + computedDep.value += 1; + }); + expect(scratch.innerHTML).toBe(""); + expect(renderSpy).toHaveBeenCalledTimes(3); // Should not be called again + }); + + describe("useSignal()", () => { + it("should create a signal from a primitive value", async () => { + function App() { + const count = useSignal(1); + return ( +
+ {count} + +
+ ); + } + + await render(); + expect(scratch.textContent).to.equal("1Increment"); + + await act(() => { + scratch.querySelector("button")!.click(); + }); + expect(scratch.textContent).to.equal("2Increment"); + }); + }); + + describe("useSignalEffect()", () => { + it("should be invoked after commit", async () => { + const ref = createRef(); + const sig = signal("foo"); + const spy = vi.fn(); + let count = 0; + + function App() { + useSignalEffect(() => + spy( + sig.value, + ref.current, + ref.current!.getAttribute("data-render-id") + ) + ); + return ( +

+ {sig.value} +

+ ); + } + + await render(); + expect(scratch.textContent).toBe("foo"); + + expect(spy).toHaveBeenCalledWith("foo", scratch.firstElementChild, "0"); + + spy.mockReset(); + + await act(() => { + sig.value = "bar"; + }); + + expect(scratch.textContent).toBe("bar"); + + expect(spy).toHaveBeenCalledWith( + "bar", + scratch.firstElementChild, + isReact16 && isProd ? "1" : "0" + ); + }); + + it("should invoke any returned cleanup function for updates", async () => { + const ref = createRef(); + const sig = signal("foo"); + const spy = vi.fn(); + const cleanup = vi.fn(); + let count = 0; + + function App() { + useSignalEffect(() => { + const id = ref.current!.getAttribute("data-render-id"); + const value = sig.value; + spy(value, ref.current, id); + return () => cleanup(value, ref.current, id); + }); + return ( +

+ {sig.value} +

+ ); + } + + await render(); + + expect(cleanup).not.toHaveBeenCalled(); + expect(spy).toHaveBeenCalledWith("foo", scratch.firstElementChild, "0"); + spy.mockReset(); + + await act(() => { + sig.value = "bar"; + }); + + expect(scratch.textContent).toBe("bar"); + + const child = scratch.firstElementChild; + + expect(cleanup).toHaveBeenCalledWith("foo", child, "0"); + + expect(spy).toHaveBeenCalledWith( + "bar", + child, + isReact16 && isProd ? "1" : "0" + ); + }); + + it("should invoke any returned cleanup function for unmounts", async () => { + const ref = createRef(); + const sig = signal("foo"); + const spy = vi.fn(); + const cleanup = vi.fn(); + + function App() { + useSignalEffect(() => { + const value = sig.value; + spy(value, ref.current); + return () => cleanup(value, ref.current); + }); + return

{sig.value}

; + } + + await render(); + + const child = scratch.firstElementChild; + + expect(scratch.innerHTML).toBe("

foo

"); + expect(cleanup).not.toHaveBeenCalled(); + expect(spy).toHaveBeenCalledWith("foo", child); + spy.mockReset(); + + await act(() => { + root.unmount(); + }); + + expect(scratch.innerHTML).toBe(""); + expect(spy).not.toHaveBeenCalled(); + expect(cleanup).toHaveBeenCalledTimes(1); + expect(cleanup).toHaveBeenCalledWith("foo", isReact16 ? child : null); + }); + }); + }); }); diff --git a/packages/react/test/node/renderToStaticMarkup.test.tsx b/packages/react/test/node/renderToStaticMarkup.test.tsx index 08ad99be..fba7ba8b 100644 --- a/packages/react/test/node/renderToStaticMarkup.test.tsx +++ b/packages/react/test/node/renderToStaticMarkup.test.tsx @@ -1,22 +1,23 @@ -import { signal, useSignalEffect } from "@preact/signals-react"; -import { createElement } from "react"; +import { signal, useSignalEffect } from "../../src"; import { renderToStaticMarkup } from "react-dom/server"; import { mountSignalsTests } from "../shared/mounting"; +import { vi, describe, it, expect } from "vitest"; +import React from "react"; describe("renderToStaticMarkup", () => { - mountSignalsTests(renderToStaticMarkup); + mountSignalsTests(renderToStaticMarkup); - it("should not invoke useSignalEffect", async () => { - const spy = sinon.spy(); - const sig = signal("foo"); + it("should not invoke useSignalEffect", async () => { + const spy = vi.fn(); + const sig = signal("foo"); - function App() { - useSignalEffect(() => spy(sig.value)); - return

{sig.value}

; - } + function App() { + useSignalEffect(() => spy(sig.value)); + return

{sig.value}

; + } - const html = await renderToStaticMarkup(); - expect(html).to.equal("

foo

"); - expect(spy.called).to.be.false; - }); + const html = await renderToStaticMarkup(); + expect(html).to.equal("

foo

"); + expect(spy).not.toHaveBeenCalled(); + }); }); diff --git a/packages/react/test/shared/mounting.tsx b/packages/react/test/shared/mounting.tsx index cef29aca..6b952b6a 100644 --- a/packages/react/test/shared/mounting.tsx +++ b/packages/react/test/shared/mounting.tsx @@ -1,184 +1,176 @@ -// @ts-ignore-next-line -globalThis.IS_REACT_ACT_ENVIRONMENT = true; - -import { - signal, - computed, - useComputed, - useSignal, -} from "@preact/signals-react"; -import { expect } from "chai"; -import { createElement, useReducer, StrictMode, useState } from "react"; +import { signal, computed, useComputed, useSignal } from "../../src"; +import React, { useReducer, StrictMode, useState } from "react"; +import { vi, describe, it, beforeEach, afterEach, expect } from "vitest"; import { getConsoleErrorSpy, checkConsoleErrorLogs } from "./utils"; export function mountSignalsTests( - render: (element: JSX.Element) => string | Promise + render: (element: JSX.Element) => string | Promise ) { - beforeEach(async () => { - getConsoleErrorSpy().resetHistory(); - }); - - afterEach(async () => { - checkConsoleErrorLogs(); - }); - - describe("mount text bindings", () => { - it("should render text without signals", async () => { - const html = await render(test); - expect(html).to.equal("test"); - }); - - it("should render Signals as SignalValue", async () => { - const sig = signal("test"); - const html = await render({sig}); - expect(html).to.equal("test"); - }); - - it("should render computed as SignalValue", async () => { - const sig = signal("test"); - const comp = computed(() => `${sig} ${sig}`); - const html = await render({comp}); - expect(html).to.equal("test test"); - }); - }); - - describe("mount component bindings", () => { - it("should mount component with signals as text", async () => { - const sig = signal("foo"); - - function App() { - const value = sig.value; - return

{value}

; - } - - const html = await render(); - expect(html).to.equal("

foo

"); - }); - - it("should activate signal accessed in render", async () => { - const sig = signal(null); - - function App() { - const arr = useComputed(() => { - // trigger read - sig.value; - - return []; - }); - - const str = arr.value.join(", "); - return

{str}

; - } - - try { - await render(); - } catch (e: any) { - expect.fail(e.stack); - } - }); - - it("should properly mount in strict mode", async () => { - const sig = signal(-1); - - const Test = () =>

{sig.value}

; - const App = () => ( - - - - ); - - const html = await render(); - expect(html).to.equal("

-1

"); - }); - - it("should correctly mount components that have useReducer()", async () => { - const count = signal(0); - - const Test = () => { - const [state] = useReducer((state: number, action: number) => { - return state + action; - }, -2); - - const doubled = count.value * 2; - - return ( -
-						{state}
-						{doubled}
-					
- ); - }; - - const html = await render(); - expect(html).to.equal("
-20
"); - }); - - it("should not fail when a component calls setState while mounting", async () => { - function App() { - const [state, setState] = useState(0); - if (state == 0) { - setState(1); - } - - return
{state}
; - } - - const html = await render(); - expect(html).to.equal("
1
"); - }); - - it("should not fail when a component calls setState multiple times while mounting", async () => { - function App() { - const [state, setState] = useState(0); - if (state < 5) { - setState(state + 1); - } - - return
{state}
; - } - - const html = await render(); - expect(html).to.equal("
5
"); - }); - }); - - describe("useSignal()", () => { - it("should create a signal from a primitive value", async () => { - function App() { - const count = useSignal(1); - return ( -
- {count} - -
- ); - } - - const html = await render(); - expect(html).to.equal("
1
"); - }); - - it("should properly update signal values changed during mount", async () => { - function App() { - const count = useSignal(0); - if (count.value == 0) { - count.value++; - } - - return ( -
- {count} - -
- ); - } - - const html = await render(); - expect(html).to.equal("
1
"); - - const html2 = await render(); - expect(html2).to.equal("
1
"); - }); - }); + beforeEach(async () => { + getConsoleErrorSpy().mockClear(); + }); + + afterEach(async () => { + checkConsoleErrorLogs(); + }); + + describe("mount text bindings", () => { + it("should render text without signals", async () => { + const html = await render(test); + expect(html).to.equal("test"); + }); + + it("should render Signals as SignalValue", async () => { + const sig = signal("test"); + const html = await render({sig}); + expect(html).to.equal("test"); + }); + + it("should render computed as SignalValue", async () => { + const sig = signal("test"); + const comp = computed(() => `${sig} ${sig}`); + const html = await render({comp}); + expect(html).to.equal("test test"); + }); + }); + + describe("mount component bindings", () => { + it("should mount component with signals as text", async () => { + const sig = signal("foo"); + + function App() { + const value = sig.value; + return

{value}

; + } + + const html = await render(); + expect(html).to.equal("

foo

"); + }); + + it("should activate signal accessed in render", async () => { + const sig = signal(null); + + function App() { + const arr = useComputed(() => { + // trigger read + sig.value; + + return []; + }); + + const str = arr.value.join(", "); + return

{str}

; + } + + try { + await render(); + } catch (e: any) { + expect.fail(e.stack); + } + }); + + it("should properly mount in strict mode", async () => { + const sig = signal(-1); + + const Test = () =>

{sig.value}

; + const App = () => ( + + + + ); + + const html = await render(); + expect(html).to.equal("

-1

"); + }); + + it("should correctly mount components that have useReducer()", async () => { + const count = signal(0); + + const Test = () => { + const [state] = useReducer((state: number, action: number) => { + return state + action; + }, -2); + + const doubled = count.value * 2; + + return ( +
+            {state}
+            {doubled}
+          
+ ); + }; + + const html = await render(); + expect(html).to.equal("
-20
"); + }); + + it("should not fail when a component calls setState while mounting", async () => { + function App() { + const [state, setState] = useState(0); + if (state == 0) { + setState(1); + } + + return
{state}
; + } + + const html = await render(); + expect(html).to.equal("
1
"); + }); + + it("should not fail when a component calls setState multiple times while mounting", async () => { + function App() { + const [state, setState] = useState(0); + if (state < 5) { + setState(state + 1); + } + + return
{state}
; + } + + const html = await render(); + expect(html).to.equal("
5
"); + }); + }); + + describe("useSignal()", () => { + it("should create a signal from a primitive value", async () => { + function App() { + const count = useSignal(1); + return ( +
+ {count} + +
+ ); + } + + const html = await render(); + expect(html).to.equal("
1
"); + }); + + it("should properly update signal values changed during mount", async () => { + function App() { + const count = useSignal(0); + if (count.value == 0) { + count.value++; + } + + return ( +
+ {count} + +
+ ); + } + + const html = await render(); + expect(html).to.equal("
1
"); + + const html2 = await render(); + expect(html2).to.equal("
1
"); + }); + }); } diff --git a/packages/react/test/shared/utils.ts b/packages/react/test/shared/utils.ts index 2d561b93..b74a31d5 100644 --- a/packages/react/test/shared/utils.ts +++ b/packages/react/test/shared/utils.ts @@ -1,10 +1,10 @@ import React from "react"; -import sinon from "sinon"; import { act as realAct } from "react-dom/test-utils"; +import { SpyInstance, assert, vi, expect } from "vitest"; export interface Root { - render(element: JSX.Element | null): void; - unmount(): void; + render(element: JSX.Element | null): void; + unmount(): void; } export const isProd = process.env.NODE_ENV === "production"; @@ -15,29 +15,29 @@ export const isReact16 = React.version.startsWith("16."); // createRoot() that uses render() and unmountComponentAtNode() instead. let createRootCache: ((container: Element) => Root) | undefined; export async function createRoot(container: Element): Promise { - if (!createRootCache) { - try { - // @ts-expect-error ESBuild will replace this import with a require() call - // if it resolves react-dom/client. If it doesn't, it will leave the - // import untouched causing a runtime error we'll handle below. - const { createRoot } = await import("react-dom/client"); - createRootCache = createRoot; - } catch (e) { - // @ts-expect-error ESBuild will replace this import with a require() call - // if it resolves react-dom. - const { render, unmountComponentAtNode } = await import("react-dom"); - createRootCache = (container: Element) => ({ - render(element: JSX.Element) { - render(element, container); - }, - unmount() { - unmountComponentAtNode(container); - }, - }); - } - } + if (!createRootCache) { + try { + // @ts-expect-error ESBuild will replace this import with a require() call + // if it resolves react-dom/client. If it doesn't, it will leave the + // import untouched causing a runtime error we'll handle below. + const { createRoot } = await import("react-dom/client"); + createRootCache = createRoot; + } catch (e) { + // @ts-expect-error ESBuild will replace this import with a require() call + // if it resolves react-dom. + const { render, unmountComponentAtNode } = await import("react-dom"); + createRootCache = (container: Element) => ({ + render(element: JSX.Element) { + render(element, container); + }, + unmount() { + unmountComponentAtNode(container); + }, + }); + } + } - return createRootCache(container); + return createRootCache(container); } // When testing using react's production build, we can't use act (React @@ -47,31 +47,31 @@ export async function createRoot(container: Element): Promise { // helpful error in afterEach if we detect that act() was called but not // awaited. const afterFrame = (ms: number) => - new Promise(r => requestAnimationFrame(() => setTimeout(r, ms))); + new Promise((r) => requestAnimationFrame(() => setTimeout(r, ms))); let acting = 0; async function prodActShim(cb: () => void | Promise): Promise { - acting++; - try { - await cb(); - await afterFrame(10); - } finally { - acting--; - } + acting++; + try { + await cb(); + await afterFrame(10); + } finally { + acting--; + } } export function checkHangingAct() { - if (acting > 0) { - throw new Error( - `It appears act() was called but not awaited. This could happen if a test threw an Error or if a test forgot to await a call to act. Make sure to await act() calls in tests.` - ); - } + if (acting > 0) { + throw new Error( + `It appears act() was called but not awaited. This could happen if a test threw an Error or if a test forgot to await a call to act. Make sure to await act() calls in tests.` + ); + } } export const act = - process.env.NODE_ENV === "production" - ? (prodActShim as typeof realAct) - : realAct; + process.env.NODE_ENV === "production" + ? (prodActShim as typeof realAct) + : realAct; /** * `console.log` supports formatting strings with `%s` for string substitutions. @@ -79,49 +79,45 @@ export const act = * a string with the values substituted in. */ export function consoleFormat(str: string, ...values: unknown[]): string { - let idx = 0; - return str.replace(/%s/g, () => String(values[idx++])); + let idx = 0; + return str.replace(/%s/g, () => String(values[idx++])); } declare global { - let errorSpy: sinon.SinonSpy | undefined; + let errorSpy: SpyInstance | undefined; } // Only one spy can be active on an object at a time and since all tests share // the same console object we need to make sure we're only spying on it once. // We'll use this method to share the spy across all tests. -export function getConsoleErrorSpy(): sinon.SinonSpy { - if (typeof errorSpy === "undefined") { - (globalThis as any).errorSpy = sinon.spy(console, "error"); - } - - return errorSpy!; +export function getConsoleErrorSpy(): SpyInstance { + return ((globalThis as any).errorSpy ??= vi.spyOn(console, "error")); } const messagesToIgnore = [ - // Ignore errors for timeouts of tests that often happen while debugging - /async tests and hooks,/, - // Ignore React 16 warnings about awaiting `act` calls (warning removed in React 18) - /Do not await the result of calling act/, - // Ignore how chai or mocha uses `console.error` to print out errors - /AssertionError/, + // Ignore errors for timeouts of tests that often happen while debugging + /async tests and hooks,/, + // Ignore React 16 warnings about awaiting `act` calls (warning removed in React 18) + /Do not await the result of calling act/, + // Ignore how chai or mocha uses `console.error` to print out errors + /AssertionError/, ]; export function checkConsoleErrorLogs(): void { - const errorSpy = getConsoleErrorSpy(); - if (errorSpy.called) { - let message: string; - if (errorSpy.firstCall.args[0].toString().includes("%s")) { - const firstArg = errorSpy.firstCall.args[0]; - message = consoleFormat(firstArg, ...errorSpy.firstCall.args.slice(1)); - } else { - message = errorSpy.firstCall.args.join(" "); - } + const errorSpy = getConsoleErrorSpy(); + if (errorSpy.mock.calls.length > 0) { + let message: string; + const firstCall = errorSpy.mock.calls[0]; + assert(firstCall, "first call should be"); + if (firstCall?.[0].toString().includes("%s")) { + const firstArg = firstCall[0]; + message = consoleFormat(firstArg, ...firstCall.slice(1)); + } else { + message = firstCall?.join(" "); + } - if (messagesToIgnore.every(re => re.test(message) === false)) { - expect.fail( - `Console.error was unexpectedly called with this message: \n${message}` - ); - } - } + if (messagesToIgnore.every((re) => re.test(message) === false)) { + expect.fail(message); + } + } } diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts new file mode 100644 index 00000000..6fada3ad --- /dev/null +++ b/packages/react/vitest.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "happy-dom", + setupFiles: "./setupVitest.ts", + }, + define: { + __DEV__: true, + }, +}); diff --git a/packages/type/src/codegen.ts b/packages/type/src/codegen.ts index 31819db8..58d50ae0 100644 --- a/packages/type/src/codegen.ts +++ b/packages/type/src/codegen.ts @@ -46,7 +46,7 @@ const getComponentInterfaces = (reactTypings: string) => { return [`declare module '${module}' {`, ...resultInterfaces, "}"].join("\n"); }; -(async () => { +void (async () => { const reactTypes = await readFile( "node_modules/@types/react/index.d.ts", "utf8" diff --git a/packages/utils/src/__tests__/$.test.tsx b/packages/utils/src/__tests__/$.test.tsx index 5e89e302..026b6539 100644 --- a/packages/utils/src/__tests__/$.test.tsx +++ b/packages/utils/src/__tests__/$.test.tsx @@ -1,9 +1,9 @@ import { computed, signal } from "@preact-signals/unified-signals"; import React from "react"; -import { describe, expect, it, vi } from "vitest"; +import { describe, expect, it } from "vitest"; import { $ } from "../$"; -import { createRenderer, sleep } from "./utils"; +import { createRenderer } from "./utils"; describe("$()", () => { const { reactRoot, root, act } = createRenderer(); diff --git a/packages/utils/src/__tests__/hoc.test.tsx b/packages/utils/src/__tests__/hoc.test.tsx index 09f5c453..f8b6ae16 100644 --- a/packages/utils/src/__tests__/hoc.test.tsx +++ b/packages/utils/src/__tests__/hoc.test.tsx @@ -6,29 +6,27 @@ import { ReactiveProps, reactifyLite, withSignalProps } from "../hocs"; import { reactify } from "../hocs/reactify"; import { itRenderer } from "./utils"; -describe.concurrent("withSignalProps()", () => { +describe("withSignalProps()", () => { for (const valueType of ["signal", "Uncached"] as const) { itRenderer( `should force rerender dependent component (${valueType})`, - ({ act, reactRoot, expect, root }) => { + async ({ act, reactRoot, expect, root }) => { const B = withSignalProps( vi.fn((props: { value: number }) =>
{props.value}
) ); const sig = signal(10); - act(() => { - reactRoot().render( - sig.value)} /> - ); - }); + await reactRoot().render( + sig.value)} /> + ); expect(B).toHaveBeenCalledTimes(1); expect(B).toHaveBeenCalledWith({ value: 10 }, {}); expect(root.firstChild).is.instanceOf(HTMLDivElement); expect(root.firstChild).has.property("textContent", "10"); - act(() => { + await act(() => { sig.value = 20; }); @@ -50,19 +48,17 @@ describe.concurrent("withSignalProps()", () => { itRenderer( "should not rerender when unread signal changed", - ({ expect, act, reactRoot }) => { + async ({ expect, act, reactRoot }) => { const B = withSignalProps(vi.fn((props: { value: number }) => null)); const sig = signal(10); - act(() => { - reactRoot().render( sig.value)} />); - }); + await reactRoot().render( sig.value)} />); expect(B).toHaveBeenCalledTimes(1); expect(B).toHaveBeenCalledWith({ value: 10 }, {}); - act(() => { + await act(() => { sig.value = 20; }); @@ -86,7 +82,7 @@ describe.concurrent("withSignalProps()", () => { }); }); -describe.concurrent("reactifyLite()", () => { +describe("reactifyLite()", () => { it("should handle explicitly defined reactive props", () => { const A = reactifyLite((props: ReactiveProps<{ value: number }>) => (
{props.value}
@@ -152,7 +148,7 @@ describe.concurrent("reactifyLite()", () => { ); }); -describe.concurrent("reactify()", () => { +describe("reactify()", () => { itRenderer( "should support value$ postfix", async ({ expect, root, reactRoot }) => { diff --git a/packages/utils/src/__tests__/utils.ts b/packages/utils/src/__tests__/utils.ts index c388d8c1..261e99e2 100644 --- a/packages/utils/src/__tests__/utils.ts +++ b/packages/utils/src/__tests__/utils.ts @@ -3,19 +3,11 @@ import { createRoot } from "react-dom/client"; import { act as reactAct } from "react-dom/test-utils"; import { TestFunction, afterEach, it } from "vitest"; -const raf = (): Promise => - new Promise((resolve) => requestAnimationFrame(() => resolve())); - -let prevAct = Promise.resolve(); -const _act = async (callback: () => unknown): Promise => { - const res = reactAct(callback); - - await res; - await raf(); - await res; -}; -const act = (callback: () => unknown): Promise => - (prevAct = prevAct.finally(() => _act(callback))); +// let prevAct = Promise.resolve(); +// const concurrentAct = (callback: () => unknown): Promise => +// (prevAct = prevAct.finally(async () => { +// await reactAct(callback); +// })); export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); @@ -28,7 +20,7 @@ export const _createRenderer = () => { let reactRoot = createRoot(root); const dispose = async () => { - await act(() => { + await reactAct(() => { reactRoot.unmount(); }); root.innerHTML = ""; @@ -38,14 +30,14 @@ export const _createRenderer = () => { reactRoot: () => ({ ...reactRoot, render: async (data: React.ReactNode) => { - await act(() => reactRoot.render(data)); + await reactAct(() => reactRoot.render(data)); }, }), recreateRoot: () => { reactRoot = createRoot(root); }, dispose, - act, + act: reactAct, }; }; diff --git a/packages/utils/src/resource/resource.test.ts b/packages/utils/src/resource/resource.test.ts index 9262b5fa..424c47d4 100644 --- a/packages/utils/src/resource/resource.test.ts +++ b/packages/utils/src/resource/resource.test.ts @@ -104,7 +104,7 @@ describe("resource", () => { expect(fetcher).toHaveBeenCalled(); expect(r()).toBe(220); - r.refetch(); + void r.refetch(); expect(fetcher).toHaveBeenCalledTimes(2); expect(r()).toBe(220); }); @@ -157,7 +157,7 @@ describe("resource", () => { } as any); }); - r.refetch(); + void r.refetch(); expect(fetcher).toHaveBeenCalledTimes(2); expect(r.state).toBe("ready"); expect(states).toEqual( @@ -202,7 +202,7 @@ describe("resource", () => { await sleep(); - r.refetch(); + await r.refetch(); await sleep(); expect(fetcher).toHaveBeenCalledTimes(2); @@ -285,7 +285,7 @@ describe("resource", () => { }) ); - r.refetch(); + void r.refetch(); expect(fetcher).toHaveBeenCalledTimes(2); expect(fetcher).toHaveBeenCalledWith( true, @@ -295,7 +295,7 @@ describe("resource", () => { }) ); - r.refetch(false); + void r.refetch(false); expect(fetcher).toHaveBeenCalledTimes(3); expect(fetcher).toHaveBeenCalledWith( true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 73c8e016..bdd9d1ac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,15 @@ importers: '@changesets/cli': specifier: ^2.26.2 version: 2.26.2 + '@typescript-eslint/eslint-plugin': + specifier: ^6.10.0 + version: 6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.1.6) + '@typescript-eslint/parser': + specifier: ^6.10.0 + version: 6.10.0(eslint@8.53.0)(typescript@5.1.6) + eslint: + specifier: ^8.53.0 + version: 8.53.0 rimraf: specifier: ^5.0.1 version: 5.0.1 @@ -76,12 +85,6 @@ importers: '@types/react-dom': specifier: ^18.0.11 version: 18.2.7 - '@typescript-eslint/eslint-plugin': - specifier: ^5.59.0 - version: 5.59.0(@typescript-eslint/parser@5.59.0)(eslint@8.38.0)(typescript@5.1.6) - '@typescript-eslint/parser': - specifier: ^5.59.0 - version: 5.59.0(eslint@8.38.0)(typescript@5.1.6) '@vitejs/plugin-react-swc': specifier: ^3.0.0 version: 3.0.1(vite@4.4.0) @@ -91,15 +94,6 @@ importers: daisyui: specifier: ^3.5.1 version: 3.5.1 - eslint: - specifier: ^8.38.0 - version: 8.38.0 - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.0(eslint@8.38.0) - eslint-plugin-react-refresh: - specifier: ^0.3.4 - version: 0.3.4(eslint@8.38.0) postcss: specifier: ^8.4.27 version: 8.4.27 @@ -220,6 +214,34 @@ importers: specifier: ^8.13.1 version: 8.13.1(typescript@5.1.6) + packages/react: + dependencies: + '@preact/signals-core': + specifier: ^1.4.0 + version: 1.5.0 + use-sync-external-store: + specifier: ^1.2.0 + version: 1.2.0(react@18.2.0) + devDependencies: + '@types/react': + specifier: ^18.0.18 + version: 18.2.15 + '@types/react-dom': + specifier: ^18.0.6 + version: 18.2.7 + '@types/use-sync-external-store': + specifier: ^0.0.3 + version: 0.0.3 + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + react-router-dom: + specifier: ^6.9.0 + version: 6.18.0(react-dom@18.2.0)(react@18.2.0) + packages/type: dependencies: '@preact/signals-core': @@ -987,14 +1009,19 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.38.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.53.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.38.0 - eslint-visitor-keys: 3.4.1 + eslint: 8.53.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true /@eslint-community/regexpp@4.5.1: @@ -1002,13 +1029,13 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.1.0: - resolution: {integrity: sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==} + /@eslint/eslintrc@2.1.3: + resolution: {integrity: sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.6.0 + espree: 9.6.1 globals: 13.20.0 ignore: 5.2.4 import-fresh: 3.3.0 @@ -1019,8 +1046,8 @@ packages: - supports-color dev: true - /@eslint/js@8.38.0: - resolution: {integrity: sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==} + /@eslint/js@8.53.0: + resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -1032,11 +1059,11 @@ packages: react: 18.2.0 dev: false - /@humanwhocodes/config-array@0.11.10: - resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} + /@humanwhocodes/config-array@0.11.13: + resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 1.2.1 + '@humanwhocodes/object-schema': 2.0.1 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: @@ -1048,8 +1075,8 @@ packages: engines: {node: '>=12.22'} dev: true - /@humanwhocodes/object-schema@1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + /@humanwhocodes/object-schema@2.0.1: + resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true /@isaacs/cliui@8.0.2: @@ -1293,6 +1320,11 @@ packages: - supports-color dev: true + /@remix-run/router@1.11.0: + resolution: {integrity: sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ==} + engines: {node: '>=14.0.0'} + dev: true + /@rollup/plugin-replace@5.0.2(rollup@3.29.2): resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} engines: {node: '>=14.0.0'} @@ -1729,136 +1761,141 @@ packages: dev: true optional: true - /@typescript-eslint/eslint-plugin@5.59.0(@typescript-eslint/parser@5.59.0)(eslint@8.38.0)(typescript@5.1.6): - resolution: {integrity: sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.1.6): + resolution: {integrity: sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 5.59.0(eslint@8.38.0)(typescript@5.1.6) - '@typescript-eslint/scope-manager': 5.59.0 - '@typescript-eslint/type-utils': 5.59.0(eslint@8.38.0)(typescript@5.1.6) - '@typescript-eslint/utils': 5.59.0(eslint@8.38.0)(typescript@5.1.6) + '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.1.6) + '@typescript-eslint/scope-manager': 6.10.0 + '@typescript-eslint/type-utils': 6.10.0(eslint@8.53.0)(typescript@5.1.6) + '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.1.6) + '@typescript-eslint/visitor-keys': 6.10.0 debug: 4.3.4 - eslint: 8.38.0 - grapheme-splitter: 1.0.4 + eslint: 8.53.0 + graphemer: 1.4.0 ignore: 5.2.4 - natural-compare-lite: 1.4.0 + natural-compare: 1.4.0 semver: 7.5.4 - tsutils: 3.21.0(typescript@5.1.6) + ts-api-utils: 1.0.3(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@5.59.0(eslint@8.38.0)(typescript@5.1.6): - resolution: {integrity: sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/parser@6.10.0(eslint@8.53.0)(typescript@5.1.6): + resolution: {integrity: sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.59.0 - '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/typescript-estree': 5.59.0(typescript@5.1.6) + '@typescript-eslint/scope-manager': 6.10.0 + '@typescript-eslint/types': 6.10.0 + '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.1.6) + '@typescript-eslint/visitor-keys': 6.10.0 debug: 4.3.4 - eslint: 8.38.0 + eslint: 8.53.0 typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@5.59.0: - resolution: {integrity: sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/scope-manager@6.10.0: + resolution: {integrity: sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==} + engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/visitor-keys': 5.59.0 + '@typescript-eslint/types': 6.10.0 + '@typescript-eslint/visitor-keys': 6.10.0 dev: true - /@typescript-eslint/type-utils@5.59.0(eslint@8.38.0)(typescript@5.1.6): - resolution: {integrity: sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/type-utils@6.10.0(eslint@8.53.0)(typescript@5.1.6): + resolution: {integrity: sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: '*' + eslint: ^7.0.0 || ^8.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.59.0(typescript@5.1.6) - '@typescript-eslint/utils': 5.59.0(eslint@8.38.0)(typescript@5.1.6) + '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.1.6) + '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.1.6) debug: 4.3.4 - eslint: 8.38.0 - tsutils: 3.21.0(typescript@5.1.6) + eslint: 8.53.0 + ts-api-utils: 1.0.3(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@5.59.0: - resolution: {integrity: sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/types@6.10.0: + resolution: {integrity: sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==} + engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@5.59.0(typescript@5.1.6): - resolution: {integrity: sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/typescript-estree@6.10.0(typescript@5.1.6): + resolution: {integrity: sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/visitor-keys': 5.59.0 + '@typescript-eslint/types': 6.10.0 + '@typescript-eslint/visitor-keys': 6.10.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - tsutils: 3.21.0(typescript@5.1.6) + ts-api-utils: 1.0.3(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@5.59.0(eslint@8.38.0)(typescript@5.1.6): - resolution: {integrity: sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/utils@6.10.0(eslint@8.53.0)(typescript@5.1.6): + resolution: {integrity: sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==} + engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.38.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 5.59.0 - '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/typescript-estree': 5.59.0(typescript@5.1.6) - eslint: 8.38.0 - eslint-scope: 5.1.1 + '@typescript-eslint/scope-manager': 6.10.0 + '@typescript-eslint/types': 6.10.0 + '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.1.6) + eslint: 8.53.0 semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@5.59.0: - resolution: {integrity: sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /@typescript-eslint/visitor-keys@6.10.0: + resolution: {integrity: sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==} + engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 5.59.0 + '@typescript-eslint/types': 6.10.0 eslint-visitor-keys: 3.4.1 dev: true + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + /@vitejs/plugin-react-swc@3.0.1(vite@4.4.0): resolution: {integrity: sha512-3GQ2oruZO9j8dSHcI0MUeOZQBhjYyDQsF/pKY4Px+CJxn0M16OhgFeEzUjeuwci4zhhjoNIDE9aFNaV5GMQ09g==} peerDependencies: @@ -3240,33 +3277,8 @@ packages: engines: {node: '>=10'} dev: true - /eslint-plugin-react-hooks@4.6.0(eslint@8.38.0): - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - dependencies: - eslint: 8.38.0 - dev: true - - /eslint-plugin-react-refresh@0.3.4(eslint@8.38.0): - resolution: {integrity: sha512-E0ViBglxSQAERBp6eTj5fPgtCRtDonnbCFiVQBhf4Dto2blJRxg1dFUMdMh7N6ljTI4UwPhHwYDQ3Dyo4m6bwA==} - peerDependencies: - eslint: '>=7' - dependencies: - eslint: 8.38.0 - dev: true - - /eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true - - /eslint-scope@7.2.0: - resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: esrecurse: 4.3.0 @@ -3278,27 +3290,33 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.38.0: - resolution: {integrity: sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==} + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.53.0: + resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.38.0) - '@eslint-community/regexpp': 4.5.1 - '@eslint/eslintrc': 2.1.0 - '@eslint/js': 8.38.0 - '@humanwhocodes/config-array': 0.11.10 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.3 + '@eslint/js': 8.53.0 + '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.4 doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.0 - eslint-visitor-keys: 3.4.1 - espree: 9.6.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -3306,13 +3324,11 @@ packages: find-up: 5.0.0 glob-parent: 6.0.2 globals: 13.20.0 - grapheme-splitter: 1.0.4 + graphemer: 1.4.0 ignore: 5.2.4 - import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-sdsl: 4.4.1 js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 @@ -3321,19 +3337,18 @@ packages: natural-compare: 1.4.0 optionator: 0.9.3 strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 text-table: 0.2.0 transitivePeerDependencies: - supports-color dev: true - /espree@9.6.0: - resolution: {integrity: sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==} + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.10.0 acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.4.1 + eslint-visitor-keys: 3.4.3 dev: true /esprima@4.0.1: @@ -3356,11 +3371,6 @@ packages: estraverse: 5.3.0 dev: true - /estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -3755,6 +3765,10 @@ packages: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + /happy-dom@10.5.2: resolution: {integrity: sha512-dTA1cDcLOPIkAdykLd9Wo1k8Ly36Hh2OdKGkWEHWuAHb89KcVVRLSj1OFev7ir90xhRLSGCGrEdDvS6u9l13kg==} dependencies: @@ -4225,10 +4239,6 @@ packages: engines: {node: '>=10'} dev: true - /js-sdsl@4.4.1: - resolution: {integrity: sha512-6Gsx8R0RucyePbWqPssR8DyfuXmLBooYN5cZFZKjHGnQuaf7pEzhtpceagJxVu4LqhYY5EYA7nko3FmeHZ1KbA==} - dev: true - /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -4697,10 +4707,6 @@ packages: hasBin: true dev: true - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true - /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true @@ -5234,6 +5240,29 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true + /react-router-dom@6.18.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.11.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.18.0(react@18.2.0) + dev: true + + /react-router@6.18.0(react@18.2.0): + resolution: {integrity: sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.11.0 + react: 18.2.0 + dev: true + /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -5987,28 +6016,23 @@ packages: engines: {node: '>=8'} dev: true - /ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + /ts-api-utils@1.0.3(typescript@5.1.6): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.1.6 dev: true - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true /tslib@2.6.0: resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==} dev: true - /tsutils@3.21.0(typescript@5.1.6): - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 5.1.6 - dev: true - /tty-table@4.2.1: resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==} engines: {node: '>=8.0.0'} diff --git a/tsconfig.json b/tsconfig.json index 46c940f7..5cb0021f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,6 +32,5 @@ "exclude": [ "**/node_modules", "packages/*/dist/**/*" - // "packages/*/src/**/*.d.ts" ] } From 2f983fb5eb087d41a59f565a6e3f64e36a073460 Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Sun, 12 Nov 2023 21:09:04 +0100 Subject: [PATCH 04/21] successful build --- package.json | 2 +- packages/query/src/types.ts | 2 +- packages/query/tsconfig.json | 3 - packages/query/tsconfig.node.json | 1 - packages/react/global.d.ts | 21 + packages/react/jsx-dev-runtime.cjs | 8 + packages/react/jsx-dev-runtime/package.json | 4 + packages/react/jsx-runtime.cjs | 9 + packages/react/jsx-runtime/package.json | 4 + packages/react/package.json | 14 +- "packages/react/react.\321\201js" | 10 + packages/react/react/package.json | 4 + packages/react/runtime/package.json | 27 -- packages/react/runtime/src/auto.ts | 362 ------------------ .../{runtime/src/index.ts => src/hooks.ts} | 20 +- packages/react/src/index.ts | 6 +- packages/react/test/browser/updates.test.tsx | 213 ++++++++--- .../{runtime => }/test/useSignals.test.tsx | 4 +- packages/react/tsconfig.json | 7 + packages/react/vitest.config.ts | 43 +++ packages/react/wrap-jsx.cjs | 32 ++ packages/unified-signals/tsconfig.json | 7 +- packages/unified-signals/tsconfig.node.json | 1 - packages/utils/tsconfig.json | 3 + pnpm-lock.yaml | 299 +++++++++++++-- pnpm-workspace.yaml | 6 +- tsconfig.json | 10 +- 27 files changed, 592 insertions(+), 530 deletions(-) create mode 100644 packages/react/global.d.ts create mode 100644 packages/react/jsx-dev-runtime.cjs create mode 100644 packages/react/jsx-dev-runtime/package.json create mode 100644 packages/react/jsx-runtime.cjs create mode 100644 packages/react/jsx-runtime/package.json create mode 100644 "packages/react/react.\321\201js" create mode 100644 packages/react/react/package.json delete mode 100644 packages/react/runtime/package.json delete mode 100644 packages/react/runtime/src/auto.ts rename packages/react/{runtime/src/index.ts => src/hooks.ts} (91%) rename packages/react/{runtime => }/test/useSignals.test.tsx (99%) create mode 100644 packages/react/tsconfig.json create mode 100644 packages/react/wrap-jsx.cjs diff --git a/package.json b/package.json index 93fa469f..acf0e514 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "build:with-apps": "turbo run build", "watch": "turbo run watch --parallel", "test": "turbo run test --parallel", - "eslint": "eslint --ext .ts,.tsx . --cache --cache-location=node_modules/.eslintcache", + "eslint": "eslint --ext .ts,.tsx,.js,.jsx,.cjs,.mjs . --cache --cache-location=node_modules/.eslintcache", "lint": "turbo run lint", "changeset": "changeset", "release": "pnpm build && changeset publish" diff --git a/packages/query/src/types.ts b/packages/query/src/types.ts index 95982fa2..4634585c 100644 --- a/packages/query/src/types.ts +++ b/packages/query/src/types.ts @@ -1,4 +1,4 @@ -import { FlatStore, ReadonlyFlatStore } from "@preact-signals/utils/flat-store"; +import type { FlatStore, ReadonlyFlatStore } from "@preact-signals/utils"; import type { InfiniteQueryObserverOptions, InfiniteQueryObserverResult, diff --git a/packages/query/tsconfig.json b/packages/query/tsconfig.json index baf701fd..6f104e40 100644 --- a/packages/query/tsconfig.json +++ b/packages/query/tsconfig.json @@ -13,9 +13,6 @@ "exclude": ["**/node_modules", "./dist/**/*", "./*.ts", "**/__tests__/**"], "references": [ - { - "path": "./tsconfig.node.json" - }, { "path": "../utils" }, diff --git a/packages/query/tsconfig.node.json b/packages/query/tsconfig.node.json index fa78fa1d..d2537ba6 100644 --- a/packages/query/tsconfig.node.json +++ b/packages/query/tsconfig.node.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "composite": true, "module": "ESNext", "moduleResolution": "Node", "rootDir": "./", diff --git a/packages/react/global.d.ts b/packages/react/global.d.ts new file mode 100644 index 00000000..9e4a0967 --- /dev/null +++ b/packages/react/global.d.ts @@ -0,0 +1,21 @@ +type _JSXFunction = ( + type: React.ComponentType, + props: Record, + key: React.Key, + isStaticChildren: boolean, + __source: unknown, + __self: unknown +) => React.ElementType; +declare module "react/jsx-runtime" { + export type JSXFunction = _JSXFunction; + export const jsx: _JSXFunction; + export const jsxs: _JSXFunction; + export const Fragment: React.ComponentType; +} + +declare module "react/jsx-dev-runtime" { + export type JSXFunction = _JSXFunction; + export const jsxDEV: _JSXFunction; + + export const Fragment: React.ComponentType; +} diff --git a/packages/react/jsx-dev-runtime.cjs b/packages/react/jsx-dev-runtime.cjs new file mode 100644 index 00000000..969302f4 --- /dev/null +++ b/packages/react/jsx-dev-runtime.cjs @@ -0,0 +1,8 @@ +// @ts-check +const { jsxDEV: _jsxDEV, Fragment } = require("react/jsx-dev-runtime"); +const wrapJSX = require("./wrap-jsx.cjs"); + +module.exports = /** @type {import('react/jsx-dev-runtime')} */ ({ + Fragment, + jsxDEV: wrapJSX(_jsxDEV), +}); diff --git a/packages/react/jsx-dev-runtime/package.json b/packages/react/jsx-dev-runtime/package.json new file mode 100644 index 00000000..3f40a247 --- /dev/null +++ b/packages/react/jsx-dev-runtime/package.json @@ -0,0 +1,4 @@ +{ + "main": "../jsx-dev-runtime.cjs", + "type": "commonjs" +} diff --git a/packages/react/jsx-runtime.cjs b/packages/react/jsx-runtime.cjs new file mode 100644 index 00000000..92f28f42 --- /dev/null +++ b/packages/react/jsx-runtime.cjs @@ -0,0 +1,9 @@ +// @ts-check +const { jsxs: _jsxs, jsx: _jsx, Fragment } = require("react/jsx-runtime"); +const wrapJSX = require("./wrap-jsx.cjs"); + +module.exports = /** @type {import('react/jsx-runtime')} */ ({ + Fragment, + jsxs: wrapJSX(_jsxs), + jsx: wrapJSX(_jsx), +}); diff --git a/packages/react/jsx-runtime/package.json b/packages/react/jsx-runtime/package.json new file mode 100644 index 00000000..e8bbf2f7 --- /dev/null +++ b/packages/react/jsx-runtime/package.json @@ -0,0 +1,4 @@ +{ + "main": "../jsx-runtime.cjs", + "type": "commonjs" +} diff --git a/packages/react/package.json b/packages/react/package.json index 722b5fe2..cccf5079 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,5 +1,5 @@ { - "name": "@preact-signals/react", + "name": "@preact-signals/safe-react", "version": "0.0.1", "license": "MIT", "description": "Manage state with style in React", @@ -31,13 +31,9 @@ "import": "./dist/signals.mjs", "require": "./dist/signals.js" }, - "./runtime": { - "types": "./runtime/dist/index.d.ts", - "browser": "./runtime/dist/runtime.module.js", - "import": "./runtime/dist/runtime.mjs", - "require": "./runtime/dist/runtime.js" - }, - "./runtime/package.json": "./runtime/package.json" + "./react": "./react.сjs", + "./jsx-runtime": "./jsx-runtime.cjs", + "./jsx-dev-runtime": "./jsx-dev-runtime.cjs" }, "mangle": "../../mangle.json", "files": [ @@ -61,9 +57,11 @@ "react": "^16.14.0 || 17.x || 18.x" }, "devDependencies": { + "@preact/signals-react-transform": "^0.1.0", "@types/react": "^18.0.18", "@types/react-dom": "^18.0.6", "@types/use-sync-external-store": "^0.0.3", + "@vitejs/plugin-react": "^4.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.9.0" diff --git "a/packages/react/react.\321\201js" "b/packages/react/react.\321\201js" new file mode 100644 index 00000000..7c0a181a --- /dev/null +++ "b/packages/react/react.\321\201js" @@ -0,0 +1,10 @@ +// @ts-check +const React = require("react"); +const wrapJsx = require("./wrapJsx"); + +// didn't wrapper React.createFactory possibly not needed +module.exports = { + ...React, + // @ts-expect-error + createElement: wrapJsx(React.createElement), +}; diff --git a/packages/react/react/package.json b/packages/react/react/package.json new file mode 100644 index 00000000..c4eced1f --- /dev/null +++ b/packages/react/react/package.json @@ -0,0 +1,4 @@ +{ + "main": "../react.сjs", + "type": "commonjs" +} diff --git a/packages/react/runtime/package.json b/packages/react/runtime/package.json deleted file mode 100644 index a394d186..00000000 --- a/packages/react/runtime/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "@preact-signals/react-runtime", - "description": "Sub package for @preact/signals-react that contains the pure runtime functions", - "private": true, - "amdName": "reactSignalsRuntime", - "main": "dist/runtime.js", - "module": "dist/runtime.module.js", - "unpkg": "dist/runtime.min.js", - "types": "dist/index.d.ts", - "source": "src/index.ts", - "mangle": "../../../mangle.json", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "browser": "./dist/runtime.module.js", - "import": "./dist/runtime.mjs", - "require": "./dist/runtime.js" - } - }, - "dependencies": { - "@preact/signals-core": "workspace:^1.3.0", - "use-sync-external-store": "^1.2.0" - }, - "peerDependencies": { - "react": "^16.14.0 || 17.x || 18.x" - } -} diff --git a/packages/react/runtime/src/auto.ts b/packages/react/runtime/src/auto.ts deleted file mode 100644 index b5d505ec..00000000 --- a/packages/react/runtime/src/auto.ts +++ /dev/null @@ -1,362 +0,0 @@ -import { - // @ts-ignore-next-line - // eslint-disable-next-line @typescript-eslint/no-unused-vars - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as ReactInternals, -} from "react"; -import React from "react"; -import jsxRuntime from "react/jsx-runtime"; -import jsxRuntimeDev from "react/jsx-dev-runtime"; -import { EffectStore, useSignals, wrapJsx } from "./index"; - -export interface ReactDispatcher { - useRef: typeof React.useRef; - useCallback: typeof React.useCallback; - useReducer: typeof React.useReducer; - useSyncExternalStore: typeof React.useSyncExternalStore; - useEffect: typeof React.useEffect; - useImperativeHandle: typeof React.useImperativeHandle; -} - -// In order for signals to work in React, we need to observe what signals a -// component uses while rendering. To do this, we need to know when a component -// is rendering. To do this, we watch the transition of the -// ReactCurrentDispatcher to know when a component is rerendering. -// -// To track when we are entering and exiting a component render (i.e. before and -// after React renders a component), we track how the dispatcher changes. -// Outside of a component rendering, the dispatcher is set to an instance that -// errors or warns when any hooks are called. This behavior is prevents hooks -// from being used outside of components. Right before React renders a -// component, the dispatcher is set to an instance that doesn't warn or error -// and contains the implementations of all hooks. Right after React finishes -// rendering a component, the dispatcher is set to the erroring one again. This -// erroring dispatcher is called the `ContextOnlyDispatcher` in React's source. -// -// So, we watch the getter and setter on `ReactCurrentDispatcher.current` to -// monitor the changes to the current ReactDispatcher. When the dispatcher -// changes from the ContextOnlyDispatcher to a "valid" dispatcher, we assume we -// are entering a component render. At this point, we setup our -// auto-subscriptions for any signals used in the component. We do this by -// creating an Signal effect and manually starting the Signal effect. We use -// `useSyncExternalStore` to trigger rerenders on the component when any signals -// it uses changes. -// -// When the dispatcher changes from a valid dispatcher back to the -// ContextOnlyDispatcher, we assume we are exiting a component render. At this -// point we stop the effect. -// -// Some additional complexities to be aware of: -// - If a component calls `setState` while rendering, React will re-render the -// component immediately. Before triggering the re-render, React will change -// the dispatcher to the HooksDispatcherOnRerender. When we transition to this -// rerendering adapter, we need to re-trigger our hooks to keep the order of -// hooks the same for every render of a component. -// -// - In development, useReducer, useState, and useMemo change the dispatcher to -// a different warning dispatcher (not ContextOnlyDispatcher) before invoking -// the reducer and resets it right after. -// -// The useSyncExternalStore shim will use some of these hooks when we invoke -// it while entering a component render. We need to prevent this dispatcher -// change caused by these hooks from re-triggering our entering logic (it -// would cause an infinite loop if we did not). We do this by using a lock to -// prevent the setter from running while we are in the setter. -// -// When a Component's function body invokes useReducer, useState, or useMemo, -// this change in dispatcher should not signal that we are entering or exiting -// a component render. We ignore this change by detecting these dispatchers as -// different from ContextOnlyDispatcher and other valid dispatchers. -// -// - The `use` hook will change the dispatcher to from a valid update dispatcher -// to a valid mount dispatcher in some cases. Similarly to useReducer -// mentioned above, we should not signal that we are exiting a component -// during this change. Because these other valid dispatchers do not pass the -// ContextOnlyDispatcher check, they do not affect our logic. -// -// - When server rendering, React does not change the dispatcher before and -// after each component render. It sets it once for before the first render -// and once for after the last render. This means that we will not be able to -// detect when we are entering or exiting a component render. This is fine -// because we don't need to detect this for server rendering. A component -// can't trigger async rerenders in SSR so we don't need to track signals. -// -// If a component updates a signal value while rendering during SSR, we will -// not rerender the component because the signal value will synchronously -// change so all reads of the signal further down the tree will see the new -// value. - -/* -Below is a state machine definition for transitions between the various -dispatchers in React's prod build. (It does not include dev time warning -dispatchers which are just always ignored). - -ENTER and EXIT suffixes indicates whether this ReactCurrentDispatcher transition -signals we are entering or exiting a component render, or if it doesn't signal a -change in the component rendering lifecyle (NOOP). - -```js -// Paste this into https://stately.ai/viz to visualize the state machine. -import { createMachine } from "xstate"; - -// ENTER, EXIT, NOOP suffixes indicates whether this ReactCurrentDispatcher -// transition signals we are entering or exiting a component render, or -// if it doesn't signal a change in the component rendering lifecyle (NOOP). - -const dispatcherMachinePROD = createMachine({ - id: "ReactCurrentDispatcher_PROD", - initial: "null", - states: { - null: { - on: { - pushDispatcher: "ContextOnlyDispatcher", - }, - }, - ContextOnlyDispatcher: { - on: { - renderWithHooks_Mount_ENTER: "HooksDispatcherOnMount", - renderWithHooks_Update_ENTER: "HooksDispatcherOnUpdate", - pushDispatcher_NOOP: "ContextOnlyDispatcher", - popDispatcher_NOOP: "ContextOnlyDispatcher", - }, - }, - HooksDispatcherOnMount: { - on: { - renderWithHooksAgain_ENTER: "HooksDispatcherOnRerender", - resetHooksAfterThrow_EXIT: "ContextOnlyDispatcher", - finishRenderingHooks_EXIT: "ContextOnlyDispatcher", - }, - }, - HooksDispatcherOnUpdate: { - on: { - renderWithHooksAgain_ENTER: "HooksDispatcherOnRerender", - resetHooksAfterThrow_EXIT: "ContextOnlyDispatcher", - finishRenderingHooks_EXIT: "ContextOnlyDispatcher", - use_ResumeSuspensedMount_NOOP: "HooksDispatcherOnMount", - }, - }, - HooksDispatcherOnRerender: { - on: { - renderWithHooksAgain_ENTER: "HooksDispatcherOnRerender", - resetHooksAfterThrow_EXIT: "ContextOnlyDispatcher", - finishRenderingHooks_EXIT: "ContextOnlyDispatcher", - }, - }, - }, -}); -``` -*/ - -let store: EffectStore | null = null; -let lock = false; -let currentDispatcher: ReactDispatcher | null = null; - -function installCurrentDispatcherHook() { - Object.defineProperty(ReactInternals.ReactCurrentDispatcher, "current", { - get() { - return currentDispatcher; - }, - set(nextDispatcher: ReactDispatcher) { - if (lock) { - currentDispatcher = nextDispatcher; - return; - } - - const currentDispatcherType = getDispatcherType(currentDispatcher); - const nextDispatcherType = getDispatcherType(nextDispatcher); - - // Update the current dispatcher now so the hooks inside of the - // useSyncExternalStore shim get the right dispatcher. - currentDispatcher = nextDispatcher; - if ( - isEnteringComponentRender(currentDispatcherType, nextDispatcherType) - ) { - lock = true; - store = useSignals(); - lock = false; - } else if ( - isExitingComponentRender(currentDispatcherType, nextDispatcherType) - ) { - store?.f(); - store = null; - } - }, - }); -} - -type DispatcherType = number; -const ContextOnlyDispatcherType = 1 << 0; -const WarningDispatcherType = 1 << 1; -const MountDispatcherType = 1 << 2; -const UpdateDispatcherType = 1 << 3; -const RerenderDispatcherType = 1 << 4; -const ServerDispatcherType = 1 << 5; -const BrowserClientDispatcherType = - MountDispatcherType | UpdateDispatcherType | RerenderDispatcherType; - -const dispatcherTypeCache = new Map(); -function getDispatcherType(dispatcher: ReactDispatcher | null): DispatcherType { - // Treat null the same as the ContextOnlyDispatcher. - if (!dispatcher) return ContextOnlyDispatcherType; - - const cached = dispatcherTypeCache.get(dispatcher); - if (cached !== undefined) return cached; - - // The ContextOnlyDispatcher sets all the hook implementations to a function - // that takes no arguments and throws and error. This dispatcher is the only - // dispatcher where useReducer and useEffect will have the same - // implementation. - let type: DispatcherType; - const useCallbackImpl = dispatcher.useCallback.toString(); - if (dispatcher.useReducer === dispatcher.useEffect) { - type = ContextOnlyDispatcherType; - - // @ts-expect-error When server rendering, useEffect and useImperativeHandle - // are both set to noop functions and so have the same implementation. - } else if (dispatcher.useEffect === dispatcher.useImperativeHandle) { - type = ServerDispatcherType; - } else if (/Invalid/.test(useCallbackImpl)) { - // We first check for warning dispatchers because they would also pass some - // of the checks below. - type = WarningDispatcherType; - } else if ( - // The development mount dispatcher invokes a function called - // `mountCallback` whereas the development update/re-render dispatcher - // invokes a function called `updateCallback`. Use that difference to - // determine if we are in a mount or update-like dispatcher in development. - // The production mount dispatcher defines an array of the form [callback, - // deps] whereas update/re-render dispatchers read the array using array - // indices (e.g. `[0]` and `[1]`). Use those differences to determine if we - // are in a mount or update-like dispatcher in production. - /updateCallback/.test(useCallbackImpl) || - (/\[0\]/.test(useCallbackImpl) && /\[1\]/.test(useCallbackImpl)) - ) { - // The update and rerender dispatchers have different implementations for - // useReducer. We'll check it's implementation to determine if this is the - // rerender or update dispatcher. - let useReducerImpl = dispatcher.useReducer.toString(); - if ( - // The development rerender dispatcher invokes a function called - // `rerenderReducer` whereas the update dispatcher invokes a function - // called `updateReducer`. The production rerender dispatcher returns an - // array of the form `[state, dispatch]` whereas the update dispatcher - // returns an array of `[fiber.memoizedState, dispatch]` so we check the - // return statement in the implementation of useReducer to differentiate - // between the two. - /rerenderReducer/.test(useReducerImpl) || - /return\s*\[\w+,/.test(useReducerImpl) - ) { - type = RerenderDispatcherType; - } else { - type = UpdateDispatcherType; - } - } else { - type = MountDispatcherType; - } - - dispatcherTypeCache.set(dispatcher, type); - return type; -} - -function isEnteringComponentRender( - currentDispatcherType: DispatcherType, - nextDispatcherType: DispatcherType -): boolean { - if ( - currentDispatcherType & ContextOnlyDispatcherType && - nextDispatcherType & BrowserClientDispatcherType - ) { - // ## Mount or update (ContextOnlyDispatcher -> ValidDispatcher (Mount or Update)) - // - // If the current dispatcher is the ContextOnlyDispatcher and the next - // dispatcher is a valid dispatcher, we are entering a component render. - return true; - } else if ( - currentDispatcherType & WarningDispatcherType || - nextDispatcherType & WarningDispatcherType - ) { - // ## Warning dispatcher - // - // If the current dispatcher or next dispatcher is an warning dispatcher, - // we are not entering a component render. The current warning dispatchers - // are used to warn when hooks are nested improperly and do not indicate - // entering a new component render. - return false; - } else if (nextDispatcherType & RerenderDispatcherType) { - // Any transition into the rerender dispatcher is the beginning of a - // component render, so we should invoke our hooks. Details below. - // - // ## In-place rerendering (e.g. Mount -> Rerender) - // - // If we are transitioning from the mount, update, or rerender dispatcher to - // the rerender dispatcher (e.g. HooksDispatcherOnMount to - // HooksDispatcherOnRerender), then this component is rerendering due to - // calling setState inside of its function body. We are re-entering a - // component's render method and so we should re-invoke our hooks. - return true; - } else { - // ## Resuming suspended mount edge case (Update -> Mount) - // - // If we are transitioning from the update dispatcher to the mount - // dispatcher, then this component is using the `use` hook and is resuming - // from a mount. We should not re-invoke our hooks in this situation since - // we are not entering a new component render, but instead continuing a - // previous render. - // - // ## Other transitions - // - // For example, Mount -> Mount, Update -> Update, Mount -> Update, any - // transition in and out of invalid dispatchers. - // - // There is no known transition for the following transitions so we default - // to not triggering a re-enter of the component. - // - HooksDispatcherOnMount -> HooksDispatcherOnMount - // - HooksDispatcherOnMount -> HooksDispatcherOnUpdate - // - HooksDispatcherOnUpdate -> HooksDispatcherOnUpdate - return false; - } -} - -/** - * We are exiting a component render if the current dispatcher is a valid - * dispatcher and the next dispatcher is the ContextOnlyDispatcher. - */ -function isExitingComponentRender( - currentDispatcherType: DispatcherType, - nextDispatcherType: DispatcherType -): boolean { - return Boolean( - currentDispatcherType & BrowserClientDispatcherType && - nextDispatcherType & ContextOnlyDispatcherType - ); -} - -interface JsxRuntimeModule { - jsx?(type: any, ...rest: any[]): unknown; - jsxs?(type: any, ...rest: any[]): unknown; - jsxDEV?(type: any, ...rest: any[]): unknown; -} - -export function installJSXHooks() { - const JsxPro: JsxRuntimeModule = jsxRuntime; - const JsxDev: JsxRuntimeModule = jsxRuntimeDev; - - /** - * createElement _may_ be called by jsx runtime as a fallback in certain cases, - * so we need to wrap it regardless. - * - * The jsx exports depend on the `NODE_ENV` var to ensure the users' bundler doesn't - * include both, so one of them will be set with `undefined` values. - */ - React.createElement = wrapJsx(React.createElement); - JsxDev.jsx && /* */ (JsxDev.jsx = wrapJsx(JsxDev.jsx)); - JsxPro.jsx && /* */ (JsxPro.jsx = wrapJsx(JsxPro.jsx)); - JsxDev.jsxs && /* */ (JsxDev.jsxs = wrapJsx(JsxDev.jsxs)); - JsxPro.jsxs && /* */ (JsxPro.jsxs = wrapJsx(JsxPro.jsxs)); - JsxDev.jsxDEV && /**/ (JsxDev.jsxDEV = wrapJsx(JsxDev.jsxDEV)); - JsxPro.jsxDEV && /**/ (JsxPro.jsxDEV = wrapJsx(JsxPro.jsxDEV)); -} - -export function installAutoSignalTracking() { - installCurrentDispatcherHook(); - installJSXHooks(); -} diff --git a/packages/react/runtime/src/index.ts b/packages/react/src/hooks.ts similarity index 91% rename from packages/react/runtime/src/index.ts rename to packages/react/src/hooks.ts index 1ba168fb..38da97f6 100644 --- a/packages/react/runtime/src/index.ts +++ b/packages/react/src/hooks.ts @@ -2,28 +2,9 @@ import { signal, computed, effect, Signal } from "@preact/signals-core"; import { useRef, useMemo, useEffect } from "react"; import { useSyncExternalStore } from "use-sync-external-store/shim/index.js"; -export { installAutoSignalTracking } from "./auto"; - const Empty = [] as const; const ReactElemType = Symbol.for("react.element"); // https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15 -export function wrapJsx(jsx: T): T { - if (typeof jsx !== "function") return jsx; - - return function (type: any, props: any, ...rest: any[]) { - if (typeof type === "string" && props) { - for (let i in props) { - let v = props[i]; - if (i !== "children" && v instanceof Signal) { - props[i] = v.value; - } - } - } - - return jsx.call(jsx, type, props, ...rest); - } as any as T; -} - const symDispose: unique symbol = (Symbol as any).dispose || Symbol.for("Symbol.dispose"); @@ -124,6 +105,7 @@ let finalCleanup: Promise | undefined; const _queueMicroTask = Promise.prototype.then.bind(Promise.resolve()); /** + * @description this hook is for `@preact/signals-react-transform` * Custom hook to create the effect to track signals used during render and * subscribe to changes to rerender the component when the signals change. */ diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 7eb15845..912d4fa7 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -8,8 +8,7 @@ import { untracked, } from "@preact/signals-core"; import type { ReactElement } from "react"; -import { useSignal, useComputed, useSignalEffect } from "../runtime/src"; -import { installAutoSignalTracking } from "../runtime/src/auto"; +import { useSignal, useComputed, useSignalEffect, useSignals } from "./hooks"; export { signal, @@ -22,6 +21,7 @@ export { useComputed, useSignalEffect, untracked, + useSignals, }; declare module "@preact/signals-core" { @@ -29,5 +29,3 @@ declare module "@preact/signals-core" { // eslint-disable-next-line @typescript-eslint/no-empty-interface interface Signal extends ReactElement {} } - -installAutoSignalTracking(); diff --git a/packages/react/test/browser/updates.test.tsx b/packages/react/test/browser/updates.test.tsx index e83a3711..574b3c74 100644 --- a/packages/react/test/browser/updates.test.tsx +++ b/packages/react/test/browser/updates.test.tsx @@ -144,10 +144,14 @@ describe("@preact/signals-react updating", () => { describe("Component bindings", () => { it("should subscribe to signals", async () => { - const sig = signal("foo"); + const _sig = signal("foo"); + /** + * + * @trackSignals + **/ function App() { - const value = sig.value; + const value = _sig.value; return

{value}

; } @@ -155,7 +159,7 @@ describe("@preact/signals-react updating", () => { expect(scratch.textContent).to.equal("foo"); await act(() => { - sig.value = "bar"; + _sig.value = "bar"; }); expect(scratch.textContent).to.equal("bar"); }); @@ -196,6 +200,11 @@ describe("@preact/signals-react updating", () => { it("should subscribe to signals passed as props to DOM elements", async () => { const className = signal("foo"); + + /** + * + * @trackSignals + **/ function App() { // @ts-expect-error React types don't allow signals on DOM elements :/ return
; @@ -237,6 +246,10 @@ describe("@preact/signals-react updating", () => { it("should not subscribe to child signals", async () => { const sig = signal("foo"); + /** + * + * @trackSignals + **/ function Child() { const value = sig.value; return

{value}

; @@ -259,11 +272,19 @@ describe("@preact/signals-react updating", () => { it("should update memo'ed component via signals", async () => { const sig = signal("foo"); + /** + * + * @trackSignals + **/ function Inner() { const value = sig.value; return

{value}

; } + /** + * + * @trackSignals + **/ function App() { sig.value; return useMemo(() => , []); @@ -281,9 +302,15 @@ describe("@preact/signals-react updating", () => { it("should update forwardRef'ed component via signals", async () => { const sig = signal("foo"); - const Inner = forwardRef(() => { - return

{sig.value}

; - }); + const Inner = forwardRef( + /** + * + * @trackSignals + **/ + () => { + return

{sig.value}

; + } + ); function App() { return ; @@ -301,6 +328,10 @@ describe("@preact/signals-react updating", () => { it("should consistently rerender in strict mode", async () => { const sig = signal(-1); + /** + * + * @trackSignals + **/ const Test = () =>

{sig.value}

; const App = () => ( @@ -322,7 +353,13 @@ describe("@preact/signals-react updating", () => { it("should consistently rerender in strict mode (with memo)", async () => { const sig = signal(-1); - const Test = memo(() =>

{sig.value}

); + const Test = memo( + /** + * + * @trackSignals + **/ + () =>

{sig.value}

+ ); const App = () => ( @@ -343,6 +380,10 @@ describe("@preact/signals-react updating", () => { it.fails("should render static markup of a component", async () => { const count = signal(0); + /** + * + * @trackSignals + **/ const Test = () => { return (
@@ -369,6 +410,10 @@ describe("@preact/signals-react updating", () => {
       const count = signal(0);
 
       let increment: () => void;
+      /**
+       *
+       * @trackSignals
+       **/
       const Test = () => {
         const [state, dispatch] = useReducer(
           (state: number, action: number) => {
@@ -515,36 +560,60 @@ describe("@preact/signals-react updating", () => {
       }
 
       // Manually read signal value below so we can watch whether components rerender
-      const Origin = spyOn(function Origin() {
-        const origin = useContext(URLModelContext).origin;
-        return {origin.value};
-      });
+      const Origin = spyOn(
+        /**
+         *
+         * @trackSignals
+         **/
+        function Origin() {
+          const origin = useContext(URLModelContext).origin;
+          return {origin.value};
+        }
+      );
 
-      const Pathname = spyOn(function Pathname() {
-        const pathname = useContext(URLModelContext).pathname;
-        return {pathname.value};
-      });
+      const Pathname = spyOn(
+        /**
+         *
+         * @trackSignals
+         **/
+        function Pathname() {
+          const pathname = useContext(URLModelContext).pathname;
+          return {pathname.value};
+        }
+      );
 
-      const Search = spyOn(function Search() {
-        const search = useContext(URLModelContext).search;
-        return {search.value};
-      });
+      const Search = spyOn(
+        /**
+         *
+         * @trackSignals
+         **/
+        function Search() {
+          const search = useContext(URLModelContext).search;
+          return {search.value};
+        }
+      );
 
       // Never reads signal value during render so should never rerender
-      const UpdateURL = spyOn(function UpdateURL() {
-        const update = useContext(URLModelContext).update;
-        return (
-          
-        );
-      });
+      const UpdateURL = spyOn(
+        /**
+         *
+         * @trackSignals
+         **/
+        function UpdateURL() {
+          const update = useContext(URLModelContext).update;
+          return (
+            
+          );
+        }
+      );
 
       interface URLModel {
         origin: ReadonlySignal;
@@ -555,29 +624,35 @@ describe("@preact/signals-react updating", () => {
 
       // Also never reads signal value during render so should never rerender
       const URLModelContext = createContext(null as any);
-      const URLModelProvider = spyOn(function SignalProvider({ children }) {
-        const url = useSignal(new URL("https://domain.com/test?a=1"));
-        const modelRef = useRef(null);
-
-        if (modelRef.current == null) {
-          modelRef.current = {
-            origin: computed(() => url.value.origin),
-            pathname: computed(() => url.value.pathname),
-            search: computed(() => url.value.search),
-            update(updater) {
-              const newURL = new URL(url.value);
-              updater(newURL);
-              url.value = newURL;
-            },
-          };
-        }
+      const URLModelProvider = spyOn(
+        /**
+         *
+         * @trackSignals
+         **/
+        function SignalProvider({ children }) {
+          const url = useSignal(new URL("https://domain.com/test?a=1"));
+          const modelRef = useRef(null);
+
+          if (modelRef.current == null) {
+            modelRef.current = {
+              origin: computed(() => url.value.origin),
+              pathname: computed(() => url.value.pathname),
+              search: computed(() => url.value.search),
+              update(updater) {
+                const newURL = new URL(url.value);
+                updater(newURL);
+                url.value = newURL;
+              },
+            };
+          }
 
-        return (
-          
-            {children}
-          
-        );
-      });
+          return (
+            
+              {children}
+            
+          );
+        }
+      );
 
       function App() {
         return (
@@ -616,11 +691,19 @@ describe("@preact/signals-react updating", () => {
       const childSpy = vi.fn();
       const parentSpy = vi.fn();
 
+      /**
+       *
+       * @trackSignals
+       **/
       function Child({ num }: { num: Signal }) {
         childSpy();
         return 

{num.value}

; } + /** + * + * @trackSignals + **/ function Parent({ num }: { num: Signal }) { parentSpy(); const sig2 = useComputed(() => num.value + 1); @@ -645,6 +728,10 @@ describe("@preact/signals-react updating", () => { const renderComputed = signal(true); const renderSpy = vi.fn(); + /** + * + * @trackSignals + **/ function App() { renderSpy(); const computed = useComputed(() => computedDep.value + 1); @@ -676,6 +763,10 @@ describe("@preact/signals-react updating", () => { describe("useSignal()", () => { it("should create a signal from a primitive value", async () => { + /** + * + * @trackSignals + **/ function App() { const count = useSignal(1); return ( @@ -703,6 +794,10 @@ describe("@preact/signals-react updating", () => { const spy = vi.fn(); let count = 0; + /** + * + * @trackSignals + **/ function App() { useSignalEffect(() => spy( @@ -745,6 +840,10 @@ describe("@preact/signals-react updating", () => { const cleanup = vi.fn(); let count = 0; + /** + * + * @trackSignals + **/ function App() { useSignalEffect(() => { const id = ref.current!.getAttribute("data-render-id"); @@ -788,6 +887,10 @@ describe("@preact/signals-react updating", () => { const spy = vi.fn(); const cleanup = vi.fn(); + /** + * + * @trackSignals + **/ function App() { useSignalEffect(() => { const value = sig.value; diff --git a/packages/react/runtime/test/useSignals.test.tsx b/packages/react/test/useSignals.test.tsx similarity index 99% rename from packages/react/runtime/test/useSignals.test.tsx rename to packages/react/test/useSignals.test.tsx index b8de6c91..51d78849 100644 --- a/packages/react/runtime/test/useSignals.test.tsx +++ b/packages/react/test/useSignals.test.tsx @@ -1,6 +1,6 @@ import React, { Fragment } from "react"; import { Signal, signal, batch } from "@preact/signals-core"; -import { useSignals } from "../src"; +import { useSignals } from "../src/hooks"; import { describe, expect, afterEach, beforeEach, it, vi } from "vitest"; import { Root, @@ -9,7 +9,7 @@ import { checkHangingAct, getConsoleErrorSpy, checkConsoleErrorLogs, -} from "../../test/shared/utils"; +} from "./shared/utils"; describe("useSignals", () => { let scratch: HTMLDivElement; diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json new file mode 100644 index 00000000..80419b57 --- /dev/null +++ b/packages/react/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src/**/*", "package.json", "./*.cjs"], + "compilerOptions": { + "types": ["./global.d.ts"] + } +} diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts index 6fada3ad..34291742 100644 --- a/packages/react/vitest.config.ts +++ b/packages/react/vitest.config.ts @@ -1,10 +1,53 @@ import { defineConfig } from "vitest/config"; +import react from "@vitejs/plugin-react"; +import packageJson from "./package.json"; export default defineConfig({ + esbuild: { + jsx: "preserve", + }, test: { environment: "happy-dom", setupFiles: "./setupVitest.ts", + + alias: [ + { + find: /^react$/, + replacement: "./react.js", + }, + { + find: "@preact-signals/react/jsx-runtime", + replacement: packageJson.exports["./jsx-runtime"], + }, + { + find: "@preact-signals/react/jsx-dev-runtime", + replacement: packageJson.exports["./jsx-dev-runtime"], + }, + { + find: "@preact-signals/react", + replacement: "./src/index.ts", + }, + { + find: "@preact/signals-react", + replacement: "./src/index.ts", + }, + ], }, + plugins: [ + react({ + jsxImportSource: "@preact-signals/react", + babel: { + plugins: [ + [ + "module:@preact/signals-react-transform", + { + importSource: "@preact-signals/react", + }, + ], + ], + }, + }), + ], define: { __DEV__: true, }, diff --git a/packages/react/wrap-jsx.cjs b/packages/react/wrap-jsx.cjs new file mode 100644 index 00000000..5de68a7f --- /dev/null +++ b/packages/react/wrap-jsx.cjs @@ -0,0 +1,32 @@ +// @ts-check + +// for some reason if using require() here, it duplicates signals +const preactSignalSymbol = Symbol.for("preact-signals"); + +/** + * + * @param {*} value + * @returns {value is import('@preact/signals-core').Signal} + */ +function isSignal(value) { + return !!value && value?.brand === preactSignalSymbol; +} + +/** + * @param {import('react/jsx-runtime').JSXFunction} jsx + * @returns {import('react/jsx-runtime').JSXFunction} + */ +module.exports = function wrapJsx(jsx) { + return function (type, props, ...rest) { + if (typeof type === "string" && props) { + for (let i in props) { + let v = props[i]; + if (i !== "children" && isSignal(v)) { + props[i] = v.value; + } + } + } + + return jsx.call(jsx, type, props, ...rest); + }; +}; diff --git a/packages/unified-signals/tsconfig.json b/packages/unified-signals/tsconfig.json index 55799146..e16dc0b8 100644 --- a/packages/unified-signals/tsconfig.json +++ b/packages/unified-signals/tsconfig.json @@ -13,10 +13,5 @@ "vitest.config.ts", "**/*.test.*" ], - "extends": "../../tsconfig.json", - "references": [ - { - "path": "./tsconfig.node.json" - } - ] + "extends": "../../tsconfig.json" } diff --git a/packages/unified-signals/tsconfig.node.json b/packages/unified-signals/tsconfig.node.json index fa78fa1d..d2537ba6 100644 --- a/packages/unified-signals/tsconfig.node.json +++ b/packages/unified-signals/tsconfig.node.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "composite": true, "module": "ESNext", "moduleResolution": "Node", "rootDir": "./", diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index 9301c937..1ba78db7 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -1,5 +1,7 @@ { "compilerOptions": { + "noEmit": false, + "emitDeclarationOnly": true, "rootDir": "./src", "tsBuildInfoFile": "./dist/.tsbuildinfo", "outDir": "./dist/types", @@ -8,6 +10,7 @@ "exclude": [ "**/dist/**", "**/node_modules/**", + "rollup.config.mjs", "vitest.config.ts", "setupVitest.ts", "**/*.test.*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bdd9d1ac..297e3d5d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,7 +47,7 @@ importers: devDependencies: '@preact/preset-vite': specifier: ^2.5.0 - version: 2.5.0(@babel/core@7.22.9)(preact@10.15.1)(vite@4.4.0) + version: 2.5.0(@babel/core@7.23.3)(preact@10.15.1)(vite@4.4.0) autoprefixer: specifier: ^10.4.14 version: 10.4.14(postcss@8.4.27) @@ -223,6 +223,9 @@ importers: specifier: ^1.2.0 version: 1.2.0(react@18.2.0) devDependencies: + '@preact/signals-react-transform': + specifier: ^0.1.0 + version: 0.1.0(@babel/core@7.23.3)(react@18.2.0) '@types/react': specifier: ^18.0.18 version: 18.2.15 @@ -232,6 +235,9 @@ importers: '@types/use-sync-external-store': specifier: ^0.0.3 version: 0.0.3 + '@vitejs/plugin-react': + specifier: ^4.1.1 + version: 4.1.1(vite@4.4.8) react: specifier: ^18.2.0 version: 18.2.0 @@ -398,7 +404,7 @@ packages: '@babel/parser': 7.22.7 '@babel/template': 7.22.5 '@babel/traverse': 7.22.8 - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 convert-source-map: 1.9.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -408,11 +414,44 @@ packages: - supports-color dev: true + /@babel/core@7.23.3: + resolution: {integrity: sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.3 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.3) + '@babel/helpers': 7.23.2 + '@babel/parser': 7.23.3 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.3 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/generator@7.22.9: resolution: {integrity: sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + jsesc: 2.5.2 + dev: true + + /@babel/generator@7.23.3: + resolution: {integrity: sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.3 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 @@ -422,7 +461,18 @@ packages: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 + dev: true + + /@babel/helper-compilation-targets@7.22.15: + resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/helper-validator-option': 7.22.15 + browserslist: 4.21.9 + lru-cache: 5.1.1 + semver: 6.3.1 dev: true /@babel/helper-compilation-targets@7.22.9(@babel/core@7.22.9): @@ -439,6 +489,11 @@ packages: semver: 6.3.1 dev: true + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-environment-visitor@7.22.5: resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} engines: {node: '>=6.9.0'} @@ -449,14 +504,29 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.5 - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 + dev: true + + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.3 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 + dev: true + + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.3 dev: true /@babel/helper-module-imports@7.22.5: @@ -474,10 +544,24 @@ packages: dependencies: '@babel/core': 7.22.9 '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.5 + '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 dev: true /@babel/helper-plugin-utils@7.22.5: @@ -489,14 +573,14 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 dev: true /@babel/helper-string-parser@7.22.5: @@ -504,11 +588,21 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-identifier@7.22.5: resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-option@7.22.15: + resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-option@7.22.5: resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} engines: {node: '>=6.9.0'} @@ -520,7 +614,18 @@ packages: dependencies: '@babel/template': 7.22.5 '@babel/traverse': 7.22.8 - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helpers@7.23.2: + resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.3 + '@babel/types': 7.23.3 transitivePeerDependencies: - supports-color dev: true @@ -529,7 +634,7 @@ packages: resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 dev: true @@ -539,40 +644,68 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 dev: true - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.9): + /@babel/parser@7.23.3: + resolution: {integrity: sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.3 + dev: true + + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.3): resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.23.3 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.22.9): + /@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.23.3): resolution: {integrity: sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.9) + '@babel/core': 7.23.3 + '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.23.3) dev: true - /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.22.9): + /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.23.3): resolution: {integrity: sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.23.3 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.22.5 + '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.3) '@babel/types': 7.22.5 dev: true @@ -582,13 +715,22 @@ packages: dependencies: regenerator-runtime: 0.13.11 + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 + dev: true + /@babel/template@7.22.5: resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 '@babel/parser': 7.22.7 - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 dev: true /@babel/traverse@7.22.8: @@ -602,7 +744,25 @@ packages: '@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 + '@babel/types': 7.23.3 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/traverse@7.23.3: + resolution: {integrity: sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.23.3 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -618,6 +778,15 @@ packages: to-fast-properties: 2.0.0 dev: true + /@babel/types@7.23.3: + resolution: {integrity: sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + /@changesets/apply-release-plan@6.1.4: resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} dependencies: @@ -1207,18 +1376,18 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true - /@preact/preset-vite@2.5.0(@babel/core@7.22.9)(preact@10.15.1)(vite@4.4.0): + /@preact/preset-vite@2.5.0(@babel/core@7.23.3)(preact@10.15.1)(vite@4.4.0): resolution: {integrity: sha512-BUhfB2xQ6ex0yPkrT1Z3LbfPzjpJecOZwQ/xJrXGFSZD84+ObyS//41RdEoQCMWsM0t7UHGaujUxUBub7WM1Jw==} peerDependencies: '@babel/core': 7.x vite: 2.x || 3.x || 4.x dependencies: - '@babel/core': 7.22.9 - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.22.9) + '@babel/core': 7.23.3 + '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.23.3) + '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.23.3) '@prefresh/vite': 2.4.1(preact@10.15.1)(vite@4.4.0) '@rollup/pluginutils': 4.2.1 - babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.22.9) + babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.23.3) debug: 4.3.4 kolorist: 1.8.0 resolve: 1.22.4 @@ -1235,6 +1404,20 @@ packages: /@preact/signals-core@1.5.0: resolution: {integrity: sha512-U2diO1Z4i1n2IoFgMYmRdHWGObNrcuTRxyNEn7deSq2cru0vj0583HYQZHsAqcs7FE+hQyX3mjIV7LAfHCvy8w==} + /@preact/signals-react-transform@0.1.0(@babel/core@7.23.3)(react@18.2.0): + resolution: {integrity: sha512-l2ry5CCqAN6GM7cF2yZZS5iXMKQDlr9qoqEss8Yo9Qi40ErzdSRlqzzC2kao9cqq0iEVgx+XMZro2xuZxEEbUQ==} + peerDependencies: + '@babel/core': ^7.0.0 + react: ^16.14.0 || 17.x || 18.x + dependencies: + '@babel/core': 7.23.3 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@preact/signals-react': 1.3.6(react@18.2.0) + react: 18.2.0 + use-sync-external-store: 1.2.0(react@18.2.0) + dev: true + /@preact/signals-react@1.3.4(react@18.2.0): resolution: {integrity: sha512-+MIGr7ZXpRwGhk9VrK4sT5SGQSzzNCgNHuPRJ1so4rwj/DY0Ks1//2ie0sMyPhWjO7NDA91Mp4ph1Nzo3hDHhA==} peerDependencies: @@ -1606,6 +1789,35 @@ packages: resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} dev: true + /@types/babel__core@7.20.4: + resolution: {integrity: sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==} + dependencies: + '@babel/parser': 7.22.7 + '@babel/types': 7.22.5 + '@types/babel__generator': 7.6.7 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.4 + dev: true + + /@types/babel__generator@7.6.7: + resolution: {integrity: sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==} + dependencies: + '@babel/types': 7.23.3 + dev: true + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.22.7 + '@babel/types': 7.23.3 + dev: true + + /@types/babel__traverse@7.20.4: + resolution: {integrity: sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==} + dependencies: + '@babel/types': 7.23.3 + dev: true + /@types/chai-subset@1.3.3: resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} dependencies: @@ -1905,6 +2117,22 @@ packages: vite: 4.4.0 dev: true + /@vitejs/plugin-react@4.1.1(vite@4.4.8): + resolution: {integrity: sha512-Jie2HERK+uh27e+ORXXwEP5h0Y2lS9T2PRGbfebiHGlwzDO0dEnd2aNtOR/qjBlPb1YgxwAONeblL1xqLikLag==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 + dependencies: + '@babel/core': 7.23.3 + '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.3) + '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.3) + '@types/babel__core': 7.20.4 + react-refresh: 0.14.0 + vite: 4.4.8(@types/node@18.15.3) + transitivePeerDependencies: + - supports-color + dev: true + /@vitest/browser@0.33.0(rollup@2.79.1)(vitest@0.33.0): resolution: {integrity: sha512-lY7iEFqTAYsd2Dv8ej/my2ySomv38leWxudFnqI8McYFoF74U5r3vnw0+ke1JXk2NJOtMSQiGlV8yyIc7gON+w==} peerDependencies: @@ -2220,12 +2448,12 @@ packages: engines: {node: '>= 0.4'} dev: true - /babel-plugin-transform-hook-names@1.0.2(@babel/core@7.22.9): + /babel-plugin-transform-hook-names@1.0.2(@babel/core@7.23.3): resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==} peerDependencies: '@babel/core': ^7.12.10 dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.23.3 dev: true /balanced-match@1.0.2: @@ -2560,6 +2788,10 @@ packages: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} dev: true + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true @@ -5240,6 +5472,11 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true + /react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + dev: true + /react-router-dom@6.18.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw==} engines: {node: '>=14.0.0'} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 40a67ae1..0e5a0737 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,3 @@ -packages: - - 'packages/*' - - 'apps/*' \ No newline at end of file +packages: + - "packages/*" + - "apps/*" diff --git a/tsconfig.json b/tsconfig.json index 5cb0021f..3bf23811 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,8 @@ "compilerOptions": { "target": "ES2021", "lib": ["DOM", "DOM.Iterable", "ESNext"], - "allowJs": false, + "allowJs": true, + "noEmit": true, "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, @@ -19,7 +20,7 @@ "incremental": true, "preserveWatchOutput": true, "jsx": "react", - "baseUrl": ".", + "rootDir": "./", "sourceMap": true, "paths": { "@preact-signals/utils/*": ["./packages/utils/src/*"], @@ -29,8 +30,5 @@ "components-for-tests/*": ["./packages/components-for-test/src/*"] } }, - "exclude": [ - "**/node_modules", - "packages/*/dist/**/*" - ] + "exclude": ["**/node_modules", "packages/*/dist/**/*"] } From f7c4d963234eb4440ce6c0ccf9cd4d16a4efae95 Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Sun, 12 Nov 2023 21:54:19 +0100 Subject: [PATCH 05/21] passes tests --- apps/react-test/package.json | 1 - packages/query/package.json | 3 +- packages/react/package.json | 47 +++++----- .../react/react.cjs | 2 +- packages/react/rollup.config.mjs | 85 +++++++++++++++++++ packages/react/tsconfig.build.json | 10 +++ packages/react/tsconfig.json | 8 +- packages/react/vitest.config.ts | 2 +- packages/utils/package.json | 10 +-- packages/utils/tsconfig.json | 2 + packages/utils/tsconfig.lint.json | 8 ++ pnpm-lock.yaml | 21 +++++ 12 files changed, 166 insertions(+), 33 deletions(-) rename "packages/react/react.\321\201js" => packages/react/react.cjs (82%) create mode 100644 packages/react/rollup.config.mjs create mode 100644 packages/react/tsconfig.build.json create mode 100644 packages/utils/tsconfig.lint.json diff --git a/apps/react-test/package.json b/apps/react-test/package.json index ad8de6b5..11bd219e 100644 --- a/apps/react-test/package.json +++ b/apps/react-test/package.json @@ -7,7 +7,6 @@ "dev": "vite", "build": "tsc && vite build", "watch": "pnpm dev", - "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, "dependencies": { diff --git a/packages/query/package.json b/packages/query/package.json index ba4bd06c..28ad005a 100644 --- a/packages/query/package.json +++ b/packages/query/package.json @@ -28,7 +28,8 @@ ".": { "types": "./dist/esm/index.d.ts", "import": "./dist/esm/index.js", - "main": "./dist/cjs/index.js" + "require": "./dist/cjs/index.js", + "react-native": "./src/index.ts" } }, "scripts": { diff --git a/packages/react/package.json b/packages/react/package.json index cccf5079..305ebd5d 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -19,35 +19,29 @@ "url": "https://opencollective.com/preact" }, "amdName": "reactSignals", - "main": "dist/signals.js", - "module": "dist/signals.module.js", - "unpkg": "dist/signals.min.js", - "types": "dist/signals.d.ts", + "main": "./dist/cjs/index.cjs", + "module": "./dist/esm/index.mjs", + "types": "./dist/esm/index.d.ts", "source": "src/index.ts", "exports": { ".": { - "types": "./dist/signals.d.ts", - "browser": "./dist/signals.module.js", - "import": "./dist/signals.mjs", - "require": "./dist/signals.js" + "types": "./dist/types/index.d.ts", + "import": "./dist/esm/index.mjs", + "require": "./dist/cjs/index.cjs", + "react-native": "./src/index.ts" }, - "./react": "./react.сjs", + "./react": "./react.cjs", "./jsx-runtime": "./jsx-runtime.cjs", - "./jsx-dev-runtime": "./jsx-dev-runtime.cjs" + "./jsx-dev-runtime": "./jsx-dev-runtime.cjs", + "./package.json": "./package.json" }, - "mangle": "../../mangle.json", - "files": [ - "src", - "dist", - "runtime/dist", - "runtime/src", - "runtime/package.json", - "CHANGELOG.md", - "LICENSE", - "README.md" - ], "scripts": { - "test": "vitest" + "clean": "rimraf dist", + "test": "vitest", + "build": "pnpm clean && rollup -c && pnpm build:types", + "build:types": "tsc --project tsconfig.build.json", + "build:rollup": "rollup -c", + "lint": "check-export-map" }, "dependencies": { "@preact/signals-core": "^1.4.0", @@ -57,6 +51,7 @@ "react": "^16.14.0 || 17.x || 18.x" }, "devDependencies": { + "concurrently": "^8.2.0", "@preact/signals-react-transform": "^0.1.0", "@types/react": "^18.0.18", "@types/react-dom": "^18.0.6", @@ -64,6 +59,12 @@ "@vitejs/plugin-react": "^4.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router-dom": "^6.9.0" + "react-router-dom": "^6.9.0", + "check-export-map": "^1.3.0", + "@rollup/plugin-replace": "^5.0.2", + "@rollup/plugin-typescript": "^11.1.3", + "rollup": "^3.29.2", + "rollup-plugin-esbuild": "^5.0.0", + "rollup-plugin-node-externals": "^6.1.1" } } diff --git "a/packages/react/react.\321\201js" b/packages/react/react.cjs similarity index 82% rename from "packages/react/react.\321\201js" rename to packages/react/react.cjs index 7c0a181a..d761e586 100644 --- "a/packages/react/react.\321\201js" +++ b/packages/react/react.cjs @@ -1,6 +1,6 @@ // @ts-check const React = require("react"); -const wrapJsx = require("./wrapJsx"); +const wrapJsx = require("./wrap-jsx.cjs"); // didn't wrapper React.createFactory possibly not needed module.exports = { diff --git a/packages/react/rollup.config.mjs b/packages/react/rollup.config.mjs new file mode 100644 index 00000000..c581d88f --- /dev/null +++ b/packages/react/rollup.config.mjs @@ -0,0 +1,85 @@ +// @ts-check +// rollup.config.mjs +import replace from "@rollup/plugin-replace"; +import typescript from "@rollup/plugin-typescript"; +import esbuild from "rollup-plugin-esbuild"; +import externals from "rollup-plugin-node-externals"; + +const usePreferConst = true; // Use "const" instead of "var" +const usePreserveModules = true; // `true` -> keep modules structure, `false` -> combine everything into a single file +const usePreserveModulesRoot = "src"; // Root directory for `preserveModules` +const useStrict = true; // Use "strict" +const useThrowOnError = true; // On error throw and exception +const useSourceMap = true; // Generate source map files +const useEsbuild = true; // `true` -> use esbuild, `false` use tsc + +const input = ["src/index.ts"]; + +const commonPlugins = [ + externals(), + replace({ + preventAssignment: true, + values: { + __DEV__: "process.env.NODE_ENV !== 'production'", + }, + }), +]; + +/** + * @type {import("rollup").RollupOptions[]} + */ +export default [ + { + // CJS build + input, + output: { + dir: "dist/cjs", + format: "cjs", + generatedCode: { + constBindings: usePreferConst, + }, + preserveModules: usePreserveModules, + preserveModulesRoot: usePreserveModulesRoot, + strict: useStrict, + entryFileNames: "[name].cjs", + sourcemap: useSourceMap, + }, + plugins: [ + ...commonPlugins, + useEsbuild + ? esbuild() + : typescript({ + noEmitOnError: useThrowOnError, + outDir: "dist/cjs", + removeComments: true, + }), + ], + }, + { + // ESM builds + input, + output: { + dir: "dist/esm", + format: "es", + generatedCode: { + constBindings: usePreferConst, + }, + preserveModules: usePreserveModules, + preserveModulesRoot: usePreserveModulesRoot, + strict: useStrict, + entryFileNames: "[name].mjs", + assetFileNames: "[name].mjs", + sourcemap: useSourceMap, + }, + plugins: [ + ...commonPlugins, + useEsbuild + ? esbuild() + : typescript({ + noEmitOnError: useThrowOnError, + outDir: "dist/esm", + removeComments: true, + }), + ], + }, +]; diff --git a/packages/react/tsconfig.build.json b/packages/react/tsconfig.build.json new file mode 100644 index 00000000..331600c4 --- /dev/null +++ b/packages/react/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/types", + "noEmit": false, + "rootDir": "./src", + "emitDeclarationOnly": true + }, + "include": ["./src"] +} diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json index 80419b57..3de24dac 100644 --- a/packages/react/tsconfig.json +++ b/packages/react/tsconfig.json @@ -1,6 +1,12 @@ { "extends": "../../tsconfig.json", - "include": ["src/**/*", "package.json", "./*.cjs"], + "include": [ + "src/**/*", + "rollup.config.mjs", + "vitest.config.ts", + "package.json", + "./*.cjs" + ], "compilerOptions": { "types": ["./global.d.ts"] } diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts index 34291742..28fab918 100644 --- a/packages/react/vitest.config.ts +++ b/packages/react/vitest.config.ts @@ -13,7 +13,7 @@ export default defineConfig({ alias: [ { find: /^react$/, - replacement: "./react.js", + replacement: packageJson.exports["./react"], }, { find: "@preact-signals/react/jsx-runtime", diff --git a/packages/utils/package.json b/packages/utils/package.json index 878124ae..f1558f66 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -70,11 +70,11 @@ "scripts": { "clean": "rimraf dist", "test": "vitest", - "lint": "tsc --noEmit && check-export-map", + "lint": "tsc --noEmit --emitDeclarationOnly false && check-export-map", + "build": "pnpm clean && rollup -c && pnpm build:types", "build:types": "tsc", "build:rollup": "rollup -c", - "watch": "concurrently \"pnpm build:rollup -w\" \"pnpm build:types -w\"", - "build": "pnpm clean && rollup -c && pnpm build:types" + "watch": "concurrently \"pnpm build:rollup -w\" \"pnpm build:types -w\"" }, "typesVersions": { "*": { @@ -122,8 +122,6 @@ "devDependencies": { "@preact-signals/unified-signals": "workspace:*", "@preact/signals-react": "^1.3.6", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-typescript": "^11.1.3", "@types/react": "^18", "@types/react-dom": "^18", "check-export-map": "^1.3.0", @@ -133,6 +131,8 @@ "radash": "^11.0.0", "react": "^18", "react-dom": "^18", + "@rollup/plugin-replace": "^5.0.2", + "@rollup/plugin-typescript": "^11.1.3", "rollup": "^3.29.2", "rollup-plugin-esbuild": "^5.0.0", "rollup-plugin-node-externals": "^6.1.1", diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index 1ba78db7..a44d6a0f 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -9,6 +9,8 @@ }, "exclude": [ "**/dist/**", + "**/__tests__/**", + "**/__test__/**", "**/node_modules/**", "rollup.config.mjs", "vitest.config.ts", diff --git a/packages/utils/tsconfig.lint.json b/packages/utils/tsconfig.lint.json new file mode 100644 index 00000000..d17c57c1 --- /dev/null +++ b/packages/utils/tsconfig.lint.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noEmit": true, + "emitDeclarationOnly": false, + "tsBuildInfoFile": "./node_modules/lint.tsbuildinfo" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 297e3d5d..475d0812 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -226,6 +226,12 @@ importers: '@preact/signals-react-transform': specifier: ^0.1.0 version: 0.1.0(@babel/core@7.23.3)(react@18.2.0) + '@rollup/plugin-replace': + specifier: ^5.0.2 + version: 5.0.2(rollup@3.29.2) + '@rollup/plugin-typescript': + specifier: ^11.1.3 + version: 11.1.3(rollup@3.29.2)(typescript@5.1.6) '@types/react': specifier: ^18.0.18 version: 18.2.15 @@ -238,6 +244,12 @@ importers: '@vitejs/plugin-react': specifier: ^4.1.1 version: 4.1.1(vite@4.4.8) + check-export-map: + specifier: ^1.3.0 + version: 1.3.0 + concurrently: + specifier: ^8.2.0 + version: 8.2.0 react: specifier: ^18.2.0 version: 18.2.0 @@ -247,6 +259,15 @@ importers: react-router-dom: specifier: ^6.9.0 version: 6.18.0(react-dom@18.2.0)(react@18.2.0) + rollup: + specifier: ^3.29.2 + version: 3.29.2 + rollup-plugin-esbuild: + specifier: ^5.0.0 + version: 5.0.0(esbuild@0.18.18)(rollup@3.29.2) + rollup-plugin-node-externals: + specifier: ^6.1.1 + version: 6.1.1(rollup@3.29.2) packages/type: dependencies: From 14979ed7983316a4f60375f36121b39e1ebda09f Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Sun, 12 Nov 2023 22:02:32 +0100 Subject: [PATCH 06/21] packges updates --- .gitignore | 1 + apps/preact-test/package.json | 16 +- apps/react-test/package.json | 16 +- package.json | 6 +- packages/components-for-test/package.json | 10 +- packages/query/package.json | 30 +- packages/react/package.json | 18 +- packages/type/package.json | 8 +- packages/unified-signals/package.json | 8 +- packages/utils/package.json | 24 +- pnpm-lock.yaml | 2033 +++++++++++++-------- 11 files changed, 1368 insertions(+), 802 deletions(-) diff --git a/.gitignore b/.gitignore index 5e58b00e..085cd154 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ dist-ssr *.sln *.sw? +.turbo tsconfig.tsbuildinfo \ No newline at end of file diff --git a/apps/preact-test/package.json b/apps/preact-test/package.json index c34d6c97..41eafe2b 100644 --- a/apps/preact-test/package.json +++ b/apps/preact-test/package.json @@ -10,16 +10,16 @@ "preview": "vite preview" }, "dependencies": { - "@preact/signals": "^1.1.4", + "@preact/signals": "^1.2.1", "components-for-test": "workspace:*", - "preact": "^10.15.1" + "preact": "^10.19.1" }, "devDependencies": { - "@preact/preset-vite": "^2.5.0", - "autoprefixer": "^10.4.14", - "daisyui": "^3.5.1", - "postcss": "^8.4.27", - "tailwindcss": "^3.3.3", - "vite": "^4.4.0" + "@preact/preset-vite": "^2.6.0", + "autoprefixer": "^10.4.16", + "daisyui": "^3.9.4", + "postcss": "^8.4.31", + "tailwindcss": "^3.3.5", + "vite": "^4.5.0" } } diff --git a/apps/react-test/package.json b/apps/react-test/package.json index 11bd219e..f74c2dbd 100644 --- a/apps/react-test/package.json +++ b/apps/react-test/package.json @@ -16,13 +16,13 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "@types/react": "^18.0.37", - "@types/react-dom": "^18.0.11", - "@vitejs/plugin-react-swc": "^3.0.0", - "autoprefixer": "^10.4.14", - "daisyui": "^3.5.1", - "postcss": "^8.4.27", - "tailwindcss": "^3.3.3", - "vite": "^4.3.9" + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "@vitejs/plugin-react-swc": "^3.4.1", + "autoprefixer": "^10.4.16", + "daisyui": "^3.9.4", + "postcss": "^8.4.31", + "tailwindcss": "^3.3.5", + "vite": "^4.5.0" } } diff --git a/package.json b/package.json index acf0e514..ad8c0081 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "@typescript-eslint/eslint-plugin": "^6.10.0", "@typescript-eslint/parser": "^6.10.0", "eslint": "^8.53.0", - "rimraf": "^5.0.1", - "turbo": "^1.10.12", - "typescript": "^5.1.6", + "rimraf": "^5.0.5", + "turbo": "^1.10.16", + "typescript": "^5.2.2", "vitest": "^0.33.0" }, "scripts": { diff --git a/packages/components-for-test/package.json b/packages/components-for-test/package.json index a0f0e9da..af09bbca 100644 --- a/packages/components-for-test/package.json +++ b/packages/components-for-test/package.json @@ -34,8 +34,8 @@ }, "peerDependencies": { "@preact-signals/query": "workspace:*", - "@preact/signals-react": "^1.3", "@preact/signals": "^1.*", + "@preact/signals-react": "^1.3", "react": "17.*.* || 18.*.*" }, "peerDependenciesMeta": { @@ -46,12 +46,12 @@ "devDependencies": { "@preact-signals/query": "workspace:*", "@preact/signals-react": "^1.3.6", - "@types/react": "^18", - "@types/react-dom": "^18", - "concurrently": "^8.2.0", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "concurrently": "^8.2.2", "react": "^18", "react-dom": "^18", - "type-fest": "^3.12.0" + "type-fest": "^3.13.1" }, "keywords": [], "license": "MIT" diff --git a/packages/query/package.json b/packages/query/package.json index 28ad005a..198762b0 100644 --- a/packages/query/package.json +++ b/packages/query/package.json @@ -42,11 +42,11 @@ "build": "pnpm clean && concurrently \"pnpm build:esm\" \"pnpm build:cjs\"" }, "peerDependencies": { - "react": "17.*.* || 18.*.*", - "react-dom": "^18.2.0", - "@preact/signals-react": ">=1.2.0", "@preact/signals": ">=1.1.0", - "@preact/signals-core": ">=1.1.0" + "@preact/signals-core": ">=1.1.0", + "@preact/signals-react": ">=1.2.0", + "react": "17.*.* || 18.*.*", + "react-dom": "^18.2.0" }, "peerDependenciesMeta": { "react": { @@ -67,26 +67,26 @@ }, "devDependencies": { "@preact/signals-react": ">=1.2.0", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^13.0.0", - "@types/jsdom": "^21.1.1", - "@types/react": "^18.2.15", - "@types/react-dom": "^18.2.7", - "@types/testing-library__jest-dom": "^5.14.8", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@types/jsdom": "^21.1.5", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", + "@types/testing-library__jest-dom": "^5.14.9", "@types/use-sync-external-store": "^0.0.3", "@vitest/browser": "^0.33.0", - "concurrently": "^8.2.0", + "concurrently": "^8.2.2", "jsdom": "^22.1.0", "react": "18.2.0", "react-dom": "^18.2.0", - "react-error-boundary": "^4.0.10", - "type-fest": "^3.13.0", + "react-error-boundary": "^4.0.11", + "type-fest": "^3.13.1", "vitest": "^0.33.0", - "webdriverio": "^8.13.1" + "webdriverio": "^8.22.1" }, "dependencies": { - "@preact-signals/utils": "workspace:*", "@preact-signals/unified-signals": "workspace:*", + "@preact-signals/utils": "workspace:*", "@tanstack/query-core": "4.29.23", "use-sync-external-store": "^1.2.0" }, diff --git a/packages/react/package.json b/packages/react/package.json index 305ebd5d..f9f029ab 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -44,27 +44,27 @@ "lint": "check-export-map" }, "dependencies": { - "@preact/signals-core": "^1.4.0", + "@preact/signals-core": "^1.5.0", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { "react": "^16.14.0 || 17.x || 18.x" }, "devDependencies": { - "concurrently": "^8.2.0", "@preact/signals-react-transform": "^0.1.0", - "@types/react": "^18.0.18", - "@types/react-dom": "^18.0.6", + "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-typescript": "^11.1.5", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", "@types/use-sync-external-store": "^0.0.3", "@vitejs/plugin-react": "^4.1.1", + "check-export-map": "^1.3.0", + "concurrently": "^8.2.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.9.0", - "check-export-map": "^1.3.0", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-typescript": "^11.1.3", - "rollup": "^3.29.2", + "rollup": "^3.29.4", "rollup-plugin-esbuild": "^5.0.0", - "rollup-plugin-node-externals": "^6.1.1" + "rollup-plugin-node-externals": "^6.1.2" } } diff --git a/packages/type/package.json b/packages/type/package.json index 364c5fad..fb9457cc 100644 --- a/packages/type/package.json +++ b/packages/type/package.json @@ -8,13 +8,13 @@ "author": "", "license": "ISC", "dependencies": { - "@preact/signals-core": "^1.2.3", + "@preact/signals-core": "^1.5.0", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { - "@types/node": "^18.15.3", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.9" + "@types/node": "^18.18.9", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15" } } diff --git a/packages/unified-signals/package.json b/packages/unified-signals/package.json index b25fdd5a..51295641 100644 --- a/packages/unified-signals/package.json +++ b/packages/unified-signals/package.json @@ -41,9 +41,9 @@ "build": "pnpm clean && concurrently \"pnpm build:esm\" \"pnpm build:cjs\"" }, "peerDependencies": { - "@preact/signals-react": ">=1.2.0", "@preact/signals": ">=1.1.0", - "@preact/signals-core": ">=1.1.0" + "@preact/signals-core": ">=1.1.0", + "@preact/signals-react": ">=1.2.0" }, "peerDependenciesMeta": { "@preact/signals-react": { @@ -57,9 +57,9 @@ } }, "devDependencies": { - "happy-dom": "^10.5.2", "@preact/signals-react": "1.3.4", - "concurrently": "^8.2.0" + "concurrently": "^8.2.2", + "happy-dom": "^10.11.2" }, "keywords": [], "license": "MIT" diff --git a/packages/utils/package.json b/packages/utils/package.json index f1558f66..f23ec96c 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -96,10 +96,10 @@ } }, "peerDependencies": { - "react": "17.*.* || 18.*.*", - "@preact/signals-react": ">=1.2.0", "@preact/signals": ">=1.1.0", - "@preact/signals-core": ">=1.1.0" + "@preact/signals-core": ">=1.1.0", + "@preact/signals-react": ">=1.2.0", + "react": "17.*.* || 18.*.*" }, "peerDependenciesMeta": { "react": { @@ -122,21 +122,21 @@ "devDependencies": { "@preact-signals/unified-signals": "workspace:*", "@preact/signals-react": "^1.3.6", - "@types/react": "^18", - "@types/react-dom": "^18", + "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-typescript": "^11.1.5", + "@types/react": "^18.2.37", + "@types/react-dom": "^18.2.15", "check-export-map": "^1.3.0", - "concurrently": "^8.2.0", - "happy-dom": "^10.5.2", + "concurrently": "^8.2.2", + "happy-dom": "^10.11.2", "hotscript": "^1.0.13", "radash": "^11.0.0", "react": "^18", "react-dom": "^18", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-typescript": "^11.1.3", - "rollup": "^3.29.2", + "rollup": "^3.29.4", "rollup-plugin-esbuild": "^5.0.0", - "rollup-plugin-node-externals": "^6.1.1", - "type-fest": "^3.13.0" + "rollup-plugin-node-externals": "^6.1.2", + "type-fest": "^3.13.1" }, "keywords": [ "preact signals", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 475d0812..9f4414bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,56 +13,56 @@ importers: version: 2.26.2 '@typescript-eslint/eslint-plugin': specifier: ^6.10.0 - version: 6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.1.6) + version: 6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^6.10.0 - version: 6.10.0(eslint@8.53.0)(typescript@5.1.6) + version: 6.10.0(eslint@8.53.0)(typescript@5.2.2) eslint: specifier: ^8.53.0 version: 8.53.0 rimraf: - specifier: ^5.0.1 - version: 5.0.1 + specifier: ^5.0.5 + version: 5.0.5 turbo: - specifier: ^1.10.12 - version: 1.10.12 + specifier: ^1.10.16 + version: 1.10.16 typescript: - specifier: ^5.1.6 - version: 5.1.6 + specifier: ^5.2.2 + version: 5.2.2 vitest: specifier: ^0.33.0 - version: 0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.13.1) + version: 0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.22.1) apps/preact-test: dependencies: '@preact/signals': - specifier: ^1.1.4 - version: 1.1.4(preact@10.15.1) + specifier: ^1.2.1 + version: 1.2.1(preact@10.19.1) components-for-test: specifier: workspace:* version: link:../../packages/components-for-test preact: - specifier: ^10.15.1 - version: 10.15.1 + specifier: ^10.19.1 + version: 10.19.1 devDependencies: '@preact/preset-vite': - specifier: ^2.5.0 - version: 2.5.0(@babel/core@7.23.3)(preact@10.15.1)(vite@4.4.0) + specifier: ^2.6.0 + version: 2.6.0(@babel/core@7.23.3)(preact@10.19.1)(vite@4.5.0) autoprefixer: - specifier: ^10.4.14 - version: 10.4.14(postcss@8.4.27) + specifier: ^10.4.16 + version: 10.4.16(postcss@8.4.31) daisyui: - specifier: ^3.5.1 - version: 3.5.1 + specifier: ^3.9.4 + version: 3.9.4 postcss: - specifier: ^8.4.27 - version: 8.4.27 + specifier: ^8.4.31 + version: 8.4.31 tailwindcss: - specifier: ^3.3.3 - version: 3.3.3 + specifier: ^3.3.5 + version: 3.3.5 vite: - specifier: ^4.4.0 - version: 4.4.0 + specifier: ^4.5.0 + version: 4.5.0(@types/node@20.9.0) apps/react-test: dependencies: @@ -80,29 +80,29 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@types/react': - specifier: ^18.0.37 - version: 18.2.15 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18.0.11 - version: 18.2.7 + specifier: ^18.2.15 + version: 18.2.15 '@vitejs/plugin-react-swc': - specifier: ^3.0.0 - version: 3.0.1(vite@4.4.0) + specifier: ^3.4.1 + version: 3.4.1(vite@4.5.0) autoprefixer: - specifier: ^10.4.14 - version: 10.4.14(postcss@8.4.27) + specifier: ^10.4.16 + version: 10.4.16(postcss@8.4.31) daisyui: - specifier: ^3.5.1 - version: 3.5.1 + specifier: ^3.9.4 + version: 3.9.4 postcss: - specifier: ^8.4.27 - version: 8.4.27 + specifier: ^8.4.31 + version: 8.4.31 tailwindcss: - specifier: ^3.3.3 - version: 3.3.3 + specifier: ^3.3.5 + version: 3.3.5 vite: - specifier: ^4.3.9 - version: 4.4.0 + specifier: ^4.5.0 + version: 4.5.0(@types/node@20.9.0) packages/components-for-test: dependencies: @@ -123,14 +123,14 @@ importers: specifier: ^1.3.6 version: 1.3.6(react@18.2.0) '@types/react': - specifier: ^18 - version: 18.2.15 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18 - version: 18.2.7 + specifier: ^18.2.15 + version: 18.2.15 concurrently: - specifier: ^8.2.0 - version: 8.2.0 + specifier: ^8.2.2 + version: 8.2.2 react: specifier: ^18 version: 18.2.0 @@ -138,8 +138,8 @@ importers: specifier: ^18 version: 18.2.0(react@18.2.0) type-fest: - specifier: ^3.12.0 - version: 3.13.0 + specifier: ^3.13.1 + version: 3.13.1 packages/query: dependencies: @@ -166,23 +166,23 @@ importers: specifier: '>=1.2.0' version: 1.3.6(react@18.2.0) '@testing-library/jest-dom': - specifier: ^5.16.5 - version: 5.16.5 + specifier: ^5.17.0 + version: 5.17.0 '@testing-library/react': - specifier: ^13.0.0 - version: 13.0.0(react-dom@18.2.0)(react@18.2.0) + specifier: ^13.4.0 + version: 13.4.0(react-dom@18.2.0)(react@18.2.0) '@types/jsdom': - specifier: ^21.1.1 - version: 21.1.1 + specifier: ^21.1.5 + version: 21.1.5 '@types/react': + specifier: ^18.2.37 + version: 18.2.37 + '@types/react-dom': specifier: ^18.2.15 version: 18.2.15 - '@types/react-dom': - specifier: ^18.2.7 - version: 18.2.7 '@types/testing-library__jest-dom': - specifier: ^5.14.8 - version: 5.14.8 + specifier: ^5.14.9 + version: 5.14.9 '@types/use-sync-external-store': specifier: ^0.0.3 version: 0.0.3 @@ -190,8 +190,8 @@ importers: specifier: ^0.33.0 version: 0.33.0(rollup@2.79.1)(vitest@0.33.0) concurrently: - specifier: ^8.2.0 - version: 8.2.0 + specifier: ^8.2.2 + version: 8.2.2 jsdom: specifier: ^22.1.0 version: 22.1.0 @@ -202,22 +202,22 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) react-error-boundary: - specifier: ^4.0.10 - version: 4.0.10(react@18.2.0) + specifier: ^4.0.11 + version: 4.0.11(react@18.2.0) type-fest: - specifier: ^3.13.0 - version: 3.13.0 + specifier: ^3.13.1 + version: 3.13.1 vitest: specifier: ^0.33.0 - version: 0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.13.1) + version: 0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.22.1) webdriverio: - specifier: ^8.13.1 - version: 8.13.1(typescript@5.1.6) + specifier: ^8.22.1 + version: 8.22.1(typescript@5.2.2) packages/react: dependencies: '@preact/signals-core': - specifier: ^1.4.0 + specifier: ^1.5.0 version: 1.5.0 use-sync-external-store: specifier: ^1.2.0 @@ -227,29 +227,29 @@ importers: specifier: ^0.1.0 version: 0.1.0(@babel/core@7.23.3)(react@18.2.0) '@rollup/plugin-replace': - specifier: ^5.0.2 - version: 5.0.2(rollup@3.29.2) + specifier: ^5.0.5 + version: 5.0.5(rollup@3.29.4) '@rollup/plugin-typescript': - specifier: ^11.1.3 - version: 11.1.3(rollup@3.29.2)(typescript@5.1.6) + specifier: ^11.1.5 + version: 11.1.5(rollup@3.29.4)(typescript@5.2.2) '@types/react': - specifier: ^18.0.18 - version: 18.2.15 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18.0.6 - version: 18.2.7 + specifier: ^18.2.15 + version: 18.2.15 '@types/use-sync-external-store': specifier: ^0.0.3 version: 0.0.3 '@vitejs/plugin-react': specifier: ^4.1.1 - version: 4.1.1(vite@4.4.8) + version: 4.1.1(vite@4.5.0) check-export-map: specifier: ^1.3.0 version: 1.3.0 concurrently: - specifier: ^8.2.0 - version: 8.2.0 + specifier: ^8.2.2 + version: 8.2.2 react: specifier: ^18.2.0 version: 18.2.0 @@ -260,20 +260,20 @@ importers: specifier: ^6.9.0 version: 6.18.0(react-dom@18.2.0)(react@18.2.0) rollup: - specifier: ^3.29.2 - version: 3.29.2 + specifier: ^3.29.4 + version: 3.29.4 rollup-plugin-esbuild: specifier: ^5.0.0 - version: 5.0.0(esbuild@0.18.18)(rollup@3.29.2) + version: 5.0.0(esbuild@0.19.5)(rollup@3.29.4) rollup-plugin-node-externals: - specifier: ^6.1.1 - version: 6.1.1(rollup@3.29.2) + specifier: ^6.1.2 + version: 6.1.2(rollup@3.29.4) packages/type: dependencies: '@preact/signals-core': - specifier: ^1.2.3 - version: 1.2.3 + specifier: ^1.5.0 + version: 1.5.0 react: specifier: ^18.2.0 version: 18.2.0 @@ -282,14 +282,14 @@ importers: version: 18.2.0(react@18.2.0) devDependencies: '@types/node': - specifier: ^18.15.3 - version: 18.15.3 + specifier: ^18.18.9 + version: 18.18.9 '@types/react': - specifier: ^18.0.26 - version: 18.2.15 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18.0.9 - version: 18.2.7 + specifier: ^18.2.15 + version: 18.2.15 packages/unified-signals: dependencies: @@ -304,11 +304,11 @@ importers: specifier: 1.3.4 version: 1.3.4(react@18.2.0) concurrently: - specifier: ^8.2.0 - version: 8.2.0 + specifier: ^8.2.2 + version: 8.2.2 happy-dom: - specifier: ^10.5.2 - version: 10.5.2 + specifier: ^10.11.2 + version: 10.11.2 packages/utils: dependencies: @@ -329,26 +329,26 @@ importers: specifier: ^1.3.6 version: 1.3.6(react@18.2.0) '@rollup/plugin-replace': - specifier: ^5.0.2 - version: 5.0.2(rollup@3.29.2) + specifier: ^5.0.5 + version: 5.0.5(rollup@3.29.4) '@rollup/plugin-typescript': - specifier: ^11.1.3 - version: 11.1.3(rollup@3.29.2)(typescript@5.1.6) + specifier: ^11.1.5 + version: 11.1.5(rollup@3.29.4)(typescript@5.2.2) '@types/react': - specifier: ^18 - version: 18.2.15 + specifier: ^18.2.37 + version: 18.2.37 '@types/react-dom': - specifier: ^18 - version: 18.2.7 + specifier: ^18.2.15 + version: 18.2.15 check-export-map: specifier: ^1.3.0 version: 1.3.0 concurrently: - specifier: ^8.2.0 - version: 8.2.0 + specifier: ^8.2.2 + version: 8.2.2 happy-dom: - specifier: ^10.5.2 - version: 10.5.2 + specifier: ^10.11.2 + version: 10.11.2 hotscript: specifier: ^1.0.13 version: 1.0.13 @@ -362,17 +362,17 @@ importers: specifier: ^18 version: 18.2.0(react@18.2.0) rollup: - specifier: ^3.29.2 - version: 3.29.2 + specifier: ^3.29.4 + version: 3.29.4 rollup-plugin-esbuild: specifier: ^5.0.0 - version: 5.0.0(esbuild@0.18.18)(rollup@3.29.2) + version: 5.0.0(esbuild@0.19.5)(rollup@3.29.4) rollup-plugin-node-externals: - specifier: ^6.1.1 - version: 6.1.1(rollup@3.29.2) + specifier: ^6.1.2 + version: 6.1.2(rollup@3.29.4) type-fest: - specifier: ^3.13.0 - version: 3.13.0 + specifier: ^3.13.1 + version: 3.13.1 packages: @@ -491,7 +491,7 @@ packages: dependencies: '@babel/compat-data': 7.22.9 '@babel/helper-validator-option': 7.22.15 - browserslist: 4.21.9 + browserslist: 4.22.1 lru-cache: 5.1.1 semver: 6.3.1 dev: true @@ -505,7 +505,7 @@ packages: '@babel/compat-data': 7.22.9 '@babel/core': 7.22.9 '@babel/helper-validator-option': 7.22.5 - browserslist: 4.21.9 + browserslist: 4.22.1 lru-cache: 5.1.1 semver: 6.3.1 dev: true @@ -665,7 +665,7 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.22.5 dev: true /@babel/parser@7.23.3: @@ -676,8 +676,8 @@ packages: '@babel/types': 7.23.3 dev: true - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.3): - resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.3): + resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -693,7 +693,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.3 - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.23.3) + '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.3) dev: true /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.3): @@ -716,8 +716,8 @@ packages: '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.23.3): - resolution: {integrity: sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==} + /@babel/plugin-transform-react-jsx@7.22.15(@babel/core@7.23.3): + resolution: {integrity: sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -726,8 +726,8 @@ packages: '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.3) - '@babel/types': 7.22.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.3) + '@babel/types': 7.23.3 dev: true /@babel/runtime@7.22.6: @@ -1001,6 +1001,15 @@ packages: dev: true optional: true + /@esbuild/android-arm64@0.19.5: + resolution: {integrity: sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm@0.18.18: resolution: {integrity: sha512-oBymf7ZwplAawSxmiSlBCf+FMcY0f4bs5QP2jn43JKUf0M9DnrUTjqa5RvFPl1elw+sMfcpfBRPK+rb+E1q7zg==} engines: {node: '>=12'} @@ -1010,6 +1019,15 @@ packages: dev: true optional: true + /@esbuild/android-arm@0.19.5: + resolution: {integrity: sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64@0.18.18: resolution: {integrity: sha512-r7/pVcrUQMYkjvtE/1/n6BxhWM+/9tvLxDG1ev1ce4z3YsqoxMK9bbOM6bFcj0BowMeGQvOZWcBV182lFFKmrw==} engines: {node: '>=12'} @@ -1019,6 +1037,15 @@ packages: dev: true optional: true + /@esbuild/android-x64@0.19.5: + resolution: {integrity: sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64@0.18.18: resolution: {integrity: sha512-MSe2iV9MAH3wfP0g+vzN9bp36rtPPuCSk+bT5E2vv/d8krvW5uB/Pi/Q5+txUZuxsG3GcO8dhygjnFq0wJU9hQ==} engines: {node: '>=12'} @@ -1028,6 +1055,15 @@ packages: dev: true optional: true + /@esbuild/darwin-arm64@0.19.5: + resolution: {integrity: sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64@0.18.18: resolution: {integrity: sha512-ARFYISOWkaifjcr48YtO70gcDNeOf1H2RnmOj6ip3xHIj66f3dAbhcd5Nph5np6oHI7DhHIcr9MWO18RvUL1bw==} engines: {node: '>=12'} @@ -1037,6 +1073,15 @@ packages: dev: true optional: true + /@esbuild/darwin-x64@0.19.5: + resolution: {integrity: sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64@0.18.18: resolution: {integrity: sha512-BHnXmexzEWRU2ZySJosU0Ts0NRnJnNrMB6t4EiIaOSel73I8iLsNiTPLH0rJulAh19cYZutsB5XHK6N8fi5eMg==} engines: {node: '>=12'} @@ -1046,6 +1091,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-arm64@0.19.5: + resolution: {integrity: sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64@0.18.18: resolution: {integrity: sha512-n823w35wm0ZOobbuE//0sJjuz1Qj619+AwjgOcAJMN2pomZhH9BONCtn+KlfrmM/NWZ+27yB/eGVFzUIWLeh3w==} engines: {node: '>=12'} @@ -1055,6 +1109,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-x64@0.19.5: + resolution: {integrity: sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64@0.18.18: resolution: {integrity: sha512-zANxnwF0sCinDcAqoMohGoWBK9QaFJ65Vgh0ZE+RXtURaMwx+RfmfLElqtnn7X8OYNckMoIXSg7u+tZ3tqTlrA==} engines: {node: '>=12'} @@ -1064,6 +1127,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm64@0.19.5: + resolution: {integrity: sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm@0.18.18: resolution: {integrity: sha512-Kck3jxPLQU4VeAGwe8Q4NU+IWIx+suULYOFUI9T0C2J1+UQlOHJ08ITN+MaJJ+2youzJOmKmcphH/t3SJxQ1Tw==} engines: {node: '>=12'} @@ -1073,6 +1145,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm@0.19.5: + resolution: {integrity: sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32@0.18.18: resolution: {integrity: sha512-+VHz2sIRlY5u8IlaLJpdf5TL2kM76yx186pW7bpTB+vLWpzcFQVP04L842ZB2Ty13A1VXUvy3DbU1jV65P2skg==} engines: {node: '>=12'} @@ -1082,6 +1163,15 @@ packages: dev: true optional: true + /@esbuild/linux-ia32@0.19.5: + resolution: {integrity: sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64@0.14.54: resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} engines: {node: '>=12'} @@ -1100,6 +1190,15 @@ packages: dev: true optional: true + /@esbuild/linux-loong64@0.19.5: + resolution: {integrity: sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el@0.18.18: resolution: {integrity: sha512-dLvRB87pIBIRnEIC32LIcgwK1JzlIuADIRjLKdUIpxauKwMuS/xMpN+cFl+0nN4RHNYOZ57DmXFFmQAcdlFOmw==} engines: {node: '>=12'} @@ -1109,6 +1208,15 @@ packages: dev: true optional: true + /@esbuild/linux-mips64el@0.19.5: + resolution: {integrity: sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64@0.18.18: resolution: {integrity: sha512-fRChqIJZ7hLkXSKfBLYgsX9Ssb5OGCjk3dzCETF5QSS1qjTgayLv0ALUdJDB9QOh/nbWwp+qfLZU6md4XcjL7w==} engines: {node: '>=12'} @@ -1118,6 +1226,15 @@ packages: dev: true optional: true + /@esbuild/linux-ppc64@0.19.5: + resolution: {integrity: sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64@0.18.18: resolution: {integrity: sha512-ALK/BT3u7Hoa/vHjow6W6+MKF0ohYcVcVA1EpskI4bkBPVuDLrUDqt2YFifg5UcZc8qup0CwQqWmFUd6VMNgaA==} engines: {node: '>=12'} @@ -1127,6 +1244,15 @@ packages: dev: true optional: true + /@esbuild/linux-riscv64@0.19.5: + resolution: {integrity: sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x@0.18.18: resolution: {integrity: sha512-crT7jtOXd9iirY65B+mJQ6W0HWdNy8dtkZqKGWNcBnunpLcTCfne5y5bKic9bhyYzKpQEsO+C/VBPD8iF0RhRw==} engines: {node: '>=12'} @@ -1136,6 +1262,15 @@ packages: dev: true optional: true + /@esbuild/linux-s390x@0.19.5: + resolution: {integrity: sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64@0.18.18: resolution: {integrity: sha512-/NSgghjBOW9ELqjXDYxOCCIsvQUZpvua1/6NdnA9Vnrp9UzEydyDdFXljUjMMS9p5KxMzbMO9frjHYGVHBfCHg==} engines: {node: '>=12'} @@ -1145,6 +1280,15 @@ packages: dev: true optional: true + /@esbuild/linux-x64@0.19.5: + resolution: {integrity: sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64@0.18.18: resolution: {integrity: sha512-8Otf05Vx5sZjLLDulgr5QS5lsWXMplKZEyHMArH9/S4olLlhzmdhQBPhzhJTNwaL2FJNdWcUPNGAcoD5zDTfUA==} engines: {node: '>=12'} @@ -1154,6 +1298,15 @@ packages: dev: true optional: true + /@esbuild/netbsd-x64@0.19.5: + resolution: {integrity: sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64@0.18.18: resolution: {integrity: sha512-tFiFF4kT5L5qhVrWJUNxEXWvvX8nK/UX9ZrB7apuTwY3f6+Xy4aFMBPwAVrBYtBd5MOUuyOVHK6HBZCAHkwUlw==} engines: {node: '>=12'} @@ -1163,6 +1316,15 @@ packages: dev: true optional: true + /@esbuild/openbsd-x64@0.19.5: + resolution: {integrity: sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64@0.18.18: resolution: {integrity: sha512-MPogVV8Bzh8os4OM+YDGGsSzCzmNRiyKGtHoJyZLtI4BMmd6EcxmGlcEGK1uM46h1BiOyi7Z7teUtzzQhvkC+w==} engines: {node: '>=12'} @@ -1172,6 +1334,15 @@ packages: dev: true optional: true + /@esbuild/sunos-x64@0.19.5: + resolution: {integrity: sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64@0.18.18: resolution: {integrity: sha512-YKD6LF/XXY9REu+ZL5RAsusiG48n602qxsMVh/E8FFD9hp4OyTQaL9fpE1ovxwQXqFio+tT0ITUGjDSSSPN13w==} engines: {node: '>=12'} @@ -1181,6 +1352,15 @@ packages: dev: true optional: true + /@esbuild/win32-arm64@0.19.5: + resolution: {integrity: sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32@0.18.18: resolution: {integrity: sha512-NjSBmBsyZBTsZB6ga6rA6PfG/RHnwruUz/9YEVXcm4STGauFWvhYhOMhEyw1yU5NVgYYm8CH5AltCm77TS21/Q==} engines: {node: '>=12'} @@ -1190,6 +1370,15 @@ packages: dev: true optional: true + /@esbuild/win32-ia32@0.19.5: + resolution: {integrity: sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64@0.18.18: resolution: {integrity: sha512-eTSg/gC3p3tdjj4roDhe5xu94l1s2jMazP8u2FsYO8SEKvSpPOO71EucprDn/IuErDPvTFUhV9lTw5z5WJCRKQ==} engines: {node: '>=12'} @@ -1199,6 +1388,15 @@ packages: dev: true optional: true + /@esbuild/win32-x64@0.19.5: + resolution: {integrity: sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.53.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1302,7 +1500,7 @@ packages: '@jest/schemas': 29.6.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.15.3 + '@types/node': 20.9.0 '@types/yargs': 17.0.24 chalk: 4.1.2 dev: true @@ -1397,22 +1595,22 @@ packages: resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} dev: true - /@preact/preset-vite@2.5.0(@babel/core@7.23.3)(preact@10.15.1)(vite@4.4.0): - resolution: {integrity: sha512-BUhfB2xQ6ex0yPkrT1Z3LbfPzjpJecOZwQ/xJrXGFSZD84+ObyS//41RdEoQCMWsM0t7UHGaujUxUBub7WM1Jw==} + /@preact/preset-vite@2.6.0(@babel/core@7.23.3)(preact@10.19.1)(vite@4.5.0): + resolution: {integrity: sha512-5nztNzXbCpqyVum/K94nB2YQ5PTnvWdz4u7/X0jc8+kLyskSSpkNUxLQJeI90zfGSFIX1Ibj2G2JIS/mySHWYQ==} peerDependencies: '@babel/core': 7.x vite: 2.x || 3.x || 4.x dependencies: '@babel/core': 7.23.3 - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.23.3) + '@babel/plugin-transform-react-jsx': 7.22.15(@babel/core@7.23.3) '@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.23.3) - '@prefresh/vite': 2.4.1(preact@10.15.1)(vite@4.4.0) + '@prefresh/vite': 2.4.1(preact@10.19.1)(vite@4.5.0) '@rollup/pluginutils': 4.2.1 babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.23.3) debug: 4.3.4 kolorist: 1.8.0 - resolve: 1.22.4 - vite: 4.4.0 + resolve: 1.22.8 + vite: 4.5.0(@types/node@20.9.0) transitivePeerDependencies: - preact - supports-color @@ -1467,23 +1665,32 @@ packages: preact: 10.15.1 dev: false + /@preact/signals@1.2.1(preact@10.19.1): + resolution: {integrity: sha512-hRPvp1C2ooDzOHqfnhdpHgoIFDbYFAXLhoid3+jSItuPPD/J0r/UsiWKv/8ZO/oEhjRaP0M5niuRYsWqmY2GEA==} + peerDependencies: + preact: 10.x + dependencies: + '@preact/signals-core': 1.5.0 + preact: 10.19.1 + dev: false + /@prefresh/babel-plugin@0.5.0: resolution: {integrity: sha512-joAwpkUDwo7ZqJnufXRGzUb+udk20RBgfA8oLPBh5aJH2LeStmV1luBfeJTztPdyCscC2j2SmZ/tVxFRMIxAEw==} dev: true - /@prefresh/core@1.5.1(preact@10.15.1): + /@prefresh/core@1.5.1(preact@10.19.1): resolution: {integrity: sha512-e0mB0Oxtog6ZpKPDBYbzFniFJDIktuKMzOHp7sguntU+ot0yi6dbhJRE9Css1qf0u16wdSZjpL2W2ODWuU05Cw==} peerDependencies: preact: ^10.0.0 dependencies: - preact: 10.15.1 + preact: 10.19.1 dev: true /@prefresh/utils@1.2.0: resolution: {integrity: sha512-KtC/fZw+oqtwOLUFM9UtiitB0JsVX0zLKNyRTA332sqREqSALIIQQxdUCS1P3xR/jT1e2e8/5rwH6gdcMLEmsQ==} dev: true - /@prefresh/vite@2.4.1(preact@10.15.1)(vite@4.4.0): + /@prefresh/vite@2.4.1(preact@10.19.1)(vite@4.5.0): resolution: {integrity: sha512-vthWmEqu8TZFeyrBNc9YE5SiC3DVSzPgsOCp/WQ7FqdHpOIJi7Z8XvCK06rBPOtG4914S52MjG9Ls22eVAiuqQ==} peerDependencies: preact: ^10.4.0 @@ -1491,18 +1698,18 @@ packages: dependencies: '@babel/core': 7.22.9 '@prefresh/babel-plugin': 0.5.0 - '@prefresh/core': 1.5.1(preact@10.15.1) + '@prefresh/core': 1.5.1(preact@10.19.1) '@prefresh/utils': 1.2.0 '@rollup/pluginutils': 4.2.1 - preact: 10.15.1 - vite: 4.4.0 + preact: 10.19.1 + vite: 4.5.0(@types/node@20.9.0) transitivePeerDependencies: - supports-color dev: true - /@puppeteer/browsers@1.3.0(typescript@5.1.6): - resolution: {integrity: sha512-an3QdbNPkuU6qpxpbssxAbjRLJcF+eP4L8UqIY3+6n0sbaVxw5pz7PiCLy9g32XEZuoamUlV5ZQPnA6FxvkIHA==} - engines: {node: '>=16.0.0'} + /@puppeteer/browsers@1.4.6(typescript@5.2.2): + resolution: {integrity: sha512-x4BEjr2SjOPowNeiguzjozQbsc6h437ovD/wu+JpaenxVLm3jkgzHY2xOslMTp50HoTvQreMjiexiGQw1sqZlQ==} + engines: {node: '>=16.3.0'} hasBin: true peerDependencies: typescript: '>= 4.7.4' @@ -1512,42 +1719,56 @@ packages: dependencies: debug: 4.3.4 extract-zip: 2.0.1 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 progress: 2.0.3 - proxy-from-env: 1.1.0 - tar-fs: 2.1.1 - typescript: 5.1.6 + proxy-agent: 6.3.0 + tar-fs: 3.0.4 + typescript: 5.2.2 unbzip2-stream: 1.4.3 yargs: 17.7.1 transitivePeerDependencies: - supports-color dev: true + /@puppeteer/browsers@1.8.0: + resolution: {integrity: sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==} + engines: {node: '>=16.3.0'} + hasBin: true + dependencies: + debug: 4.3.4 + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.3.1 + tar-fs: 3.0.4 + unbzip2-stream: 1.4.3 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + dev: true + /@remix-run/router@1.11.0: resolution: {integrity: sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ==} engines: {node: '>=14.0.0'} dev: true - /@rollup/plugin-replace@5.0.2(rollup@3.29.2): - resolution: {integrity: sha512-M9YXNekv/C/iHHK+cvORzfRYfPbq0RDD8r0G+bMiTXjNGKulPnCT9O3Ss46WfhI6ZOCgApOP7xAdmCQJ+U2LAA==} + /@rollup/plugin-replace@5.0.5(rollup@3.29.4): + resolution: {integrity: sha512-rYO4fOi8lMaTg/z5Jb+hKnrHHVn8j2lwkqwyS4kTRhKyWOLf2wST2sWXr4WzWiTcoHTp2sTjqUbqIj2E39slKQ==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.4(rollup@3.29.2) - magic-string: 0.27.0 - rollup: 3.29.2 + '@rollup/pluginutils': 5.0.4(rollup@3.29.4) + magic-string: 0.30.5 + rollup: 3.29.4 dev: true - /@rollup/plugin-typescript@11.1.3(rollup@3.29.2)(typescript@5.1.6): - resolution: {integrity: sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==} + /@rollup/plugin-typescript@11.1.5(rollup@3.29.4)(typescript@5.2.2): + resolution: {integrity: sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^2.14.0||^3.0.0 + rollup: ^2.14.0||^3.0.0||^4.0.0 tslib: '*' typescript: '>=3.7.0' peerDependenciesMeta: @@ -1556,10 +1777,10 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.4(rollup@3.29.2) + '@rollup/pluginutils': 5.0.4(rollup@3.29.4) resolve: 1.22.4 - rollup: 3.29.2 - typescript: 5.1.6 + rollup: 3.29.4 + typescript: 5.2.2 dev: true /@rollup/pluginutils@3.1.0(rollup@2.79.1): @@ -1582,7 +1803,7 @@ packages: picomatch: 2.3.1 dev: true - /@rollup/pluginutils@5.0.4(rollup@3.29.2): + /@rollup/pluginutils@5.0.4(rollup@3.29.4): resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==} engines: {node: '>=14.0.0'} peerDependencies: @@ -1594,20 +1815,20 @@ packages: '@types/estree': 1.0.1 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 3.29.2 + rollup: 3.29.4 dev: true /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true - /@sindresorhus/is@5.5.0: - resolution: {integrity: sha512-3rO1QIz6mL0MvFVTOxqhDJRVsLfG/vK2VSlKKPghALA6FhJqU7L+RUHnFvH5BP5HhkWiMQqq514i9ZFTcqoGCQ==} + /@sindresorhus/is@5.6.0: + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} dev: true - /@swc/core-darwin-arm64@1.3.27: - resolution: {integrity: sha512-IKlxkhEy99CnP9nduaf5IJWIFcr6D5cZCjYmCs7nWkjMV+aAieyDO9AX4LT8AcHy6CF7ByOX7SKoqk+gVMAaKw==} + /@swc/core-darwin-arm64@1.3.96: + resolution: {integrity: sha512-8hzgXYVd85hfPh6mJ9yrG26rhgzCmcLO0h1TIl8U31hwmTbfZLzRitFQ/kqMJNbIBCwmNH1RU2QcJnL3d7f69A==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] @@ -1615,8 +1836,8 @@ packages: dev: true optional: true - /@swc/core-darwin-x64@1.3.27: - resolution: {integrity: sha512-MtabZIhFf/dL3vs6UMbd+vJsjIkm2NaFqulGV0Jofy2bfVZPTj/b5pXeOlUsTWy7JcH1uixjdx4RvJRyvqJxQA==} + /@swc/core-darwin-x64@1.3.96: + resolution: {integrity: sha512-mFp9GFfuPg+43vlAdQZl0WZpZSE8sEzqL7sr/7Reul5McUHP0BaLsEzwjvD035ESfkY8GBZdLpMinblIbFNljQ==} engines: {node: '>=10'} cpu: [x64] os: [darwin] @@ -1624,8 +1845,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm-gnueabihf@1.3.27: - resolution: {integrity: sha512-XELMoGcUTAkk+G4buwIIhu6AIr1U418Odt22HUW8+ZvV+Wty2ICgR/myOIhM3xMb6U2L8ay+evMqoVNMQ0RRTg==} + /@swc/core-linux-arm-gnueabihf@1.3.96: + resolution: {integrity: sha512-8UEKkYJP4c8YzYIY/LlbSo8z5Obj4hqcv/fUTHiEePiGsOddgGf7AWjh56u7IoN/0uEmEro59nc1ChFXqXSGyg==} engines: {node: '>=10'} cpu: [arm] os: [linux] @@ -1633,8 +1854,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm64-gnu@1.3.27: - resolution: {integrity: sha512-O6vtT6bnrVR9PzEIuA5U7tIfYo7bv97H9K9Vqy2oyHNeGN0H36DKwS4UqPreHtziXNF5+7ubdUYUkrG/j8UnUQ==} + /@swc/core-linux-arm64-gnu@1.3.96: + resolution: {integrity: sha512-c/IiJ0s1y3Ymm2BTpyC/xr6gOvoqAVETrivVXHq68xgNms95luSpbYQ28rqaZC8bQC8M5zdXpSc0T8DJu8RJGw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -1642,8 +1863,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm64-musl@1.3.27: - resolution: {integrity: sha512-Oa0E1i7dOTWpaEZumKoNbTE/Ap+da6nlhqKVUdYrFDrOBi25tz76SdxZIyvAszzmgY89b5yd1naourKmkPXpww==} + /@swc/core-linux-arm64-musl@1.3.96: + resolution: {integrity: sha512-i5/UTUwmJLri7zhtF6SAo/4QDQJDH2fhYJaBIUhrICmIkRO/ltURmpejqxsM/ye9Jqv5zG7VszMC0v/GYn/7BQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -1651,8 +1872,8 @@ packages: dev: true optional: true - /@swc/core-linux-x64-gnu@1.3.27: - resolution: {integrity: sha512-S3v9H8oL2a8Ur6AjQyhkC6HfBVPOxKMdBhcZmdNuVgEUHbHdbf/Lka85F9IOYXEarMn0FtQw3ywowS22O9L5Uw==} + /@swc/core-linux-x64-gnu@1.3.96: + resolution: {integrity: sha512-USdaZu8lTIkm4Yf9cogct/j5eqtdZqTgcTib4I+NloUW0E/hySou3eSyp3V2UAA1qyuC72ld1otXuyKBna0YKQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -1660,8 +1881,8 @@ packages: dev: true optional: true - /@swc/core-linux-x64-musl@1.3.27: - resolution: {integrity: sha512-6DDkdXlOADpwICFZTRphCR+cIeS8aEYh4NlyzBito0mOWwIIdfCgALzhkTQOzTOkcD42bP97CIoZ97hqV/puOg==} + /@swc/core-linux-x64-musl@1.3.96: + resolution: {integrity: sha512-QYErutd+G2SNaCinUVobfL7jWWjGTI0QEoQ6hqTp7PxCJS/dmKmj3C5ZkvxRYcq7XcZt7ovrYCTwPTHzt6lZBg==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -1669,8 +1890,8 @@ packages: dev: true optional: true - /@swc/core-win32-arm64-msvc@1.3.27: - resolution: {integrity: sha512-baxfH4AbEcaTNo08wxV0W6hiMXwVCxPS4qc0amHpXPti92unvSqeDR1W3C9GjHqzXlWtmCRsq8Ww1pal6ZVLrw==} + /@swc/core-win32-arm64-msvc@1.3.96: + resolution: {integrity: sha512-hjGvvAduA3Un2cZ9iNP4xvTXOO4jL3G9iakhFsgVhpkU73SGmK7+LN8ZVBEu4oq2SUcHO6caWvnZ881cxGuSpg==} engines: {node: '>=10'} cpu: [arm64] os: [win32] @@ -1678,8 +1899,8 @@ packages: dev: true optional: true - /@swc/core-win32-ia32-msvc@1.3.27: - resolution: {integrity: sha512-7iLJnH71k5qCwxv9NcM/P7nIEzTsC7r1sIiQW6bu+CpC8qZvwl0PS+XvQRlLly2gCZM+Le98tksYG14MEh+Hrw==} + /@swc/core-win32-ia32-msvc@1.3.96: + resolution: {integrity: sha512-Far2hVFiwr+7VPCM2GxSmbh3ikTpM3pDombE+d69hkedvYHYZxtTF+2LTKl/sXtpbUnsoq7yV/32c9R/xaaWfw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] @@ -1687,8 +1908,8 @@ packages: dev: true optional: true - /@swc/core-win32-x64-msvc@1.3.27: - resolution: {integrity: sha512-mFM907PDw/jrQ44+TRjIVGEOy2Mu06mMMz0HPMFuRsBzl5t0Kajp3vmn8FkkpS9wH5982VPi6hPYVTb7QJo5Qg==} + /@swc/core-win32-x64-msvc@1.3.96: + resolution: {integrity: sha512-4VbSAniIu0ikLf5mBX81FsljnfqjoVGleEkCQv4+zRlyZtO3FHoDPkeLVoy6WRlj7tyrRcfUJ4mDdPkbfTO14g==} engines: {node: '>=10'} cpu: [x64] os: [win32] @@ -1696,21 +1917,37 @@ packages: dev: true optional: true - /@swc/core@1.3.27: - resolution: {integrity: sha512-praRNgpeYGvwDIm/Cl6JU+yHMvwVraL0U6ejMgGyzvpcm1FVsZd1/EYXGqzbBJ0ALv7Gx4eK56h4GnwV6d4L0w==} + /@swc/core@1.3.96: + resolution: {integrity: sha512-zwE3TLgoZwJfQygdv2SdCK9mRLYluwDOM53I+dT6Z5ZvrgVENmY3txvWDvduzkV+/8IuvrRbVezMpxcojadRdQ==} engines: {node: '>=10'} requiresBuild: true + peerDependencies: + '@swc/helpers': ^0.5.0 + peerDependenciesMeta: + '@swc/helpers': + optional: true + dependencies: + '@swc/counter': 0.1.2 + '@swc/types': 0.1.5 optionalDependencies: - '@swc/core-darwin-arm64': 1.3.27 - '@swc/core-darwin-x64': 1.3.27 - '@swc/core-linux-arm-gnueabihf': 1.3.27 - '@swc/core-linux-arm64-gnu': 1.3.27 - '@swc/core-linux-arm64-musl': 1.3.27 - '@swc/core-linux-x64-gnu': 1.3.27 - '@swc/core-linux-x64-musl': 1.3.27 - '@swc/core-win32-arm64-msvc': 1.3.27 - '@swc/core-win32-ia32-msvc': 1.3.27 - '@swc/core-win32-x64-msvc': 1.3.27 + '@swc/core-darwin-arm64': 1.3.96 + '@swc/core-darwin-x64': 1.3.96 + '@swc/core-linux-arm-gnueabihf': 1.3.96 + '@swc/core-linux-arm64-gnu': 1.3.96 + '@swc/core-linux-arm64-musl': 1.3.96 + '@swc/core-linux-x64-gnu': 1.3.96 + '@swc/core-linux-x64-musl': 1.3.96 + '@swc/core-win32-arm64-msvc': 1.3.96 + '@swc/core-win32-ia32-msvc': 1.3.96 + '@swc/core-win32-x64-msvc': 1.3.96 + dev: true + + /@swc/counter@0.1.2: + resolution: {integrity: sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==} + dev: true + + /@swc/types@0.1.5: + resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} dev: true /@szmarczak/http-timer@5.0.1: @@ -1772,13 +2009,13 @@ packages: pretty-format: 27.5.1 dev: true - /@testing-library/jest-dom@5.16.5: - resolution: {integrity: sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==} + /@testing-library/jest-dom@5.17.0: + resolution: {integrity: sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==} engines: {node: '>=8', npm: '>=6', yarn: '>=1'} dependencies: '@adobe/css-tools': 4.2.0 '@babel/runtime': 7.22.6 - '@types/testing-library__jest-dom': 5.14.8 + '@types/testing-library__jest-dom': 5.14.9 aria-query: 5.1.3 chalk: 3.0.0 css.escape: 1.5.1 @@ -1787,8 +2024,8 @@ packages: redent: 3.0.0 dev: true - /@testing-library/react@13.0.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w==} + /@testing-library/react@13.4.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==} engines: {node: '>=12'} peerDependencies: react: ^18.0.0 @@ -1796,7 +2033,7 @@ packages: dependencies: '@babel/runtime': 7.22.6 '@testing-library/dom': 8.20.1 - '@types/react-dom': 18.2.7 + '@types/react-dom': 18.2.15 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true @@ -1806,6 +2043,10 @@ packages: engines: {node: '>= 10'} dev: true + /@tootallnate/quickjs-emscripten@0.23.0: + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + dev: true + /@types/aria-query@5.0.1: resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} dev: true @@ -1823,20 +2064,20 @@ packages: /@types/babel__generator@7.6.7: resolution: {integrity: sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==} dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.22.5 dev: true /@types/babel__template@7.4.4: resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} dependencies: '@babel/parser': 7.22.7 - '@babel/types': 7.23.3 + '@babel/types': 7.22.5 dev: true /@types/babel__traverse@7.20.4: resolution: {integrity: sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==} dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.22.5 dev: true /@types/chai-subset@1.3.3: @@ -1857,8 +2098,8 @@ packages: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: true - /@types/http-cache-semantics@4.0.1: - resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} + /@types/http-cache-semantics@4.0.4: + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} dev: true /@types/is-ci@3.0.0: @@ -1890,10 +2131,10 @@ packages: pretty-format: 29.6.1 dev: true - /@types/jsdom@21.1.1: - resolution: {integrity: sha512-cZFuoVLtzKP3gmq9eNosUL1R50U+USkbLtUQ1bYVgl/lKp0FZM7Cq4aIHAL8oIvQ17uSHi7jXPtfDOdjPwBE7A==} + /@types/jsdom@21.1.5: + resolution: {integrity: sha512-sBK/3YjS3uuPj+HzZyhB4GGTnFmk0mdyQfhzZ/sqs9ciyG41QJdZZdwcPa6OfW97OTNTwl5tBAsfEOm/dui9pQ==} dependencies: - '@types/node': 18.15.3 + '@types/node': 20.9.0 '@types/tough-cookie': 4.0.2 parse5: 7.1.2 dev: true @@ -1910,12 +2151,16 @@ packages: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: true - /@types/node@18.15.3: - resolution: {integrity: sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw==} + /@types/node@18.18.9: + resolution: {integrity: sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ==} + dependencies: + undici-types: 5.26.5 dev: true - /@types/node@20.4.8: - resolution: {integrity: sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==} + /@types/node@20.9.0: + resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==} + dependencies: + undici-types: 5.26.5 dev: true /@types/normalize-package-data@2.4.1: @@ -1926,14 +2171,14 @@ packages: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} dev: true - /@types/react-dom@18.2.7: - resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} + /@types/react-dom@18.2.15: + resolution: {integrity: sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==} dependencies: - '@types/react': 18.2.15 + '@types/react': 18.2.37 dev: true - /@types/react@18.2.15: - resolution: {integrity: sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==} + /@types/react@18.2.37: + resolution: {integrity: sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.3 @@ -1952,8 +2197,8 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true - /@types/testing-library__jest-dom@5.14.8: - resolution: {integrity: sha512-NRfJE9Cgpmu4fx716q9SYmU4jxxhYRU1BQo239Txt/9N3EC745XZX1Yl7h/SBIDlo1ANVOCRB4YDXjaQdoKCHQ==} + /@types/testing-library__jest-dom@5.14.9: + resolution: {integrity: sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==} dependencies: '@types/jest': 29.5.3 dev: true @@ -1970,10 +2215,10 @@ packages: resolution: {integrity: sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==} dev: true - /@types/ws@8.5.5: - resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} + /@types/ws@8.5.9: + resolution: {integrity: sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==} dependencies: - '@types/node': 18.15.3 + '@types/node': 20.9.0 dev: true /@types/yargs-parser@21.0.0: @@ -1986,15 +2231,15 @@ packages: '@types/yargs-parser': 21.0.0 dev: true - /@types/yauzl@2.10.0: - resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} + /@types/yauzl@2.10.3: + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 18.15.3 + '@types/node': 20.9.0 dev: true optional: true - /@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.1.6): + /@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.2.2): resolution: {integrity: sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2006,10 +2251,10 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.1.6) + '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/type-utils': 6.10.0(eslint@8.53.0)(typescript@5.1.6) - '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.1.6) + '@typescript-eslint/type-utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.10.0 debug: 4.3.4 eslint: 8.53.0 @@ -2017,13 +2262,13 @@ packages: ignore: 5.2.4 natural-compare: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.1.6) - typescript: 5.1.6 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.10.0(eslint@8.53.0)(typescript@5.1.6): + /@typescript-eslint/parser@6.10.0(eslint@8.53.0)(typescript@5.2.2): resolution: {integrity: sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2035,11 +2280,11 @@ packages: dependencies: '@typescript-eslint/scope-manager': 6.10.0 '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.1.6) + '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.10.0 debug: 4.3.4 eslint: 8.53.0 - typescript: 5.1.6 + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true @@ -2052,7 +2297,7 @@ packages: '@typescript-eslint/visitor-keys': 6.10.0 dev: true - /@typescript-eslint/type-utils@6.10.0(eslint@8.53.0)(typescript@5.1.6): + /@typescript-eslint/type-utils@6.10.0(eslint@8.53.0)(typescript@5.2.2): resolution: {integrity: sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2062,12 +2307,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.1.6) - '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.1.6) + '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) + '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) debug: 4.3.4 eslint: 8.53.0 - ts-api-utils: 1.0.3(typescript@5.1.6) - typescript: 5.1.6 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true @@ -2077,7 +2322,7 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.10.0(typescript@5.1.6): + /@typescript-eslint/typescript-estree@6.10.0(typescript@5.2.2): resolution: {integrity: sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2092,13 +2337,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.1.6) - typescript: 5.1.6 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.10.0(eslint@8.53.0)(typescript@5.1.6): + /@typescript-eslint/utils@6.10.0(eslint@8.53.0)(typescript@5.2.2): resolution: {integrity: sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2109,7 +2354,7 @@ packages: '@types/semver': 7.5.0 '@typescript-eslint/scope-manager': 6.10.0 '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.1.6) + '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) eslint: 8.53.0 semver: 7.5.4 transitivePeerDependencies: @@ -2129,16 +2374,18 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitejs/plugin-react-swc@3.0.1(vite@4.4.0): - resolution: {integrity: sha512-3GQ2oruZO9j8dSHcI0MUeOZQBhjYyDQsF/pKY4Px+CJxn0M16OhgFeEzUjeuwci4zhhjoNIDE9aFNaV5GMQ09g==} + /@vitejs/plugin-react-swc@3.4.1(vite@4.5.0): + resolution: {integrity: sha512-7YQOQcVV5x1luD8nkbCDdyYygFvn1hjqJk68UvNAzY2QG4o4N5EwAhLLFNOcd1HrdMwDl0VElP8VutoWf9IvJg==} peerDependencies: vite: ^4 dependencies: - '@swc/core': 1.3.27 - vite: 4.4.0 + '@swc/core': 1.3.96 + vite: 4.5.0(@types/node@20.9.0) + transitivePeerDependencies: + - '@swc/helpers' dev: true - /@vitejs/plugin-react@4.1.1(vite@4.4.8): + /@vitejs/plugin-react@4.1.1(vite@4.5.0): resolution: {integrity: sha512-Jie2HERK+uh27e+ORXXwEP5h0Y2lS9T2PRGbfebiHGlwzDO0dEnd2aNtOR/qjBlPb1YgxwAONeblL1xqLikLag==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -2149,7 +2396,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.3) '@types/babel__core': 7.20.4 react-refresh: 0.14.0 - vite: 4.4.8(@types/node@18.15.3) + vite: 4.5.0(@types/node@20.9.0) transitivePeerDependencies: - supports-color dev: true @@ -2161,7 +2408,7 @@ packages: dependencies: modern-node-polyfills: 0.1.3(rollup@2.79.1) sirv: 2.0.3 - vitest: 0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.13.1) + vitest: 0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.22.1) transitivePeerDependencies: - rollup dev: true @@ -2204,22 +2451,23 @@ packages: pretty-format: 29.6.1 dev: true - /@wdio/config@8.12.1: - resolution: {integrity: sha512-6DfTU+5Ugg6HKMSqVNCLEgdFd7l+QnaMoDe2/tZ8zoYNdJlFu0NfClXLL4qnTCCjebmz3eu0/O+aRPJyxo6GGQ==} + /@wdio/config@8.22.1: + resolution: {integrity: sha512-ttxvtKFaOB5BJ6eDl1Lcq8STLN3V+yOEEkVXIrNqOdFOrAaljqzX20vaEmNtj9pQIoTZs2WoX8K2cmXdyxw+DA==} engines: {node: ^16.13 || >=18} dependencies: - '@wdio/logger': 8.11.0 - '@wdio/types': 8.10.4 - '@wdio/utils': 8.12.1 + '@wdio/logger': 8.16.17 + '@wdio/types': 8.21.0 + '@wdio/utils': 8.22.0 decamelize: 6.0.0 deepmerge-ts: 5.1.0 - glob: 10.3.3 + glob: 10.3.10 import-meta-resolve: 3.0.0 - read-pkg-up: 9.1.0 + transitivePeerDependencies: + - supports-color dev: true - /@wdio/logger@8.11.0: - resolution: {integrity: sha512-IsuKSaYi7NKEdgA57h8muzlN/MVp1dQG+V4C//7g4m03YJUnNQLvDhJzLjdeNTfvZy61U7foQSyt+3ktNzZkXA==} + /@wdio/logger@8.16.17: + resolution: {integrity: sha512-zeQ41z3T+b4IsrriZZipayXxLNDuGsm7TdExaviNGojPVrIsQUCSd/FvlLHM32b7ZrMyInHenu/zx1cjAZO71g==} engines: {node: ^16.13 || >=18} dependencies: chalk: 5.3.0 @@ -2228,32 +2476,44 @@ packages: strip-ansi: 7.1.0 dev: true - /@wdio/protocols@8.11.0: - resolution: {integrity: sha512-eXTMYt/XoaX53H/Q2qmsn1uWthIC5aSTGtX9YyXD/AkagG2hXeX3lLmzNWBaSIvKR+vWXRYbg3Y/7IvL2s25Wg==} + /@wdio/protocols@8.22.0: + resolution: {integrity: sha512-2y5lTYAAzQWvExL1FGCe6gujVpOpTxk+czT0Qx0j0iUlfdOwp9gWVLYl8ochTJHzfeM45GHvuZ/ndT52grsTtg==} dev: true /@wdio/repl@8.10.1: resolution: {integrity: sha512-VZ1WFHTNKjR8Ga97TtV2SZM6fvRjWbYI2i/f4pJB4PtusorKvONAMJf2LQcUBIyzbVobqr7KSrcjmSwRolI+yw==} engines: {node: ^16.13 || >=18} dependencies: - '@types/node': 20.4.8 + '@types/node': 20.9.0 dev: true - /@wdio/types@8.10.4: - resolution: {integrity: sha512-aLJ1QQW+hhALeRK3bvMLjIrlUVyhOs3Od+91pR4Z4pLwyeNG1bJZCJRD5bAJK/mm7CnFa0NsdixPS9jJxZcRrw==} + /@wdio/types@8.21.0: + resolution: {integrity: sha512-mZFOipmu541z0BXBW7mBAUjM4zZWhNnP/w321OSYx082Jy4d0UHMFXYWaOC98DIMBPahJu/yLX2WH5iCrazKSA==} engines: {node: ^16.13 || >=18} dependencies: - '@types/node': 20.4.8 + '@types/node': 20.9.0 dev: true - /@wdio/utils@8.12.1: - resolution: {integrity: sha512-VmF6O++84FTH3AKaVFyqn0MJA65/1G6dbm6p61KBqkD25LxaWo4398lCCbt264hzBIobtXRZoQ87bSxdfnlUKQ==} + /@wdio/utils@8.22.0: + resolution: {integrity: sha512-n09ZLfe6NADQ7XyeO45nPBtNHi8nwu1RpOI18c94SrRS7gmO0CQWpjSilJCoHvu10ekUPJE7Oh/1Nw28w7ceVg==} engines: {node: ^16.13 || >=18} dependencies: - '@wdio/logger': 8.11.0 - '@wdio/types': 8.10.4 + '@puppeteer/browsers': 1.8.0 + '@wdio/logger': 8.16.17 + '@wdio/types': 8.21.0 + decamelize: 6.0.0 + deepmerge-ts: 5.1.0 + edgedriver: 5.3.8 + geckodriver: 4.2.1 + get-port: 7.0.0 + got: 13.0.0 import-meta-resolve: 3.0.0 - p-iteration: 1.1.8 + locate-app: 2.1.0 + safaridriver: 0.1.0 + split2: 4.2.0 + wait-port: 1.1.0 + transitivePeerDependencies: + - supports-color dev: true /abab@2.0.6: @@ -2288,6 +2548,15 @@ packages: - supports-color dev: true + /agent-base@7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: @@ -2348,33 +2617,29 @@ packages: picomatch: 2.3.1 dev: true - /archiver-utils@2.1.0: - resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} - engines: {node: '>= 6'} + /archiver-utils@4.0.1: + resolution: {integrity: sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==} + engines: {node: '>= 12.0.0'} dependencies: - glob: 7.2.3 + glob: 8.1.0 graceful-fs: 4.2.11 lazystream: 1.0.1 - lodash.defaults: 4.2.0 - lodash.difference: 4.5.0 - lodash.flatten: 4.4.0 - lodash.isplainobject: 4.0.6 - lodash.union: 4.6.0 + lodash: 4.17.21 normalize-path: 3.0.0 - readable-stream: 2.3.8 + readable-stream: 3.6.2 dev: true - /archiver@5.3.1: - resolution: {integrity: sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w==} - engines: {node: '>= 10'} + /archiver@6.0.1: + resolution: {integrity: sha512-CXGy4poOLBKptiZH//VlWdFuUC1RESbdZjGjILwBuZ73P7WkAUN0htfSfBq/7k6FRFlpu7bg4JOkj1vU9G6jcQ==} + engines: {node: '>= 12.0.0'} dependencies: - archiver-utils: 2.1.0 - async: 3.2.4 + archiver-utils: 4.0.1 + async: 3.2.5 buffer-crc32: 0.2.13 readable-stream: 3.6.2 readdir-glob: 1.1.3 - tar-stream: 2.2.0 - zip-stream: 4.1.0 + tar-stream: 3.1.6 + zip-stream: 5.0.1 dev: true /arg@5.0.2: @@ -2440,27 +2705,34 @@ packages: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true - /async@3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + /ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.2 + dev: true + + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} dev: true /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: true - /autoprefixer@10.4.14(postcss@8.4.27): - resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} + /autoprefixer@10.4.16(postcss@8.4.31): + resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: - browserslist: 4.21.9 - caniuse-lite: 1.0.30001512 - fraction.js: 4.2.0 + browserslist: 4.22.1 + caniuse-lite: 1.0.30001561 + fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.27 + postcss: 8.4.31 postcss-value-parser: 4.2.0 dev: true @@ -2469,6 +2741,10 @@ packages: engines: {node: '>= 0.4'} dev: true + /b4a@1.6.4: + resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + dev: true + /babel-plugin-transform-hook-names@1.0.2(@babel/core@7.23.3): resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==} peerDependencies: @@ -2485,6 +2761,11 @@ packages: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: true + /basic-ftp@5.0.3: + resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==} + engines: {node: '>=10.0.0'} + dev: true + /better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} @@ -2492,17 +2773,25 @@ packages: is-windows: 1.0.2 dev: true + /big-integer@1.6.51: + resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} + engines: {node: '>=0.6'} + dev: true + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: true - /bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + /binary@0.3.0: + resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 + buffers: 0.1.1 + chainsaw: 0.1.0 + dev: true + + /bluebird@3.4.7: + resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} dev: true /brace-expansion@1.1.11: @@ -2531,21 +2820,26 @@ packages: wcwidth: 1.0.1 dev: true - /browserslist@4.21.9: - resolution: {integrity: sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==} + /browserslist@4.22.1: + resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001512 - electron-to-chromium: 1.4.451 - node-releases: 2.0.12 - update-browserslist-db: 1.0.11(browserslist@4.21.9) + caniuse-lite: 1.0.30001561 + electron-to-chromium: 1.4.581 + node-releases: 2.0.13 + update-browserslist-db: 1.0.13(browserslist@4.22.1) dev: true /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} dev: true + /buffer-indexof-polyfill@1.0.2: + resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} + engines: {node: '>=0.10'} + dev: true + /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: @@ -2553,6 +2847,11 @@ packages: ieee754: 1.2.1 dev: true + /buffers@0.1.1: + resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} + engines: {node: '>=0.2.0'} + dev: true + /cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -2563,14 +2862,14 @@ packages: engines: {node: '>=14.16'} dev: true - /cacheable-request@10.2.12: - resolution: {integrity: sha512-qtWGB5kn2OLjx47pYUkWicyOpK1vy9XZhq8yRTXOy+KAmjjESSRLx6SiExnnaGGUP1NM6/vmygMu0fGylNh9tw==} + /cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} dependencies: - '@types/http-cache-semantics': 4.0.1 + '@types/http-cache-semantics': 4.0.4 get-stream: 6.0.1 http-cache-semantics: 4.1.1 - keyv: 4.5.2 + keyv: 4.5.4 mimic-response: 4.0.0 normalize-url: 8.0.0 responselike: 3.0.0 @@ -2607,8 +2906,8 @@ packages: engines: {node: '>=6'} dev: true - /caniuse-lite@1.0.30001512: - resolution: {integrity: sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==} + /caniuse-lite@1.0.30001561: + resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==} dev: true /chai@4.3.7: @@ -2624,6 +2923,12 @@ packages: type-detect: 4.0.8 dev: true + /chainsaw@0.1.0: + resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} + dependencies: + traverse: 0.3.9 + dev: true + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -2682,32 +2987,15 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 - dev: true - - /chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: true - - /chrome-launcher@0.15.2: - resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==} - engines: {node: '>=12.13.0'} - hasBin: true - dependencies: - '@types/node': 18.15.3 - escape-string-regexp: 4.0.0 - is-wsl: 2.2.0 - lighthouse-logger: 1.4.2 - transitivePeerDependencies: - - supports-color + fsevents: 2.3.3 dev: true - /chromium-bidi@0.4.9(devtools-protocol@0.0.1120988): - resolution: {integrity: sha512-u3DC6XwgLCA9QJ5ak1voPslCmacQdulZNCPsI3qNXxSnEcZS7DFIbww+5RM2bznMEje7cc0oydavRLRvOIZtHw==} + /chromium-bidi@0.4.16(devtools-protocol@0.0.1147663): + resolution: {integrity: sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==} peerDependencies: devtools-protocol: '*' dependencies: - devtools-protocol: 0.0.1120988 + devtools-protocol: 0.0.1147663 mitt: 3.0.0 dev: true @@ -2775,12 +3063,17 @@ packages: engines: {node: '>= 6'} dev: true - /compress-commons@4.1.1: - resolution: {integrity: sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==} - engines: {node: '>= 10'} + /commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + dev: true + + /compress-commons@5.0.1: + resolution: {integrity: sha512-MPh//1cERdLtqwO3pOFLeXtpuai0Y2WCd5AhtKxznqM7WtaMYaOEMSgn45d9D10sIHSfIKE603HlOp8OPGrvag==} + engines: {node: '>= 12.0.0'} dependencies: - buffer-crc32: 0.2.13 - crc32-stream: 4.0.2 + crc-32: 1.2.2 + crc32-stream: 5.0.0 normalize-path: 3.0.0 readable-stream: 3.6.2 dev: true @@ -2789,8 +3082,8 @@ packages: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} dev: true - /concurrently@8.2.0: - resolution: {integrity: sha512-nnLMxO2LU492mTUj9qX/az/lESonSZu81UznYDoXtz1IQf996ixVqPAgHXwvHiHCAef/7S8HIK+fTFK7Ifk8YA==} + /concurrently@8.2.2: + resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==} engines: {node: ^14.13.0 || >=16.0.0} hasBin: true dependencies: @@ -2823,18 +3116,18 @@ packages: hasBin: true dev: true - /crc32-stream@4.0.2: - resolution: {integrity: sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==} - engines: {node: '>= 10'} + /crc32-stream@5.0.0: + resolution: {integrity: sha512-B0EPa1UK+qnpBZpG+7FgPCu0J2ETLpXq09o9BkLkEAhdB6Z61Qo4pJ3JYu0c+Qi+/SAL7QThqnzS06pmSSyZaw==} + engines: {node: '>= 12.0.0'} dependencies: crc-32: 1.2.2 readable-stream: 3.6.2 dev: true - /cross-fetch@3.1.6: - resolution: {integrity: sha512-riRvo06crlE8HiqOwIpQhxwdOk4fOeR7FVM/wXoxchFEqMNUjvbs3bfo4OTgMEMHzppd4DxFBDbyySj8Cv781g==} + /cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} dependencies: - node-fetch: 2.6.12 + node-fetch: 2.7.0 transitivePeerDependencies: - encoding dev: true @@ -2914,19 +3207,29 @@ packages: stream-transform: 2.1.3 dev: true - /daisyui@3.5.1: - resolution: {integrity: sha512-7GG+9QXnr2qQMCqnyFU8TxpaOYJigXiEtmzoivmiiZZHvxqIwYdaMAkgivqTVxEgy3Hot3m1suzZjmt1zUrvmA==} + /daisyui@3.9.4: + resolution: {integrity: sha512-fvi2RGH4YV617/6DntOVGcOugOPym9jTGWW2XySb5ZpvdWO4L7bEG77VHirrnbRUEWvIEVXkBpxUz2KFj0rVnA==} engines: {node: '>=16.9.0'} dependencies: colord: 2.9.3 css-selector-tokenizer: 0.8.0 - postcss: 8.4.27 - postcss-js: 4.0.1(postcss@8.4.27) - tailwindcss: 3.3.3 + postcss: 8.4.31 + postcss-js: 4.0.1(postcss@8.4.31) + tailwindcss: 3.3.5 transitivePeerDependencies: - ts-node dev: true + /data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + dev: true + + /data-uri-to-buffer@6.0.1: + resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==} + engines: {node: '>= 14'} + dev: true + /data-urls@4.0.0: resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} engines: {node: '>=14'} @@ -2943,17 +3246,6 @@ packages: '@babel/runtime': 7.22.6 dev: true - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: true - /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -3053,6 +3345,15 @@ packages: object-keys: 1.1.1 dev: true + /degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + dev: true + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -3063,38 +3364,12 @@ packages: engines: {node: '>=8'} dev: true - /devtools-protocol@0.0.1120988: - resolution: {integrity: sha512-39fCpE3Z78IaIPChJsP6Lhmkbf4dWXOmzLk/KFTdRkNk/0JymRIfUynDVRndV9HoDz8PyalK1UH21ST/ivwW5Q==} + /devtools-protocol@0.0.1147663: + resolution: {integrity: sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==} dev: true - /devtools-protocol@0.0.1161598: - resolution: {integrity: sha512-MQNeVRDiJ9yAfHUlumx7OCweu15GgMIqEIvz/DTZwpZKjT7oGo9FcwUqS7PyH0mDJsWnuJIn41BZ4SPoQbZfew==} - dev: true - - /devtools@8.12.1(typescript@5.1.6): - resolution: {integrity: sha512-R72raQLN1lDSqbr2DVj9SRh07JRyojzmrcLa33VBa2nw3cf5ZyHOHe0DgxlJ/5c2Dfs1+wGNJy16gWKGBq+xgg==} - engines: {node: ^16.13 || >=18} - dependencies: - '@types/node': 20.4.8 - '@wdio/config': 8.12.1 - '@wdio/logger': 8.11.0 - '@wdio/protocols': 8.11.0 - '@wdio/types': 8.10.4 - '@wdio/utils': 8.12.1 - chrome-launcher: 0.15.2 - edge-paths: 3.0.5 - import-meta-resolve: 3.0.0 - puppeteer-core: 20.3.0(typescript@5.1.6) - query-selector-shadow-dom: 1.0.1 - ua-parser-js: 1.0.35 - uuid: 9.0.0 - which: 3.0.1 - transitivePeerDependencies: - - bufferutil - - encoding - - supports-color - - typescript - - utf-8-validate + /devtools-protocol@0.0.1213968: + resolution: {integrity: sha512-o4n/beY+3CcZwFctYapjGelKptR4AuQT5gXS1Kvgbig+ArwkxK7f8wDVuD1wsoswiJWCwV6OK+Qb7vhNzNmABQ==} dev: true /didyoumean@1.2.2: @@ -3135,6 +3410,12 @@ packages: webidl-conversions: 7.0.0 dev: true + /duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + dependencies: + readable-stream: 2.3.8 + dev: true + /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true @@ -3147,8 +3428,21 @@ packages: which: 2.0.2 dev: true - /electron-to-chromium@1.4.451: - resolution: {integrity: sha512-YYbXHIBxAHe3KWvGOJOuWa6f3tgow44rBW+QAuwVp2DvGqNZeE//K2MowNdWS7XE8li5cgQDrX1LdBr41LufkA==} + /edgedriver@5.3.8: + resolution: {integrity: sha512-FWLPDuwJDeGGgtmlqTXb4lQi/HV9yylLo1F9O1g9TLqSemA5T6xH28seUIfyleVirLFtDQyKNUxKsMhMT4IfnA==} + hasBin: true + requiresBuild: true + dependencies: + '@wdio/logger': 8.16.17 + decamelize: 6.0.0 + edge-paths: 3.0.5 + node-fetch: 3.3.2 + unzipper: 0.10.14 + which: 4.0.0 + dev: true + + /electron-to-chromium@1.4.581: + resolution: {integrity: sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==} dev: true /emoji-regex@8.0.0: @@ -3510,6 +3804,36 @@ packages: '@esbuild/win32-x64': 0.18.18 dev: true + /esbuild@0.19.5: + resolution: {integrity: sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.19.5 + '@esbuild/android-arm64': 0.19.5 + '@esbuild/android-x64': 0.19.5 + '@esbuild/darwin-arm64': 0.19.5 + '@esbuild/darwin-x64': 0.19.5 + '@esbuild/freebsd-arm64': 0.19.5 + '@esbuild/freebsd-x64': 0.19.5 + '@esbuild/linux-arm': 0.19.5 + '@esbuild/linux-arm64': 0.19.5 + '@esbuild/linux-ia32': 0.19.5 + '@esbuild/linux-loong64': 0.19.5 + '@esbuild/linux-mips64el': 0.19.5 + '@esbuild/linux-ppc64': 0.19.5 + '@esbuild/linux-riscv64': 0.19.5 + '@esbuild/linux-s390x': 0.19.5 + '@esbuild/linux-x64': 0.19.5 + '@esbuild/netbsd-x64': 0.19.5 + '@esbuild/openbsd-x64': 0.19.5 + '@esbuild/sunos-x64': 0.19.5 + '@esbuild/win32-arm64': 0.19.5 + '@esbuild/win32-ia32': 0.19.5 + '@esbuild/win32-x64': 0.19.5 + dev: true + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -3530,6 +3854,18 @@ packages: engines: {node: '>=10'} dev: true + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + /eslint-scope@7.2.2: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3647,7 +3983,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/expect-utils': 29.6.1 - '@types/node': 18.15.3 + '@types/node': 20.9.0 jest-get-type: 29.4.3 jest-matcher-utils: 29.6.1 jest-message-util: 29.6.1 @@ -3676,7 +4012,7 @@ packages: get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: - '@types/yauzl': 2.10.0 + '@types/yauzl': 2.10.3 transitivePeerDependencies: - supports-color dev: true @@ -3689,6 +4025,10 @@ packages: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true + /fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + dev: true + /fast-glob@3.3.0: resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==} engines: {node: '>=8.6.0'} @@ -3724,6 +4064,14 @@ packages: pend: 1.2.0 dev: true + /fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.2.1 + dev: true + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -3754,14 +4102,6 @@ packages: path-exists: 4.0.0 dev: true - /find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - dev: true - /find-yarn-workspace-root2@1.2.16: resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} dependencies: @@ -3792,7 +4132,7 @@ packages: engines: {node: '>=14'} dependencies: cross-spawn: 7.0.3 - signal-exit: 4.0.2 + signal-exit: 4.1.0 dev: true /form-data-encoder@2.1.4: @@ -3809,12 +4149,15 @@ packages: mime-types: 2.1.35 dev: true - /fraction.js@4.2.0: - resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + /formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + dependencies: + fetch-blob: 3.2.0 dev: true - /fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} dev: true /fs-extra@7.0.1: @@ -3839,18 +4182,32 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true dev: true optional: true + /fstream@1.0.12: + resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} + engines: {node: '>=0.6'} + dependencies: + graceful-fs: 4.2.11 + inherits: 2.0.4 + mkdirp: 0.5.6 + rimraf: 2.7.1 + dev: true + /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: true + /function.prototype.name@1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} engines: {node: '>= 0.4'} @@ -3865,6 +4222,24 @@ packages: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true + /geckodriver@4.2.1: + resolution: {integrity: sha512-4m/CRk0OI8MaANRuFIahvOxYTSjlNAO2p9JmE14zxueknq6cdtB5M9UGRQ8R9aMV0bLGNVHHDnDXmoXdOwJfWg==} + engines: {node: ^16.13 || >=18 || >=20} + hasBin: true + requiresBuild: true + dependencies: + '@wdio/logger': 8.16.17 + decamelize: 6.0.0 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + node-fetch: 3.3.2 + tar-fs: 3.0.4 + unzipper: 0.10.14 + which: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -3888,6 +4263,11 @@ packages: has-symbols: 1.0.3 dev: true + /get-port@7.0.0: + resolution: {integrity: sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==} + engines: {node: '>=16'} + dev: true + /get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} @@ -3908,6 +4288,18 @@ packages: get-intrinsic: 1.2.1 dev: true + /get-uri@6.0.2: + resolution: {integrity: sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==} + engines: {node: '>= 14'} + dependencies: + basic-ftp: 5.0.3 + data-uri-to-buffer: 6.0.1 + debug: 4.3.4 + fs-extra: 8.1.0 + transitivePeerDependencies: + - supports-color + dev: true + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -3922,15 +4314,15 @@ packages: is-glob: 4.0.3 dev: true - /glob@10.3.3: - resolution: {integrity: sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==} + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true dependencies: foreground-child: 3.1.1 - jackspeak: 2.2.2 + jackspeak: 2.3.6 minimatch: 9.0.3 - minipass: 7.0.2 + minipass: 7.0.4 path-scurry: 1.10.1 dev: true @@ -3956,6 +4348,17 @@ packages: path-is-absolute: 1.0.1 dev: true + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + dev: true + /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -3997,14 +4400,31 @@ packages: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} engines: {node: '>=14.16'} dependencies: - '@sindresorhus/is': 5.5.0 + '@sindresorhus/is': 5.6.0 '@szmarczak/http-timer': 5.0.1 cacheable-lookup: 7.0.0 - cacheable-request: 10.2.12 + cacheable-request: 10.2.14 decompress-response: 6.0.0 form-data-encoder: 2.1.4 get-stream: 6.0.1 - http2-wrapper: 2.2.0 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + dev: true + + /got@13.0.0: + resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} + engines: {node: '>=16'} + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 lowercase-keys: 3.0.0 p-cancelable: 3.0.0 responselike: 3.0.0 @@ -4022,8 +4442,8 @@ packages: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} dev: true - /happy-dom@10.5.2: - resolution: {integrity: sha512-dTA1cDcLOPIkAdykLd9Wo1k8Ly36Hh2OdKGkWEHWuAHb89KcVVRLSj1OFev7ir90xhRLSGCGrEdDvS6u9l13kg==} + /happy-dom@10.11.2: + resolution: {integrity: sha512-rzgmLjLkhyaOdFEyU8CWXzbgyCyM7wJHLqhaoeEVSTyur1fjcUaiNTHx+D4CPaLvx16tGy+SBPd9TVnP/kzL3w==} dependencies: css.escape: 1.5.1 entities: 4.5.0 @@ -4082,15 +4502,15 @@ packages: function-bind: 1.1.1 dev: true - /hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 dev: true - /hosted-git-info@4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} - dependencies: - lru-cache: 6.0.0 + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true /hotscript@1.0.13: @@ -4118,8 +4538,18 @@ packages: - supports-color dev: true - /http2-wrapper@2.2.0: - resolution: {integrity: sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==} + /http-proxy-agent@7.0.0: + resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} engines: {node: '>=10.19.0'} dependencies: quick-lru: 5.1.1 @@ -4136,6 +4566,16 @@ packages: - supports-color dev: true + /https-proxy-agent@7.0.2: + resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + /human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true @@ -4205,6 +4645,14 @@ packages: side-channel: 1.0.4 dev: true + /ip@1.1.8: + resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==} + dev: true + + /ip@2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + dev: true + /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -4264,6 +4712,12 @@ packages: has: 1.0.3 dev: true + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.0 + dev: true + /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} @@ -4271,12 +4725,6 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - dev: true - /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -4402,13 +4850,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - dev: true - /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} dev: true @@ -4421,8 +4862,13 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /jackspeak@2.2.2: - resolution: {integrity: sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg==} + /isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + dev: true + + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} dependencies: '@isaacs/cliui': 8.0.2 @@ -4475,7 +4921,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.1 - '@types/node': 18.15.3 + '@types/node': 20.9.0 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 @@ -4586,8 +5032,8 @@ packages: graceful-fs: 4.2.11 dev: true - /keyv@4.5.2: - resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==} + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: json-buffer: 3.0.1 dev: true @@ -4626,15 +5072,6 @@ packages: type-check: 0.4.0 dev: true - /lighthouse-logger@1.4.2: - resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} - dependencies: - debug: 2.6.9 - marky: 1.2.5 - transitivePeerDependencies: - - supports-color - dev: true - /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -4644,6 +5081,10 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true + /listenercount@1.0.1: + resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} + dev: true + /load-yaml-file@0.2.0: resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} engines: {node: '>=6'} @@ -4659,6 +5100,14 @@ packages: engines: {node: '>=14'} dev: true + /locate-app@2.1.0: + resolution: {integrity: sha512-rcVo/iLUxrd9d0lrmregK/Z5Y5NCpSwf9KlMbPpOHmKmdxdQY1Fj8NDQ5QymJTryCsBLqwmniFv2f3JKbk9Bvg==} + dependencies: + n12: 0.4.0 + type-fest: 2.13.0 + userhome: 1.0.0 + dev: true + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -4673,33 +5122,10 @@ packages: p-locate: 5.0.0 dev: true - /locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-locate: 6.0.0 - dev: true - /lodash.clonedeep@4.5.0: resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} dev: true - /lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - dev: true - - /lodash.difference@4.5.0: - resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} - dev: true - - /lodash.flatten@4.4.0: - resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} - dev: true - - /lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - dev: true - /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true @@ -4708,10 +5134,6 @@ packages: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} dev: true - /lodash.union@4.6.0: - resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} - dev: true - /lodash.zip@4.2.0: resolution: {integrity: sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==} dev: true @@ -4746,9 +5168,11 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true - /lru-cache@10.0.0: - resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==} + /lru-cache@10.0.2: + resolution: {integrity: sha512-Yj9mA8fPiVgOUpByoTZO5pNrcl5Yk37FcSHsUINpAsaBIEZIuqcCclDZJCVxqQShDsmYX8QG63svJiTbOATZwg==} engines: {node: 14 || >=16.14} + dependencies: + semver: 7.5.4 dev: true /lru-cache@4.1.5: @@ -4771,20 +5195,25 @@ packages: yallist: 4.0.0 dev: true + /lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + dev: true + /lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true dev: true - /magic-string@0.27.0: - resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + /magic-string@0.30.3: + resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==} engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /magic-string@0.30.3: - resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==} + /magic-string@0.30.5: + resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 @@ -4800,10 +5229,6 @@ packages: engines: {node: '>=8'} dev: true - /marky@1.2.5: - resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==} - dev: true - /meow@6.1.1: resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} engines: {node: '>=8'} @@ -4890,8 +5315,12 @@ packages: kind-of: 6.0.3 dev: true - /minipass@7.0.2: - resolution: {integrity: sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA==} + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} dev: true @@ -4908,6 +5337,13 @@ packages: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} dev: true + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + /mlly@1.4.0: resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} dependencies: @@ -4938,10 +5374,6 @@ packages: engines: {node: '>=10'} dev: true - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: true - /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: true @@ -4954,6 +5386,10 @@ packages: thenify-all: 1.6.0 dev: true + /n12@0.4.0: + resolution: {integrity: sha512-p/hj4zQ8d3pbbFLQuN1K9honUxiDDhueOWyFLw/XgBv+wZCE44bcLH4CIcsolOceJQduh4Jf7m/LfaTxyGmGtQ==} + dev: true + /nanoid@3.3.6: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -4964,8 +5400,18 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /node-fetch@2.6.12: - resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} + /netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + dev: true + + /node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + dev: true + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} peerDependencies: encoding: ^0.1.0 @@ -4976,29 +5422,28 @@ packages: whatwg-url: 5.0.0 dev: true - /node-releases@2.0.12: - resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} + /node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + dev: true + + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} dev: true /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.4 + resolve: 1.22.8 semver: 5.7.2 validate-npm-package-license: 3.0.4 dev: true - /normalize-package-data@3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} - dependencies: - hosted-git-info: 4.1.0 - is-core-module: 2.13.0 - semver: 7.5.4 - validate-npm-package-license: 3.0.4 - dev: true - /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -5094,11 +5539,6 @@ packages: p-map: 2.1.0 dev: true - /p-iteration@1.1.8: - resolution: {integrity: sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==} - engines: {node: '>=8.0.0'} - dev: true - /p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -5134,13 +5574,6 @@ packages: p-limit: 3.1.0 dev: true - /p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - p-limit: 4.0.0 - dev: true - /p-map@2.1.0: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} @@ -5151,6 +5584,31 @@ packages: engines: {node: '>=6'} dev: true + /pac-proxy-agent@7.0.1: + resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==} + engines: {node: '>= 14'} + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.0 + debug: 4.3.4 + get-uri: 6.0.2 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + pac-resolver: 7.0.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /pac-resolver@7.0.0: + resolution: {integrity: sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==} + engines: {node: '>= 14'} + dependencies: + degenerator: 5.0.1 + ip: 1.1.8 + netmask: 2.0.2 + dev: true + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -5179,11 +5637,6 @@ packages: engines: {node: '>=8'} dev: true - /path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -5202,8 +5655,8 @@ packages: resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} engines: {node: '>=16 || 14 >=14.17'} dependencies: - lru-cache: 10.0.0 - minipass: 7.0.2 + lru-cache: 10.0.2 + minipass: 7.0.4 dev: true /path-type@4.0.0: @@ -5262,29 +5715,29 @@ packages: pathe: 1.1.1 dev: true - /postcss-import@15.1.0(postcss@8.4.27): + /postcss-import@15.1.0(postcss@8.4.31): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.27 + postcss: 8.4.31 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.4 dev: true - /postcss-js@4.0.1(postcss@8.4.27): + /postcss-js@4.0.1(postcss@8.4.31): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.27 + postcss: 8.4.31 dev: true - /postcss-load-config@4.0.1(postcss@8.4.27): + /postcss-load-config@4.0.1(postcss@8.4.31): resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} engines: {node: '>= 14'} peerDependencies: @@ -5297,17 +5750,17 @@ packages: optional: true dependencies: lilconfig: 2.1.0 - postcss: 8.4.27 + postcss: 8.4.31 yaml: 2.3.1 dev: true - /postcss-nested@6.0.1(postcss@8.4.27): + /postcss-nested@6.0.1(postcss@8.4.31): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.27 + postcss: 8.4.31 postcss-selector-parser: 6.0.13 dev: true @@ -5323,8 +5776,8 @@ packages: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} dev: true - /postcss@8.4.27: - resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==} + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.6 @@ -5334,6 +5787,10 @@ packages: /preact@10.15.1: resolution: {integrity: sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==} + dev: false + + /preact@10.19.1: + resolution: {integrity: sha512-ZSsUr6EFlwWH0btdXMj6+X+hJAZ1v+aUzKlfwBGokKB1ZO6Shz+D16LxQhM8f+E/UgkKbVe2tsWXtGTUMCkGpQ==} /preferred-pm@3.0.3: resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} @@ -5383,6 +5840,38 @@ packages: engines: {node: '>=0.4.0'} dev: true + /proxy-agent@6.3.0: + resolution: {integrity: sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + lru-cache: 7.18.3 + pac-proxy-agent: 7.0.1 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /proxy-agent@6.3.1: + resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + http-proxy-agent: 7.0.0 + https-proxy-agent: 7.0.2 + lru-cache: 7.18.3 + pac-proxy-agent: 7.0.1 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: true + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: true @@ -5407,21 +5896,21 @@ packages: engines: {node: '>=6'} dev: true - /puppeteer-core@20.3.0(typescript@5.1.6): - resolution: {integrity: sha512-264pBrIui5bO6NJeOcbJrLa0OCwmA4+WK00JMrLIKTfRiqe2gx8KWTzLsjyw/bizErp3TKS7vt/I0i5fTC+mAw==} - engines: {node: '>=16.0.0'} + /puppeteer-core@20.9.0(typescript@5.2.2): + resolution: {integrity: sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==} + engines: {node: '>=16.3.0'} peerDependencies: typescript: '>= 4.7.4' peerDependenciesMeta: typescript: optional: true dependencies: - '@puppeteer/browsers': 1.3.0(typescript@5.1.6) - chromium-bidi: 0.4.9(devtools-protocol@0.0.1120988) - cross-fetch: 3.1.6 + '@puppeteer/browsers': 1.4.6(typescript@5.2.2) + chromium-bidi: 0.4.16(devtools-protocol@0.0.1147663) + cross-fetch: 4.0.0 debug: 4.3.4 - devtools-protocol: 0.0.1120988 - typescript: 5.1.6 + devtools-protocol: 0.0.1147663 + typescript: 5.2.2 ws: 8.13.0 transitivePeerDependencies: - bufferutil @@ -5442,6 +5931,10 @@ packages: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true + /queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + dev: true + /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} @@ -5466,8 +5959,8 @@ packages: react: 18.2.0 scheduler: 0.23.0 - /react-error-boundary@4.0.10(react@18.2.0): - resolution: {integrity: sha512-pvVKdi77j2OoPHo+p3rorgE43OjDWiqFkaqkJz8sJKK6uf/u8xtzuaVfj5qJ2JnDLIgF1De3zY5AJDijp+LVPA==} + /react-error-boundary@4.0.11(react@18.2.0): + resolution: {integrity: sha512-U13ul67aP5DOSPNSCWQ/eO0AQEYzEFkVljULQIjMV0KlffTAhxuDoBKdO0pb/JZ8mDhMKFZ9NZi0BmLGUiNphw==} peerDependencies: react: '>=16.13.1' dependencies: @@ -5542,15 +6035,6 @@ packages: type-fest: 0.8.1 dev: true - /read-pkg-up@9.1.0: - resolution: {integrity: sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - find-up: 6.3.0 - read-pkg: 7.1.0 - type-fest: 2.19.0 - dev: true - /read-pkg@5.2.0: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} @@ -5561,16 +6045,6 @@ packages: type-fest: 0.6.0 dev: true - /read-pkg@7.1.0: - resolution: {integrity: sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==} - engines: {node: '>=12.20'} - dependencies: - '@types/normalize-package-data': 2.4.1 - normalize-package-data: 3.0.3 - parse-json: 5.2.0 - type-fest: 2.19.0 - dev: true - /read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} @@ -5671,6 +6145,15 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /responselike@3.0.0: resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} engines: {node: '>=14.16'} @@ -5693,6 +6176,13 @@ packages: resolution: {integrity: sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==} dev: true + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true @@ -5700,39 +6190,39 @@ packages: glob: 7.2.3 dev: true - /rimraf@5.0.1: - resolution: {integrity: sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==} + /rimraf@5.0.5: + resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==} engines: {node: '>=14'} hasBin: true dependencies: - glob: 10.3.3 + glob: 10.3.10 dev: true - /rollup-plugin-esbuild@5.0.0(esbuild@0.18.18)(rollup@3.29.2): + /rollup-plugin-esbuild@5.0.0(esbuild@0.19.5)(rollup@3.29.4): resolution: {integrity: sha512-1cRIOHAPh8WQgdQQyyvFdeOdxuiyk+zB5zJ5+YOwrZP4cJ0MT3Fs48pQxrZeyZHcn+klFherytILVfE4aYrneg==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} peerDependencies: esbuild: '>=0.10.1' rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 dependencies: - '@rollup/pluginutils': 5.0.4(rollup@3.29.2) + '@rollup/pluginutils': 5.0.4(rollup@3.29.4) debug: 4.3.4 es-module-lexer: 1.3.1 - esbuild: 0.18.18 + esbuild: 0.19.5 joycon: 3.1.1 jsonc-parser: 3.2.0 - rollup: 3.29.2 + rollup: 3.29.4 transitivePeerDependencies: - supports-color dev: true - /rollup-plugin-node-externals@6.1.1(rollup@3.29.2): - resolution: {integrity: sha512-127OFMkpH5rBVlRHRBDUMk1m1sGuzbGy7so5aj/IkpUb2r3+wOWjR/erUzd2ChEQWPsxsyQG6xpYYvPBAdcBRA==} + /rollup-plugin-node-externals@6.1.2(rollup@3.29.4): + resolution: {integrity: sha512-2TWan0u0/zHcgPrKpIPgKSY8OMqwDAYD380I0hxx7iUQw8mrN34DWwG9sQUMEo5Yy4xd6/5QEAySYgiKN9fdBQ==} engines: {node: '>=16.0.0'} peerDependencies: - rollup: ^3.0.0 + rollup: ^3.0.0 || ^4.0.0 dependencies: - rollup: 3.29.2 + rollup: 3.29.4 dev: true /rollup@2.79.1: @@ -5740,15 +6230,15 @@ packages: engines: {node: '>=10.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true - /rollup@3.29.2: - resolution: {integrity: sha512-CJouHoZ27v6siztc21eEQGo0kIcE5D1gVPA571ez0mMYb25LGYGKnVNXpEj5MGlepmDWGXNjDB5q7uNiPHC11A==} + /rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /rrweb-cssom@0.6.0: @@ -5767,6 +6257,10 @@ packages: tslib: 2.6.0 dev: true + /safaridriver@0.1.0: + resolution: {integrity: sha512-azzzIP3gR1TB9bVPv7QO4Zjw0rR1BWEU/s2aFdUMN48gxDjxEB13grAEuXDmkKPgE74cObymDxmAmZnL3clj4w==} + dev: true + /safe-array-concat@1.0.0: resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==} engines: {node: '>=0.4'} @@ -5827,17 +6321,21 @@ packages: lru-cache: 6.0.0 dev: true - /serialize-error@8.1.0: - resolution: {integrity: sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==} - engines: {node: '>=10'} + /serialize-error@11.0.3: + resolution: {integrity: sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==} + engines: {node: '>=14.16'} dependencies: - type-fest: 0.20.2 + type-fest: 2.19.0 dev: true /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true + /setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + dev: true + /shebang-command@1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -5882,8 +6380,8 @@ packages: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true - /signal-exit@4.0.2: - resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} dev: true @@ -5901,6 +6399,11 @@ packages: engines: {node: '>=8'} dev: true + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: true + /smartwrap@2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} engines: {node: '>=6'} @@ -5914,11 +6417,37 @@ packages: yargs: 15.4.1 dev: true + /socks-proxy-agent@8.0.2: + resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.0 + debug: 4.3.4 + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: true + + /socks@2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: true + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} dev: true + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dev: true + optional: true + /spawn-command@0.0.2: resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} dev: true @@ -5952,6 +6481,11 @@ packages: resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} dev: true + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: true + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true @@ -5984,6 +6518,13 @@ packages: mixme: 0.5.9 dev: true + /streamx@2.15.4: + resolution: {integrity: sha512-uSXKl88bibiUCQ1eMpItRljCzDENcDx18rsfDmV79r0e/ThfrAwxG4Y2FarQZ2G4/21xcOKmFFd1Hue+ZIDwHw==} + dependencies: + fast-fifo: 1.3.2 + queue-tick: 1.0.1 + dev: true + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -6120,8 +6661,8 @@ packages: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true - /tailwindcss@3.3.3: - resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==} + /tailwindcss@3.3.5: + resolution: {integrity: sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -6139,11 +6680,11 @@ packages: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.27 - postcss-import: 15.1.0(postcss@8.4.27) - postcss-js: 4.0.1(postcss@8.4.27) - postcss-load-config: 4.0.1(postcss@8.4.27) - postcss-nested: 6.0.1(postcss@8.4.27) + postcss: 8.4.31 + postcss-import: 15.1.0(postcss@8.4.31) + postcss-js: 4.0.1(postcss@8.4.31) + postcss-load-config: 4.0.1(postcss@8.4.31) + postcss-nested: 6.0.1(postcss@8.4.31) postcss-selector-parser: 6.0.13 resolve: 1.22.4 sucrase: 3.34.0 @@ -6151,24 +6692,20 @@ packages: - ts-node dev: true - /tar-fs@2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + /tar-fs@3.0.4: + resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} dependencies: - chownr: 1.1.4 mkdirp-classic: 0.5.3 pump: 3.0.0 - tar-stream: 2.2.0 + tar-stream: 3.1.6 dev: true - /tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} + /tar-stream@3.1.6: + resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 + b4a: 1.6.4 + fast-fifo: 1.3.2 + streamx: 2.15.4 dev: true /term-size@2.2.1: @@ -6264,6 +6801,10 @@ packages: punycode: 2.3.0 dev: true + /traverse@0.3.9: + resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} + dev: true + /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -6274,13 +6815,13 @@ packages: engines: {node: '>=8'} dev: true - /ts-api-utils@1.0.3(typescript@5.1.6): + /ts-api-utils@1.0.3(typescript@5.2.2): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.1.6 + typescript: 5.2.2 dev: true /ts-interface-checker@0.1.13: @@ -6291,6 +6832,10 @@ packages: resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==} dev: true + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: true + /tty-table@4.2.1: resolution: {integrity: sha512-xz0uKo+KakCQ+Dxj1D/tKn2FSyreSYWzdkL/BYhgN6oMW808g8QRMuh1atAV9fjTPbWBjfbkKQpI/5rEcnAc7g==} engines: {node: '>=8.0.0'} @@ -6305,65 +6850,65 @@ packages: yargs: 17.7.2 dev: true - /turbo-darwin-64@1.10.12: - resolution: {integrity: sha512-vmDfGVPl5/aFenAbOj3eOx3ePNcWVUyZwYr7taRl0ZBbmv2TzjRiFotO4vrKCiTVnbqjQqAFQWY2ugbqCI1kOQ==} + /turbo-darwin-64@1.10.16: + resolution: {integrity: sha512-+Jk91FNcp9e9NCLYlvDDlp2HwEDp14F9N42IoW3dmHI5ZkGSXzalbhVcrx3DOox3QfiNUHxzWg4d7CnVNCuuMg==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.10.12: - resolution: {integrity: sha512-3JliEESLNX2s7g54SOBqqkqJ7UhcOGkS0ywMr5SNuvF6kWVTbuUq7uBU/sVbGq8RwvK1ONlhPvJne5MUqBCTCQ==} + /turbo-darwin-arm64@1.10.16: + resolution: {integrity: sha512-jqGpFZipIivkRp/i+jnL8npX0VssE6IAVNKtu573LXtssZdV/S+fRGYA16tI46xJGxSAivrZ/IcgZrV6Jk80bw==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.10.12: - resolution: {integrity: sha512-siYhgeX0DidIfHSgCR95b8xPee9enKSOjCzx7EjTLmPqPaCiVebRYvbOIYdQWRqiaKh9yfhUtFmtMOMScUf1gg==} + /turbo-linux-64@1.10.16: + resolution: {integrity: sha512-PpqEZHwLoizQ6sTUvmImcRmACyRk9EWLXGlqceogPZsJ1jTRK3sfcF9fC2W56zkSIzuLEP07k5kl+ZxJd8JMcg==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.10.12: - resolution: {integrity: sha512-K/ZhvD9l4SslclaMkTiIrnfcACgos79YcAo4kwc8bnMQaKuUeRpM15sxLpZp3xDjDg8EY93vsKyjaOhdFG2UbA==} + /turbo-linux-arm64@1.10.16: + resolution: {integrity: sha512-TMjFYz8to1QE0fKVXCIvG/4giyfnmqcQIwjdNfJvKjBxn22PpbjeuFuQ5kNXshUTRaTJihFbuuCcb5OYFNx4uw==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.10.12: - resolution: {integrity: sha512-7FSgSwvktWDNOqV65l9AbZwcoueAILeE4L7JvjauNASAjjbuzXGCEq5uN8AQU3U5BOFj4TdXrVmO2dX+lLu8Zg==} + /turbo-windows-64@1.10.16: + resolution: {integrity: sha512-+jsf68krs0N66FfC4/zZvioUap/Tq3sPFumnMV+EBo8jFdqs4yehd6+MxIwYTjSQLIcpH8KoNMB0gQYhJRLZzw==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.10.12: - resolution: {integrity: sha512-gCNXF52dwom1HLY9ry/cneBPOKTBHhzpqhMylcyvJP0vp9zeMQQkt6yjYv+6QdnmELC92CtKNp2FsNZo+z0pyw==} + /turbo-windows-arm64@1.10.16: + resolution: {integrity: sha512-sKm3hcMM1bl0B3PLG4ifidicOGfoJmOEacM5JtgBkYM48ncMHjkHfFY7HrJHZHUnXM4l05RQTpLFoOl/uIo2HQ==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.10.12: - resolution: {integrity: sha512-WM3+jTfQWnB9W208pmP4oeehZcC6JQNlydb/ZHMRrhmQa+htGhWLCzd6Q9rLe0MwZLPpSPFV2/bN5egCLyoKjQ==} + /turbo@1.10.16: + resolution: {integrity: sha512-2CEaK4FIuSZiP83iFa9GqMTQhroW2QryckVqUydmg4tx78baftTOS0O+oDAhvo9r9Nit4xUEtC1RAHoqs6ZEtg==} hasBin: true requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.10.12 - turbo-darwin-arm64: 1.10.12 - turbo-linux-64: 1.10.12 - turbo-linux-arm64: 1.10.12 - turbo-windows-64: 1.10.12 - turbo-windows-arm64: 1.10.12 + turbo-darwin-64: 1.10.16 + turbo-darwin-arm64: 1.10.16 + turbo-linux-64: 1.10.16 + turbo-linux-arm64: 1.10.16 + turbo-windows-64: 1.10.16 + turbo-windows-arm64: 1.10.16 dev: true /type-check@0.4.0: @@ -6398,13 +6943,18 @@ packages: engines: {node: '>=8'} dev: true + /type-fest@2.13.0: + resolution: {integrity: sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==} + engines: {node: '>=12.20'} + dev: true + /type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} dev: true - /type-fest@3.13.0: - resolution: {integrity: sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==} + /type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} engines: {node: '>=14.16'} dev: true @@ -6446,16 +6996,12 @@ packages: is-typed-array: 1.1.12 dev: true - /typescript@5.1.6: - resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} engines: {node: '>=14.17'} hasBin: true dev: true - /ua-parser-js@1.0.35: - resolution: {integrity: sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==} - dev: true - /ufo@1.1.2: resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} dev: true @@ -6476,6 +7022,10 @@ packages: through: 2.3.8 dev: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -6486,13 +7036,28 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /update-browserslist-db@1.0.11(browserslist@4.21.9): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + /unzipper@0.10.14: + resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} + dependencies: + big-integer: 1.6.51 + binary: 0.3.0 + bluebird: 3.4.7 + buffer-indexof-polyfill: 1.0.2 + duplexer2: 0.1.4 + fstream: 1.0.12 + graceful-fs: 4.2.11 + listenercount: 1.0.1 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + dev: true + + /update-browserslist-db@1.0.13(browserslist@4.22.1): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.21.9 + browserslist: 4.22.1 escalade: 3.1.1 picocolors: 1.0.0 dev: true @@ -6517,13 +7082,13 @@ packages: dependencies: react: 18.2.0 - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + /userhome@1.0.0: + resolution: {integrity: sha512-ayFKY3H+Pwfy4W98yPdtH1VqH4psDeyW8lYYFzfecR9d6hqLpqhecktvYR3SEEXt7vG0S1JEpciI3g94pMErig==} + engines: {node: '>= 0.8.0'} dev: true - /uuid@9.0.0: - resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} - hasBin: true + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true /validate-npm-package-license@3.0.4: @@ -6533,7 +7098,7 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vite-node@0.33.0(@types/node@18.15.3): + /vite-node@0.33.0(@types/node@20.9.0): resolution: {integrity: sha512-19FpHYbwWWxDr73ruNahC+vtEdza52kA90Qb3La98yZ0xULqV8A5JLNPUff0f5zID4984tW7l3DH2przTJUZSw==} engines: {node: '>=v14.18.0'} hasBin: true @@ -6543,7 +7108,7 @@ packages: mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.4.8(@types/node@18.15.3) + vite: 4.5.0(@types/node@20.9.0) transitivePeerDependencies: - '@types/node' - less @@ -6555,43 +7120,8 @@ packages: - terser dev: true - /vite@4.4.0: - resolution: {integrity: sha512-Wf+DCEjuM8aGavEYiF77hnbxEZ+0+/jC9nABR46sh5Xi+GYeSvkeEFRiVuI3x+tPjxgZeS91h1jTAQTPFgePpA==} - engines: {node: ^14.18.0 || >=16.0.0} - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - esbuild: 0.18.18 - postcss: 8.4.27 - rollup: 3.29.2 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /vite@4.4.8(@types/node@18.15.3): - resolution: {integrity: sha512-LONawOUUjxQridNWGQlNizfKH89qPigK36XhMI7COMGztz8KNY0JHim7/xDd71CZwGT4HtSRgI7Hy+RlhG0Gvg==} + /vite@4.5.0(@types/node@20.9.0): + resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -6618,15 +7148,15 @@ packages: terser: optional: true dependencies: - '@types/node': 18.15.3 + '@types/node': 20.9.0 esbuild: 0.18.18 - postcss: 8.4.27 - rollup: 3.29.2 + postcss: 8.4.31 + rollup: 3.29.4 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true - /vitest@0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.13.1): + /vitest@0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.22.1): resolution: {integrity: sha512-1CxaugJ50xskkQ0e969R/hW47za4YXDUfWJDxip1hwbnhUjYolpfUn2AMOulqG/Dtd9WYAtkHmM/m3yKVrEejQ==} engines: {node: '>=v14.18.0'} hasBin: true @@ -6659,7 +7189,7 @@ packages: dependencies: '@types/chai': 4.3.5 '@types/chai-subset': 1.3.3 - '@types/node': 18.15.3 + '@types/node': 20.9.0 '@vitest/browser': 0.33.0(rollup@2.79.1)(vitest@0.33.0) '@vitest/expect': 0.33.0 '@vitest/runner': 0.33.0 @@ -6680,9 +7210,9 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.0 tinypool: 0.6.0 - vite: 4.4.8(@types/node@18.15.3) - vite-node: 0.33.0(@types/node@18.15.3) - webdriverio: 8.13.1(typescript@5.1.6) + vite: 4.5.0(@types/node@20.9.0) + vite-node: 0.33.0(@types/node@20.9.0) + webdriverio: 8.22.1(typescript@5.2.2) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -6701,61 +7231,83 @@ packages: xml-name-validator: 4.0.0 dev: true + /wait-port@1.1.0: + resolution: {integrity: sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==} + engines: {node: '>=10'} + hasBin: true + dependencies: + chalk: 4.1.2 + commander: 9.5.0 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + /wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: defaults: 1.0.4 dev: true - /webdriver@8.13.1: - resolution: {integrity: sha512-v6EDyGEtZB8wpqd3kxEDOVU/Z21XY23SObHwoi4xe72sQeVbC8nIR0Y7Ri/gbQMv1bK58YIK01BAf7JmBZAcUw==} + /web-streams-polyfill@3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} + engines: {node: '>= 8'} + dev: true + + /webdriver@8.22.1: + resolution: {integrity: sha512-EQY2YjbOZInuvYAqEEP7w7voWSy9cPMt3UB1o1+obKhrD8dkIDZNkPocpZUI59PokqHTXk4zIclV50k1KpyyiA==} engines: {node: ^16.13 || >=18} dependencies: - '@types/node': 20.4.8 - '@types/ws': 8.5.5 - '@wdio/config': 8.12.1 - '@wdio/logger': 8.11.0 - '@wdio/protocols': 8.11.0 - '@wdio/types': 8.10.4 - '@wdio/utils': 8.12.1 + '@types/node': 20.9.0 + '@types/ws': 8.5.9 + '@wdio/config': 8.22.1 + '@wdio/logger': 8.16.17 + '@wdio/protocols': 8.22.0 + '@wdio/types': 8.21.0 + '@wdio/utils': 8.22.0 deepmerge-ts: 5.1.0 got: 12.6.1 ky: 0.33.3 - ws: 8.13.0 + ws: 8.14.2 transitivePeerDependencies: - bufferutil + - supports-color - utf-8-validate dev: true - /webdriverio@8.13.1(typescript@5.1.6): - resolution: {integrity: sha512-7+nYYe3+SpMXszyzMi9VS8ynTMXgnWMwuHWfrIuNieVmHGqAF8S3nLa4/5POpegNOJwOXNE6dEucf5l9MLxC/Q==} + /webdriverio@8.22.1(typescript@5.2.2): + resolution: {integrity: sha512-SFqCKM93DPZU5Vn2r9OMi5EFbJHmWnIf8KXZvdzVOkGzQxFDtJ8LDgzwH1/LZxjG9nO+D7y+4wyQl7V24b8L+Q==} engines: {node: ^16.13 || >=18} + peerDependencies: + devtools: ^8.14.0 + peerDependenciesMeta: + devtools: + optional: true dependencies: - '@types/node': 20.4.8 - '@wdio/config': 8.12.1 - '@wdio/logger': 8.11.0 - '@wdio/protocols': 8.11.0 + '@types/node': 20.9.0 + '@wdio/config': 8.22.1 + '@wdio/logger': 8.16.17 + '@wdio/protocols': 8.22.0 '@wdio/repl': 8.10.1 - '@wdio/types': 8.10.4 - '@wdio/utils': 8.12.1 - archiver: 5.3.1 + '@wdio/types': 8.21.0 + '@wdio/utils': 8.22.0 + archiver: 6.0.1 aria-query: 5.1.3 css-shorthand-properties: 1.1.1 css-value: 0.0.1 - devtools: 8.12.1(typescript@5.1.6) - devtools-protocol: 0.0.1161598 + devtools-protocol: 0.0.1213968 grapheme-splitter: 1.0.4 import-meta-resolve: 3.0.0 is-plain-obj: 4.1.0 lodash.clonedeep: 4.5.0 lodash.zip: 4.2.0 minimatch: 9.0.3 - puppeteer-core: 20.3.0(typescript@5.1.6) + puppeteer-core: 20.9.0(typescript@5.2.2) query-selector-shadow-dom: 1.0.1 resq: 1.11.0 rgb2hex: 0.2.5 - serialize-error: 8.1.0 - webdriver: 8.13.1 + serialize-error: 11.0.3 + webdriver: 8.22.1 transitivePeerDependencies: - bufferutil - encoding @@ -6857,12 +7409,12 @@ packages: isexe: 2.0.0 dev: true - /which@3.0.1: - resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + /which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} hasBin: true dependencies: - isexe: 2.0.0 + isexe: 3.1.1 dev: true /why-is-node-running@2.2.2: @@ -6918,6 +7470,19 @@ packages: optional: true dev: true + /ws@8.14.2: + resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + /xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -7026,11 +7591,11 @@ packages: engines: {node: '>=12.20'} dev: true - /zip-stream@4.1.0: - resolution: {integrity: sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==} - engines: {node: '>= 10'} + /zip-stream@5.0.1: + resolution: {integrity: sha512-UfZ0oa0C8LI58wJ+moL46BDIMgCQbnsb+2PoiJYtonhBsMh2bq1eRBVkvjfVsqbEHd9/EgKPUuL9saSSsec8OA==} + engines: {node: '>= 12.0.0'} dependencies: - archiver-utils: 2.1.0 - compress-commons: 4.1.1 + archiver-utils: 4.0.1 + compress-commons: 5.0.1 readable-stream: 3.6.2 dev: true From b0859ceffc224c6e60dc4f99cdc70b3db188ae8a Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 09:27:42 +0100 Subject: [PATCH 07/21] wip --- .changeset/young-parents-reflect.md | 5 +++++ packages/query/src/useInfiniteQuery$.ts | 3 --- packages/query/src/useIsFetching$.ts | 1 - packages/query/src/useMutation$.ts | 3 --- packages/query/src/useObserver.ts | 6 ------ packages/query/src/useQuery$.ts | 7 +------ 6 files changed, 6 insertions(+), 19 deletions(-) create mode 100644 .changeset/young-parents-reflect.md diff --git a/.changeset/young-parents-reflect.md b/.changeset/young-parents-reflect.md new file mode 100644 index 00000000..a696a450 --- /dev/null +++ b/.changeset/young-parents-reflect.md @@ -0,0 +1,5 @@ +--- +"@preact-signals/query": minor +--- + +Removed incorrect `@trackSignals` directives for `@preact/signals-react-transform` diff --git a/packages/query/src/useInfiniteQuery$.ts b/packages/query/src/useInfiniteQuery$.ts index d169abd5..85d4cade 100644 --- a/packages/query/src/useInfiniteQuery$.ts +++ b/packages/query/src/useInfiniteQuery$.ts @@ -2,9 +2,6 @@ import { InfiniteQueryObserver, QueryObserver } from "@tanstack/query-core"; import { createBaseQuery } from "./createBaseQuery$"; import { UseInfiniteQuery$ } from "./types"; -/** - * @trackSignals - */ export const useInfiniteQuery$ = createBaseQuery( InfiniteQueryObserver as typeof QueryObserver ) as UseInfiniteQuery$; diff --git a/packages/query/src/useIsFetching$.ts b/packages/query/src/useIsFetching$.ts index 9f2ae335..55dd5bd5 100644 --- a/packages/query/src/useIsFetching$.ts +++ b/packages/query/src/useIsFetching$.ts @@ -14,7 +14,6 @@ const isFetching = (queryClient: QueryClient, filters: QueryFilters) => * @param options * @returns * - * @trackSignals */ export const useIsFetching$ = >( _filters: T, diff --git a/packages/query/src/useMutation$.ts b/packages/query/src/useMutation$.ts index 73580f64..65798381 100644 --- a/packages/query/src/useMutation$.ts +++ b/packages/query/src/useMutation$.ts @@ -17,9 +17,6 @@ import { EMPTY_ARRAY, wrapFunctionsInUntracked } from "./utils"; function noop() {} -/** - * @trackSignals - */ export const useMutation$ = < TData = unknown, TError = unknown, diff --git a/packages/query/src/useObserver.ts b/packages/query/src/useObserver.ts index 718ebd0e..5565dece 100644 --- a/packages/query/src/useObserver.ts +++ b/packages/query/src/useObserver.ts @@ -14,9 +14,6 @@ type Observer = { subscribe: (emit: (value: T) => void) => Dispose; }; -/** - * @trackSignals - */ export const useObserverSignal = ( createObserver: () => Observer ): ReadonlySignal => { @@ -34,9 +31,6 @@ export const useObserverSignal = ( return s; }; -/** - * @trackSignals - */ export const useObserverStore = >( createObserverStore: () => Observer ): ReadonlyFlatStore => { diff --git a/packages/query/src/useQuery$.ts b/packages/query/src/useQuery$.ts index f0c50e19..6f418268 100644 --- a/packages/query/src/useQuery$.ts +++ b/packages/query/src/useQuery$.ts @@ -1,10 +1,5 @@ import { QueryObserver } from "@tanstack/query-core"; import { createBaseQuery } from "./createBaseQuery$"; -import { - UseQuery$ -} from "./types"; +import { UseQuery$ } from "./types"; -/** - * @trackSignals - */ export const useQuery$ = createBaseQuery(QueryObserver) as UseQuery$; From 8c3d95994ca68d8bea427d55000f27cc5052cfcb Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 13:22:13 +0100 Subject: [PATCH 08/21] semiworking transform --- apps/react-test/package.json | 13 +- apps/react-test/vite.config.ts | 102 +++- packages/components-for-test/package.json | 2 + packages/query/package.json | 4 + packages/react/src/hooks.ts | 1 - packages/react/vitest.config.ts | 8 +- packages/unified-signals/package.json | 6 +- packages/utils/package.json | 5 + packages/utils/rollup.config.mjs | 6 +- packages/utils/src/hocs/reactify.ts | 26 +- packages/utils/src/hocs/reactifyLite.ts | 24 +- packages/utils/src/hocs/withSignalProps.ts | 6 +- packages/utils/src/hooks/flat-store.ts | 7 - packages/utils/src/hooks/resource.ts | 2 - packages/utils/src/resource/resource.ts | 7 +- packages/utils/src/store/deepSignal.ts | 6 +- packages/utils/src/store/hooks.ts | 9 - pnpm-lock.yaml | 512 ++++++++++++--------- tsconfig.json | 1 + 19 files changed, 452 insertions(+), 295 deletions(-) diff --git a/apps/react-test/package.json b/apps/react-test/package.json index f74c2dbd..582573f3 100644 --- a/apps/react-test/package.json +++ b/apps/react-test/package.json @@ -4,22 +4,29 @@ "version": "0.0.13", "type": "module", "scripts": { - "dev": "vite", - "build": "tsc && vite build", + "dev:transform": "cross-env USE_TRANSFORM=1 vite", + "dev": "cross-env USE_TRANSFORM=0 vite", + "build": "tsc && cross-env USE_TRANSFORM=0 vite build", "watch": "pnpm dev", "preview": "vite preview" }, "dependencies": { + "@preact-signals/safe-react": "workspace:*", "@preact/signals-react": "^1.3.3", "components-for-test": "workspace:*", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "vite-plugin-babel": "^1.1.3", + "zod": "^3.22.4" }, "devDependencies": { + "@babel/plugin-syntax-jsx": "^7.23.3", "@types/react": "^18.2.37", "@types/react-dom": "^18.2.15", + "@vitejs/plugin-react": "^4.1.1", "@vitejs/plugin-react-swc": "^3.4.1", "autoprefixer": "^10.4.16", + "cross-env": "^7.0.3", "daisyui": "^3.9.4", "postcss": "^8.4.31", "tailwindcss": "^3.3.5", diff --git a/apps/react-test/vite.config.ts b/apps/react-test/vite.config.ts index 17aa4d49..dac8b637 100644 --- a/apps/react-test/vite.config.ts +++ b/apps/react-test/vite.config.ts @@ -1,7 +1,103 @@ -import react from "@vitejs/plugin-react-swc"; -import { defineConfig } from "vite"; +import reactSWC from "@vitejs/plugin-react-swc"; +import reactBabel from "@vitejs/plugin-react"; +import babel from "vite-plugin-babel"; +import { PluginOption, defineConfig } from "vite"; +import { z } from "zod"; +import { createRequire } from "node:module"; +import path from "node:path"; + +const resolve = createRequire(import.meta.url).resolve; + +const envSchema = z + .object({ + USE_TRANSFORM: z.enum(["0", "1"]), + }) + .transform((it) => ({ + USE_TRANSFORM: it.USE_TRANSFORM === "0" ? false : true, + })); +const { USE_TRANSFORM } = envSchema.parse(process.env); + +console.log( + path.resolve(resolve("@preact-signals/safe-react"), "../../esm/index.mjs") +); // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], + resolve: USE_TRANSFORM && { + alias: [ + { + find: /^react$/, + replacement: "@preact-signals/safe-react/react", + // TODO: extract to lib + customResolver: (() => { + const reactUrl = resolve("react"); + const fakeUrl = resolve("@preact-signals/safe-react/react"); + return { + resolveId(source, importer) { + const useRealImport = importer?.endsWith("react.cjs"); + return useRealImport ? reactUrl : fakeUrl; + }, + }; + })(), + }, + { + find: "@preact/signals-react", + replacement: path.resolve( + resolve("@preact-signals/safe-react"), + "../../esm/index.mjs" + ), + }, + ], + }, + plugins: [ + USE_TRANSFORM && + babel({ + babelConfig: { + plugins: [ + "@babel/plugin-syntax-jsx", + [ + "module:@preact/signals-react-transform", + { + importSource: "@preact-signals/safe-react", + }, + ], + ], + }, + filter: /utils\/dist\/.+\.mjs$/, + }), + , + reactBabel({ + jsxImportSource: "@preact-signals/safe-react", + babel: { + plugins: [ + [ + "module:@preact/signals-react-transform", + { + importSource: "@preact-signals/safe-react", + }, + ], + ], + }, + include: /\.(mdx|js|jsx|ts|tsx)$/, + }) as PluginOption[], + // reactSWC({ + // jsxImportSource: "@preact-signals/safe-react", + // }), + // USE_TRANSFORM + // ? (reactBabel({ + // jsxImportSource: "@preact-signals/safe-react", + // babel: { + // plugins: [ + // [ + // "module:@preact/signals-react-transform", + // { + // importSource: "@preact-signals/safe-react", + // }, + // ], + // ], + // }, + // include: ["./src/**/*.{jsx,tsx}", "@preact-signals/utils/**"], + // }) as PluginOption[]) + // : reactSWC(), + ], }); diff --git a/packages/components-for-test/package.json b/packages/components-for-test/package.json index af09bbca..1054c866 100644 --- a/packages/components-for-test/package.json +++ b/packages/components-for-test/package.json @@ -30,10 +30,12 @@ }, "dependencies": { "@preact-signals/utils": "workspace:*", + "@tanstack/react-router": "0.0.1-beta.209", "@tanstack/router": "0.0.1-beta.140" }, "peerDependencies": { "@preact-signals/query": "workspace:*", + "@preact-signals/safe-react": "*", "@preact/signals": "^1.*", "@preact/signals-react": "^1.3", "react": "17.*.* || 18.*.*" diff --git a/packages/query/package.json b/packages/query/package.json index 198762b0..82c5a67c 100644 --- a/packages/query/package.json +++ b/packages/query/package.json @@ -45,6 +45,7 @@ "@preact/signals": ">=1.1.0", "@preact/signals-core": ">=1.1.0", "@preact/signals-react": ">=1.2.0", + "@preact-signals/safe-react": "*", "react": "17.*.* || 18.*.*", "react-dom": "^18.2.0" }, @@ -63,6 +64,9 @@ }, "@preact/signals-core": { "optional": true + }, + "@preact-signals/safe-react": { + "optional": true } }, "devDependencies": { diff --git a/packages/react/src/hooks.ts b/packages/react/src/hooks.ts index 38da97f6..381f985a 100644 --- a/packages/react/src/hooks.ts +++ b/packages/react/src/hooks.ts @@ -16,7 +16,6 @@ const symDispose: unique symbol = // _dispose(): void; // } interface Effect { - _sources: object | undefined; S(): () => void; c(): void; d(): void; diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts index 28fab918..a6d3d98e 100644 --- a/packages/react/vitest.config.ts +++ b/packages/react/vitest.config.ts @@ -2,6 +2,8 @@ import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; import packageJson from "./package.json"; +const selfName = packageJson.name; + export default defineConfig({ esbuild: { jsx: "preserve", @@ -24,7 +26,7 @@ export default defineConfig({ replacement: packageJson.exports["./jsx-dev-runtime"], }, { - find: "@preact-signals/react", + find: selfName, replacement: "./src/index.ts", }, { @@ -35,13 +37,13 @@ export default defineConfig({ }, plugins: [ react({ - jsxImportSource: "@preact-signals/react", + jsxImportSource: selfName, babel: { plugins: [ [ "module:@preact/signals-react-transform", { - importSource: "@preact-signals/react", + importSource: selfName, }, ], ], diff --git a/packages/unified-signals/package.json b/packages/unified-signals/package.json index 51295641..a1d505e2 100644 --- a/packages/unified-signals/package.json +++ b/packages/unified-signals/package.json @@ -43,7 +43,8 @@ "peerDependencies": { "@preact/signals": ">=1.1.0", "@preact/signals-core": ">=1.1.0", - "@preact/signals-react": ">=1.2.0" + "@preact/signals-react": ">=1.2.0", + "@preact-signals/safe-react": "*" }, "peerDependenciesMeta": { "@preact/signals-react": { @@ -54,6 +55,9 @@ }, "@preact/signals-core": { "optional": true + }, + "@preact-signals/safe-react": { + "optional": true } }, "devDependencies": { diff --git a/packages/utils/package.json b/packages/utils/package.json index f23ec96c..39236324 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -96,6 +96,7 @@ } }, "peerDependencies": { + "@preact-signals/safe-react": "*", "@preact/signals": ">=1.1.0", "@preact/signals-core": ">=1.1.0", "@preact/signals-react": ">=1.2.0", @@ -113,6 +114,9 @@ }, "@preact/signals-core": { "optional": true + }, + "@preact-signals/safe-react": { + "optional": true } }, "dependencies": { @@ -136,6 +140,7 @@ "rollup": "^3.29.4", "rollup-plugin-esbuild": "^5.0.0", "rollup-plugin-node-externals": "^6.1.2", + "rollup-plugin-swc3": "^0.10.3", "type-fest": "^3.13.1" }, "keywords": [ diff --git a/packages/utils/rollup.config.mjs b/packages/utils/rollup.config.mjs index 67daf50e..01071302 100644 --- a/packages/utils/rollup.config.mjs +++ b/packages/utils/rollup.config.mjs @@ -11,7 +11,7 @@ const usePreserveModulesRoot = "src"; // Root directory for `preserveModules` const useStrict = true; // Use "strict" const useThrowOnError = true; // On error throw and exception const useSourceMap = true; // Generate source map files -const useEsbuild = true; // `true` -> use esbuild, `false` use tsc +const useEsbuild = false; // `true` -> use esbuild, `false` use tsc const input = [ "src/index.ts", @@ -58,7 +58,7 @@ export default [ : typescript({ noEmitOnError: useThrowOnError, outDir: "dist/cjs", - removeComments: true, + removeComments: false, }), ], }, @@ -85,7 +85,7 @@ export default [ : typescript({ noEmitOnError: useThrowOnError, outDir: "dist/esm", - removeComments: true, + removeComments: false, }), ], }, diff --git a/packages/utils/src/hocs/reactify.ts b/packages/utils/src/hocs/reactify.ts index fca2749e..94e8caf3 100644 --- a/packages/utils/src/hocs/reactify.ts +++ b/packages/utils/src/hocs/reactify.ts @@ -66,17 +66,17 @@ export type ReactifyComponentReturn< }; class ReactifyPropsHandler { - #implicitSignals: Map> = new Map(); - #props: Record; + _implicitSignals: Map> = new Map(); + _props: Record; constructor(props: Record) { - this.#props = props; + this._props = props; } onRender(props: Record) { - if (this.#props === props) { + if (this._props === props) { return; } - for (const [key, value] of this.#implicitSignals) { + for (const [key, value] of this._implicitSignals) { if (!(key in props)) { value.value = undefined; } @@ -86,7 +86,7 @@ class ReactifyPropsHandler { // this.#implicitSignals.delete(key); // } // } - this.#props = props; + this._props = props; } createReactiveProps< @@ -94,8 +94,8 @@ class ReactifyPropsHandler { >(): ReactiveProps { const res = {} as ReactiveProps; const self = this; - for (const key in this.#props) { - const value = this.#props[key]; + for (const key in this._props) { + const value = this._props[key]; if (IGNORED_PROPS.includes(key)) { // @ts-expect-error res.ref = value; @@ -107,7 +107,7 @@ class ReactifyPropsHandler { Object.defineProperty(res, keyWithout$, { get() { if (isEndsWith$) { - return self.#props[key](); + return self._props[key](); } if (value && typeof value === "object" && value instanceof Signal) { return value.value; @@ -117,10 +117,10 @@ class ReactifyPropsHandler { } return ( - self.#implicitSignals.has(key) - ? self.#implicitSignals.get(key)! - : self.#implicitSignals - .set(key, signal(self.#props[key])) + self._implicitSignals.has(key) + ? self._implicitSignals.get(key)! + : self._implicitSignals + .set(key, signal(self._props[key])) .get(key)! ).value; }, diff --git a/packages/utils/src/hocs/reactifyLite.ts b/packages/utils/src/hocs/reactifyLite.ts index 10bcbdea..843918ba 100644 --- a/packages/utils/src/hocs/reactifyLite.ts +++ b/packages/utils/src/hocs/reactifyLite.ts @@ -29,17 +29,17 @@ export type ReactiveProps> = Opaque< >; class ReactifyPropsLiteHandler { - #implicitSignals: Map> = new Map(); - #props: Record; + _implicitSignals: Map> = new Map(); + _props: Record; constructor(props: Record) { - this.#props = props; + this._props = props; } onRender(props: Record) { - if (this.#props === props) { + if (this._props === props) { return; } - for (const [key, value] of this.#implicitSignals) { + for (const [key, value] of this._implicitSignals) { if (!(key in props)) { value.value = undefined; } @@ -49,7 +49,7 @@ class ReactifyPropsLiteHandler { // this.#implicitSignals.delete(key); // } // } - this.#props = props; + this._props = props; } createReactiveProps< @@ -57,8 +57,8 @@ class ReactifyPropsLiteHandler { >(): ReactiveProps { const res = {} as ReactiveProps; const self = this; - for (const key in this.#props) { - const value = this.#props[key]; + for (const key in this._props) { + const value = this._props[key]; if (IGNORED_PROPS.includes(key)) { // @ts-expect-error res.ref = value; @@ -75,10 +75,10 @@ class ReactifyPropsLiteHandler { } return ( - self.#implicitSignals.has(key) - ? self.#implicitSignals.get(key)! - : self.#implicitSignals - .set(key, signal(self.#props[key])) + self._implicitSignals.has(key) + ? self._implicitSignals.get(key)! + : self._implicitSignals + .set(key, signal(self._props[key])) .get(key)! ).value; }, diff --git a/packages/utils/src/hocs/withSignalProps.ts b/packages/utils/src/hocs/withSignalProps.ts index 1c36ae77..6cb5592c 100644 --- a/packages/utils/src/hocs/withSignalProps.ts +++ b/packages/utils/src/hocs/withSignalProps.ts @@ -16,7 +16,7 @@ export interface WithSignalProp extends Fn { class WithSignalPropsHandler implements ProxyHandler> { - #valuesCache = new Map(); + _valuesCache = new Map(); get(target: Record, p: string | symbol) { const value = target[p]; @@ -25,8 +25,8 @@ class WithSignalPropsHandler } if (value instanceof Signal) { return ( - this.#valuesCache.get(p) ?? - this.#valuesCache.set(p, value.value).get(p)! + this._valuesCache.get(p) ?? + this._valuesCache.set(p, value.value).get(p)! ); } diff --git a/packages/utils/src/hooks/flat-store.ts b/packages/utils/src/hooks/flat-store.ts index 644b4e22..11e4101f 100644 --- a/packages/utils/src/hooks/flat-store.ts +++ b/packages/utils/src/hooks/flat-store.ts @@ -7,7 +7,6 @@ export type AnyRecord = Record; /** * Create a flat store and its setter. - * @trackSignals */ export const useFlatStore = (storeCreator: () => T) => { const storeRef = useRef> | null>(); @@ -18,9 +17,6 @@ export const useFlatStore = (storeCreator: () => T) => { return storeRef.current; }; -/** - * @trackSignals - */ export const useFlatStoreOfSignals = ( storeCreator: () => T ) => { @@ -34,9 +30,6 @@ export const useFlatStoreOfSignals = ( return storeRef.current; }; -/** - * @trackSignals - */ export const useComputedFlatStore = ( storeUpdater: () => T ) => { diff --git a/packages/utils/src/hooks/resource.ts b/packages/utils/src/hooks/resource.ts index dedab22e..49600ef4 100644 --- a/packages/utils/src/hooks/resource.ts +++ b/packages/utils/src/hooks/resource.ts @@ -7,8 +7,6 @@ import { import { Accessor, AnyReactive } from "../utils"; /** - * @trackSignals - * * @param options resource are created once, so only first options matter * @returns */ diff --git a/packages/utils/src/resource/resource.ts b/packages/utils/src/resource/resource.ts index 837949ca..71335d95 100644 --- a/packages/utils/src/resource/resource.ts +++ b/packages/utils/src/resource/resource.ts @@ -356,6 +356,7 @@ const _fetch: Resource["_fetch"] = function ( if (!result) { return; } + // TODO: fix - here can be previous data this.pr = result.then( (value) => { if (abortController.signal.aborted) { @@ -446,12 +447,10 @@ const _onRead: Resource["_onRead"] = function ( const activate: Resource["activate"] = function ( this: Resource ) { - if (this.initialized) { - return () => {}; + if (!this.initialized) { + this._init(); } - this._init(); - return this.dispose.bind(this); }; diff --git a/packages/utils/src/store/deepSignal.ts b/packages/utils/src/store/deepSignal.ts index 06cdb2d3..1cc93742 100644 --- a/packages/utils/src/store/deepSignal.ts +++ b/packages/utils/src/store/deepSignal.ts @@ -1,6 +1,10 @@ import { Signal } from "@preact-signals/unified-signals"; import { CollectionTypes } from "./collectionHandlers"; -import { RawSymbol, ShallowReactiveMarker, toDeepReactive } from "./reactivity"; +import { + type RawSymbol, + type ShallowReactiveMarker, + toDeepReactive, +} from "./reactivity"; import { isSignal } from "./utils"; type BaseTypes = string | number | boolean; diff --git a/packages/utils/src/store/hooks.ts b/packages/utils/src/store/hooks.ts index 5d2e06d1..77283636 100644 --- a/packages/utils/src/store/hooks.ts +++ b/packages/utils/src/store/hooks.ts @@ -4,20 +4,11 @@ import { EMPTY_ARRAY } from "../constants"; import { deepSignal } from "../store"; import { deepReactive, shallowReactive } from "./reactivity"; -/** - * @trackSignals - */ export const useDeepSignal = (creator: () => T) => useMemo(() => deepSignal(untracked(creator)), EMPTY_ARRAY); -/** - * @trackSignals - */ export const useDeepReactive = (creator: () => T) => useMemo(() => deepReactive(untracked(creator)), EMPTY_ARRAY); -/** - * @trackSignals - */ export const useShallowReactive = (creator: () => T) => useMemo(() => shallowReactive(untracked(creator)), EMPTY_ARRAY); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9f4414bc..0e52354e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,6 +66,9 @@ importers: apps/react-test: dependencies: + '@preact-signals/safe-react': + specifier: workspace:* + version: link:../../packages/react '@preact/signals-react': specifier: ^1.3.3 version: 1.3.6(react@18.2.0) @@ -78,19 +81,34 @@ importers: react-dom: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) + vite-plugin-babel: + specifier: ^1.1.3 + version: 1.1.3(@babel/core@7.23.3)(vite@4.5.0) + zod: + specifier: ^3.22.4 + version: 3.22.4 devDependencies: + '@babel/plugin-syntax-jsx': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.3) '@types/react': specifier: ^18.2.37 version: 18.2.37 '@types/react-dom': specifier: ^18.2.15 version: 18.2.15 + '@vitejs/plugin-react': + specifier: ^4.1.1 + version: 4.1.1(vite@4.5.0) '@vitejs/plugin-react-swc': specifier: ^3.4.1 version: 3.4.1(vite@4.5.0) autoprefixer: specifier: ^10.4.16 version: 10.4.16(postcss@8.4.31) + cross-env: + specifier: ^7.0.3 + version: 7.0.3 daisyui: specifier: ^3.9.4 version: 3.9.4 @@ -106,12 +124,18 @@ importers: packages/components-for-test: dependencies: + '@preact-signals/safe-react': + specifier: '*' + version: link:../react '@preact-signals/utils': specifier: workspace:* version: link:../utils '@preact/signals': specifier: ^1.* - version: 1.1.4(preact@10.15.1) + version: 1.1.4(preact@10.19.1) + '@tanstack/react-router': + specifier: 0.0.1-beta.209 + version: 0.0.1-beta.209(react-dom@18.2.0)(react@18.2.0) '@tanstack/router': specifier: 0.0.1-beta.140 version: 0.0.1-beta.140(react-dom@18.2.0)(react@18.2.0) @@ -143,6 +167,9 @@ importers: packages/query: dependencies: + '@preact-signals/safe-react': + specifier: '*' + version: link:../react '@preact-signals/unified-signals': specifier: workspace:* version: link:../unified-signals @@ -151,7 +178,7 @@ importers: version: link:../utils '@preact/signals': specifier: '>=1.1.0' - version: 1.1.4(preact@10.15.1) + version: 1.1.4(preact@10.19.1) '@preact/signals-core': specifier: '>=1.1.0' version: 1.2.3 @@ -293,9 +320,12 @@ importers: packages/unified-signals: dependencies: + '@preact-signals/safe-react': + specifier: '*' + version: link:../react '@preact/signals': specifier: '>=1.1.0' - version: 1.1.4(preact@10.15.1) + version: 1.1.4(preact@10.19.1) '@preact/signals-core': specifier: '>=1.1.0' version: 1.2.3 @@ -312,12 +342,15 @@ importers: packages/utils: dependencies: + '@preact-signals/safe-react': + specifier: '*' + version: link:../react '@preact-signals/unified-signals': specifier: workspace:* version: link:../unified-signals '@preact/signals': specifier: '>=1.1.0' - version: 1.1.4(preact@10.15.1) + version: 1.1.4(preact@10.19.1) '@preact/signals-core': specifier: '>=1.1.0' version: 1.2.3 @@ -370,6 +403,9 @@ importers: rollup-plugin-node-externals: specifier: ^6.1.2 version: 6.1.2(rollup@3.29.4) + rollup-plugin-swc3: + specifier: ^0.10.3 + version: 0.10.3(@swc/core@1.3.96)(rollup@3.29.4) type-fest: specifier: ^3.13.1 version: 3.13.1 @@ -396,7 +432,6 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 - dev: true /@babel/code-frame@7.22.13: resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} @@ -405,35 +440,10 @@ packages: dependencies: '@babel/highlight': 7.22.13 chalk: 2.4.2 - dev: true /@babel/compat-data@7.22.9: resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} engines: {node: '>=6.9.0'} - dev: true - - /@babel/core@7.22.9: - resolution: {integrity: sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.22.9 - '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) - '@babel/helper-module-transforms': 7.22.9(@babel/core@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.23.3 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true /@babel/core@7.23.3: resolution: {integrity: sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==} @@ -456,17 +466,6 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: true - - /@babel/generator@7.22.9: - resolution: {integrity: sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.3 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - jsesc: 2.5.2 - dev: true /@babel/generator@7.23.3: resolution: {integrity: sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==} @@ -476,7 +475,6 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 - dev: true /@babel/helper-annotate-as-pure@7.22.5: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} @@ -494,39 +492,10 @@ packages: browserslist: 4.22.1 lru-cache: 5.1.1 semver: 6.3.1 - dev: true - - /@babel/helper-compilation-targets@7.22.9(@babel/core@7.22.9): - resolution: {integrity: sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.22.9 - '@babel/core': 7.22.9 - '@babel/helper-validator-option': 7.22.5 - browserslist: 4.22.1 - lru-cache: 5.1.1 - semver: 6.3.1 - dev: true /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-environment-visitor@7.22.5: - resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-function-name@7.22.5: - resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.23.3 - dev: true /@babel/helper-function-name@7.23.0: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} @@ -534,21 +503,18 @@ packages: dependencies: '@babel/template': 7.22.15 '@babel/types': 7.23.3 - dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.23.3 - dev: true /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.23.3 - dev: true /@babel/helper-module-imports@7.22.5: resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} @@ -557,20 +523,6 @@ packages: '@babel/types': 7.22.5 dev: true - /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.9): - resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.9 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.15 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.20 - dev: true - /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.3): resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} @@ -583,7 +535,6 @@ packages: '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 - dev: true /@babel/helper-plugin-utils@7.22.5: resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} @@ -595,24 +546,20 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.23.3 - dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.23.3 - dev: true /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier@7.22.5: resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} @@ -622,23 +569,6 @@ packages: /@babel/helper-validator-option@7.22.15: resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-option@7.22.5: - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helpers@7.22.6: - resolution: {integrity: sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.8 - '@babel/types': 7.23.3 - transitivePeerDependencies: - - supports-color - dev: true /@babel/helpers@7.23.2: resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} @@ -649,7 +579,6 @@ packages: '@babel/types': 7.23.3 transitivePeerDependencies: - supports-color - dev: true /@babel/highlight@7.22.13: resolution: {integrity: sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==} @@ -658,15 +587,6 @@ packages: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true - - /@babel/parser@7.22.7: - resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.22.5 - dev: true /@babel/parser@7.23.3: resolution: {integrity: sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==} @@ -674,7 +594,6 @@ packages: hasBin: true dependencies: '@babel/types': 7.23.3 - dev: true /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.3): resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} @@ -743,34 +662,6 @@ packages: '@babel/code-frame': 7.22.13 '@babel/parser': 7.23.3 '@babel/types': 7.23.3 - dev: true - - /@babel/template@7.22.5: - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.22.7 - '@babel/types': 7.23.3 - dev: true - - /@babel/traverse@7.22.8: - resolution: {integrity: sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.22.9 - '@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.23.3 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true /@babel/traverse@7.23.3: resolution: {integrity: sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==} @@ -788,7 +679,6 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: true /@babel/types@7.22.5: resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} @@ -806,7 +696,6 @@ packages: '@babel/helper-string-parser': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - dev: true /@changesets/apply-release-plan@6.1.4: resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} @@ -998,7 +887,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm64@0.19.5: @@ -1016,7 +904,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm@0.19.5: @@ -1034,7 +921,6 @@ packages: cpu: [x64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-x64@0.19.5: @@ -1052,7 +938,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-arm64@0.19.5: @@ -1070,7 +955,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-x64@0.19.5: @@ -1088,7 +972,6 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-arm64@0.19.5: @@ -1106,7 +989,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-x64@0.19.5: @@ -1124,7 +1006,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm64@0.19.5: @@ -1142,7 +1023,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm@0.19.5: @@ -1160,7 +1040,6 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ia32@0.19.5: @@ -1187,7 +1066,6 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-loong64@0.19.5: @@ -1205,7 +1083,6 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-mips64el@0.19.5: @@ -1223,7 +1100,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ppc64@0.19.5: @@ -1241,7 +1117,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-riscv64@0.19.5: @@ -1259,7 +1134,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-s390x@0.19.5: @@ -1277,7 +1151,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-x64@0.19.5: @@ -1295,7 +1168,6 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true - dev: true optional: true /@esbuild/netbsd-x64@0.19.5: @@ -1313,7 +1185,6 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true - dev: true optional: true /@esbuild/openbsd-x64@0.19.5: @@ -1331,7 +1202,6 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true - dev: true optional: true /@esbuild/sunos-x64@0.19.5: @@ -1349,7 +1219,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-arm64@0.19.5: @@ -1367,7 +1236,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-ia32@0.19.5: @@ -1385,7 +1253,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-x64@0.19.5: @@ -1439,6 +1306,10 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@fastify/deepmerge@1.3.0: + resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} + dev: true + /@gisatcz/cross-package-react-context@0.2.0(react@18.2.0): resolution: {integrity: sha512-E7aR/o1ArpXETO8bQi+Hltj3duHeZiLjR+x1VZrCDs3jplSLGoy+oqCcqNNE1BamTBa0YQTs8Go1Q1dtt3LEUg==} peerDependencies: @@ -1512,32 +1383,26 @@ packages: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.18 - dev: true /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/sourcemap-codec@1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true /@jridgewell/trace-mapping@0.3.18: resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@jspm/core@2.0.0-beta.24: resolution: {integrity: sha512-a4Bo/80Z6CoJNor5ldgs6002utmmbttP4JYd/FJ0Ob2fVdf6O6ha5SORBCqrnDnBvMc1TlrHY7dCfat5+H0a6A==} @@ -1563,6 +1428,142 @@ packages: read-yaml-file: 1.1.0 dev: true + /@napi-rs/magic-string-android-arm-eabi@0.3.4: + resolution: {integrity: sha512-sszAYxqtzzJ4FDerDNHcqL9NhqPhj8W4DNiOanXYy50mA5oojlRtaAFPiB5ZMrWDBM32v5Q30LrmxQ4eTtu2Dg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-android-arm64@0.3.4: + resolution: {integrity: sha512-jdQ6HuO0X5rkX4MauTcWR4HWdgjakTOmmzqXg8L26+jOHVVG1LZE+Su5qvV4bP8vMb2h+vPE+JsnwqSmWymu3Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-darwin-arm64@0.3.4: + resolution: {integrity: sha512-6NmMtvURce9/oq09XBZmuIeI6lPLGtEJ2ZPO/QzL3nLZa6wygiCnO/sFACKYNg5/73ET5HMMTeuogE1JI+r2Lw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-darwin-x64@0.3.4: + resolution: {integrity: sha512-f9LmfMiUAKDOtl0meOuLYeVb6OERrgGzrTg1Tn3R3fTAShM2kxRbfAuPE9ljuXxIFzOv/uqRNLSl/LqCJwpREA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-freebsd-x64@0.3.4: + resolution: {integrity: sha512-rqduQ4odiDK4QdM45xHWRTU4wtFIfpp8g8QGpz+3qqg7ivldDqbbNOrBaf6Oeu77uuEvWggnkyuChotfKgJdJQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-linux-arm-gnueabihf@0.3.4: + resolution: {integrity: sha512-pVaJEdEpiPqIfq3M4+yMAATS7Z9muDcWYn8H7GFH1ygh8GwgLgKfy/n/lG2M6zp18Mwd0x7E2E/qg9GgCyUzoQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-linux-arm64-gnu@0.3.4: + resolution: {integrity: sha512-9FwoAih/0tzEZx0BjYYIxWkSRMjonIn91RFM3q3MBs/evmThXUYXUqLNa1PPIkK1JoksswtDi48qWWLt8nGflQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-linux-arm64-musl@0.3.4: + resolution: {integrity: sha512-wCR7R+WPOcAKmVQc1s6h6HwfwW1vL9pM8BjUY9Ljkdb8wt1LmZEmV2Sgfc1SfbRQzbyl+pKeufP6adRRQVzYDA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-linux-x64-gnu@0.3.4: + resolution: {integrity: sha512-sbxFDpYnt5WFbxQ1xozwOvh5A7IftqSI0WnE9O7KsQIOi0ej2dvFbfOW4tmFkvH/YP8KJELo5AhP2+kEq1DpYA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-linux-x64-musl@0.3.4: + resolution: {integrity: sha512-jN4h/7e2Ul8v3UK5IZu38NXLMdzVWhY4uEDlnwuUAhwRh26wBQ1/pLD97Uy/Z3dFNBQPcsv60XS9fOM1YDNT6w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-win32-arm64-msvc@0.3.4: + resolution: {integrity: sha512-gMUyTRHLWpzX2ntJFCbW2Gnla9Y/WUmbkZuW5SBAo/Jo8QojHn76Y4PNgnoXdzcsV9b/45RBxurYKAfFg9WTyg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-win32-ia32-msvc@0.3.4: + resolution: {integrity: sha512-QIMauMOvEHgL00K9np/c9CT/CRtLOz3mRTQqcZ9XGzSoAMrpxH71KSpDJrKl7h7Ro6TZ+hJ0C3T+JVuTCZNv4A==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string-win32-x64-msvc@0.3.4: + resolution: {integrity: sha512-V8FMSf828MzOI3P6/765MR7zHU6CUZqiyPhmAnwYoKFNxfv7oCviN/G6NcENeCdcYOvNgh5fYzaNLB96ndId5A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@napi-rs/magic-string@0.3.4: + resolution: {integrity: sha512-DEWl/B99RQsyMT3F9bvrXuhL01/eIQp/dtNSE3G1jQ4mTGRcP4iHWxoPZ577WrbjUinrNgvRA5+08g8fkPgimQ==} + engines: {node: '>= 10'} + optionalDependencies: + '@napi-rs/magic-string-android-arm-eabi': 0.3.4 + '@napi-rs/magic-string-android-arm64': 0.3.4 + '@napi-rs/magic-string-darwin-arm64': 0.3.4 + '@napi-rs/magic-string-darwin-x64': 0.3.4 + '@napi-rs/magic-string-freebsd-x64': 0.3.4 + '@napi-rs/magic-string-linux-arm-gnueabihf': 0.3.4 + '@napi-rs/magic-string-linux-arm64-gnu': 0.3.4 + '@napi-rs/magic-string-linux-arm64-musl': 0.3.4 + '@napi-rs/magic-string-linux-x64-gnu': 0.3.4 + '@napi-rs/magic-string-linux-x64-musl': 0.3.4 + '@napi-rs/magic-string-win32-arm64-msvc': 0.3.4 + '@napi-rs/magic-string-win32-ia32-msvc': 0.3.4 + '@napi-rs/magic-string-win32-x64-msvc': 0.3.4 + dev: true + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1656,13 +1657,13 @@ packages: react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) - /@preact/signals@1.1.4(preact@10.15.1): + /@preact/signals@1.1.4(preact@10.19.1): resolution: {integrity: sha512-4s0U8yHfy6OzBjTx8lgG0JZGFq1y+ye7xLmaaI8SXyJ5p+jAtMKW40Mg3GDLISM5WyKnqbfrQ4SOmbq1VTBtTw==} peerDependencies: preact: 10.x dependencies: '@preact/signals-core': 1.5.0 - preact: 10.15.1 + preact: 10.19.1 dev: false /@preact/signals@1.2.1(preact@10.19.1): @@ -1696,7 +1697,7 @@ packages: preact: ^10.4.0 vite: '>=2.0.0' dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.23.3 '@prefresh/babel-plugin': 0.5.0 '@prefresh/core': 1.5.1(preact@10.19.1) '@prefresh/utils': 1.2.0 @@ -1818,6 +1819,21 @@ packages: rollup: 3.29.4 dev: true + /@rollup/pluginutils@5.0.5(rollup@3.29.4): + resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.1 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 3.29.4 + dev: true + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -1957,10 +1973,30 @@ packages: defer-to-connect: 2.0.1 dev: true + /@tanstack/history@0.0.1-beta.209: + resolution: {integrity: sha512-L7H1bQ0nN4rjCW3xsIh+jo7/z0aHkgxq3xsVPfhju+5WijCQ0j7ZcbepMzRlGYTbHRy9kQL9Jqu+8wREYHz9kg==} + engines: {node: '>=12'} + dev: false + /@tanstack/query-core@4.29.23: resolution: {integrity: sha512-4BMHPrkfYmLP+NvqbbkV7Mk1nnphu+bNmxhhuB0+EMjKA7VfyFCfiyiTf55RRDgLaevyb9LrFK16lHW2owF52w==} dev: false + /@tanstack/react-router@0.0.1-beta.209(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Rg/2xHUERNVH7YhFmFn27RFqRKcimBb/fo6LxH5vxcVkMUCFp9jBTteKh3v19YURBVYMCzWkWYZBS4Khba8eKA==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16' + react-dom: '>=16' + dependencies: + '@babel/runtime': 7.22.6 + '@tanstack/history': 0.0.1-beta.209 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tiny-invariant: 1.3.1 + tiny-warning: 1.0.3 + dev: false + /@tanstack/react-store@0.0.1-beta.134(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-sdd78TYYp2uye6QTRMCafREkummomQPILI8egKgquu3/Cww/QbEIu+BVAssWw5At94j7ZXpVEyHGHXt0Iyuliw==} engines: {node: '>=12'} @@ -2054,8 +2090,8 @@ packages: /@types/babel__core@7.20.4: resolution: {integrity: sha512-mLnSC22IC4vcWiuObSRjrLd9XcBTGf59vUSoq2jkQDJ/QQ8PMI9rSuzE+aEV8karUMbskw07bKYoUJCKTUaygg==} dependencies: - '@babel/parser': 7.22.7 - '@babel/types': 7.22.5 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 '@types/babel__generator': 7.6.7 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.4 @@ -2064,20 +2100,20 @@ packages: /@types/babel__generator@7.6.7: resolution: {integrity: sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ==} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 dev: true /@types/babel__template@7.4.4: resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} dependencies: - '@babel/parser': 7.22.7 - '@babel/types': 7.22.5 + '@babel/parser': 7.23.3 + '@babel/types': 7.23.3 dev: true /@types/babel__traverse@7.20.4: resolution: {integrity: sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==} dependencies: - '@babel/types': 7.22.5 + '@babel/types': 7.23.3 dev: true /@types/chai-subset@1.3.3: @@ -2161,7 +2197,6 @@ packages: resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==} dependencies: undici-types: 5.26.5 - dev: true /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -2586,7 +2621,6 @@ packages: engines: {node: '>=4'} dependencies: color-convert: 1.9.3 - dev: true /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} @@ -2829,7 +2863,6 @@ packages: electron-to-chromium: 1.4.581 node-releases: 2.0.13 update-browserslist-db: 1.0.13(browserslist@4.22.1) - dev: true /buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} @@ -2908,7 +2941,6 @@ packages: /caniuse-lite@1.0.30001561: resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==} - dev: true /chai@4.3.7: resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} @@ -2936,7 +2968,6 @@ packages: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 - dev: true /chalk@3.0.0: resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} @@ -3030,7 +3061,6 @@ packages: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 - dev: true /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} @@ -3041,7 +3071,6 @@ packages: /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} @@ -3098,13 +3127,8 @@ packages: yargs: 17.7.2 dev: true - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3124,6 +3148,14 @@ packages: readable-stream: 3.6.2 dev: true + /cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + dependencies: + cross-spawn: 7.0.3 + dev: true + /cross-fetch@4.0.0: resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} dependencies: @@ -3256,7 +3288,6 @@ packages: optional: true dependencies: ms: 2.1.2 - dev: true /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -3443,7 +3474,6 @@ packages: /electron-to-chromium@1.4.581: resolution: {integrity: sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==} - dev: true /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -3802,7 +3832,6 @@ packages: '@esbuild/win32-arm64': 0.18.18 '@esbuild/win32-ia32': 0.18.18 '@esbuild/win32-x64': 0.18.18 - dev: true /esbuild@0.19.5: resolution: {integrity: sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==} @@ -3837,12 +3866,10 @@ packages: /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} - dev: true /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - dev: true /escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} @@ -4187,7 +4214,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: true optional: true /fstream@1.0.12: @@ -4243,7 +4269,6 @@ packages: /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - dev: true /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} @@ -4288,6 +4313,12 @@ packages: get-intrinsic: 1.2.1 dev: true + /get-tsconfig@4.7.2: + resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + /get-uri@6.0.2: resolution: {integrity: sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==} engines: {node: '>= 14'} @@ -4362,7 +4393,6 @@ packages: /globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - dev: true /globals@13.20.0: resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} @@ -4465,7 +4495,6 @@ packages: /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} - dev: true /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} @@ -4998,7 +5027,6 @@ packages: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true - dev: true /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -5020,7 +5048,6 @@ packages: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true - dev: true /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} @@ -5186,7 +5213,6 @@ packages: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: yallist: 3.1.1 - dev: true /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} @@ -5376,7 +5402,6 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true /mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -5394,7 +5419,6 @@ packages: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -5433,7 +5457,6 @@ packages: /node-releases@2.0.13: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} - dev: true /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -5678,7 +5701,6 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -5783,11 +5805,6 @@ packages: nanoid: 3.3.6 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: true - - /preact@10.15.1: - resolution: {integrity: sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==} - dev: false /preact@10.19.1: resolution: {integrity: sha512-ZSsUr6EFlwWH0btdXMj6+X+hJAZ1v+aUzKlfwBGokKB1ZO6Shz+D16LxQhM8f+E/UgkKbVe2tsWXtGTUMCkGpQ==} @@ -6136,6 +6153,10 @@ packages: engines: {node: '>=8'} dev: true + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + /resolve@1.22.4: resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} hasBin: true @@ -6225,6 +6246,32 @@ packages: rollup: 3.29.4 dev: true + /rollup-plugin-swc3@0.10.3(@swc/core@1.3.96)(rollup@3.29.4): + resolution: {integrity: sha512-GWoMkm3ATumN8EPHBKLrpCufcRNn7SfLyvMKWUfCVLidPuPjlQZfNBeQXP6OEiHBguZzriCssX43EnV3+Y54bA==} + engines: {node: '>=12'} + peerDependencies: + '@swc/core': '>=1.2.165' + rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 + dependencies: + '@fastify/deepmerge': 1.3.0 + '@rollup/pluginutils': 5.0.5(rollup@3.29.4) + '@swc/core': 1.3.96 + get-tsconfig: 4.7.2 + rollup: 3.29.4 + rollup-swc-preserve-directives: 0.5.0(@swc/core@1.3.96)(rollup@3.29.4) + dev: true + + /rollup-swc-preserve-directives@0.5.0(@swc/core@1.3.96)(rollup@3.29.4): + resolution: {integrity: sha512-6lnPZn2laSsdYcdCSE28z4Dwg2mCN5loF+/wBjybh25GJmONjHTf3orWa5j1zjEWY3RcGRjJ8K/52ePqtfy6dw==} + peerDependencies: + '@swc/core': '>=1.3.79' + rollup: ^2.0.0 || ^3.0.0 + dependencies: + '@napi-rs/magic-string': 0.3.4 + '@swc/core': 1.3.96 + rollup: 3.29.4 + dev: true + /rollup@2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} @@ -6239,7 +6286,6 @@ packages: hasBin: true optionalDependencies: fsevents: 2.3.3 - dev: true /rrweb-cssom@0.6.0: resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} @@ -6311,7 +6357,6 @@ packages: /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - dev: true /semver@7.5.4: resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} @@ -6439,7 +6484,6 @@ packages: /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - dev: true /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} @@ -6636,7 +6680,6 @@ packages: engines: {node: '>=4'} dependencies: has-flag: 3.0.0 - dev: true /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} @@ -6766,7 +6809,6 @@ packages: /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} - dev: true /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -7024,7 +7066,6 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true /universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} @@ -7060,7 +7101,6 @@ packages: browserslist: 4.22.1 escalade: 3.1.1 picocolors: 1.0.0 - dev: true /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -7120,6 +7160,16 @@ packages: - terser dev: true + /vite-plugin-babel@1.1.3(@babel/core@7.23.3)(vite@4.5.0): + resolution: {integrity: sha512-WE8ORQm8530kj0geiDL1r/+P2MaU0b+5wL5E8Jq07aounFwRIUeJXziGiMr2DFQs78vaefB5GRKh257M8Z6gFQ==} + peerDependencies: + '@babel/core': ^7.0.0 + vite: ^2.7.0 || ^3.0.0 || ^4.0.0 + dependencies: + '@babel/core': 7.23.3 + vite: 4.5.0(@types/node@20.9.0) + dev: false + /vite@4.5.0(@types/node@20.9.0): resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7154,7 +7204,6 @@ packages: rollup: 3.29.4 optionalDependencies: fsevents: 2.3.3 - dev: true /vitest@0.33.0(@vitest/browser@0.33.0)(jsdom@22.1.0)(webdriverio@8.22.1): resolution: {integrity: sha512-1CxaugJ50xskkQ0e969R/hW47za4YXDUfWJDxip1hwbnhUjYolpfUn2AMOulqG/Dtd9WYAtkHmM/m3yKVrEejQ==} @@ -7507,7 +7556,6 @@ packages: /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} @@ -7599,3 +7647,7 @@ packages: compress-commons: 5.0.1 readable-stream: 3.6.2 dev: true + + /zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + dev: false diff --git a/tsconfig.json b/tsconfig.json index 3bf23811..38d33d0e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,7 @@ "emitDeclarationOnly": false, "composite": true, "incremental": true, + "removeComments": false, "preserveWatchOutput": true, "jsx": "react", "rootDir": "./", From 8f49a335aa69408cce69d272756b8dee514e5f4e Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 21:37:09 +0100 Subject: [PATCH 09/21] fix tests --- packages/react/vitest.config.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts index a6d3d98e..9b9dfc0e 100644 --- a/packages/react/vitest.config.ts +++ b/packages/react/vitest.config.ts @@ -4,6 +4,8 @@ import packageJson from "./package.json"; const selfName = packageJson.name; +const exactRegEx = (it: string) => new RegExp(`^${it}$`); + export default defineConfig({ esbuild: { jsx: "preserve", @@ -14,19 +16,19 @@ export default defineConfig({ alias: [ { - find: /^react$/, + find: exactRegEx("react"), replacement: packageJson.exports["./react"], }, { - find: "@preact-signals/react/jsx-runtime", + find: exactRegEx(`${selfName}/jsx-runtime`), replacement: packageJson.exports["./jsx-runtime"], }, { - find: "@preact-signals/react/jsx-dev-runtime", + find: `${selfName}/jsx-dev-runtime`, replacement: packageJson.exports["./jsx-dev-runtime"], }, { - find: selfName, + find: exactRegEx(selfName), replacement: "./src/index.ts", }, { From e2dd020b3715e668dcb0eb4a559556b5d32926bb Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 21:42:16 +0100 Subject: [PATCH 10/21] test fix --- ....timestamp-1699871136378-d821d7a015a31.mjs | 84 +++++++++++++++++++ packages/react/package.json | 1 + packages/react/wrap-jsx/package.json | 4 + 3 files changed, 89 insertions(+) create mode 100644 apps/react-test/vite.config.ts.timestamp-1699871136378-d821d7a015a31.mjs create mode 100644 packages/react/wrap-jsx/package.json diff --git a/apps/react-test/vite.config.ts.timestamp-1699871136378-d821d7a015a31.mjs b/apps/react-test/vite.config.ts.timestamp-1699871136378-d821d7a015a31.mjs new file mode 100644 index 00000000..da69b74f --- /dev/null +++ b/apps/react-test/vite.config.ts.timestamp-1699871136378-d821d7a015a31.mjs @@ -0,0 +1,84 @@ +// vite.config.ts +import reactSWC from "file:///D:/Projects/open-source/preact-signals/node_modules/.pnpm/@vitejs+plugin-react-swc@3.4.1_vite@4.5.0/node_modules/@vitejs/plugin-react-swc/index.mjs"; +import babel from "file:///D:/Projects/open-source/preact-signals/node_modules/.pnpm/vite-plugin-babel@1.1.3_@babel+core@7.23.3_vite@4.5.0/node_modules/vite-plugin-babel/dist/index.mjs"; +import { defineConfig } from "file:///D:/Projects/open-source/preact-signals/node_modules/.pnpm/vite@4.5.0_@types+node@20.9.0/node_modules/vite/dist/node/index.js"; +import { z } from "file:///D:/Projects/open-source/preact-signals/node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/index.mjs"; +import { createRequire } from "node:module"; +import path from "node:path"; +var __vite_injected_original_import_meta_url = "file:///D:/Projects/open-source/preact-signals/apps/react-test/vite.config.ts"; +var resolve = createRequire(__vite_injected_original_import_meta_url).resolve; +var envSchema = z.object({ + USE_TRANSFORM: z.enum(["0", "1"]) +}).transform((it) => ({ + USE_TRANSFORM: it.USE_TRANSFORM === "0" ? false : true +})); +var { USE_TRANSFORM } = envSchema.parse(process.env); +console.log( + path.resolve(resolve("@preact-signals/safe-react"), "../../esm/index.mjs") +); +var vite_config_default = defineConfig({ + resolve: USE_TRANSFORM && { + alias: [ + { + find: /^react$/, + replacement: "@preact-signals/safe-react/react", + // TODO: extract to lib + customResolver: (() => { + const reactUrl = resolve("react"); + const fakeUrl = resolve("@preact-signals/safe-react/react"); + return { + resolveId(source, importer) { + const useRealImport = importer == null ? void 0 : importer.endsWith("react.cjs"); + return useRealImport ? reactUrl : fakeUrl; + } + }; + })() + }, + { + find: "@preact/signals-react", + replacement: path.resolve( + resolve("@preact-signals/safe-react"), + "../../esm/index.mjs" + ) + } + ] + }, + // define: { + // __DEV__: "process.env.NODE_ENV !== 'production'", + // }, + plugins: [ + USE_TRANSFORM && babel({ + babelConfig: { + plugins: [ + "module:@preact/signals-react-transform", + { + importSource: "@preact-signals/safe-react" + } + ] + } + }), + reactSWC({ + jsxImportSource: "@preact-signals/safe-react" + }) + // USE_TRANSFORM + // ? (reactBabel({ + // jsxImportSource: "@preact-signals/safe-react", + // babel: { + // plugins: [ + // [ + // "module:@preact/signals-react-transform", + // { + // importSource: "@preact-signals/safe-react", + // }, + // ], + // ], + // }, + // include: ["./src/**/*.{jsx,tsx}", "@preact-signals/utils/**"], + // }) as PluginOption[]) + // : reactSWC(), + ] +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxQcm9qZWN0c1xcXFxvcGVuLXNvdXJjZVxcXFxwcmVhY3Qtc2lnbmFsc1xcXFxhcHBzXFxcXHJlYWN0LXRlc3RcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkQ6XFxcXFByb2plY3RzXFxcXG9wZW4tc291cmNlXFxcXHByZWFjdC1zaWduYWxzXFxcXGFwcHNcXFxccmVhY3QtdGVzdFxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vRDovUHJvamVjdHMvb3Blbi1zb3VyY2UvcHJlYWN0LXNpZ25hbHMvYXBwcy9yZWFjdC10ZXN0L3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHJlYWN0U1dDIGZyb20gXCJAdml0ZWpzL3BsdWdpbi1yZWFjdC1zd2NcIjtcbmltcG9ydCByZWFjdEJhYmVsIGZyb20gXCJAdml0ZWpzL3BsdWdpbi1yZWFjdFwiO1xuaW1wb3J0IGJhYmVsIGZyb20gXCJ2aXRlLXBsdWdpbi1iYWJlbFwiO1xuaW1wb3J0IHsgUGx1Z2luT3B0aW9uLCBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcblxuY29uc3QgcmVzb2x2ZSA9IGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKS5yZXNvbHZlO1xuXG5jb25zdCBlbnZTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIFVTRV9UUkFOU0ZPUk06IHouZW51bShbXCIwXCIsIFwiMVwiXSksXG4gIH0pXG4gIC50cmFuc2Zvcm0oKGl0KSA9PiAoe1xuICAgIFVTRV9UUkFOU0ZPUk06IGl0LlVTRV9UUkFOU0ZPUk0gPT09IFwiMFwiID8gZmFsc2UgOiB0cnVlLFxuICB9KSk7XG5jb25zdCB7IFVTRV9UUkFOU0ZPUk0gfSA9IGVudlNjaGVtYS5wYXJzZShwcm9jZXNzLmVudik7XG5cbmNvbnNvbGUubG9nKFxuICBwYXRoLnJlc29sdmUocmVzb2x2ZShcIkBwcmVhY3Qtc2lnbmFscy9zYWZlLXJlYWN0XCIpLCBcIi4uLy4uL2VzbS9pbmRleC5tanNcIilcbik7XG5cbi8vIGh0dHBzOi8vdml0ZWpzLmRldi9jb25maWcvXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xuICByZXNvbHZlOiBVU0VfVFJBTlNGT1JNICYmIHtcbiAgICBhbGlhczogW1xuICAgICAge1xuICAgICAgICBmaW5kOiAvXnJlYWN0JC8sXG4gICAgICAgIHJlcGxhY2VtZW50OiBcIkBwcmVhY3Qtc2lnbmFscy9zYWZlLXJlYWN0L3JlYWN0XCIsXG4gICAgICAgIC8vIFRPRE86IGV4dHJhY3QgdG8gbGliXG4gICAgICAgIGN1c3RvbVJlc29sdmVyOiAoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlYWN0VXJsID0gcmVzb2x2ZShcInJlYWN0XCIpO1xuICAgICAgICAgIGNvbnN0IGZha2VVcmwgPSByZXNvbHZlKFwiQHByZWFjdC1zaWduYWxzL3NhZmUtcmVhY3QvcmVhY3RcIik7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlc29sdmVJZChzb3VyY2UsIGltcG9ydGVyKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHVzZVJlYWxJbXBvcnQgPSBpbXBvcnRlcj8uZW5kc1dpdGgoXCJyZWFjdC5janNcIik7XG4gICAgICAgICAgICAgIHJldHVybiB1c2VSZWFsSW1wb3J0ID8gcmVhY3RVcmwgOiBmYWtlVXJsO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9KSgpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZmluZDogXCJAcHJlYWN0L3NpZ25hbHMtcmVhY3RcIixcbiAgICAgICAgcmVwbGFjZW1lbnQ6IHBhdGgucmVzb2x2ZShcbiAgICAgICAgICByZXNvbHZlKFwiQHByZWFjdC1zaWduYWxzL3NhZmUtcmVhY3RcIiksXG4gICAgICAgICAgXCIuLi8uLi9lc20vaW5kZXgubWpzXCJcbiAgICAgICAgKSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAgLy8gZGVmaW5lOiB7XG4gIC8vICAgX19ERVZfXzogXCJwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nXCIsXG4gIC8vIH0sXG4gIHBsdWdpbnM6IFtcbiAgICBVU0VfVFJBTlNGT1JNICYmXG4gICAgICBiYWJlbCh7XG4gICAgICAgIGJhYmVsQ29uZmlnOiB7XG4gICAgICAgICAgcGx1Z2luczogW1xuICAgICAgICAgICAgXCJtb2R1bGU6QHByZWFjdC9zaWduYWxzLXJlYWN0LXRyYW5zZm9ybVwiLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpbXBvcnRTb3VyY2U6IFwiQHByZWFjdC1zaWduYWxzL3NhZmUtcmVhY3RcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIHJlYWN0U1dDKHtcbiAgICAgIGpzeEltcG9ydFNvdXJjZTogXCJAcHJlYWN0LXNpZ25hbHMvc2FmZS1yZWFjdFwiLFxuICAgIH0pLFxuICAgIC8vIFVTRV9UUkFOU0ZPUk1cbiAgICAvLyAgID8gKHJlYWN0QmFiZWwoe1xuICAgIC8vICAgICAgIGpzeEltcG9ydFNvdXJjZTogXCJAcHJlYWN0LXNpZ25hbHMvc2FmZS1yZWFjdFwiLFxuICAgIC8vICAgICAgIGJhYmVsOiB7XG4gICAgLy8gICAgICAgICBwbHVnaW5zOiBbXG4gICAgLy8gICAgICAgICAgIFtcbiAgICAvLyAgICAgICAgICAgICBcIm1vZHVsZTpAcHJlYWN0L3NpZ25hbHMtcmVhY3QtdHJhbnNmb3JtXCIsXG4gICAgLy8gICAgICAgICAgICAge1xuICAgIC8vICAgICAgICAgICAgICAgaW1wb3J0U291cmNlOiBcIkBwcmVhY3Qtc2lnbmFscy9zYWZlLXJlYWN0XCIsXG4gICAgLy8gICAgICAgICAgICAgfSxcbiAgICAvLyAgICAgICAgICAgXSxcbiAgICAvLyAgICAgICAgIF0sXG4gICAgLy8gICAgICAgfSxcbiAgICAvLyAgICAgICBpbmNsdWRlOiBbXCIuL3NyYy8qKi8qLntqc3gsdHN4fVwiLCBcIkBwcmVhY3Qtc2lnbmFscy91dGlscy8qKlwiXSxcbiAgICAvLyAgICAgfSkgYXMgUGx1Z2luT3B0aW9uW10pXG4gICAgLy8gICA6IHJlYWN0U1dDKCksXG4gIF0sXG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBZ1csT0FBTyxjQUFjO0FBRXJYLE9BQU8sV0FBVztBQUNsQixTQUF1QixvQkFBb0I7QUFDM0MsU0FBUyxTQUFTO0FBQ2xCLFNBQVMscUJBQXFCO0FBQzlCLE9BQU8sVUFBVTtBQU44TSxJQUFNLDJDQUEyQztBQVFoUixJQUFNLFVBQVUsY0FBYyx3Q0FBZSxFQUFFO0FBRS9DLElBQU0sWUFBWSxFQUNmLE9BQU87QUFBQSxFQUNOLGVBQWUsRUFBRSxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUM7QUFDbEMsQ0FBQyxFQUNBLFVBQVUsQ0FBQyxRQUFRO0FBQUEsRUFDbEIsZUFBZSxHQUFHLGtCQUFrQixNQUFNLFFBQVE7QUFDcEQsRUFBRTtBQUNKLElBQU0sRUFBRSxjQUFjLElBQUksVUFBVSxNQUFNLFFBQVEsR0FBRztBQUVyRCxRQUFRO0FBQUEsRUFDTixLQUFLLFFBQVEsUUFBUSw0QkFBNEIsR0FBRyxxQkFBcUI7QUFDM0U7QUFHQSxJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixTQUFTLGlCQUFpQjtBQUFBLElBQ3hCLE9BQU87QUFBQSxNQUNMO0FBQUEsUUFDRSxNQUFNO0FBQUEsUUFDTixhQUFhO0FBQUE7QUFBQSxRQUViLGlCQUFpQixNQUFNO0FBQ3JCLGdCQUFNLFdBQVcsUUFBUSxPQUFPO0FBQ2hDLGdCQUFNLFVBQVUsUUFBUSxrQ0FBa0M7QUFDMUQsaUJBQU87QUFBQSxZQUNMLFVBQVUsUUFBUSxVQUFVO0FBQzFCLG9CQUFNLGdCQUFnQixxQ0FBVSxTQUFTO0FBQ3pDLHFCQUFPLGdCQUFnQixXQUFXO0FBQUEsWUFDcEM7QUFBQSxVQUNGO0FBQUEsUUFDRixHQUFHO0FBQUEsTUFDTDtBQUFBLE1BQ0E7QUFBQSxRQUNFLE1BQU07QUFBQSxRQUNOLGFBQWEsS0FBSztBQUFBLFVBQ2hCLFFBQVEsNEJBQTRCO0FBQUEsVUFDcEM7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJQSxTQUFTO0FBQUEsSUFDUCxpQkFDRSxNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsUUFDWCxTQUFTO0FBQUEsVUFDUDtBQUFBLFVBQ0E7QUFBQSxZQUNFLGNBQWM7QUFBQSxVQUNoQjtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUEsSUFDRixDQUFDO0FBQUEsSUFDSCxTQUFTO0FBQUEsTUFDUCxpQkFBaUI7QUFBQSxJQUNuQixDQUFDO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWlCSDtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg== diff --git a/packages/react/package.json b/packages/react/package.json index f9f029ab..8f78fd3e 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -33,6 +33,7 @@ "./react": "./react.cjs", "./jsx-runtime": "./jsx-runtime.cjs", "./jsx-dev-runtime": "./jsx-dev-runtime.cjs", + "./wrap-jsx": "./wrap-jsx.cjs", "./package.json": "./package.json" }, "scripts": { diff --git a/packages/react/wrap-jsx/package.json b/packages/react/wrap-jsx/package.json new file mode 100644 index 00000000..fe18198a --- /dev/null +++ b/packages/react/wrap-jsx/package.json @@ -0,0 +1,4 @@ +{ + "main": "../wrap-jsx.cjs", + "type": "commonjs" +} From 2649185bc341b77dc7f12132221a1c5e520671c6 Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 21:48:38 +0100 Subject: [PATCH 11/21] test fix --- packages/react/jsx-dev-runtime.cjs | 2 +- packages/react/jsx-runtime.cjs | 2 +- packages/react/react.cjs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react/jsx-dev-runtime.cjs b/packages/react/jsx-dev-runtime.cjs index 969302f4..5d27577e 100644 --- a/packages/react/jsx-dev-runtime.cjs +++ b/packages/react/jsx-dev-runtime.cjs @@ -1,6 +1,6 @@ // @ts-check const { jsxDEV: _jsxDEV, Fragment } = require("react/jsx-dev-runtime"); -const wrapJSX = require("./wrap-jsx.cjs"); +const wrapJSX = require("./wrap-jsx"); module.exports = /** @type {import('react/jsx-dev-runtime')} */ ({ Fragment, diff --git a/packages/react/jsx-runtime.cjs b/packages/react/jsx-runtime.cjs index 92f28f42..ba6bde6c 100644 --- a/packages/react/jsx-runtime.cjs +++ b/packages/react/jsx-runtime.cjs @@ -1,6 +1,6 @@ // @ts-check const { jsxs: _jsxs, jsx: _jsx, Fragment } = require("react/jsx-runtime"); -const wrapJSX = require("./wrap-jsx.cjs"); +const wrapJSX = require("./wrap-jsx"); module.exports = /** @type {import('react/jsx-runtime')} */ ({ Fragment, diff --git a/packages/react/react.cjs b/packages/react/react.cjs index d761e586..56c09733 100644 --- a/packages/react/react.cjs +++ b/packages/react/react.cjs @@ -1,6 +1,6 @@ // @ts-check const React = require("react"); -const wrapJsx = require("./wrap-jsx.cjs"); +const wrapJsx = require("./wrap-jsx"); // didn't wrapper React.createFactory possibly not needed module.exports = { From 44d87ce4f73cef3f995c6e9681a55aada441c3e8 Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:01:26 +0100 Subject: [PATCH 12/21] resource test improvement --- packages/utils/src/resource/resource.test.ts | 37 +++++++++++++++++++- packages/utils/src/resource/resource.ts | 1 - 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/resource/resource.test.ts b/packages/utils/src/resource/resource.test.ts index 424c47d4..ebfeeb0e 100644 --- a/packages/utils/src/resource/resource.test.ts +++ b/packages/utils/src/resource/resource.test.ts @@ -5,7 +5,14 @@ import { signal, } from "@preact-signals/unified-signals"; import { ExpectStatic, afterEach, describe, expect, it, vi } from "vitest"; -import { Resource, ResourceState, resource } from "./resource"; +import { + Resource, + ResourceFetcher, + ResourceOptions, + ResourceState, + resource, + resource, +} from "./resource"; const sleep = (ms?: number) => new Promise((r) => setTimeout(r, ms)); describe("resource", () => { @@ -527,4 +534,32 @@ describe("resource", () => { expect(r.latest).toBe(220); }); }); + + it("is not receiving old value after dispose", async () => { + let sleepTime = 5; + let fetcherResolvedTimes = 0; + const fetcher = vi.fn( + (...args: Parameters>) => + sleep(sleepTime).then(() => ++fetcherResolvedTimes) + ); + + const sig = signal(0); + const r = resource({ fetcher, source: () => sig.value }); + + const pr = sleep(sleepTime); + sleepTime = 20; + sig.value = 1; + await pr; + + expect(fetcherResolvedTimes).toBe(1); + expect(fetcher).toHaveBeenCalledTimes(2); + expect(fetcher.mock.calls[0]?.[1]).toBeTypeOf("object"); + expect(fetcher.mock.calls[0]?.[1]?.signal?.aborted).toBe(true); + expect(r()).toBe(undefined); + await sleep(sleepTime); + + expect(fetcherResolvedTimes).toBe(2); + expect(fetcher).toHaveBeenCalledTimes(2); + expect(r()).toBe(2); + }); }); diff --git a/packages/utils/src/resource/resource.ts b/packages/utils/src/resource/resource.ts index 71335d95..d88d237f 100644 --- a/packages/utils/src/resource/resource.ts +++ b/packages/utils/src/resource/resource.ts @@ -356,7 +356,6 @@ const _fetch: Resource["_fetch"] = function ( if (!result) { return; } - // TODO: fix - here can be previous data this.pr = result.then( (value) => { if (abortController.signal.aborted) { From 5999bf78b41404940a5fc86bcace783e97917c2e Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:06:04 +0100 Subject: [PATCH 13/21] new try --- packages/react/jsx-dev-runtime.cjs | 2 +- packages/react/jsx-runtime.cjs | 2 +- packages/react/react.cjs | 4 ++-- tsconfig.json | 2 ++ 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/react/jsx-dev-runtime.cjs b/packages/react/jsx-dev-runtime.cjs index 5d27577e..d75b8ad9 100644 --- a/packages/react/jsx-dev-runtime.cjs +++ b/packages/react/jsx-dev-runtime.cjs @@ -1,6 +1,6 @@ // @ts-check const { jsxDEV: _jsxDEV, Fragment } = require("react/jsx-dev-runtime"); -const wrapJSX = require("./wrap-jsx"); +const wrapJSX = require("@preact-signals/safe-react/wrap-jsx"); module.exports = /** @type {import('react/jsx-dev-runtime')} */ ({ Fragment, diff --git a/packages/react/jsx-runtime.cjs b/packages/react/jsx-runtime.cjs index ba6bde6c..2ca59758 100644 --- a/packages/react/jsx-runtime.cjs +++ b/packages/react/jsx-runtime.cjs @@ -1,6 +1,6 @@ // @ts-check const { jsxs: _jsxs, jsx: _jsx, Fragment } = require("react/jsx-runtime"); -const wrapJSX = require("./wrap-jsx"); +const wrapJSX = require("@preact-signals/safe-react/wrap-jsx"); module.exports = /** @type {import('react/jsx-runtime')} */ ({ Fragment, diff --git a/packages/react/react.cjs b/packages/react/react.cjs index 56c09733..d2402f5f 100644 --- a/packages/react/react.cjs +++ b/packages/react/react.cjs @@ -1,10 +1,10 @@ // @ts-check const React = require("react"); -const wrapJsx = require("./wrap-jsx"); +const wrapJSX = require("@preact-signals/safe-react/wrap-jsx"); // didn't wrapper React.createFactory possibly not needed module.exports = { ...React, // @ts-expect-error - createElement: wrapJsx(React.createElement), + createElement: wrapJSX(React.createElement), }; diff --git a/tsconfig.json b/tsconfig.json index 38d33d0e..7ad442b3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,6 +25,8 @@ "sourceMap": true, "paths": { "@preact-signals/utils/*": ["./packages/utils/src/*"], + "@preact-signals/safe-react": ["./packages/react/src/index.ts"], + "@preact-signals/safe-react/wrap-jsx": ["./packages/react/wrap-jsx.cjs"], "@preact-signals/unified-signals": [ "./packages/unified-signals/src/index.d.ts" ], From df1d0e1abdd840aeda252b45ca320c29f41c2f9e Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:09:13 +0100 Subject: [PATCH 14/21] small experiment --- packages/react/vitest.config.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts index 9b9dfc0e..4e4ec5dd 100644 --- a/packages/react/vitest.config.ts +++ b/packages/react/vitest.config.ts @@ -17,15 +17,15 @@ export default defineConfig({ alias: [ { find: exactRegEx("react"), - replacement: packageJson.exports["./react"], + replacement: require.resolve(packageJson.exports["./react"]), }, { find: exactRegEx(`${selfName}/jsx-runtime`), - replacement: packageJson.exports["./jsx-runtime"], + replacement: require.resolve(packageJson.exports["./jsx-runtime"]), }, { find: `${selfName}/jsx-dev-runtime`, - replacement: packageJson.exports["./jsx-dev-runtime"], + replacement: require.resolve(packageJson.exports["./jsx-dev-runtime"]), }, { find: exactRegEx(selfName), From a006310a6e323e2602b724931eab28609b9ce941 Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:27:25 +0100 Subject: [PATCH 15/21] ci fixes --- .github/workflows/lint.yml | 6 +++++- .github/workflows/release.yml | 13 ++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 743a2292..19344eca 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,9 +6,13 @@ on: pull_request: branches: - main + jobs: test: - name: Lint x Test react-fast-hoc package + env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ vars.TURBO_TEAM }} + name: Lint x Test preact-signals monorepo runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index be2bb9e8..b2ca2df4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,6 +10,9 @@ concurrency: ${{ github.workflow }}-${{ github.ref }} jobs: release-pr: name: Release + env: + TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} + TURBO_TEAM: ${{ vars.TURBO_TEAM }} runs-on: ubuntu-latest steps: - name: Checkout Repo @@ -26,13 +29,13 @@ jobs: - name: Install Dependencies run: pnpm i - + - name: Create Release Pull Request or Publish to npm id: changesets uses: changesets/action@v1 with: - # This expects you to have a script called release which does a build for your packages and calls changeset publish - publish: pnpm run release + # This expects you to have a script called release which does a build for your packages and calls changeset publish + publish: pnpm run release env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} From 5982d13d72ebc8cce894fb2dd94868afc22fb89d Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:30:29 +0100 Subject: [PATCH 16/21] netilfy ci build --- apps/react-test/vite.config.ts | 75 +++++++++++++--------------------- 1 file changed, 29 insertions(+), 46 deletions(-) diff --git a/apps/react-test/vite.config.ts b/apps/react-test/vite.config.ts index dac8b637..63216c7d 100644 --- a/apps/react-test/vite.config.ts +++ b/apps/react-test/vite.config.ts @@ -23,32 +23,34 @@ console.log( // https://vitejs.dev/config/ export default defineConfig({ - resolve: USE_TRANSFORM && { - alias: [ - { - find: /^react$/, - replacement: "@preact-signals/safe-react/react", - // TODO: extract to lib - customResolver: (() => { - const reactUrl = resolve("react"); - const fakeUrl = resolve("@preact-signals/safe-react/react"); - return { - resolveId(source, importer) { - const useRealImport = importer?.endsWith("react.cjs"); - return useRealImport ? reactUrl : fakeUrl; - }, - }; - })(), - }, - { - find: "@preact/signals-react", - replacement: path.resolve( - resolve("@preact-signals/safe-react"), - "../../esm/index.mjs" - ), - }, - ], - }, + resolve: USE_TRANSFORM + ? { + alias: [ + { + find: /^react$/, + replacement: "@preact-signals/safe-react/react", + // TODO: extract to lib + customResolver: (() => { + const reactUrl = resolve("react"); + const fakeUrl = resolve("@preact-signals/safe-react/react"); + return { + resolveId(source, importer) { + const useRealImport = importer?.endsWith("react.cjs"); + return useRealImport ? reactUrl : fakeUrl; + }, + }; + })(), + }, + { + find: "@preact/signals-react", + replacement: path.resolve( + resolve("@preact-signals/safe-react"), + "../../esm/index.mjs" + ), + }, + ], + } + : undefined, plugins: [ USE_TRANSFORM && babel({ @@ -80,24 +82,5 @@ export default defineConfig({ }, include: /\.(mdx|js|jsx|ts|tsx)$/, }) as PluginOption[], - // reactSWC({ - // jsxImportSource: "@preact-signals/safe-react", - // }), - // USE_TRANSFORM - // ? (reactBabel({ - // jsxImportSource: "@preact-signals/safe-react", - // babel: { - // plugins: [ - // [ - // "module:@preact/signals-react-transform", - // { - // importSource: "@preact-signals/safe-react", - // }, - // ], - // ], - // }, - // include: ["./src/**/*.{jsx,tsx}", "@preact-signals/utils/**"], - // }) as PluginOption[]) - // : reactSWC(), - ], + ].filter(Boolean), }); From 68aa739397f5bddf3669b6c9894cbe942e512353 Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:35:11 +0100 Subject: [PATCH 17/21] netilify fix --- apps/react-test/package.json | 2 +- apps/react-test/vite.config.ts | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/react-test/package.json b/apps/react-test/package.json index 582573f3..faf710a2 100644 --- a/apps/react-test/package.json +++ b/apps/react-test/package.json @@ -6,7 +6,7 @@ "scripts": { "dev:transform": "cross-env USE_TRANSFORM=1 vite", "dev": "cross-env USE_TRANSFORM=0 vite", - "build": "tsc && cross-env USE_TRANSFORM=0 vite build", + "build": "cross-env USE_TRANSFORM=0 vite build", "watch": "pnpm dev", "preview": "vite preview" }, diff --git a/apps/react-test/vite.config.ts b/apps/react-test/vite.config.ts index 63216c7d..f8e1cb1a 100644 --- a/apps/react-test/vite.config.ts +++ b/apps/react-test/vite.config.ts @@ -1,4 +1,3 @@ -import reactSWC from "@vitejs/plugin-react-swc"; import reactBabel from "@vitejs/plugin-react"; import babel from "vite-plugin-babel"; import { PluginOption, defineConfig } from "vite"; @@ -17,10 +16,6 @@ const envSchema = z })); const { USE_TRANSFORM } = envSchema.parse(process.env); -console.log( - path.resolve(resolve("@preact-signals/safe-react"), "../../esm/index.mjs") -); - // https://vitejs.dev/config/ export default defineConfig({ resolve: USE_TRANSFORM From 1090bd652b6fbdb23741405adb9b8e9f8188dc0d Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:44:16 +0100 Subject: [PATCH 18/21] update safe-react package.json --- .changeset/fuzzy-meals-refuse.md | 5 +++++ packages/react/package.json | 18 +++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 .changeset/fuzzy-meals-refuse.md diff --git a/.changeset/fuzzy-meals-refuse.md b/.changeset/fuzzy-meals-refuse.md new file mode 100644 index 00000000..fe5702be --- /dev/null +++ b/.changeset/fuzzy-meals-refuse.md @@ -0,0 +1,5 @@ +--- +"@preact-signals/safe-react": patch +--- + +Package init diff --git a/packages/react/package.json b/packages/react/package.json index 8f78fd3e..29dbf005 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,23 +1,23 @@ { "name": "@preact-signals/safe-react", - "version": "0.0.1", + "version": "0.0.0", "license": "MIT", "description": "Manage state with style in React", - "keywords": [], + "keywords": [ + "preact-signals", + "react", + "signals" + ], "authors": [ + "preact-signals (https://github.com/XantreGodlike/signals/contributors)", "The Preact Authors (https://github.com/preactjs/signals/contributors)" ], "repository": { "type": "git", - "url": "https://github.com/preactjs/signals", + "url": "https://github.com/XantreGodlike/preact-signals/signals", "directory": "packages/react" }, - "bugs": "https://github.com/preactjs/signals/issues", - "homepage": "https://preactjs.com", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - }, + "bugs": "https://github.com/XantreGodlike/preact-signals/issues", "amdName": "reactSignals", "main": "./dist/cjs/index.cjs", "module": "./dist/esm/index.mjs", From f158562bad9fde041ed65548431985bf0045429b Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:44:23 +0100 Subject: [PATCH 19/21] wip --- turbo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turbo.json b/turbo.json index 49275263..44d74d33 100644 --- a/turbo.json +++ b/turbo.json @@ -22,7 +22,7 @@ }, "lint": { "dependsOn": ["^build"], - "outputs": ["tsconfig.tsbuildinfo", "dist/**"] + "outputs": ["*.tsbuildinfo"] } } } From 6b5fa85a70306fbf0e84036c440908e6f09342f8 Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:55:38 +0100 Subject: [PATCH 20/21] wip --- .changeset/silver-foxes-speak.md | 5 ++ .changeset/spotty-countries-flash.md | 7 ++ .gitignore | 4 +- ....timestamp-1699871136378-d821d7a015a31.mjs | 84 ------------------- packages/react/package.json | 4 +- 5 files changed, 17 insertions(+), 87 deletions(-) create mode 100644 .changeset/silver-foxes-speak.md create mode 100644 .changeset/spotty-countries-flash.md delete mode 100644 apps/react-test/vite.config.ts.timestamp-1699871136378-d821d7a015a31.mjs diff --git a/.changeset/silver-foxes-speak.md b/.changeset/silver-foxes-speak.md new file mode 100644 index 00000000..c360dc94 --- /dev/null +++ b/.changeset/silver-foxes-speak.md @@ -0,0 +1,5 @@ +--- +"@preact-signals/utils": patch +--- + +Removed unnecessary private varitables usage from hocs entry diff --git a/.changeset/spotty-countries-flash.md b/.changeset/spotty-countries-flash.md new file mode 100644 index 00000000..0406c673 --- /dev/null +++ b/.changeset/spotty-countries-flash.md @@ -0,0 +1,7 @@ +--- +"@preact-signals/unified-signals": patch +"@preact-signals/query": patch +"@preact-signals/utils": patch +--- + +Added `@preact-signals/safe-react` as peerDependency diff --git a/.gitignore b/.gitignore index 085cd154..2f5df8fd 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,6 @@ dist-ssr *.sw? .turbo -tsconfig.tsbuildinfo \ No newline at end of file +tsconfig.tsbuildinfo +vite.config.ts.timestamp-* +vitest.config.ts.timestamp-* \ No newline at end of file diff --git a/apps/react-test/vite.config.ts.timestamp-1699871136378-d821d7a015a31.mjs b/apps/react-test/vite.config.ts.timestamp-1699871136378-d821d7a015a31.mjs deleted file mode 100644 index da69b74f..00000000 --- a/apps/react-test/vite.config.ts.timestamp-1699871136378-d821d7a015a31.mjs +++ /dev/null @@ -1,84 +0,0 @@ -// vite.config.ts -import reactSWC from "file:///D:/Projects/open-source/preact-signals/node_modules/.pnpm/@vitejs+plugin-react-swc@3.4.1_vite@4.5.0/node_modules/@vitejs/plugin-react-swc/index.mjs"; -import babel from "file:///D:/Projects/open-source/preact-signals/node_modules/.pnpm/vite-plugin-babel@1.1.3_@babel+core@7.23.3_vite@4.5.0/node_modules/vite-plugin-babel/dist/index.mjs"; -import { defineConfig } from "file:///D:/Projects/open-source/preact-signals/node_modules/.pnpm/vite@4.5.0_@types+node@20.9.0/node_modules/vite/dist/node/index.js"; -import { z } from "file:///D:/Projects/open-source/preact-signals/node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/index.mjs"; -import { createRequire } from "node:module"; -import path from "node:path"; -var __vite_injected_original_import_meta_url = "file:///D:/Projects/open-source/preact-signals/apps/react-test/vite.config.ts"; -var resolve = createRequire(__vite_injected_original_import_meta_url).resolve; -var envSchema = z.object({ - USE_TRANSFORM: z.enum(["0", "1"]) -}).transform((it) => ({ - USE_TRANSFORM: it.USE_TRANSFORM === "0" ? false : true -})); -var { USE_TRANSFORM } = envSchema.parse(process.env); -console.log( - path.resolve(resolve("@preact-signals/safe-react"), "../../esm/index.mjs") -); -var vite_config_default = defineConfig({ - resolve: USE_TRANSFORM && { - alias: [ - { - find: /^react$/, - replacement: "@preact-signals/safe-react/react", - // TODO: extract to lib - customResolver: (() => { - const reactUrl = resolve("react"); - const fakeUrl = resolve("@preact-signals/safe-react/react"); - return { - resolveId(source, importer) { - const useRealImport = importer == null ? void 0 : importer.endsWith("react.cjs"); - return useRealImport ? reactUrl : fakeUrl; - } - }; - })() - }, - { - find: "@preact/signals-react", - replacement: path.resolve( - resolve("@preact-signals/safe-react"), - "../../esm/index.mjs" - ) - } - ] - }, - // define: { - // __DEV__: "process.env.NODE_ENV !== 'production'", - // }, - plugins: [ - USE_TRANSFORM && babel({ - babelConfig: { - plugins: [ - "module:@preact/signals-react-transform", - { - importSource: "@preact-signals/safe-react" - } - ] - } - }), - reactSWC({ - jsxImportSource: "@preact-signals/safe-react" - }) - // USE_TRANSFORM - // ? (reactBabel({ - // jsxImportSource: "@preact-signals/safe-react", - // babel: { - // plugins: [ - // [ - // "module:@preact/signals-react-transform", - // { - // importSource: "@preact-signals/safe-react", - // }, - // ], - // ], - // }, - // include: ["./src/**/*.{jsx,tsx}", "@preact-signals/utils/**"], - // }) as PluginOption[]) - // : reactSWC(), - ] -}); -export { - vite_config_default as default -}; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxQcm9qZWN0c1xcXFxvcGVuLXNvdXJjZVxcXFxwcmVhY3Qtc2lnbmFsc1xcXFxhcHBzXFxcXHJlYWN0LXRlc3RcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkQ6XFxcXFByb2plY3RzXFxcXG9wZW4tc291cmNlXFxcXHByZWFjdC1zaWduYWxzXFxcXGFwcHNcXFxccmVhY3QtdGVzdFxcXFx2aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vRDovUHJvamVjdHMvb3Blbi1zb3VyY2UvcHJlYWN0LXNpZ25hbHMvYXBwcy9yZWFjdC10ZXN0L3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHJlYWN0U1dDIGZyb20gXCJAdml0ZWpzL3BsdWdpbi1yZWFjdC1zd2NcIjtcbmltcG9ydCByZWFjdEJhYmVsIGZyb20gXCJAdml0ZWpzL3BsdWdpbi1yZWFjdFwiO1xuaW1wb3J0IGJhYmVsIGZyb20gXCJ2aXRlLXBsdWdpbi1iYWJlbFwiO1xuaW1wb3J0IHsgUGx1Z2luT3B0aW9uLCBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcblxuY29uc3QgcmVzb2x2ZSA9IGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKS5yZXNvbHZlO1xuXG5jb25zdCBlbnZTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIFVTRV9UUkFOU0ZPUk06IHouZW51bShbXCIwXCIsIFwiMVwiXSksXG4gIH0pXG4gIC50cmFuc2Zvcm0oKGl0KSA9PiAoe1xuICAgIFVTRV9UUkFOU0ZPUk06IGl0LlVTRV9UUkFOU0ZPUk0gPT09IFwiMFwiID8gZmFsc2UgOiB0cnVlLFxuICB9KSk7XG5jb25zdCB7IFVTRV9UUkFOU0ZPUk0gfSA9IGVudlNjaGVtYS5wYXJzZShwcm9jZXNzLmVudik7XG5cbmNvbnNvbGUubG9nKFxuICBwYXRoLnJlc29sdmUocmVzb2x2ZShcIkBwcmVhY3Qtc2lnbmFscy9zYWZlLXJlYWN0XCIpLCBcIi4uLy4uL2VzbS9pbmRleC5tanNcIilcbik7XG5cbi8vIGh0dHBzOi8vdml0ZWpzLmRldi9jb25maWcvXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xuICByZXNvbHZlOiBVU0VfVFJBTlNGT1JNICYmIHtcbiAgICBhbGlhczogW1xuICAgICAge1xuICAgICAgICBmaW5kOiAvXnJlYWN0JC8sXG4gICAgICAgIHJlcGxhY2VtZW50OiBcIkBwcmVhY3Qtc2lnbmFscy9zYWZlLXJlYWN0L3JlYWN0XCIsXG4gICAgICAgIC8vIFRPRE86IGV4dHJhY3QgdG8gbGliXG4gICAgICAgIGN1c3RvbVJlc29sdmVyOiAoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlYWN0VXJsID0gcmVzb2x2ZShcInJlYWN0XCIpO1xuICAgICAgICAgIGNvbnN0IGZha2VVcmwgPSByZXNvbHZlKFwiQHByZWFjdC1zaWduYWxzL3NhZmUtcmVhY3QvcmVhY3RcIik7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlc29sdmVJZChzb3VyY2UsIGltcG9ydGVyKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHVzZVJlYWxJbXBvcnQgPSBpbXBvcnRlcj8uZW5kc1dpdGgoXCJyZWFjdC5janNcIik7XG4gICAgICAgICAgICAgIHJldHVybiB1c2VSZWFsSW1wb3J0ID8gcmVhY3RVcmwgOiBmYWtlVXJsO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9KSgpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZmluZDogXCJAcHJlYWN0L3NpZ25hbHMtcmVhY3RcIixcbiAgICAgICAgcmVwbGFjZW1lbnQ6IHBhdGgucmVzb2x2ZShcbiAgICAgICAgICByZXNvbHZlKFwiQHByZWFjdC1zaWduYWxzL3NhZmUtcmVhY3RcIiksXG4gICAgICAgICAgXCIuLi8uLi9lc20vaW5kZXgubWpzXCJcbiAgICAgICAgKSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAgLy8gZGVmaW5lOiB7XG4gIC8vICAgX19ERVZfXzogXCJwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nXCIsXG4gIC8vIH0sXG4gIHBsdWdpbnM6IFtcbiAgICBVU0VfVFJBTlNGT1JNICYmXG4gICAgICBiYWJlbCh7XG4gICAgICAgIGJhYmVsQ29uZmlnOiB7XG4gICAgICAgICAgcGx1Z2luczogW1xuICAgICAgICAgICAgXCJtb2R1bGU6QHByZWFjdC9zaWduYWxzLXJlYWN0LXRyYW5zZm9ybVwiLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpbXBvcnRTb3VyY2U6IFwiQHByZWFjdC1zaWduYWxzL3NhZmUtcmVhY3RcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIHJlYWN0U1dDKHtcbiAgICAgIGpzeEltcG9ydFNvdXJjZTogXCJAcHJlYWN0LXNpZ25hbHMvc2FmZS1yZWFjdFwiLFxuICAgIH0pLFxuICAgIC8vIFVTRV9UUkFOU0ZPUk1cbiAgICAvLyAgID8gKHJlYWN0QmFiZWwoe1xuICAgIC8vICAgICAgIGpzeEltcG9ydFNvdXJjZTogXCJAcHJlYWN0LXNpZ25hbHMvc2FmZS1yZWFjdFwiLFxuICAgIC8vICAgICAgIGJhYmVsOiB7XG4gICAgLy8gICAgICAgICBwbHVnaW5zOiBbXG4gICAgLy8gICAgICAgICAgIFtcbiAgICAvLyAgICAgICAgICAgICBcIm1vZHVsZTpAcHJlYWN0L3NpZ25hbHMtcmVhY3QtdHJhbnNmb3JtXCIsXG4gICAgLy8gICAgICAgICAgICAge1xuICAgIC8vICAgICAgICAgICAgICAgaW1wb3J0U291cmNlOiBcIkBwcmVhY3Qtc2lnbmFscy9zYWZlLXJlYWN0XCIsXG4gICAgLy8gICAgICAgICAgICAgfSxcbiAgICAvLyAgICAgICAgICAgXSxcbiAgICAvLyAgICAgICAgIF0sXG4gICAgLy8gICAgICAgfSxcbiAgICAvLyAgICAgICBpbmNsdWRlOiBbXCIuL3NyYy8qKi8qLntqc3gsdHN4fVwiLCBcIkBwcmVhY3Qtc2lnbmFscy91dGlscy8qKlwiXSxcbiAgICAvLyAgICAgfSkgYXMgUGx1Z2luT3B0aW9uW10pXG4gICAgLy8gICA6IHJlYWN0U1dDKCksXG4gIF0sXG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBZ1csT0FBTyxjQUFjO0FBRXJYLE9BQU8sV0FBVztBQUNsQixTQUF1QixvQkFBb0I7QUFDM0MsU0FBUyxTQUFTO0FBQ2xCLFNBQVMscUJBQXFCO0FBQzlCLE9BQU8sVUFBVTtBQU44TSxJQUFNLDJDQUEyQztBQVFoUixJQUFNLFVBQVUsY0FBYyx3Q0FBZSxFQUFFO0FBRS9DLElBQU0sWUFBWSxFQUNmLE9BQU87QUFBQSxFQUNOLGVBQWUsRUFBRSxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUM7QUFDbEMsQ0FBQyxFQUNBLFVBQVUsQ0FBQyxRQUFRO0FBQUEsRUFDbEIsZUFBZSxHQUFHLGtCQUFrQixNQUFNLFFBQVE7QUFDcEQsRUFBRTtBQUNKLElBQU0sRUFBRSxjQUFjLElBQUksVUFBVSxNQUFNLFFBQVEsR0FBRztBQUVyRCxRQUFRO0FBQUEsRUFDTixLQUFLLFFBQVEsUUFBUSw0QkFBNEIsR0FBRyxxQkFBcUI7QUFDM0U7QUFHQSxJQUFPLHNCQUFRLGFBQWE7QUFBQSxFQUMxQixTQUFTLGlCQUFpQjtBQUFBLElBQ3hCLE9BQU87QUFBQSxNQUNMO0FBQUEsUUFDRSxNQUFNO0FBQUEsUUFDTixhQUFhO0FBQUE7QUFBQSxRQUViLGlCQUFpQixNQUFNO0FBQ3JCLGdCQUFNLFdBQVcsUUFBUSxPQUFPO0FBQ2hDLGdCQUFNLFVBQVUsUUFBUSxrQ0FBa0M7QUFDMUQsaUJBQU87QUFBQSxZQUNMLFVBQVUsUUFBUSxVQUFVO0FBQzFCLG9CQUFNLGdCQUFnQixxQ0FBVSxTQUFTO0FBQ3pDLHFCQUFPLGdCQUFnQixXQUFXO0FBQUEsWUFDcEM7QUFBQSxVQUNGO0FBQUEsUUFDRixHQUFHO0FBQUEsTUFDTDtBQUFBLE1BQ0E7QUFBQSxRQUNFLE1BQU07QUFBQSxRQUNOLGFBQWEsS0FBSztBQUFBLFVBQ2hCLFFBQVEsNEJBQTRCO0FBQUEsVUFDcEM7QUFBQSxRQUNGO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJQSxTQUFTO0FBQUEsSUFDUCxpQkFDRSxNQUFNO0FBQUEsTUFDSixhQUFhO0FBQUEsUUFDWCxTQUFTO0FBQUEsVUFDUDtBQUFBLFVBQ0E7QUFBQSxZQUNFLGNBQWM7QUFBQSxVQUNoQjtBQUFBLFFBQ0Y7QUFBQSxNQUNGO0FBQUEsSUFDRixDQUFDO0FBQUEsSUFDSCxTQUFTO0FBQUEsTUFDUCxpQkFBaUI7QUFBQSxJQUNuQixDQUFDO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWlCSDtBQUNGLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg== diff --git a/packages/react/package.json b/packages/react/package.json index 29dbf005..a5670c67 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -9,12 +9,12 @@ "signals" ], "authors": [ - "preact-signals (https://github.com/XantreGodlike/signals/contributors)", + "preact-signals (https://github.com/XantreGodlike/preact-signals/contributors)", "The Preact Authors (https://github.com/preactjs/signals/contributors)" ], "repository": { "type": "git", - "url": "https://github.com/XantreGodlike/preact-signals/signals", + "url": "https://github.com/XantreGodlike/preact-signals", "directory": "packages/react" }, "bugs": "https://github.com/XantreGodlike/preact-signals/issues", From d13881970a70e5e2577df3acd0c3b9272a5692ec Mon Sep 17 00:00:00 2001 From: XantreGodlike Date: Mon, 13 Nov 2023 22:57:55 +0100 Subject: [PATCH 21/21] no transform build fix --- apps/react-test/vite.config.ts | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/apps/react-test/vite.config.ts b/apps/react-test/vite.config.ts index f8e1cb1a..8649151c 100644 --- a/apps/react-test/vite.config.ts +++ b/apps/react-test/vite.config.ts @@ -63,19 +63,23 @@ export default defineConfig({ filter: /utils\/dist\/.+\.mjs$/, }), , - reactBabel({ - jsxImportSource: "@preact-signals/safe-react", - babel: { - plugins: [ - [ - "module:@preact/signals-react-transform", - { - importSource: "@preact-signals/safe-react", + reactBabel( + USE_TRANSFORM + ? { + jsxImportSource: "@preact-signals/safe-react", + babel: { + plugins: [ + [ + "module:@preact/signals-react-transform", + { + importSource: "@preact-signals/safe-react", + }, + ], + ], }, - ], - ], - }, - include: /\.(mdx|js|jsx|ts|tsx)$/, - }) as PluginOption[], + include: /\.(mdx|js|jsx|ts|tsx)$/, + } + : undefined + ) as PluginOption[], ].filter(Boolean), });