@@ -100,62 +100,71 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
100100 return options . clone ( true , options . cloneOf || options ) ;
101101 }
102102
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+
103111 const init = (
104112 isClone : boolean ,
105- cloneOf : Keyval < any , any , any , any > | null ,
113+ cloneOf : Keyval < Input , Enriched , Api , Shape > | null ,
106114 ) => {
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 > ;
114115 const $entities = createStore < KeyvalListState > ( {
115116 items : [ ] ,
116117 instances : [ ] ,
117118 keys : [ ] ,
118119 } ) ;
119120 const $items = $entities . map ( ( { items } ) => items ) ;
120121 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 ( ) ?? { } ;
121150 return lazyInit (
122151 {
123152 type : 'keyval' ,
124153 api : 0 ,
125154 __lens : 0 ,
126- __struct : 0 ,
155+ __struct : structShapeClone ,
127156 $items,
128157 $keys,
129158 __$listState : $entities ,
130- defaultState : ( ) => null as any ,
159+ defaultState : defaultStateClone ,
131160 edit : 0 ,
132161 editField : 0 ,
133162 clone : init ,
134163 isClone,
135164 cloneOf,
165+ getCloneData : cloneOf ?. getCloneData ?? ( ( ) => null as any ) ,
136166 } as any as Keyval < Input , Input & ModelEnhance , Api , Shape > ,
137167 ( ) => {
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-
159168 let kvModel :
160169 | Model <
161170 {
@@ -169,20 +178,55 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
169178
170179 if ( create ) {
171180 // @ts -expect-error typecast
172- kvModel = model ( { create } ) ;
181+ kvModel = model ( { create, isClone } ) ;
173182 }
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 ) ) ;
174216
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+ } ) ;
186230
187231 const api = createInstanceApi ( $entities , kvModel ) ;
188232 const editApi = createEditApi (
@@ -194,41 +238,22 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
194238 ) ;
195239 const editField = createEditFieldApi ( keyField , kvModel , editApi . update ) ;
196240
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-
214241 return {
215242 type : 'keyval' as const ,
216243 api : api as any ,
217- // @ts -expect-error bad implementation
218244 __lens : shape ,
219245 __struct : structShape ,
220246 $items,
221247 $keys,
222248 __$listState : $entities as any ,
223- defaultState ( ) {
224- return kvModel ?. defaultState ( ) ?? ( null as any ) ;
225- } ,
249+ defaultState,
226250 edit : editApi ,
227251 editField,
228252 clone : init ,
229253 isClone,
230254 cloneOf,
231- } ;
255+ getCloneData,
256+ } as Keyval < Input , Input & ModelEnhance , Api , Shape > ;
232257 } ,
233258 ) ;
234259 } ;
0 commit comments