Skip to content

Commit

Permalink
feat(redux): bump redux to v5 and react-redux to v9
Browse files Browse the repository at this point in the history
bump redux to v5 and react-redux to v9

BREAKING CHANGE: bump redux to v5 and react-redux to v9
  • Loading branch information
100terres committed Sep 14, 2024
1 parent 38e6b49 commit 8334755
Show file tree
Hide file tree
Showing 20 changed files with 257 additions and 885 deletions.
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@
"css-box-model": "^1.2.1",
"memoize-one": "^6.0.0",
"raf-schd": "^4.0.3",
"react-redux": "^8.1.3",
"redux": "^4.2.1",
"react-redux": "^9.1.2",
"redux": "^5.0.1",
"use-memo-one": "^1.1.3"
},
"devDependencies": {
Expand Down Expand Up @@ -130,7 +130,6 @@
"@types/raf-schd": "4.0.3",
"@types/react": "18.3.5",
"@types/react-dom": "18.3.0",
"@types/react-redux": "7.1.33",
"@types/react-virtualized": "9.21.30",
"@types/react-window": "1.8.8",
"@types/seedrandom": "3.0.8",
Expand Down
911 changes: 138 additions & 773 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions src/state/action-creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ import type {
Published,
} from '../types';

type ActionTypes = Action['type'];

type ExtractAction<TActionType extends ActionTypes> = Extract<
Action,
{ type: TActionType }
>;

export function guard<TActionType extends ActionTypes>(
action: unknown,
predicate: TActionType,
): action is ExtractAction<TActionType> {
return (
action instanceof Object && 'type' in action && action.type === predicate
);
}

export interface BeforeInitialCaptureArgs {
draggableId: DraggableId;
movementMode: MovementMode;
Expand Down
7 changes: 3 additions & 4 deletions src/state/create-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import type { DimensionMarshal } from './dimension-marshal/dimension-marshal-typ
import type { FocusMarshal } from '../view/use-focus-marshal/focus-marshal-types';
import type { StyleMarshal } from '../view/use-style-marshal/style-marshal-types';
import type { AutoScroller } from './auto-scroller/auto-scroller-types';
import type { Responders, Announce } from '../types';
import type { Store } from './store-types';
import type { Responders, Announce, State } from '../types';
import type { Store, Dispatch } from './store-types';

// For more config
// See: https://github.com/reduxjs/redux-devtools/blob/main/packages/redux-devtools-extension/src/index.ts#L3
Expand Down Expand Up @@ -66,7 +66,7 @@ export default ({
createStore(
reducer,
composeEnhancers(
applyMiddleware(
applyMiddleware<Dispatch, State>(
// ## Debug middleware

// > uncomment to use
Expand All @@ -80,7 +80,6 @@ export default ({
// require('../debug/middleware/action-timing-average').default(200),

// ## Application middleware

// Style updates do not cause more actions. It is important to update styles
// before responders are called: specifically the onDragEnd responder. We need to clear
// the transition styles off the elements before a reorder to prevent strange
Expand Down
23 changes: 8 additions & 15 deletions src/state/middleware/auto-scroll.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
import { invariant } from '../../invariant';
import type { AutoScroller } from '../auto-scroller/auto-scroller-types';
import type {
Action,
Middleware,
DropCompleteAction,
DropAnimateAction,
FlushAction,
} from '../store-types';
import type { Middleware } from '../store-types';
import { guard } from '../action-creators';
import type { State } from '../../types';

const shouldStop = (
action: Action,
): action is DropCompleteAction | DropAnimateAction | FlushAction =>
action.type === 'DROP_COMPLETE' ||
action.type === 'DROP_ANIMATE' ||
action.type === 'FLUSH';
const shouldStop = (action: unknown) =>
guard(action, 'DROP_COMPLETE') ||
guard(action, 'DROP_ANIMATE') ||
guard(action, 'FLUSH');

export default (autoScroller: AutoScroller): Middleware =>
(store) =>
(next) =>
(action: Action) => {
(action) => {
if (shouldStop(action)) {
autoScroller.stop();
next(action);
return;
}

if (action.type === 'INITIAL_PUBLISH') {
if (guard(action, 'INITIAL_PUBLISH')) {
// letting the action go first to hydrate the state
next(action);
const state: State = store.getState();
Expand Down
15 changes: 8 additions & 7 deletions src/state/middleware/dimension-marshal-stopper.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import type { Action, Dispatch } from '../store-types';
import { guard } from '../action-creators';
import type { Middleware } from '../store-types';
import type { DimensionMarshal } from '../dimension-marshal/dimension-marshal-types';

export default (marshal: DimensionMarshal) =>
export default (marshal: DimensionMarshal): Middleware =>
() =>
(next: Dispatch) =>
(action: Action): any => {
(next) =>
(action) => {
// Not stopping a collection on a 'DROP' as we want a collection to continue
if (
// drag is finished
action.type === 'DROP_COMPLETE' ||
action.type === 'FLUSH' ||
guard(action, 'DROP_COMPLETE') ||
guard(action, 'FLUSH') ||
// no longer accepting changes once the drop has started
action.type === 'DROP_ANIMATE'
guard(action, 'DROP_ANIMATE')
) {
marshal.stopPublishing();
}
Expand Down
4 changes: 2 additions & 2 deletions src/state/middleware/drop/drop-animation-finish-middleware.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { invariant } from '../../../invariant';
import { completeDrop } from '../../action-creators';
import { completeDrop, guard } from '../../action-creators';
import type { State } from '../../../types';
import type { Middleware } from '../../store-types';

const dropAnimationFinishMiddleware: Middleware =
(store) => (next) => (action) => {
if (action.type !== 'DROP_ANIMATION_FINISHED') {
if (!guard(action, 'DROP_ANIMATION_FINISHED')) {
next(action);
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { dropAnimationFinished } from '../../action-creators';
import { dropAnimationFinished, guard } from '../../action-creators';
import type { State } from '../../../types';
import type { Middleware } from '../../store-types';
import type { EventBinding } from '../../../view/event-bindings/event-types';
Expand All @@ -22,16 +22,16 @@ const dropAnimationFlushOnScrollMiddleware: Middleware = (store) => {

return (next) => (action) => {
if (
action.type === 'FLUSH' ||
action.type === 'DROP_COMPLETE' ||
action.type === 'DROP_ANIMATION_FINISHED'
guard(action, 'FLUSH') ||
guard(action, 'DROP_COMPLETE') ||
guard(action, 'DROP_ANIMATION_FINISHED')
) {
clear();
}

next(action);

if (action.type !== 'DROP_ANIMATE') {
if (!guard(action, 'DROP_ANIMATE')) {
return;
}

Expand Down
9 changes: 7 additions & 2 deletions src/state/middleware/drop/drop-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import type {
DraggableDimension,
} from '../../../types';
import type { Middleware } from '../../store-types';
import { animateDrop, completeDrop, dropPending } from '../../action-creators';
import {
animateDrop,
completeDrop,
dropPending,
guard,
} from '../../action-creators';
import type { AnimateDropArgs } from '../../action-creators';
import { isEqual } from '../../position';
import getDropDuration from './get-drop-duration';
Expand All @@ -25,7 +30,7 @@ const dropMiddleware: Middleware =
({ getState, dispatch }) =>
(next) =>
(action) => {
if (action.type !== 'DROP') {
if (!guard(action, 'DROP')) {
next(action);
return;
}
Expand Down
64 changes: 30 additions & 34 deletions src/state/middleware/focus.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,42 @@
import type { DropResult } from '../../types';
import type { Action, Dispatch } from '../store-types';
import type { Middleware } from '../store-types';
import { guard } from '../action-creators';
import type { FocusMarshal } from '../../view/use-focus-marshal/focus-marshal-types';

export default (marshal: FocusMarshal) => {
export default (marshal: FocusMarshal): Middleware => {
let isWatching = false;

return () =>
(next: Dispatch) =>
(action: Action): any => {
if (action.type === 'INITIAL_PUBLISH') {
isWatching = true;

marshal.tryRecordFocus(action.payload.critical.draggable.id);
next(action);
marshal.tryRestoreFocusRecorded();
return;
}
return () => (next) => (action) => {
if (guard(action, 'INITIAL_PUBLISH')) {
isWatching = true;

marshal.tryRecordFocus(action.payload.critical.draggable.id);
next(action);
marshal.tryRestoreFocusRecorded();
return;
}

if (!isWatching) {
return;
}
next(action);

if (action.type === 'FLUSH') {
isWatching = false;
marshal.tryRestoreFocusRecorded();
return;
}
if (!isWatching) {
return;
}

if (guard(action, 'FLUSH')) {
isWatching = false;
marshal.tryRestoreFocusRecorded();
return;
}

if (guard(action, 'DROP_COMPLETE')) {
isWatching = false;
const result: DropResult = action.payload.completed.result;

if (action.type === 'DROP_COMPLETE') {
isWatching = false;
const result: DropResult = action.payload.completed.result;

// give focus to the combine target when combining
if (result.combine) {
marshal.tryShiftRecord(
result.draggableId,
result.combine.draggableId,
);
}
marshal.tryRestoreFocusRecorded();
// give focus to the combine target when combining
if (result.combine) {
marshal.tryShiftRecord(result.draggableId, result.combine.draggableId);
}
};
marshal.tryRestoreFocusRecorded();
}
};
};
3 changes: 2 additions & 1 deletion src/state/middleware/lift.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import {
initialPublish,
flush,
beforeInitialCapture,
guard,
} from '../action-creators';
import validateDimensions from './util/validate-dimensions';

export default (marshal: DimensionMarshal): Middleware =>
({ getState, dispatch }) =>
(next) =>
(action) => {
if (action.type !== 'LIFT') {
if (!guard(action, 'LIFT')) {
next(action);
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/state/middleware/pending-drop.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { drop } from '../action-creators';
import { drop, guard } from '../action-creators';
import type { State } from '../../types';
import type { Middleware } from '../store-types';

const pendingDrop: Middleware = (store) => (next) => (action) => {
// Always let the action go through first
next(action);

if (action.type !== 'PUBLISH_WHILE_DRAGGING') {
if (!guard(action, 'PUBLISH_WHILE_DRAGGING')) {
return;
}

Expand Down
9 changes: 5 additions & 4 deletions src/state/middleware/responders/responders-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
Announce,
} from '../../../types';
import type { Middleware } from '../../store-types';
import { guard } from '../../action-creators';

export default (
getResponders: () => Responders,
Expand All @@ -18,15 +19,15 @@ export default (
);

return (store) => (next) => (action) => {
if (action.type === 'BEFORE_INITIAL_CAPTURE') {
if (guard(action, 'BEFORE_INITIAL_CAPTURE')) {
publisher.beforeCapture(
action.payload.draggableId,
action.payload.movementMode,
);
return;
}

if (action.type === 'INITIAL_PUBLISH') {
if (guard(action, 'INITIAL_PUBLISH')) {
const critical: Critical = action.payload.critical;
publisher.beforeStart(critical, action.payload.movementMode);
next(action);
Expand All @@ -35,7 +36,7 @@ export default (
}

// Drag end
if (action.type === 'DROP_COMPLETE') {
if (guard(action, 'DROP_COMPLETE')) {
// it is important that we use the result and not the last impact
// the last impact might be different to the result for visual reasons
const result: DropResult = action.payload.completed.result;
Expand All @@ -51,7 +52,7 @@ export default (

// Drag state resetting - need to check if
// we should fire a onDragEnd responder
if (action.type === 'FLUSH') {
if (guard(action, 'FLUSH')) {
publisher.abort();
return;
}
Expand Down
24 changes: 8 additions & 16 deletions src/state/middleware/scroll-listener.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
import type { Position } from 'css-box-model';
import { moveByWindowScroll } from '../action-creators';
import type {
Middleware,
Action,
DropAnimateAction,
DropCompleteAction,
FlushAction,
} from '../store-types';
import { moveByWindowScroll, guard } from '../action-creators';
import type { Middleware } from '../store-types';
import getScrollListener from '../../view/scroll-listener';

// TODO: this is taken from auto-scroll. Let's make it a util
const shouldEnd = (
action: Action,
): action is DropAnimateAction | DropCompleteAction | FlushAction =>
action.type === 'DROP_COMPLETE' ||
action.type === 'DROP_ANIMATE' ||
action.type === 'FLUSH';
const shouldStop = (action: unknown) =>
guard(action, 'DROP_COMPLETE') ||
guard(action, 'DROP_ANIMATE') ||
guard(action, 'FLUSH');

const scrollListener: Middleware = (store) => {
const listener = getScrollListener({
Expand All @@ -25,11 +17,11 @@ const scrollListener: Middleware = (store) => {
});

return (next) => (action) => {
if (!listener.isActive() && action.type === 'INITIAL_PUBLISH') {
if (!listener.isActive() && guard(action, 'INITIAL_PUBLISH')) {
listener.start();
}

if (listener.isActive() && shouldEnd(action)) {
if (listener.isActive() && shouldStop(action)) {
listener.stop();
}

Expand Down
Loading

0 comments on commit 8334755

Please sign in to comment.