Skip to content

Commit 3d60fad

Browse files
fix: make item drafts mutable (#408)
Co-authored-by: Sam Willis <sam.willis@gmail.com>
1 parent 25c43cd commit 3d60fad

File tree

3 files changed

+87
-5
lines changed

3 files changed

+87
-5
lines changed

.changeset/shiny-phones-stick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@tanstack/db": patch
3+
---
4+
5+
mark item drafts as a `mutable` type

packages/db/src/collection.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import type {
5858
Transaction as TransactionType,
5959
TransactionWithMutations,
6060
UtilsRecord,
61+
WritableDeep,
6162
} from "./types"
6263
import type { IndexOptions } from "./indexes/index-options.js"
6364
import type { BaseIndex, IndexResolver } from "./indexes/base-index.js"
@@ -1969,32 +1970,34 @@ export class CollectionImpl<
19691970
// Overload 1: Update multiple items with a callback
19701971
update<TItem extends object = T>(
19711972
key: Array<TKey | unknown>,
1972-
callback: (drafts: Array<TItem>) => void
1973+
callback: (drafts: Array<WritableDeep<TItem>>) => void
19731974
): TransactionType
19741975

19751976
// Overload 2: Update multiple items with config and a callback
19761977
update<TItem extends object = T>(
19771978
keys: Array<TKey | unknown>,
19781979
config: OperationConfig,
1979-
callback: (drafts: Array<TItem>) => void
1980+
callback: (drafts: Array<WritableDeep<TItem>>) => void
19801981
): TransactionType
19811982

19821983
// Overload 3: Update a single item with a callback
19831984
update<TItem extends object = T>(
19841985
id: TKey | unknown,
1985-
callback: (draft: TItem) => void
1986+
callback: (draft: WritableDeep<TItem>) => void
19861987
): TransactionType
19871988

19881989
// Overload 4: Update a single item with config and a callback
19891990
update<TItem extends object = T>(
19901991
id: TKey | unknown,
19911992
config: OperationConfig,
1992-
callback: (draft: TItem) => void
1993+
callback: (draft: WritableDeep<TItem>) => void
19931994
): TransactionType
19941995

19951996
update<TItem extends object = T>(
19961997
keys: (TKey | unknown) | Array<TKey | unknown>,
1997-
configOrCallback: ((draft: TItem | Array<TItem>) => void) | OperationConfig,
1998+
configOrCallback:
1999+
| ((draft: WritableDeep<TItem> | Array<WritableDeep<TItem>>) => void)
2000+
| OperationConfig,
19982001
maybeCallback?: (draft: TItem | Array<TItem>) => void
19992002
) {
20002003
if (typeof keys === `undefined`) {

packages/db/src/types.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,3 +629,77 @@ export type ChangeListener<
629629
T extends object = Record<string, unknown>,
630630
TKey extends string | number = string | number,
631631
> = (changes: Array<ChangeMessage<T, TKey>>) => void
632+
633+
// Adapted from https://github.com/sindresorhus/type-fest
634+
// MIT License Copyright (c) Sindre Sorhus
635+
636+
type BuiltIns =
637+
| null
638+
| undefined
639+
| string
640+
| number
641+
| boolean
642+
| symbol
643+
| bigint
644+
| void
645+
| Date
646+
| RegExp
647+
648+
type HasMultipleCallSignatures<
649+
T extends (...arguments_: Array<any>) => unknown,
650+
> = T extends {
651+
(...arguments_: infer A): unknown
652+
(...arguments_: infer B): unknown
653+
}
654+
? B extends A
655+
? A extends B
656+
? false
657+
: true
658+
: true
659+
: false
660+
661+
type WritableMapDeep<MapType extends ReadonlyMap<unknown, unknown>> =
662+
MapType extends ReadonlyMap<infer KeyType, infer ValueType>
663+
? Map<WritableDeep<KeyType>, WritableDeep<ValueType>>
664+
: MapType
665+
666+
type WritableSetDeep<SetType extends ReadonlySet<unknown>> =
667+
SetType extends ReadonlySet<infer ItemType>
668+
? Set<WritableDeep<ItemType>>
669+
: SetType
670+
671+
type WritableObjectDeep<ObjectType extends object> = {
672+
-readonly [KeyType in keyof ObjectType]: WritableDeep<ObjectType[KeyType]>
673+
}
674+
675+
type WritableArrayDeep<ArrayType extends ReadonlyArray<unknown>> =
676+
ArrayType extends readonly []
677+
? []
678+
: ArrayType extends readonly [...infer U, infer V]
679+
? [...WritableArrayDeep<U>, WritableDeep<V>]
680+
: ArrayType extends readonly [infer U, ...infer V]
681+
? [WritableDeep<U>, ...WritableArrayDeep<V>]
682+
: ArrayType extends ReadonlyArray<infer U>
683+
? Array<WritableDeep<U>>
684+
: ArrayType extends Array<infer U>
685+
? Array<WritableDeep<U>>
686+
: ArrayType
687+
688+
export type WritableDeep<T> = T extends BuiltIns
689+
? T
690+
: T extends (...arguments_: Array<any>) => unknown
691+
? {} extends WritableObjectDeep<T>
692+
? T
693+
: HasMultipleCallSignatures<T> extends true
694+
? T
695+
: ((...arguments_: Parameters<T>) => ReturnType<T>) &
696+
WritableObjectDeep<T>
697+
: T extends ReadonlyMap<unknown, unknown>
698+
? WritableMapDeep<T>
699+
: T extends ReadonlySet<unknown>
700+
? WritableSetDeep<T>
701+
: T extends ReadonlyArray<unknown>
702+
? WritableArrayDeep<T>
703+
: T extends object
704+
? WritableObjectDeep<T>
705+
: unknown

0 commit comments

Comments
 (0)