import { derived } from 'svelte/store' ; import type { Updater , Writable } from 'svelte/store' ; import type { Get } from 'type-fest' ; export const getTokens = ( key ) : string [ ] => { let keyWithoutBracket = key . replace ( /\[(\d+)\]/g , '.$1' ) ; if ( keyWithoutBracket . startsWith ( '.' ) ) { keyWithoutBracket = keyWithoutBracket . slice ( 1 ) ; } return keyWithoutBracket . split ( '.' ) ; } ; const getNested = ( root , keyTokens ) : any => { let current = root ; for ( const key of keyTokens ) { if ( current == null ) { break ; } current = current [ key ] ; } return current ; } ; export function keyed < Parent , Key extends string > ( parent , key ) ; export function keyed < Parent , Key extends string > ( parent , key ) ; export function keyed < Parent , Key extends string > ( parent , key ) { const keyTokens = getTokens ( key ) ; const branchTokens = keyTokens . slice ( 0 , keyTokens . length - 1 ) ; const leafToken = keyTokens [ keyTokens . length - 1 ] ; const keyedValue = derived ( parent , ( $parent ) => getNested ( $parent , keyTokens ) ) ; const set = ( value ) => { parent . update ( ( $parent ) => { if ( $parent == null ) { return undefined as unknown as Parent ; } const newParent = Array . isArray ( $parent ) ? [ ... $parent ] : { ... $parent } ; getNested ( newParent , branchTokens ) [ leafToken ] = value ; return newParent as Parent ; } ) ; } ; const update = ( fn ) => { parent . update ( ( $parent ) => { if ( $parent == null ) { return undefined as unknown as Parent ; } const newValue = fn ( getNested ( $parent , keyTokens ) ) ; const newParent = Array . isArray ( $parent ) ? [ ... $parent ] : { ... $parent } ; getNested ( newParent , branchTokens ) [ leafToken ] = newValue ; return newParent as Parent ; } ) ; } ; return { subscribe : keyedValue . subscribe , set , update , } ; }