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,37 @@ 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 = (
112
+ state : CanvasStagingAreaState | undefined ,
113
+ action : UnknownAction
114
+ ) : CanvasStagingAreaState => {
115
+ state = canvasStagingAreaSlice . reducer ( state , action ) ;
116
+
117
+ if ( ! isCanvasSessionAction ( action ) ) {
118
+ return state ;
119
+ }
120
+
121
+ const canvasId = action . payload . canvasId ;
122
+
123
+ return {
124
+ ...state ,
125
+ sessions : {
126
+ ...state . sessions ,
127
+ [ canvasId ] : canvasSessionFragment . reducer ( state . sessions [ canvasId ] , action ) ,
128
+ } ,
129
+ } ;
130
+ } ;
104
131
105
132
export const canvasSessionSliceConfig : SliceConfig < typeof canvasStagingAreaSlice > = {
106
133
slice : canvasStagingAreaSlice ,
107
134
schema : zCanvasStagingAreaState ,
108
- getInitialState,
135
+ getInitialState : getInitialCanvasStagingAreaState ,
109
136
persistConfig : {
110
137
migrate : ( state ) => {
111
138
assert ( isPlainObject ( state ) ) ;
@@ -117,7 +144,7 @@ export const canvasSessionSliceConfig: SliceConfig<typeof canvasStagingAreaSlice
117
144
const session = {
118
145
canvasId : MIGRATION_MULTI_CANVAS_ID_PLACEHOLDER ,
119
146
...state ,
120
- } as CanvasSessionState ;
147
+ } as CanvasSession ;
121
148
122
149
state = {
123
150
_version : 2 ,
@@ -130,7 +157,7 @@ export const canvasSessionSliceConfig: SliceConfig<typeof canvasStagingAreaSlice
130
157
} ,
131
158
} ;
132
159
133
- const findSessionByCanvasId = ( sessions : Record < string , CanvasSessionState > , canvasId : string ) => {
160
+ const findSessionByCanvasId = ( sessions : Record < string , CanvasSession > , canvasId : string ) => {
134
161
const session = sessions [ canvasId ] ;
135
162
assert ( session , 'Session must exist for a canvas once the canvas has been created' ) ;
136
163
return session ;
0 commit comments