@@ -100,62 +100,71 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
100
100
return options . clone ( true , options . cloneOf || options ) ;
101
101
}
102
102
103
+ type Enriched = Input & ModelEnhance ;
104
+ type Output = {
105
+ [ K in keyof ModelEnhance ] :
106
+ | Store < ModelEnhance [ K ] >
107
+ | Keyval < any , ModelEnhance [ K ] , any , any > ;
108
+ } ;
109
+ type KeyvalListState = ListState < Enriched , Output , Api > ;
110
+
103
111
const init = (
104
112
isClone : boolean ,
105
- cloneOf : Keyval < any , any , any , any > | null ,
113
+ cloneOf : Keyval < Input , Enriched , Api , Shape > | null ,
106
114
) => {
107
- type Enriched = Input & ModelEnhance ;
108
- type Output = {
109
- [ K in keyof ModelEnhance ] :
110
- | Store < ModelEnhance [ K ] >
111
- | Keyval < any , ModelEnhance [ K ] , any , any > ;
112
- } ;
113
- type KeyvalListState = ListState < Enriched , Output , Api > ;
114
115
const $entities = createStore < KeyvalListState > ( {
115
116
items : [ ] ,
116
117
instances : [ ] ,
117
118
keys : [ ] ,
118
119
} ) ;
119
120
const $items = $entities . map ( ( { items } ) => items ) ;
120
121
const $keys = $entities . map ( ( { keys } ) => keys ) ;
122
+ let getKeyRaw :
123
+ | keyof Input
124
+ | ( ( entity : Input ) => string | number )
125
+ | undefined ;
126
+ let create :
127
+ | void
128
+ | ( ( config : { onMount : Event < void > } ) => {
129
+ state : unknown ;
130
+ api ?: unknown ;
131
+ key : string ;
132
+ optional ?: string [ ] ;
133
+ } ) ;
134
+ let shape : Shape ;
135
+ if ( typeof options === 'function' ) {
136
+ create = options as any ;
137
+ } else {
138
+ ( {
139
+ key : getKeyRaw ,
140
+ shape = { } as Shape ,
141
+ create,
142
+ } = options as Exclude < typeof options , Keyval < any , any , any , any > > ) ;
143
+ }
144
+ const {
145
+ getKey : getKeyClone ,
146
+ keyField : keyFieldClone ,
147
+ structShape : structShapeClone ,
148
+ defaultState : defaultStateClone ,
149
+ } = cloneOf ?. getCloneData ( ) ?? { } ;
121
150
return lazyInit (
122
151
{
123
152
type : 'keyval' ,
124
153
api : 0 ,
125
154
__lens : 0 ,
126
- __struct : 0 ,
155
+ __struct : structShapeClone ,
127
156
$items,
128
157
$keys,
129
158
__$listState : $entities ,
130
- defaultState : ( ) => null as any ,
159
+ defaultState : defaultStateClone ,
131
160
edit : 0 ,
132
161
editField : 0 ,
133
162
clone : init ,
134
163
isClone,
135
164
cloneOf,
165
+ getCloneData : cloneOf ?. getCloneData ?? ( ( ) => null as any ) ,
136
166
} as any as Keyval < Input , Input & ModelEnhance , Api , Shape > ,
137
167
( ) => {
138
- let create :
139
- | void
140
- | ( ( config : { onMount : Event < void > } ) => {
141
- state : unknown ;
142
- api ?: unknown ;
143
- key : string ;
144
- optional ?: string [ ] ;
145
- } ) ;
146
- // @ts -expect-error bad implementation
147
- let getKeyRaw ;
148
- let shape : Shape ;
149
- if ( typeof options === 'function' ) {
150
- create = options as any ;
151
- } else {
152
- ( {
153
- key : getKeyRaw ,
154
- shape = { } as Shape ,
155
- create,
156
- } = options as Exclude < typeof options , Keyval < any , any , any , any > > ) ;
157
- }
158
-
159
168
let kvModel :
160
169
| Model <
161
170
{
@@ -169,20 +178,55 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
169
178
170
179
if ( create ) {
171
180
// @ts -expect-error typecast
172
- kvModel = model ( { create } ) ;
181
+ kvModel = model ( { create, isClone } ) ;
173
182
}
183
+ const getKey =
184
+ getKeyClone ??
185
+ ( ! kvModel
186
+ ? typeof getKeyRaw === 'function'
187
+ ? getKeyRaw
188
+ : // @ts -expect-error bad implementation
189
+ ( entity : Input ) => entity [ getKeyRaw ] as string | number
190
+ : ( entity : Input ) => entity [ kvModel . keyField ] as string | number ) ;
191
+ const keyField =
192
+ keyFieldClone ??
193
+ ( ! kvModel
194
+ ? typeof getKeyRaw === 'function' || getKeyRaw === undefined
195
+ ? null
196
+ : getKeyRaw
197
+ : kvModel . keyField ) ;
198
+ const structShape =
199
+ structShapeClone ??
200
+ ( kvModel
201
+ ? ( {
202
+ type : 'structKeyval' ,
203
+ getKey,
204
+ shape : kvModel . __struct ! . shape ,
205
+ defaultItem : kvModel . defaultState ,
206
+ } as StructKeyval )
207
+ : shape !
208
+ ? ( {
209
+ type : 'structKeyval' ,
210
+ getKey,
211
+ shape : { } ,
212
+ // TODO add support for .itemStore
213
+ defaultItem : ( ) => null ,
214
+ } as StructKeyval )
215
+ : ( null as any as StructKeyval ) ) ;
174
216
175
- const getKey = ! kvModel
176
- ? typeof getKeyRaw === 'function'
177
- ? getKeyRaw
178
- : // @ts -expect-error bad implementation
179
- ( entity : Input ) => entity [ getKeyRaw ] as string | number
180
- : ( entity : Input ) => entity [ kvModel . keyField ] as string | number ;
181
- const keyField = ! kvModel
182
- ? typeof getKeyRaw === 'function' || getKeyRaw === undefined
183
- ? null
184
- : getKeyRaw
185
- : kvModel . keyField ;
217
+ const defaultState =
218
+ defaultStateClone ?? ( ( ) => kvModel ?. defaultState ( ) ?? ( null as any ) ) ;
219
+
220
+ const getCloneData =
221
+ cloneOf ?. getCloneData ??
222
+ ( ( ) => {
223
+ return {
224
+ defaultState,
225
+ structShape,
226
+ keyField,
227
+ getKey,
228
+ } ;
229
+ } ) ;
186
230
187
231
const api = createInstanceApi ( $entities , kvModel ) ;
188
232
const editApi = createEditApi (
@@ -194,41 +238,22 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
194
238
) ;
195
239
const editField = createEditFieldApi ( keyField , kvModel , editApi . update ) ;
196
240
197
- const structShape = kvModel
198
- ? ( {
199
- type : 'structKeyval' ,
200
- getKey,
201
- shape : kvModel . __struct ! . shape ,
202
- defaultItem : kvModel . defaultState ,
203
- } as StructKeyval )
204
- : shape !
205
- ? ( {
206
- type : 'structKeyval' ,
207
- getKey,
208
- shape : { } ,
209
- // TODO add support for .itemStore
210
- defaultItem : ( ) => null ,
211
- } as StructKeyval )
212
- : ( null as any as StructKeyval ) ;
213
-
214
241
return {
215
242
type : 'keyval' as const ,
216
243
api : api as any ,
217
- // @ts -expect-error bad implementation
218
244
__lens : shape ,
219
245
__struct : structShape ,
220
246
$items,
221
247
$keys,
222
248
__$listState : $entities as any ,
223
- defaultState ( ) {
224
- return kvModel ?. defaultState ( ) ?? ( null as any ) ;
225
- } ,
249
+ defaultState,
226
250
edit : editApi ,
227
251
editField,
228
252
clone : init ,
229
253
isClone,
230
254
cloneOf,
231
- } ;
255
+ getCloneData,
256
+ } as Keyval < Input , Input & ModelEnhance , Api , Shape > ;
232
257
} ,
233
258
) ;
234
259
} ;
0 commit comments