diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 19a15ca..5ef474f 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -7,10 +7,10 @@ module.exports = configure({ presets.prettier(), presets.typescript(), presets.react({ newJSXTransform: true }), - presets.effector(), ], extend: { - extends: ['plugin:storybook/recommended'], + plugins: ['@reatom'], + extends: ['plugin:storybook/recommended', 'plugin:@reatom/recommended'], overrides: [ { files: ['vite.config.ts', 'src/**/*.stories.tsx'], diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 247309f..8475700 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,10 +9,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Use Node.js 16.16.0 + - name: Use Node.js 18.17.0 uses: actions/setup-node@v3 with: - node-version: 16.16.0 + node-version: 18.17.0 cache: 'yarn' - name: Install dependencies run: | diff --git a/babel.config.cjs b/babel.config.cjs deleted file mode 100644 index d9ef4ad..0000000 --- a/babel.config.cjs +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - plugins: ['effector/babel-plugin'], -}; diff --git a/package.json b/package.json index a062b97..f273255 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,13 @@ "@dnd-kit/sortable": "^7.0.1", "@heroicons/react": "^2.0.13", "@material-tailwind/react": "^1.2.4", + "@reatom/framework": "^3.4.30", + "@reatom/npm-react": "^3.8.1", + "@reatom/persist-web-storage": "^3.2.3", + "@tanstack/react-router": "^1.2.2", "@types/localforage": "^0.0.34", - "atomic-router": "^0.7.1", - "atomic-router-react": "^0.8.0", "classnames": "^2.3.2", "compose-function": "^3.0.3", - "effector": "^22.3.0", - "effector-react": "^22.3.4", "history": "^5.3.0", "localforage": "^1.10.0", "react": "^18.2.0", @@ -32,6 +32,7 @@ }, "devDependencies": { "@babel/core": "^7.19.6", + "@reatom/eslint-plugin": "^3.4.3", "@rollup/plugin-babel": "^6.0.2", "@storybook/addon-actions": "^6.5.13", "@storybook/addon-essentials": "^6.5.13", diff --git a/readme.md b/readme.md index 956937f..5168514 100644 --- a/readme.md +++ b/readme.md @@ -16,4 +16,4 @@ Tasks are stored in IndexedDB. -This app is built with with [React](https://reactjs.org/) [TypeScript](https://www.typescriptlang.org/), [Vite](https://vitejs.dev/), [TailwindCSS](https://tailwindcss.com/), [Material Tailwind](https://www.material-tailwind.com/), [Effector](https://effector.dev), [Atomic Router](https://atomic-router.github.io/), [Storybook](https://storybook.js.org/) and [GitHub Actions](https://docs.github.com/en/actions). Deployed with [Vercel](https://vercel.app). +This app is built with with [React](https://reactjs.org/) [TypeScript](https://www.typescriptlang.org/), [Vite](https://vitejs.dev/), [TailwindCSS](https://tailwindcss.com/), [Material Tailwind](https://www.material-tailwind.com/), [Reatom](https://reatom.dev), [TanStack Router](https://tanstack.com/router/v1), [Storybook](https://storybook.js.org/) and [GitHub Actions](https://docs.github.com/en/actions). Deployed with [Vercel](https://vercel.app). diff --git a/src/app/providers/index.ts b/src/app/providers/index.ts index 7798eb3..3d66b63 100644 --- a/src/app/providers/index.ts +++ b/src/app/providers/index.ts @@ -1,6 +1,5 @@ import compose from 'compose-function'; -import { withEffectorScope } from './with-effector-scope'; -import { withRouting } from './with-routing'; +import { withReatomContext } from './with-reatom-context'; import { withTheme } from './with-theme'; -export const withProviders = compose(withTheme, withRouting, withEffectorScope); +export const withProviders = compose(withTheme, withReatomContext); diff --git a/src/app/providers/with-effector-scope.tsx b/src/app/providers/with-effector-scope.tsx deleted file mode 100644 index 3ebd20b..0000000 --- a/src/app/providers/with-effector-scope.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { fork } from 'effector'; -import { Provider } from 'effector-react/scope'; - -const scope = fork(); - -export const withEffectorScope = (children: () => React.ReactNode) => () => { - return {children()}; -}; diff --git a/src/app/providers/with-reatom-context.tsx b/src/app/providers/with-reatom-context.tsx new file mode 100644 index 0000000..c94cc00 --- /dev/null +++ b/src/app/providers/with-reatom-context.tsx @@ -0,0 +1,10 @@ +import { createCtx } from '@reatom/core'; +import { reatomContext } from '@reatom/npm-react'; + +const ctx = createCtx(); + +export const withReatomContext = (children: () => React.ReactNode) => () => { + return ( + {children()} + ); +}; diff --git a/src/app/providers/with-routing.tsx b/src/app/providers/with-routing.tsx deleted file mode 100644 index a917c44..0000000 --- a/src/app/providers/with-routing.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { createHistoryRouter } from 'atomic-router'; -import { RouterProvider } from 'atomic-router-react'; -import { createBrowserHistory } from 'history'; -import React from 'react'; -import { notFoundRoute, routesMap } from '~/pages'; - -const history = createBrowserHistory(); - -const router = createHistoryRouter({ - routes: routesMap, - notFoundRoute, -}); - -router.setHistory(history); - -export const withRouting = (children: () => React.ReactNode) => () => { - return {children()}; -}; diff --git a/src/entities/task/model.ts b/src/entities/task/model.ts index cd78409..41e6241 100644 --- a/src/entities/task/model.ts +++ b/src/entities/task/model.ts @@ -1,22 +1,11 @@ -import { combine, createEvent } from 'effector'; +import { action, atom } from '@reatom/framework'; +import { withLocalStorage } from '@reatom/persist-web-storage'; import { arrayMove } from '~/shared/lib/array'; -import { createLocalStorageStore } from '~/shared/lib/effector-localstorage'; import { Id } from '~/shared/lib/id'; import { Optional } from '~/shared/lib/typescript'; type TaskStatus = 'active' | 'completed'; -export interface Filter { - status: TaskStatus | undefined; -} - -const DEFAULT_FILTER: Filter = { - status: undefined, -}; - -export const { $store: $filter, getLocalStorageValueFx: getFilterValueFx } = - createLocalStorageStore('filter', DEFAULT_FILTER); - type TaskId = Id; export interface Task { @@ -32,22 +21,15 @@ export type TaskDataWithoutStatus = Omit; export type TaskDataOptional = Optional; -const updatedTask = (task: Task, updatedTaskData: TaskDataOptional): Task => ({ - ...task, - ...updatedTaskData, -}); - -export const taskUpdated = createEvent<{ - id: TaskId; - data: TaskDataOptional; -}>(); +export interface Filter { + status: TaskStatus | undefined; +} -export const taskMoved = createEvent<{ - from: number; - to: number; -}>(); +const DEFAULT_FILTER: Filter = { + status: undefined, +}; -const initialTasks: Array = [ +const INITIAL_TASKS: Array = [ { id: '1', status: 'active', @@ -61,26 +43,50 @@ const initialTasks: Array = [ }, ]; -export const { $store: $tasks, getLocalStorageValueFx: getTasksValueFx } = - createLocalStorageStore('tasks', initialTasks); +export const filterAtom = atom(DEFAULT_FILTER, 'filterAtom').pipe( + withLocalStorage('filter'), +); -export const $visibleTasks = combine($tasks, $filter, (tasks, filter) => - tasks.filter( - (task) => filter.status === undefined || filter.status === task.status, - ), +export const tasksAtom = atom(INITIAL_TASKS, 'tasksAtom').pipe( + withLocalStorage('tasks'), ); -$tasks.on( - taskUpdated, - (currentTasks, { id: updatedTaskId, data: updatedTaskData }) => - currentTasks.map((task) => { - if (task.id === updatedTaskId) { - return updatedTask(task, updatedTaskData); +export const visibleTasksAtom = atom((ctx) => { + const tasks = ctx.spy(tasksAtom); + + const filter = ctx.spy(filterAtom); + + return tasks.filter( + (task) => filter.status === undefined || filter.status === task.status, + ); +}, 'visibleTasksAtom'); + +const updatedTask = (task: Task, updatedTaskData: TaskDataOptional): Task => ({ + ...task, + ...updatedTaskData, +}); + +export const updateTask = action( + (ctx, { id, data }: { id: TaskId; data: TaskDataOptional }) => { + const oldTasks = ctx.get(tasksAtom); + + const newTasks = oldTasks.map((task) => { + if (task.id === id) { + return updatedTask(task, data); } return task; - }), + }); + + tasksAtom(ctx, newTasks); + }, + 'updateTask', ); -$tasks.on(taskMoved, (currentTasks, { from, to }) => - arrayMove(currentTasks, { from, to }), +export const moveTask = action( + (ctx, { from, to }: { from: number; to: number }) => { + const oldTasks = ctx.get(tasksAtom); + const newTasks = arrayMove(oldTasks, { from, to }); + tasksAtom(ctx, newTasks); + }, + 'moveTask', ); diff --git a/src/entities/task/ui/task-card/ui.stories.tsx b/src/entities/task/ui/task-card/ui.stories.tsx index 2b84626..2ff47b0 100644 --- a/src/entities/task/ui/task-card/ui.stories.tsx +++ b/src/entities/task/ui/task-card/ui.stories.tsx @@ -1,7 +1,6 @@ +import { reatomContext, useCreateCtx } from '@reatom/npm-react'; import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { fork } from 'effector'; -import { Provider } from 'effector-react/scope'; -import { $tasks } from '../../model'; +import { taskModel } from '../..'; import { TaskCard } from './ui'; export default { @@ -9,23 +8,20 @@ export default { component: TaskCard, decorators: [ (storyFn) => { - const scope = fork({ - values: [ - [ - $tasks, - [ - { - id: '1', - status: 'active', - title: 'Make a leather wallet', - description: 'Check YouTube for tutorial', - }, - ], - ], - ], - }); + const ctx = useCreateCtx((ctx) => {}); - return {storyFn()}; + taskModel.tasksAtom(ctx, [ + { + id: '1', + status: 'active', + title: 'Make a leather wallet', + description: 'Check YouTube for tutorial', + }, + ]); + + return ( + {storyFn()} + ); }, ], } as ComponentMeta; diff --git a/src/entities/task/ui/task-card/ui.tsx b/src/entities/task/ui/task-card/ui.tsx index c163399..791becb 100644 --- a/src/entities/task/ui/task-card/ui.tsx +++ b/src/entities/task/ui/task-card/ui.tsx @@ -1,11 +1,11 @@ import { Typography } from '@material-tailwind/react'; +import { useAtom } from '@reatom/npm-react'; import cn from 'classnames'; -import { useStoreMap } from 'effector-react/scope'; import React from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; -import { getEntityById } from '~/shared/lib/effector'; +import { getEntityById } from '~/shared/lib/entity'; import { mergeRefs } from '~/shared/lib/react'; -import { $tasks, Task } from '../../model'; +import { Task, tasksAtom } from '../../model'; export interface TaskCardProps { id: Task['id']; @@ -24,10 +24,10 @@ export const TaskCard = ({ onDelete, onEdit, }: TaskCardProps) => { - const task = useStoreMap({ - store: $tasks, - keys: [id], - fn: (tasks, [taskId]) => getEntityById(tasks, taskId), + const [task] = useAtom((ctx) => { + const tasks = ctx.spy(tasksAtom); + + return getEntityById(tasks, id); }); const idStr = React.useMemo(() => `task-card-${id}`, [id]); @@ -67,7 +67,7 @@ export const TaskCard = ({ {task.title} - {task.description} + {task.description ?? ''}
{EditSlot} diff --git a/src/entities/task/ui/task-editor/ui.stories.tsx b/src/entities/task/ui/task-editor/ui.stories.tsx index b04ea20..5cd6958 100644 --- a/src/entities/task/ui/task-editor/ui.stories.tsx +++ b/src/entities/task/ui/task-editor/ui.stories.tsx @@ -1,6 +1,5 @@ +import { reatomContext, useCreateCtx } from '@reatom/npm-react'; import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { fork } from 'effector'; -import { Provider } from 'effector-react/scope'; import { TaskEditor } from './ui'; export default { @@ -18,9 +17,11 @@ export default { }, decorators: [ (storyFn) => { - const scope = fork(); + const ctx = useCreateCtx(); - return {storyFn()}; + return ( + {storyFn()} + ); }, ], } as ComponentMeta; diff --git a/src/features/add-task/model.ts b/src/features/add-task/model.ts index 4a99cef..a9535a8 100644 --- a/src/features/add-task/model.ts +++ b/src/features/add-task/model.ts @@ -1,17 +1,18 @@ -import { createEvent } from 'effector'; +import { action } from '@reatom/framework'; import { taskModel } from '~/entities/task'; +import { TaskDataWithoutStatus } from '~/entities/task/model'; import { getId } from '~/shared/lib/id'; -const taskCreated = createEvent(); - -export const taskCreatedByUser = - taskCreated.prepend((taskData) => ({ +export const createTask = action((ctx, data: TaskDataWithoutStatus) => { + const newTask = { id: getId(), status: 'active', - ...taskData, - })); + ...data, + } as taskModel.Task; + + const tasks = ctx.get(taskModel.tasksAtom); + + const newTasks = [...tasks, newTask]; -taskModel.$tasks.on(taskCreated, (currentTasks, newTask) => [ - ...currentTasks, - newTask, -]); + taskModel.tasksAtom(ctx, newTasks); +}, 'createTask'); diff --git a/src/features/add-task/ui.tsx b/src/features/add-task/ui.tsx index 7304fdb..cb9e6f9 100644 --- a/src/features/add-task/ui.tsx +++ b/src/features/add-task/ui.tsx @@ -1,9 +1,9 @@ import { Button } from '@material-tailwind/react'; -import { useUnit } from 'effector-react/scope'; +import { useAction } from '@reatom/npm-react'; import { useCallback, useState } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; import { TaskEditor, taskModel } from '~/entities/task'; -import { taskCreatedByUser } from './model'; +import { createTask } from './model'; export const AddTask = () => { const [showForm, setShowForm] = useState(false); @@ -13,7 +13,7 @@ export const AddTask = () => { const submitButtonText = 'Add task'; - const onSubmit = useUnit(taskCreatedByUser); + const onSubmit = useAction(createTask); const handleSubmit = (payload: taskModel.TaskDataWithoutStatus) => { setEditorKey((key) => key + 1); diff --git a/src/features/delete-task/model.ts b/src/features/delete-task/model.ts index 75e5259..a23f11c 100644 --- a/src/features/delete-task/model.ts +++ b/src/features/delete-task/model.ts @@ -1,8 +1,8 @@ -import { createEvent } from 'effector'; -import { taskModel } from '~/entities/task'; +import { action } from '@reatom/framework'; +import { tasksAtom } from '~/entities/task/model'; -export const taskRemoved = createEvent(); +export const removeTask = action((ctx, id) => { + const tasks = ctx.get(tasksAtom); -taskModel.$tasks.on(taskRemoved, (currentTasks, removedTaskId) => - currentTasks.filter((task) => task.id !== removedTaskId), -); + return tasks.filter((task) => task.id !== id); +}, 'removeTask'); diff --git a/src/features/delete-task/ui.tsx b/src/features/delete-task/ui.tsx index fbdbb4f..39dc74f 100644 --- a/src/features/delete-task/ui.tsx +++ b/src/features/delete-task/ui.tsx @@ -6,12 +6,13 @@ import { DialogHeader, IconButton, } from '@material-tailwind/react'; -import { useStoreMap, useUnit } from 'effector-react/scope'; +import { useAction, useAtom } from '@reatom/npm-react'; import { useCallback, useState } from 'react'; import { taskModel } from '~/entities/task'; -import { getEntityById } from '~/shared/lib/effector'; +import { tasksAtom } from '~/entities/task/model'; +import { getEntityById } from '~/shared/lib/entity'; import { Icon } from '~/shared/ui'; -import { taskRemoved } from './model'; +import { removeTask } from './model'; interface DeleteTaskProps { id: taskModel.Task['id']; @@ -28,10 +29,9 @@ const taskTitleString = (task: taskModel.Task | undefined): string => { }; export const DeleteTask = ({ id }: DeleteTaskProps) => { - const task = useStoreMap({ - store: taskModel.$tasks, - keys: [id], - fn: (tasks, [taskId]) => getEntityById(tasks, taskId), + const [task] = useAtom((ctx) => { + const tasks = ctx.spy(tasksAtom); + return getEntityById(tasks, id); }); const [showConfirmation, setShowConfirmation] = useState(false); @@ -41,10 +41,10 @@ export const DeleteTask = ({ id }: DeleteTaskProps) => { [], ); - const removeTask = useUnit(taskRemoved); + const onRemove = useAction(removeTask); const onSubmit = () => { - removeTask(id); + onRemove(id); handleConfirmation(); }; diff --git a/src/features/edit-task/ui.tsx b/src/features/edit-task/ui.tsx index 58abf7b..ef0cd13 100644 --- a/src/features/edit-task/ui.tsx +++ b/src/features/edit-task/ui.tsx @@ -1,6 +1,7 @@ -import { useStoreMap, useUnit } from 'effector-react/scope'; +import { useAction, useAtom } from '@reatom/npm-react'; import { TaskEditor, taskModel } from '~/entities/task'; -import { getEntityById } from '~/shared/lib/effector'; +import { tasksAtom } from '~/entities/task/model'; +import { getEntityById } from '~/shared/lib/entity'; interface EditTaskProps { id: taskModel.Task['id']; @@ -9,13 +10,13 @@ interface EditTaskProps { } export const EditTask = ({ id, onClose, onSubmit }: EditTaskProps) => { - const task = useStoreMap({ - store: taskModel.$tasks, - keys: [id], - fn: (tasks, [taskId]) => getEntityById(tasks, taskId), + const [task] = useAtom((ctx) => { + const tasks = ctx.spy(tasksAtom); + + return getEntityById(tasks, id); }); - const updateTask = useUnit(taskModel.taskUpdated); + const updateTask = useAction(taskModel.updateTask); if (!task) { return null; diff --git a/src/features/filter-tasks/model.ts b/src/features/filter-tasks/model.ts index dd38ccf..8038867 100644 --- a/src/features/filter-tasks/model.ts +++ b/src/features/filter-tasks/model.ts @@ -1,9 +1,12 @@ -import { createEvent } from 'effector'; +import { action } from '@reatom/framework'; import { taskModel } from '~/entities/task'; +import { filterAtom } from '~/entities/task/model'; -export const filterByStatusChanged = createEvent(); +export const updateStatusFilter = action( + (ctx, status: taskModel.Filter['status']) => { + const filter = ctx.get(taskModel.filterAtom); -taskModel.$filter.on(filterByStatusChanged, (currentFilter, status) => ({ - ...currentFilter, - status, -})); + filterAtom(ctx, { ...filter, status }); + }, + 'updateStatusFilter', +); diff --git a/src/features/filter-tasks/ui.tsx b/src/features/filter-tasks/ui.tsx index 989467d..3871d17 100644 --- a/src/features/filter-tasks/ui.tsx +++ b/src/features/filter-tasks/ui.tsx @@ -1,13 +1,15 @@ import { Checkbox } from '@material-tailwind/react'; -import { useUnit } from 'effector-react/scope'; +import { useAction, useAtom } from '@reatom/npm-react'; import React from 'react'; import { taskModel } from '~/entities/task'; -import { filterByStatusChanged } from './model'; +import { updateStatusFilter } from './model'; export const ShowCompletedTasks = () => { - const filterByStatusEnabled = useUnit(taskModel.$filter).status; + const [filterByStatusEnabled] = useAtom((ctx) => { + return ctx.spy(taskModel.filterAtom).status; + }); - const toggleFilter = useUnit(filterByStatusChanged); + const toggleFilter = useAction(updateStatusFilter); const handleChange = (event: React.ChangeEvent) => { if (event.target.checked) { diff --git a/src/features/toggle-task-status/model.ts b/src/features/toggle-task-status/model.ts index 5f470ae..a0d8cfc 100644 --- a/src/features/toggle-task-status/model.ts +++ b/src/features/toggle-task-status/model.ts @@ -1,6 +1,16 @@ +import { action } from '@reatom/framework'; import { taskModel } from '~/entities/task'; +import { updateTask } from '~/entities/task/model'; -export const taskStatusUpdated = taskModel.taskUpdated.prepend<{ - id: taskModel.Task['id']; - status: taskModel.Task['status']; -}>(({ id, status }) => ({ id, data: { status } })); +export const updateTaskStatus = action( + ( + ctx, + { + id, + status, + }: { id: taskModel.Task['id']; status: taskModel.Task['status'] }, + ) => { + updateTask(ctx, { id, data: { status } }); + }, + 'updateTaskStatus', +); diff --git a/src/features/toggle-task-status/ui.tsx b/src/features/toggle-task-status/ui.tsx index f5d684e..5d4016c 100644 --- a/src/features/toggle-task-status/ui.tsx +++ b/src/features/toggle-task-status/ui.tsx @@ -1,30 +1,29 @@ import { Checkbox } from '@material-tailwind/react'; -import { useStoreMap, useUnit } from 'effector-react/scope'; +import { useAction, useAtom } from '@reatom/npm-react'; import { useCallback } from 'react'; import { taskModel } from '~/entities/task'; -import { getEntityById } from '~/shared/lib/effector'; -import { taskStatusUpdated } from './model'; +import { getEntityById } from '~/shared/lib/entity'; +import { updateTaskStatus } from './model'; interface ToggleTaskProps { id: taskModel.Task['id']; } export const ToggleTask = ({ id }: ToggleTaskProps) => { - const task = useStoreMap({ - store: taskModel.$tasks, - keys: [id], - fn: (tasks, [taskId]) => getEntityById(tasks, taskId), + const [task] = useAtom((ctx) => { + const tasks = ctx.spy(taskModel.tasksAtom); + return getEntityById(tasks, id); }); - const updateTaskStatus = useUnit(taskStatusUpdated); + const handleTaskStatusUpdate = useAction(updateTaskStatus); const handleChange = useCallback( (e: React.ChangeEvent) => { const status: taskModel.Task['status'] = e.target.checked === true ? 'completed' : 'active'; - updateTaskStatus({ id, status }); + handleTaskStatusUpdate({ id, status }); }, - [id, updateTaskStatus], + [id, handleTaskStatusUpdate], ); if (!task) { diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 73353dc..49923ed 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -1,24 +1,24 @@ import { IconButton, Typography } from '@material-tailwind/react'; -import { useUnit } from 'effector-react/scope'; +import { useAction, useAtom } from '@reatom/npm-react'; import { taskModel } from '~/entities/task'; import { AddTask } from '~/features/add-task'; import { ShowCompletedTasks } from '~/features/filter-tasks'; +import { indexRoute } from '~/shared/routes'; import { Icon, SortableList } from '~/shared/ui'; import { TaskManager } from '~/widgets/task-manager'; -import { homePageRoute } from './model'; interface TasksListProps { tasks: taskModel.Task[]; } const TasksList = ({ tasks }: TasksListProps) => { - const taskMoved = useUnit(taskModel.taskMoved); + const moveTask = useAction(taskModel.moveTask); return (
{ return (
@@ -51,7 +51,7 @@ const EmptyTasksInfo = () => { }; const HomePage = () => { - const tasks = useUnit(taskModel.$visibleTasks); + const [tasks] = useAtom(taskModel.visibleTasksAtom); return (
@@ -72,4 +72,4 @@ const HomePage = () => { ); }; -export { HomePage, homePageRoute }; +export const homePageRoute = indexRoute.update({ component: HomePage }); diff --git a/src/pages/home/model.ts b/src/pages/home/model.ts deleted file mode 100644 index 7fcb143..0000000 --- a/src/pages/home/model.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { chainRoute } from 'atomic-router'; -import { taskModel } from '~/entities/task'; -import { routes } from '~/shared/routes'; - -export const homePageRoute = chainRoute({ - route: routes.home, - beforeOpen: { - effect: taskModel.getTasksValueFx, - mapParams: () => {}, - }, -}); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 9ed4e2b..cb146a9 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,17 +1,18 @@ -import { Route } from 'atomic-router-react'; -import { routes } from '~/shared/routes'; -import { HomePage, homePageRoute } from './home'; -import { NotFoundPage } from './not-found'; +import { Router, RouterProvider } from '@tanstack/react-router'; +import { rootRoute } from '~/shared/routes'; +import { homePageRoute } from './home'; +import { notFoundRoute } from './not-found'; + +const routeTree = rootRoute.addChildren([homePageRoute]); + +const router = new Router({ routeTree, notFoundRoute }); export const Pages = () => { - return ( - <> - - - - ); + return ; }; -export const routesMap = [{ path: '/', route: routes.home }]; - -export const notFoundRoute = routes.errors.notFound; +declare module '@tanstack/react-router' { + interface Register { + router: typeof router; + } +} diff --git a/src/pages/not-found/index.tsx b/src/pages/not-found/index.tsx index a4ccd8d..158ff83 100644 --- a/src/pages/not-found/index.tsx +++ b/src/pages/not-found/index.tsx @@ -1,11 +1,16 @@ -import { Link } from 'atomic-router-react'; -import { routes } from '~/shared/routes'; +import { Link, NotFoundRoute } from '@tanstack/react-router'; +import { rootRoute, routes } from '~/shared/routes'; -export const NotFoundPage = () => { +const NotFoundPage = () => { return (

Not found

- Back to home + Back to home
); }; + +export const notFoundRoute = new NotFoundRoute({ + getParentRoute: () => rootRoute, + component: NotFoundPage, +}); diff --git a/src/shared/lib/effector-localstorage/index.ts b/src/shared/lib/effector-localstorage/index.ts deleted file mode 100644 index 285ef9f..0000000 --- a/src/shared/lib/effector-localstorage/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { createEffect, createEvent, createStore, sample } from 'effector'; -import localforage from 'localforage'; - -type Key = string; - -export const createLocalStorageStore = ( - key: Key, - defaultState: TData, -) => { - const updateLocalStorageFx = createEffect(async (state: TData) => - localforage.setItem(key, state), - ); - - const getLocalStorageValueFx = createEffect(() => - localforage.getItem(key), - ); - - const storeCreated = createEvent(); - - const $store = createStore(defaultState, { - sid: `store-${key}`, - }); - - sample({ - source: $store, - target: updateLocalStorageFx, - }); - - sample({ - source: storeCreated, - target: getLocalStorageValueFx, - }); - - $store.on(getLocalStorageValueFx.doneData, (_, data) => data || undefined); - - storeCreated(); - - return { $store, getLocalStorageValueFx }; -}; diff --git a/src/shared/lib/effector/index.ts b/src/shared/lib/entity/index.ts similarity index 51% rename from src/shared/lib/effector/index.ts rename to src/shared/lib/entity/index.ts index 5787ef7..d484375 100644 --- a/src/shared/lib/effector/index.ts +++ b/src/shared/lib/entity/index.ts @@ -1,6 +1,6 @@ import { Id } from '../id'; -export const getEntityById = ( - entities: Array, +export const getEntityById = ( + entities: Array, entityId: Id, ) => entities.find(({ id }) => id === entityId); diff --git a/src/shared/routes.ts b/src/shared/routes.ts index f594a78..3b19fd5 100644 --- a/src/shared/routes.ts +++ b/src/shared/routes.ts @@ -1,8 +1,12 @@ -import { createRoute } from 'atomic-router'; +import { RootRoute, Route } from '@tanstack/react-router'; + +export const rootRoute = new RootRoute(); + +export const indexRoute = new Route({ + getParentRoute: () => rootRoute, + path: '/', +}); export const routes = { - home: createRoute(), - errors: { - notFound: createRoute(), - }, + home: indexRoute, }; diff --git a/src/widgets/task-manager/task-manager.stories.tsx b/src/widgets/task-manager/task-manager.stories.tsx index 4155c3e..25c5386 100644 --- a/src/widgets/task-manager/task-manager.stories.tsx +++ b/src/widgets/task-manager/task-manager.stories.tsx @@ -1,6 +1,5 @@ +import { reatomContext, useCreateCtx } from '@reatom/npm-react'; import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { fork } from 'effector'; -import { Provider } from 'effector-react/scope'; import { taskModel } from '~/entities/task'; import { TaskManager } from './task-manager'; @@ -9,23 +8,20 @@ export default { component: TaskManager, decorators: [ (storyFn) => { - const scope = fork({ - values: [ - [ - taskModel.$tasks, - [ - { - id: '1', - status: 'active', - title: 'Make a leather wallet', - description: 'Check YouTube for tutorial', - }, - ], - ], - ], - }); + const ctx = useCreateCtx((ctx) => {}); - return {storyFn()}; + taskModel.tasksAtom(ctx, [ + { + id: '1', + status: 'active', + title: 'Make a leather wallet', + description: 'Check YouTube for tutorial', + }, + ]); + + return ( + {storyFn()} + ); }, ], } as ComponentMeta; diff --git a/yarn.lock b/yarn.lock index bdb68c2..c2d4832 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1113,6 +1113,13 @@ dependencies: regenerator-runtime "^0.13.10" +"@babel/runtime@^7.16.7": + version "7.23.8" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650" + integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@~7.5.4": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" @@ -1731,6 +1738,127 @@ schema-utils "^3.0.0" source-map "^0.7.3" +"@reatom/async@^3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@reatom/async/-/async-3.13.3.tgz#ea67052ff79986dc118b4c13299cd82a5f2e8202" + integrity sha512-8+v7sMYhzTA3D/gD7uE5Dy5Rdn0xWZECc2/G8R/lRYypkovS8ltGf4vHrWkDQCtl2tqSRIFlawmrZvrX5OqqiA== + dependencies: + "@reatom/core" "^3.5.0" + "@reatom/effects" "^3.7.0" + "@reatom/hooks" "^3.2.0" + "@reatom/primitives" "^3.1.0" + "@reatom/utils" "^3.4.0" + +"@reatom/core@>=3.5.0", "@reatom/core@^3.1.0", "@reatom/core@^3.1.1", "@reatom/core@^3.2.0", "@reatom/core@^3.3.0", "@reatom/core@^3.4.0", "@reatom/core@^3.5.0", "@reatom/core@^3.6.5": + version "3.6.5" + resolved "https://registry.yarnpkg.com/@reatom/core/-/core-3.6.5.tgz#5d13030d5c2aa56a1d319c01dc9008f7eaa2d941" + integrity sha512-X0zUAXZPlLY9V99l4VgvYllQ63lswlAsqQYm0poNoW3KkthVrwQLkXSaZGCpV5TaOmhLaNEaJ89PlQHjjlE9rw== + +"@reatom/effects@^3.2.0", "@reatom/effects@^3.7.0", "@reatom/effects@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@reatom/effects/-/effects-3.7.2.tgz#5dc6cdc054360c73dedc6d7b1e28e270aedb99d0" + integrity sha512-6j3rhFdUSCjNC0HK7lKNFHYM8y6JV0OXpPUXKtA0psNwa5WUq2X4Q0WfMnixy7Jm8tAAQR9F6iKqy9T0U1Ej8Q== + dependencies: + "@reatom/core" "^3.2.0" + "@reatom/utils" "^3.5.0" + +"@reatom/eslint-plugin@^3.4.3": + version "3.4.3" + resolved "https://registry.yarnpkg.com/@reatom/eslint-plugin/-/eslint-plugin-3.4.3.tgz#7adf667fe72f74049d5961ad22d7401e5399b6c8" + integrity sha512-2LelP4G1FXq+89pmWfKyNLV7GtxmmiHJfl2vac9oJU7lT+eqvmWi4Pd0duAJhWTLxvg9g5S1SLeGQ7tAw/gxeg== + +"@reatom/framework@^3.4.30": + version "3.4.30" + resolved "https://registry.yarnpkg.com/@reatom/framework/-/framework-3.4.30.tgz#b4e1ae8d4f5a4896b603637f2794005213f10ee3" + integrity sha512-apSDdt5Q8ZcIv5cY2bfIII/oJ+hyR/Ra5GnOPJED7X01gRhEIYoM3saIJgnNvRk7yYVE3SnQzyfwqSr+w0fE1w== + dependencies: + "@reatom/async" "^3.13.3" + "@reatom/core" "^3.6.5" + "@reatom/effects" "^3.7.2" + "@reatom/hooks" "^3.5.2" + "@reatom/lens" "^3.9.1" + "@reatom/logger" "^3.6.0" + "@reatom/primitives" "^3.2.1" + "@reatom/utils" "^3.8.0" + +"@reatom/hooks@^3.2.0", "@reatom/hooks@^3.3.1", "@reatom/hooks@^3.4.0", "@reatom/hooks@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@reatom/hooks/-/hooks-3.5.2.tgz#475e3f3e4f056efb779dabcf1f49d5b78491f9fa" + integrity sha512-mZJP+fsv+cg35vPEbdEJ4AroSDqnXaK9DpLq8M0AXg97UPJY2c2IoztD0mvEVkFSBxoGAsTXO89m8ZgZxVud2Q== + dependencies: + "@reatom/core" "^3.2.0" + "@reatom/effects" "^3.7.0" + "@reatom/utils" "^3.3.0" + +"@reatom/jsx@^3.4.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@reatom/jsx/-/jsx-3.6.0.tgz#c03c6fcf4d52d0f39ab0763a875a0a31614f2b36" + integrity sha512-CnvZycKWCLFrzn8uvY5UOf/k345vJYO4nD6jjvfg5Vjp+Vd+Pe5m6sSWJiXA6IJPHf5eZ7wxmzcPrZ43kRmJQw== + dependencies: + "@reatom/core" ">=3.5.0" + "@reatom/lens" "^3.6.2" + "@reatom/utils" "^3.5.0" + csstype "^3.1.2" + +"@reatom/lens@^3.1.0", "@reatom/lens@^3.4.0", "@reatom/lens@^3.6.2", "@reatom/lens@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@reatom/lens/-/lens-3.9.1.tgz#a86e5a1a06d96493b0a3eb10dc2c00fdd9fdb428" + integrity sha512-od3Ni2iMfxdjWp7CKtzZX7wA6/PQdJDnSut2uOqFgxaF+PGBao+tlV+RdVO5MoSoenZTSL7IUQw8YERXhAoViA== + dependencies: + "@reatom/core" "^3.4.0" + "@reatom/effects" "^3.2.0" + "@reatom/hooks" "^3.3.1" + "@reatom/utils" "^3.1.0" + +"@reatom/logger@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@reatom/logger/-/logger-3.6.0.tgz#bd2ee652d81deb72e935b724da1e3f9aaaddb7ae" + integrity sha512-UgYivXasJN+U8vUn8wbCx+bGlyVb6PZgJynmNrPwfSulG1oaoF/oi99ahDSXdQapu+GXkeyUXwoyOlrIY5wLQg== + dependencies: + "@reatom/core" "^3.1.0" + "@reatom/jsx" "^3.4.0" + stylerun "^1.0.0" + +"@reatom/npm-react@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@reatom/npm-react/-/npm-react-3.8.1.tgz#1b0bdf083a69810744956906c1f094efb7be5e4a" + integrity sha512-yJu1oFeJO76dBneRPqlqAEchoSqds6tXC6z+wzP/ymlq6PXths04ck5+wnzX7vCN/P1c7mk7fpWlSSnF1ZpAWw== + dependencies: + "@reatom/core" "^3.5.0" + "@reatom/lens" "^3.1.0" + use-sync-external-store "^1.2.0" + +"@reatom/persist-web-storage@^3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@reatom/persist-web-storage/-/persist-web-storage-3.2.3.tgz#18000754b9cc77749af2f93280b08af061926d35" + integrity sha512-Vj60dDmyuJmKgN/+uP5UUjw0daU+TwoOjZ5ubcuLEbXyVjpqczDDD6ZEI9tNvcRT8a/toQmAu6MY1U5WSto9og== + dependencies: + "@reatom/core" "^3.3.0" + "@reatom/persist" "^3.1.0" + +"@reatom/persist@^3.1.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@reatom/persist/-/persist-3.3.0.tgz#1adafc5e04fb75cf586d89963bfc24e5fa3263a9" + integrity sha512-RM9PFxjwLje1FsMfBsborA9SyedsJIJVHqfuyoszLRv3J9SmTi4S2SJBd2EfZBbGF1hy0vwPncx1FYIHbgmU9g== + dependencies: + "@reatom/core" "^3.3.0" + "@reatom/hooks" "^3.4.0" + "@reatom/lens" "^3.4.0" + "@reatom/utils" "^3.4.0" + +"@reatom/primitives@^3.1.0", "@reatom/primitives@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@reatom/primitives/-/primitives-3.2.1.tgz#026c9b8b2923058cf84b6121a266d05cc0c36efa" + integrity sha512-INZqbPbNG0bqRrlZ0LgaRCT8+q3g1ySjKOcpugHCFK0aCRlSK/jbPYQHIg2NYkB5PCamRdJJxaJeBrI8op6Miw== + dependencies: + "@reatom/core" "^3.1.1" + "@reatom/utils" "^3.1.1" + +"@reatom/utils@^3.1.0", "@reatom/utils@^3.1.1", "@reatom/utils@^3.3.0", "@reatom/utils@^3.4.0", "@reatom/utils@^3.5.0", "@reatom/utils@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@reatom/utils/-/utils-3.8.0.tgz#3d4289032ae2b77b5e2bdab17dff8f07b671d0ad" + integrity sha512-U4cINdsQuj4jH5Q0EKXmzeXLIN4dTT6Jqk+c7IAWmdIf/FKjk6jqXRiIWZWVaj5/Yw/kCDPBIxE3IR0pLtOFHA== + "@rollup/plugin-babel@^6.0.2": version "6.0.2" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-6.0.2.tgz#92ad7a00cc0e4a6b59e1498cda9f907a9c0d2db3" @@ -2663,6 +2791,36 @@ resolved "https://registry.yarnpkg.com/@tailwindcss/line-clamp/-/line-clamp-0.4.2.tgz#f353c5a8ab2c939c6267ac5b907f012e5ee130f9" integrity sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw== +"@tanstack/history@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tanstack/history/-/history-1.2.2.tgz#05c72ec71dec9d4c02d29e62fffd30bdd2ea41c7" + integrity sha512-m22OGzj1/xmyboXR5UtDw29hDWAGCxxSnsIThMgiTy3PoxQv2+6i44oJamJ8j+9iJKrlnkSmiQk8osYca90GEA== + +"@tanstack/react-router@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tanstack/react-router/-/react-router-1.2.2.tgz#a8c8be0c52245669c7b74b1b87c1f4a24bbc6285" + integrity sha512-ZaIN0L3JMsw7OH9yEdx90TDCc358uATjmamVehpU6uNa9bM5t6VY3+luYTz/h8OH4GqROtMJDgksjz8oiqD5WA== + dependencies: + "@babel/runtime" "^7.16.7" + "@tanstack/history" "1.2.2" + "@tanstack/react-store" "^0.2.1" + "@tanstack/store" "^0.1.3" + tiny-invariant "^1.3.1" + tiny-warning "^1.0.3" + +"@tanstack/react-store@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@tanstack/react-store/-/react-store-0.2.1.tgz#c1a04c85d403d842e56c6d0709211f013bdd1021" + integrity sha512-tEbMCQjbeVw9KOP/202LfqZMSNAVi6zYkkp1kBom8nFuMx/965Hzes3+6G6b/comCwVxoJU8Gg9IrcF8yRPthw== + dependencies: + "@tanstack/store" "0.1.3" + use-sync-external-store "^1.2.0" + +"@tanstack/store@0.1.3", "@tanstack/store@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@tanstack/store/-/store-0.1.3.tgz#b8410435dac0a0f6d3fe77d49509f296905d4c73" + integrity sha512-GnolmC8Fr4mvsHE1fGQmR3Nm0eBO3KnZjDU0a+P3TeQNM/dDscFGxtA7p31NplQNW3KwBw4t1RVFmz0VeKLxcw== + "@testing-library/dom@^8.3.0": version "8.19.0" resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.19.0.tgz#bd3f83c217ebac16694329e413d9ad5fdcfd785f" @@ -3856,20 +4014,6 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -atomic-router-react@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/atomic-router-react/-/atomic-router-react-0.8.0.tgz#dda4eb11afadf8bc54382348d1f6403b370d672d" - integrity sha512-3jGOrPH2pugFSOt8aSDyR4rHH5RP81FrWbbSaa1mjRtm7NTgjUc1XAop2uWHP5Vl8sdBm8LutDsNGSewiIdb+Q== - dependencies: - clsx "^1.1.1" - -atomic-router@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/atomic-router/-/atomic-router-0.7.1.tgz#16fadadfb3465c20d08bff25b3a7305fcfb5173b" - integrity sha512-W09EU4xqpBCj8RUgu8SR93jycXRdpzZAr8YoSOHlJb1Sk8vxInKYOlapbXzOJ6HkaF0R3nTCxR+wNK4K1q9jXg== - dependencies: - path-to-regexp "^6.2.0" - autoprefixer@^10.4.13: version "10.4.13" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" @@ -4665,7 +4809,7 @@ clsx@1.1.0: resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702" integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA== -clsx@^1.0.4, clsx@^1.1.1: +clsx@^1.0.4: version "1.2.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== @@ -5077,6 +5221,11 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== +csstype@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -5455,18 +5604,6 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -effector-react@^22.3.4: - version "22.3.4" - resolved "https://registry.yarnpkg.com/effector-react/-/effector-react-22.3.4.tgz#d9020eeb0203729833472807f76d90b180b05b63" - integrity sha512-iyPMjnIW7pUoSuvxumAu4oRan4d8sbXmYPTlRXR75HOag2aH805m+xElyhyXCsQMXxQebjk7/GSC8Caeriv/+A== - dependencies: - use-sync-external-store "^1.0.0" - -effector@^22.3.0: - version "22.3.0" - resolved "https://registry.yarnpkg.com/effector/-/effector-22.3.0.tgz#c743dd7d934ec3f9a2efac76a563cd0281bc4201" - integrity sha512-Nh7IXn8U4emq8YtAZf2+y2Rs6n4W/gjPaNZpZLFOXOIAsRZSNBFjtK1vHTWNKxxmNFZOaZN6XUXdT8FDs0mAdQ== - electron-to-chromium@^1.4.251: version "1.4.284" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" @@ -9477,11 +9614,6 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== -path-to-regexp@^6.2.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" - integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== - path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -10206,6 +10338,11 @@ regenerator-runtime@^0.13.10, regenerator-runtime@^0.13.2, regenerator-runtime@^ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regenerator-transform@^0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" @@ -11145,6 +11282,11 @@ style-value-types@5.0.0: hey-listen "^1.0.8" tslib "^2.1.0" +stylerun@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stylerun/-/stylerun-1.0.0.tgz#c033974c6676316e0ff21aacfe647d14ac2dd2c0" + integrity sha512-dP6GZ+iUAsV50/YwLVP0VMc2iIZ33jydFgP8AWzmTUjoKLy/bgHDGEuEt+5oomtU4iQ0rMrZGHiMVsi/FzjQvw== + sucrase@^3.20.3: version "3.28.0" resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.28.0.tgz#7fd8b3118d2155fcdf291088ab77fa6eefd63c4c" @@ -11385,6 +11527,16 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +tiny-invariant@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + +tiny-warning@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -11815,7 +11967,7 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -use-sync-external-store@^1.0.0: +use-sync-external-store@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==