Skip to content

Commit f4cac3d

Browse files
committed
Change to use the input type for update
1 parent 380f181 commit f4cac3d

File tree

6 files changed

+451
-151
lines changed

6 files changed

+451
-151
lines changed

packages/db/src/collection.ts

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import type {
5151
OperationConfig,
5252
OptimisticChangeMessage,
5353
PendingMutation,
54-
ResolveInsertInput,
54+
ResolveInput,
5555
ResolveType,
5656
StandardSchema,
5757
SubscribeChangesOptions,
@@ -73,15 +73,15 @@ interface PendingSyncedTransaction<T extends object = Record<string, unknown>> {
7373
* @template TKey - The type of the key for the collection
7474
* @template TUtils - The utilities record type
7575
* @template TSchema - The schema type for validation and type inference
76-
* @template TInsertInput - The type for insert operations (can be different from T for schemas with defaults)
76+
* @template TInput - The type for insert and update operations (can be different from T for schemas with defaults)
7777
*/
7878
export interface Collection<
7979
T extends object = Record<string, unknown>,
8080
TKey extends string | number = string | number,
8181
TUtils extends UtilsRecord = {},
8282
TSchema extends StandardSchemaV1 = StandardSchemaV1,
83-
TInsertInput extends object = T,
84-
> extends CollectionImpl<T, TKey, TUtils, TSchema, TInsertInput> {
83+
TInput extends object = T,
84+
> extends CollectionImpl<T, TKey, TUtils, TSchema, TInput> {
8585
readonly utils: TUtils
8686
}
8787

@@ -170,7 +170,7 @@ export function createCollection<
170170
ResolveType<unknown, TSchema, TFallback>,
171171
TKey,
172172
TSchema,
173-
ResolveInsertInput<unknown, TSchema, TFallback>
173+
ResolveInput<unknown, TSchema, TFallback>
174174
> & {
175175
schema: TSchema
176176
utils?: TUtils
@@ -180,7 +180,7 @@ export function createCollection<
180180
TKey,
181181
TUtils,
182182
TSchema,
183-
ResolveInsertInput<unknown, TSchema, TFallback>
183+
ResolveInput<unknown, TSchema, TFallback>
184184
>
185185

186186
// Overload for when explicit type is provided with schema - explicit type takes precedence
@@ -195,7 +195,7 @@ export function createCollection<
195195
ResolveType<TExplicit, TSchema, TFallback>,
196196
TKey,
197197
TSchema,
198-
ResolveInsertInput<TExplicit, TSchema, TFallback>
198+
ResolveInput<TExplicit, TSchema, TFallback>
199199
> & {
200200
schema: TSchema
201201
utils?: TUtils
@@ -205,7 +205,7 @@ export function createCollection<
205205
TKey,
206206
TUtils,
207207
TSchema,
208-
ResolveInsertInput<TExplicit, TSchema, TFallback>
208+
ResolveInput<TExplicit, TSchema, TFallback>
209209
>
210210

211211
// Overload for when explicit type is provided or no schema
@@ -220,14 +220,14 @@ export function createCollection<
220220
ResolveType<TExplicit, TSchema, TFallback>,
221221
TKey,
222222
TSchema,
223-
ResolveInsertInput<TExplicit, TSchema, TFallback>
223+
ResolveInput<TExplicit, TSchema, TFallback>
224224
> & { utils?: TUtils }
225225
): Collection<
226226
ResolveType<TExplicit, TSchema, TFallback>,
227227
TKey,
228228
TUtils,
229229
TSchema,
230-
ResolveInsertInput<TExplicit, TSchema, TFallback>
230+
ResolveInput<TExplicit, TSchema, TFallback>
231231
>
232232

233233
// Implementation
@@ -242,21 +242,21 @@ export function createCollection<
242242
ResolveType<TExplicit, TSchema, TFallback>,
243243
TKey,
244244
TSchema,
245-
ResolveInsertInput<TExplicit, TSchema, TFallback>
245+
ResolveInput<TExplicit, TSchema, TFallback>
246246
> & { utils?: TUtils }
247247
): Collection<
248248
ResolveType<TExplicit, TSchema, TFallback>,
249249
TKey,
250250
TUtils,
251251
TSchema,
252-
ResolveInsertInput<TExplicit, TSchema, TFallback>
252+
ResolveInput<TExplicit, TSchema, TFallback>
253253
> {
254254
const collection = new CollectionImpl<
255255
ResolveType<TExplicit, TSchema, TFallback>,
256256
TKey,
257257
TUtils,
258258
TSchema,
259-
ResolveInsertInput<TExplicit, TSchema, TFallback>
259+
ResolveInput<TExplicit, TSchema, TFallback>
260260
>(options)
261261

262262
// Copy utils to both top level and .utils namespace
@@ -271,7 +271,7 @@ export function createCollection<
271271
TKey,
272272
TUtils,
273273
TSchema,
274-
ResolveInsertInput<TExplicit, TSchema, TFallback>
274+
ResolveInput<TExplicit, TSchema, TFallback>
275275
>
276276
}
277277

@@ -280,9 +280,9 @@ export class CollectionImpl<
280280
TKey extends string | number = string | number,
281281
TUtils extends UtilsRecord = {},
282282
TSchema extends StandardSchemaV1 = StandardSchemaV1,
283-
TInsertInput extends object = T,
283+
TInput extends object = T,
284284
> {
285-
public config: CollectionConfig<T, TKey, TSchema, TInsertInput>
285+
public config: CollectionConfig<T, TKey, TSchema, TInput>
286286

287287
// Core state - make public for testing
288288
public transactions: SortedMap<string, Transaction<any>>
@@ -478,7 +478,7 @@ export class CollectionImpl<
478478
* @param config - Configuration object for the collection
479479
* @throws Error if sync config is missing
480480
*/
481-
constructor(config: CollectionConfig<T, TKey, TSchema, TInsertInput>) {
481+
constructor(config: CollectionConfig<T, TKey, TSchema, TInput>) {
482482
// eslint-disable-next-line
483483
if (!config) {
484484
throw new CollectionRequiresConfigError()
@@ -1681,10 +1681,7 @@ export class CollectionImpl<
16811681
* console.log('Insert failed:', error)
16821682
* }
16831683
*/
1684-
insert = (
1685-
data: TInsertInput | Array<TInsertInput>,
1686-
config?: InsertConfig
1687-
) => {
1684+
insert = (data: TInput | Array<TInput>, config?: InsertConfig) => {
16881685
this.validateCollectionUsable(`insert`)
16891686
const ambientTransaction = getActiveTransaction()
16901687

@@ -1713,14 +1710,15 @@ export class CollectionImpl<
17131710
original: {},
17141711
modified: validatedData,
17151712
// Pick the values from validatedData based on what's passed in - this is for cases
1716-
// where a schema has default values. The validated data has the extra default
1717-
// values but for changes, we just want to show the data that was actually passed in.
1713+
// where a schema has default values or transforms. The validated data has the extra
1714+
// default or transformed values but for changes, we just want to show the data that
1715+
// was actually passed in.
17181716
changes: Object.fromEntries(
17191717
Object.keys(item).map((k) => [
17201718
k,
17211719
validatedData[k as keyof typeof validatedData],
17221720
])
1723-
) as TInsertInput,
1721+
) as TInput,
17241722
globalKey,
17251723
key,
17261724
metadata: config?.metadata as unknown,
@@ -1752,7 +1750,7 @@ export class CollectionImpl<
17521750
return await this.config.onInsert!({
17531751
transaction:
17541752
params.transaction as unknown as TransactionWithMutations<
1755-
TInsertInput,
1753+
T,
17561754
`insert`
17571755
>,
17581756
collection: this as unknown as Collection<T, TKey, TUtils>,
@@ -1814,35 +1812,37 @@ export class CollectionImpl<
18141812
*/
18151813

18161814
// Overload 1: Update multiple items with a callback
1817-
update<TItem extends object = T>(
1815+
update<TDraft extends object = TInput>(
18181816
key: Array<TKey | unknown>,
1819-
callback: (drafts: Array<TItem>) => void
1817+
callback: (drafts: Array<TDraft>) => void
18201818
): TransactionType
18211819

18221820
// Overload 2: Update multiple items with config and a callback
1823-
update<TItem extends object = T>(
1821+
update<TDraft extends object = TInput>(
18241822
keys: Array<TKey | unknown>,
18251823
config: OperationConfig,
1826-
callback: (drafts: Array<TItem>) => void
1824+
callback: (drafts: Array<TDraft>) => void
18271825
): TransactionType
18281826

18291827
// Overload 3: Update a single item with a callback
1830-
update<TItem extends object = T>(
1828+
update<TDraft extends object = TInput>(
18311829
id: TKey | unknown,
1832-
callback: (draft: TItem) => void
1830+
callback: (draft: TDraft) => void
18331831
): TransactionType
18341832

18351833
// Overload 4: Update a single item with config and a callback
1836-
update<TItem extends object = T>(
1834+
update<TDraft extends object = TInput>(
18371835
id: TKey | unknown,
18381836
config: OperationConfig,
1839-
callback: (draft: TItem) => void
1837+
callback: (draft: TDraft) => void
18401838
): TransactionType
18411839

1842-
update<TItem extends object = T>(
1840+
update<TDraft extends object = TInput>(
18431841
keys: (TKey | unknown) | Array<TKey | unknown>,
1844-
configOrCallback: ((draft: TItem | Array<TItem>) => void) | OperationConfig,
1845-
maybeCallback?: (draft: TItem | Array<TItem>) => void
1842+
configOrCallback:
1843+
| ((draft: TDraft | Array<TDraft>) => void)
1844+
| OperationConfig,
1845+
maybeCallback?: (draft: TDraft | Array<TDraft>) => void
18461846
) {
18471847
if (typeof keys === `undefined`) {
18481848
throw new MissingUpdateArgumentError()
@@ -1877,19 +1877,19 @@ export class CollectionImpl<
18771877
}
18781878

18791879
return item
1880-
}) as unknown as Array<TItem>
1880+
}) as unknown as Array<TDraft>
18811881

18821882
let changesArray
18831883
if (isArray) {
18841884
// Use the proxy to track changes for all objects
18851885
changesArray = withArrayChangeTracking(
18861886
currentObjects,
1887-
callback as (draft: Array<TItem>) => void
1887+
callback as (draft: Array<TDraft>) => void
18881888
)
18891889
} else {
18901890
const result = withChangeTracking(
18911891
currentObjects[0]!,
1892-
callback as (draft: TItem) => void
1892+
callback as (draft: TDraft) => void
18931893
)
18941894
changesArray = [result]
18951895
}
@@ -1933,7 +1933,16 @@ export class CollectionImpl<
19331933
mutationId: crypto.randomUUID(),
19341934
original: originalItem,
19351935
modified: modifiedItem,
1936-
changes: validatedUpdatePayload as Partial<T>,
1936+
// Pick the values from modifiedItem based on what's passed in - this is for cases
1937+
// where a schema has default values or transforms. The modified data has the extra
1938+
// default or transformed values but for changes, we just want to show the data that
1939+
// was actually passed in.
1940+
changes: Object.fromEntries(
1941+
Object.keys(itemChanges).map((k) => [
1942+
k,
1943+
modifiedItem[k as keyof typeof modifiedItem],
1944+
])
1945+
) as TInput,
19371946
globalKey,
19381947
key,
19391948
metadata: config.metadata as unknown,

packages/db/src/local-only.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {
33
DeleteMutationFnParams,
44
InsertMutationFnParams,
55
OperationType,
6-
ResolveInsertInput,
6+
ResolveInput,
77
ResolveType,
88
SyncConfig,
99
UpdateMutationFnParams,
@@ -52,7 +52,7 @@ export interface LocalOnlyCollectionConfig<
5252
*/
5353
onInsert?: (
5454
params: InsertMutationFnParams<
55-
ResolveInsertInput<TExplicit, TSchema, TFallback>,
55+
ResolveInput<TExplicit, TSchema, TFallback>,
5656
TKey,
5757
LocalOnlyCollectionUtils
5858
>
@@ -147,12 +147,12 @@ export function localOnlyCollectionOptions<
147147
ResolveType<TExplicit, TSchema, TFallback>,
148148
TKey,
149149
TSchema,
150-
ResolveInsertInput<TExplicit, TSchema, TFallback>
150+
ResolveInput<TExplicit, TSchema, TFallback>
151151
> & {
152152
utils: LocalOnlyCollectionUtils
153153
} {
154154
type TItem = ResolveType<TExplicit, TSchema, TFallback>
155-
type TInsertInput = ResolveInsertInput<TExplicit, TSchema, TFallback>
155+
type TInsertInput = ResolveInput<TExplicit, TSchema, TFallback>
156156

157157
const { initialData, onInsert, onUpdate, onDelete, ...restConfig } = config
158158

packages/db/src/local-storage.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type {
1111
DeleteMutationFnParams,
1212
InsertMutationFn,
1313
InsertMutationFnParams,
14-
ResolveInsertInput,
14+
ResolveInput,
1515
ResolveType,
1616
SyncConfig,
1717
UpdateMutationFnParams,
@@ -92,13 +92,13 @@ export interface LocalStorageCollectionConfig<
9292
ResolveType<TExplicit, TSchema, TFallback>,
9393
TKey,
9494
TSchema,
95-
ResolveInsertInput<TExplicit, TSchema, TFallback>
95+
ResolveInput<TExplicit, TSchema, TFallback>
9696
>[`getKey`]
9797
sync?: CollectionConfig<
9898
ResolveType<TExplicit, TSchema, TFallback>,
9999
TKey,
100100
TSchema,
101-
ResolveInsertInput<TExplicit, TSchema, TFallback>
101+
ResolveInput<TExplicit, TSchema, TFallback>
102102
>[`sync`]
103103

104104
/**
@@ -108,7 +108,7 @@ export interface LocalStorageCollectionConfig<
108108
*/
109109
onInsert?: (
110110
params: InsertMutationFnParams<
111-
ResolveInsertInput<TExplicit, TSchema, TFallback>,
111+
ResolveInput<TExplicit, TSchema, TFallback>,
112112
TKey
113113
>
114114
) => Promise<any>
@@ -236,15 +236,15 @@ export function localStorageCollectionOptions<
236236
ResolveType<TExplicit, TSchema, TFallback>,
237237
TKey,
238238
TSchema,
239-
ResolveInsertInput<TExplicit, TSchema, TFallback>
239+
ResolveInput<TExplicit, TSchema, TFallback>
240240
>,
241241
`id`
242242
> & {
243243
id: string
244244
utils: LocalStorageCollectionUtils
245245
} {
246246
type TItem = ResolveType<TExplicit, TSchema, TFallback>
247-
type TInsertInput = ResolveInsertInput<TExplicit, TSchema, TFallback>
247+
type TInsertInput = ResolveInput<TExplicit, TSchema, TFallback>
248248

249249
// Validate required parameters
250250
if (!config.storageKey) {

packages/db/src/types.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@ export type InferSchemaInput<T> = T extends StandardSchemaV1
2929
: Record<string, unknown>
3030

3131
/**
32-
* Helper type to determine the insert input type
32+
* Helper type to determine the input type for insert and update operations
3333
* This takes the raw generics (TExplicit, TSchema, TFallback) instead of the resolved T.
3434
*
3535
* Priority:
3636
* 1. Explicit generic TExplicit (if not 'unknown')
3737
* 2. Schema input type (if schema provided)
3838
* 3. Fallback type TFallback
3939
*
40-
* @internal This is used for collection insert type inference
40+
* @internal This is used for collection insert and update type inference
4141
*/
42-
export type ResolveInsertInput<
42+
export type ResolveInput<
4343
TExplicit = unknown,
4444
TSchema extends StandardSchemaV1 = never,
4545
TFallback extends object = Record<string, unknown>,
@@ -350,7 +350,7 @@ export interface CollectionConfig<
350350
T extends object = Record<string, unknown>,
351351
TKey extends string | number = string | number,
352352
TSchema extends StandardSchemaV1 = StandardSchemaV1,
353-
TInsertInput extends object = T,
353+
_TInput extends object = T,
354354
> {
355355
// If an id isn't passed in, a UUID will be
356356
// generated for it.
@@ -438,7 +438,7 @@ export interface CollectionConfig<
438438
* })
439439
* }
440440
*/
441-
onInsert?: InsertMutationFn<TInsertInput, TKey>
441+
onInsert?: InsertMutationFn<T, TKey>
442442

443443
/**
444444
* Optional asynchronous handler function called before an update operation

0 commit comments

Comments
 (0)