1
- import { createSelector , createSlice , type PayloadAction } from '@reduxjs/toolkit' ;
1
+ import type { PayloadAction , UnknownAction } from '@reduxjs/toolkit' ;
2
+ import { createSelector , createSlice , isAnyOf } from '@reduxjs/toolkit' ;
2
3
import { EMPTY_ARRAY } from 'app/store/constants' ;
3
4
import type { RootState } from 'app/store/store' ;
4
5
import type { SliceConfig } from 'app/store/types' ;
@@ -11,64 +12,85 @@ import z from 'zod';
11
12
import {
12
13
canvasAdding ,
13
14
canvasDeleted ,
15
+ canvasInitialized ,
14
16
canvasMultiCanvasMigrated ,
15
17
MIGRATION_MULTI_CANVAS_ID_PLACEHOLDER ,
16
18
} from './canvasSlice' ;
17
19
import { selectActiveCanvasId } from './selectors' ;
18
20
19
- const zCanvasSessionState = z . object ( {
21
+ const zCanvasSession = z . object ( {
20
22
canvasId : z . string ( ) . min ( 1 ) ,
21
23
canvasSessionId : z . string ( ) ,
22
24
canvasDiscardedQueueItems : z . array ( z . number ( ) . int ( ) ) ,
23
25
} ) ;
24
- type CanvasSessionState = z . infer < typeof zCanvasSessionState > ;
26
+ type CanvasSession = z . infer < typeof zCanvasSession > ;
25
27
const zCanvasStagingAreaState = z . object ( {
26
28
_version : z . literal ( 2 ) ,
27
- sessions : z . record ( z . string ( ) , zCanvasSessionState ) ,
29
+ sessions : z . record ( z . string ( ) , zCanvasSession ) ,
28
30
} ) ;
29
31
type CanvasStagingAreaState = z . infer < typeof zCanvasStagingAreaState > ;
30
32
31
33
type CanvasPayload < T > = { canvasId : string } & T ;
32
34
type CanvasPayloadAction < T > = PayloadAction < CanvasPayload < T > > ;
33
35
34
- const getInitialCanvasSessionState = ( canvasId : string ) : CanvasSessionState => ( {
36
+ const getInitialCanvasSessionState = ( canvasId : string ) : CanvasSession => ( {
35
37
canvasId,
36
38
canvasSessionId : getPrefixedId ( 'canvas' ) ,
37
39
canvasDiscardedQueueItems : [ ] ,
38
40
} ) ;
39
41
40
- const getInitialState = ( ) : CanvasStagingAreaState => ( {
42
+ const getInitialCanvasStagingAreaState = ( ) : CanvasStagingAreaState => ( {
41
43
_version : 2 ,
42
44
sessions : { } ,
43
45
} ) ;
44
46
45
47
const canvasStagingAreaSlice = createSlice ( {
46
48
name : 'canvasSession' ,
47
- initialState : getInitialState ( ) ,
48
- reducers : {
49
- canvasQueueItemDiscarded : ( state , action : CanvasPayloadAction < { itemId : number } > ) => {
50
- const { canvasId, itemId } = action . payload ;
51
-
52
- const session = state . sessions [ canvasId ] ;
49
+ initialState : getInitialCanvasStagingAreaState ,
50
+ reducers : { } ,
51
+ extraReducers ( builder ) {
52
+ builder . addCase ( canvasAdding , ( state , action ) => {
53
+ const session = getInitialCanvasSessionState ( action . payload . canvasId ) ;
54
+ state . sessions [ session . canvasId ] = session ;
55
+ } ) ;
56
+ builder . addCase ( canvasDeleted , ( state , action ) => {
57
+ delete state . sessions [ action . payload . canvasId ] ;
58
+ } ) ;
59
+ builder . addCase ( canvasMultiCanvasMigrated , ( state , action ) => {
60
+ const session = state . sessions [ MIGRATION_MULTI_CANVAS_ID_PLACEHOLDER ] ;
53
61
if ( ! session ) {
54
62
return ;
55
63
}
64
+ session . canvasId = action . payload . canvasId ;
65
+ state . sessions [ session . canvasId ] = session ;
66
+ delete state . sessions [ MIGRATION_MULTI_CANVAS_ID_PLACEHOLDER ] ;
67
+ } ) ;
68
+ builder . addCase ( canvasInitialized , ( state , action ) => {
69
+ const canvasId = action . payload . canvasId ;
70
+ if ( ! state . sessions [ canvasId ] ) {
71
+ state . sessions [ canvasId ] = getInitialCanvasSessionState ( canvasId ) ;
72
+ }
73
+ } ) ;
74
+ } ,
75
+ } ) ;
76
+
77
+ const canvasSessionFragment = createSlice ( {
78
+ name : 'canvasSession' ,
79
+ initialState : { } as CanvasSession ,
80
+ reducers : {
81
+ canvasQueueItemDiscarded : ( state , action : CanvasPayloadAction < { itemId : number } > ) => {
82
+ const { itemId } = action . payload ;
56
83
57
- if ( ! session . canvasDiscardedQueueItems . includes ( itemId ) ) {
58
- session . canvasDiscardedQueueItems . push ( itemId ) ;
84
+ if ( ! state . canvasDiscardedQueueItems . includes ( itemId ) ) {
85
+ state . canvasDiscardedQueueItems . push ( itemId ) ;
59
86
}
60
87
} ,
61
88
canvasSessionReset : {
62
89
reducer : ( state , action : CanvasPayloadAction < { canvasSessionId : string } > ) => {
63
- const { canvasId, canvasSessionId } = action . payload ;
64
-
65
- const session = state . sessions [ canvasId ] ;
66
- if ( ! session ) {
67
- return ;
68
- }
90
+ const { canvasSessionId } = action . payload ;
69
91
70
- session . canvasSessionId = canvasSessionId ;
71
- session . canvasDiscardedQueueItems = [ ] ;
92
+ state . canvasSessionId = canvasSessionId ;
93
+ state . canvasDiscardedQueueItems = [ ] ;
72
94
} ,
73
95
prepare : ( payload : CanvasPayload < object > ) => {
74
96
return {
@@ -80,32 +102,34 @@ const canvasStagingAreaSlice = createSlice({
80
102
} ,
81
103
} ,
82
104
} ,
83
- extraReducers ( builder ) {
84
- builder . addCase ( canvasAdding , ( state , action ) => {
85
- const session = getInitialCanvasSessionState ( action . payload . canvasId ) ;
86
- state . sessions [ session . canvasId ] = session ;
87
- } ) ;
88
- builder . addCase ( canvasDeleted , ( state , action ) => {
89
- delete state . sessions [ action . payload . canvasId ] ;
90
- } ) ;
91
- builder . addCase ( canvasMultiCanvasMigrated , ( state , action ) => {
92
- const session = state . sessions [ MIGRATION_MULTI_CANVAS_ID_PLACEHOLDER ] ;
93
- if ( ! session ) {
94
- return ;
95
- }
96
- session . canvasId = action . payload . canvasId ;
97
- state . sessions [ session . canvasId ] = session ;
98
- delete state . sessions [ MIGRATION_MULTI_CANVAS_ID_PLACEHOLDER ] ;
99
- } ) ;
100
- } ,
101
105
} ) ;
102
106
103
- export const { canvasSessionReset, canvasQueueItemDiscarded } = canvasStagingAreaSlice . actions ;
107
+ export const { canvasSessionReset, canvasQueueItemDiscarded } = canvasSessionFragment . actions ;
108
+
109
+ const isCanvasSessionAction = isAnyOf ( ...Object . values ( canvasSessionFragment . actions ) ) ;
110
+
111
+ export const canvasSessionReducer = ( state : CanvasStagingAreaState | undefined , action : UnknownAction ) : CanvasStagingAreaState => {
112
+ state = canvasStagingAreaSlice . reducer ( state , action ) ;
113
+
114
+ if ( ! isCanvasSessionAction ( action ) ) {
115
+ return state ;
116
+ }
117
+
118
+ const canvasId = action . payload . canvasId ;
119
+
120
+ return {
121
+ ...state ,
122
+ sessions : {
123
+ ...state . sessions ,
124
+ [ canvasId ] : canvasSessionFragment . reducer ( state . sessions [ canvasId ] , action ) ,
125
+ } ,
126
+ } ;
127
+ } ;
104
128
105
129
export const canvasSessionSliceConfig : SliceConfig < typeof canvasStagingAreaSlice > = {
106
130
slice : canvasStagingAreaSlice ,
107
131
schema : zCanvasStagingAreaState ,
108
- getInitialState,
132
+ getInitialState : getInitialCanvasStagingAreaState ,
109
133
persistConfig : {
110
134
migrate : ( state ) => {
111
135
assert ( isPlainObject ( state ) ) ;
@@ -117,7 +141,7 @@ export const canvasSessionSliceConfig: SliceConfig<typeof canvasStagingAreaSlice
117
141
const session = {
118
142
canvasId : MIGRATION_MULTI_CANVAS_ID_PLACEHOLDER ,
119
143
...state ,
120
- } as CanvasSessionState ;
144
+ } as CanvasSession ;
121
145
122
146
state = {
123
147
_version : 2 ,
@@ -130,7 +154,7 @@ export const canvasSessionSliceConfig: SliceConfig<typeof canvasStagingAreaSlice
130
154
} ,
131
155
} ;
132
156
133
- const findSessionByCanvasId = ( sessions : Record < string , CanvasSessionState > , canvasId : string ) => {
157
+ const findSessionByCanvasId = ( sessions : Record < string , CanvasSession > , canvasId : string ) => {
134
158
const session = sessions [ canvasId ] ;
135
159
assert ( session , 'Session must exist for a canvas once the canvas has been created' ) ;
136
160
return session ;
0 commit comments