Skip to content

Commit db41348

Browse files
committed
feat: record module mutations in the mutation history
This will be useful in the future for mutation replay/sync engines
1 parent 757d48a commit db41348

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

packages/core/src/module.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,16 @@ export function createModule<
4545
$callbacks.push(cb)
4646
}
4747

48+
/**
49+
* Allow looking up the exposed mutations.
50+
*/
51+
let _exposed: Record<string, any> = {}
52+
4853
return {
4954
...module,
5055
state,
5156
resolve(exposed: any) {
57+
_exposed = exposed
5258
const resolved: ResolvedModule<any, any> & {
5359
$callbacks: ResolveCallbacks
5460
} = {
@@ -66,6 +72,20 @@ export function createModule<
6672
},
6773
onResolve,
6874
defineMutation(mutation) {
75+
let key: string | undefined
76+
const originalMutation = mutation
77+
mutation = ((...args: Parameters<typeof mutation>) => {
78+
if (!key) {
79+
key = Object.keys(_exposed).find(k => _exposed[k] === mutation)
80+
}
81+
store.$mutationHistory.push({
82+
operation: 'module-mutation',
83+
module: module.name,
84+
key: key!,
85+
payload: args,
86+
})
87+
return originalMutation(...args)
88+
}) as typeof mutation
6989
mutation = store.$wrapMutation(mutation)
7090
;(mutation as any).__brand = 'rstore-module-mutation'
7191
return mutation as ModuleMutation<typeof mutation>

packages/shared/src/types/module.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* eslint-disable ts/no-unsafe-function-type */
2-
31
import type { MutationSpecialProps } from './mutation'
42
import type { Awaitable, Brand } from './utils'
53

@@ -18,10 +16,10 @@ export type ResolvedModule<
1816
$state: ResolvedModuleState<TModule>
1917
}
2018

21-
export type ModuleMutation<TMutation extends Function> = Brand<TMutation, 'rstore-module-mutation'> & MutationSpecialProps
19+
export type ModuleMutation<TMutation extends (...args: any[]) => unknown> = Brand<TMutation, 'rstore-module-mutation'> & MutationSpecialProps
2220

2321
export type CreateModuleApi<TModule extends Module> = TModule & {
2422
resolve: <const TModuleExposed extends Record<string, any>> (exposed: TModuleExposed) => ResolvedModule<TModule, TModuleExposed>
25-
defineMutation: <const TMutation extends Function> (mutation: TMutation) => ModuleMutation<TMutation>
23+
defineMutation: <const TMutation extends (...args: any[]) => unknown> (mutation: TMutation) => ModuleMutation<TMutation>
2624
onResolve: (cb: () => Awaitable<unknown>) => void
2725
}

packages/shared/src/types/mutation.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ export interface MutationOperation<
66
TModelDefaults extends ModelDefaults,
77
TModelList extends ModelList,
88
> {
9-
operation: 'create' | 'update' | 'delete'
10-
model: ResolvedModel<TModel, TModelDefaults, TModelList>
9+
operation: 'create' | 'update' | 'delete' | 'module-mutation'
10+
model?: ResolvedModel<TModel, TModelDefaults, TModelList>
11+
module?: string
12+
/**
13+
* Either the key of the item in the model or the key of the exposed mutation in the module.
14+
*/
1115
key?: string | number
1216
payload?: Partial<ResolvedModelItem<TModel, TModelDefaults, TModelList>>
1317
}

0 commit comments

Comments
 (0)