mobx-keystone 1.20.0 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +864 -853
  2. package/README.md +61 -61
  3. package/dist/mobx-keystone.esm.js +11336 -11148
  4. package/dist/mobx-keystone.esm.mjs +11336 -11148
  5. package/dist/mobx-keystone.umd.js +12229 -11738
  6. package/dist/types/actionMiddlewares/undoMiddleware.d.ts +1 -1
  7. package/dist/types/modelShared/prop.d.ts +5 -0
  8. package/dist/types/redux/connectReduxDevTools.d.ts +17 -4
  9. package/dist/types/ref/Ref.d.ts +1 -1
  10. package/dist/types/treeUtils/sandbox.d.ts +1 -1
  11. package/dist/types/types/TypeChecker.d.ts +1 -1
  12. package/dist/types/types/arrayBased/typesArray.d.ts +1 -1
  13. package/dist/types/types/arrayBased/typesTuple.d.ts +1 -1
  14. package/dist/types/types/objectBased/typesArraySet.d.ts +1 -1
  15. package/dist/types/types/objectBased/typesDataModelData.d.ts +1 -1
  16. package/dist/types/types/objectBased/typesModel.d.ts +1 -1
  17. package/dist/types/types/objectBased/typesObject.d.ts +3 -3
  18. package/dist/types/types/objectBased/typesObjectMap.d.ts +1 -1
  19. package/dist/types/types/objectBased/typesRecord.d.ts +1 -1
  20. package/dist/types/types/primitiveBased/typesPrimitive.d.ts +1 -1
  21. package/dist/types/types/types.d.ts +3 -3
  22. package/dist/types/types/utility/typesCodec.d.ts +1 -6
  23. package/dist/types/types/utility/typesCodecCore.d.ts +1 -1
  24. package/dist/types/types/utility/typesOr.d.ts +1 -1
  25. package/dist/types/types/utility/typesRefinement.d.ts +1 -1
  26. package/dist/types/types/utility/typesSkipCheck.d.ts +1 -1
  27. package/dist/types/types/utility/typesTag.d.ts +1 -1
  28. package/dist/types/wrappers/ObjectMap.d.ts +2 -0
  29. package/dist/types/wrappers/asMap.d.ts +10 -6
  30. package/package.json +14 -12
  31. package/src/action/applyAction.ts +125 -114
  32. package/src/action/applyMethodCall.ts +37 -37
  33. package/src/action/isModelAction.ts +16 -16
  34. package/src/action/middleware.ts +137 -137
  35. package/src/action/modelFlow.ts +240 -240
  36. package/src/action/modelFlowPromiseGenerator.ts +127 -125
  37. package/src/action/pendingActions.ts +42 -42
  38. package/src/action/wrapInAction.ts +156 -156
  39. package/src/actionMiddlewares/actionSerialization/actionSerialization.ts +1 -1
  40. package/src/actionMiddlewares/actionSerialization/applySerializedAction.ts +172 -172
  41. package/src/actionMiddlewares/actionSerialization/arraySerializer.ts +20 -20
  42. package/src/actionMiddlewares/actionSerialization/dateSerializer.ts +17 -17
  43. package/src/actionMiddlewares/actionSerialization/mapSerializer.ts +42 -42
  44. package/src/actionMiddlewares/actionSerialization/objectPathSerializer.ts +50 -50
  45. package/src/actionMiddlewares/actionSerialization/objectSnapshotSerializer.ts +21 -21
  46. package/src/actionMiddlewares/actionSerialization/plainObjectSerializer.ts +24 -32
  47. package/src/actionMiddlewares/actionSerialization/primitiveSerializer.ts +51 -51
  48. package/src/actionMiddlewares/actionSerialization/setSerializer.ts +37 -37
  49. package/src/actionMiddlewares/actionTrackingMiddleware.ts +3 -3
  50. package/src/actionMiddlewares/onActionMiddleware.ts +2 -2
  51. package/src/actionMiddlewares/readonlyMiddleware.ts +2 -2
  52. package/src/actionMiddlewares/transactionMiddleware.ts +4 -4
  53. package/src/actionMiddlewares/undoMiddleware.ts +804 -796
  54. package/src/actionMiddlewares/utils.ts +2 -2
  55. package/src/computedTree/computedTree.ts +143 -143
  56. package/src/context/context.ts +1 -1
  57. package/src/dataModel/BaseDataModel.ts +194 -192
  58. package/src/dataModel/actions.ts +1 -1
  59. package/src/dataModel/newDataModel.ts +57 -57
  60. package/src/deepChange/index.ts +1 -1
  61. package/src/deepChange/onDeepChange.ts +244 -244
  62. package/src/frozen/Frozen.ts +146 -146
  63. package/src/globalConfig/globalConfig.ts +107 -107
  64. package/src/index.ts +24 -24
  65. package/src/model/BaseModel.ts +275 -273
  66. package/src/model/ModelConstructorOptions.ts +15 -15
  67. package/src/model/getModelMetadata.ts +51 -51
  68. package/src/model/index.ts +6 -6
  69. package/src/model/mixins.ts +288 -288
  70. package/src/model/newModel.ts +301 -301
  71. package/src/model/utils.ts +249 -249
  72. package/src/modelShared/modelDecorator.ts +260 -253
  73. package/src/modelShared/modelInfo.ts +50 -50
  74. package/src/modelShared/modelSymbols.ts +3 -3
  75. package/src/modelShared/newModel.ts +25 -25
  76. package/src/modelShared/prop.ts +713 -684
  77. package/src/modelShared/sharedInternalModel.ts +427 -417
  78. package/src/modelShared/utils.ts +24 -24
  79. package/src/parent/core.ts +65 -65
  80. package/src/parent/coreObjectChildren.ts +180 -180
  81. package/src/parent/detach.ts +47 -47
  82. package/src/parent/findParent.ts +1 -1
  83. package/src/parent/getChildrenObjects.ts +25 -25
  84. package/src/parent/path.ts +386 -381
  85. package/src/parent/setParent.ts +149 -149
  86. package/src/parent/walkTree.ts +1 -1
  87. package/src/patch/applyPatches.ts +187 -187
  88. package/src/patch/jsonPatch.ts +108 -108
  89. package/src/patch/patchRecorder.ts +6 -1
  90. package/src/redux/connectReduxDevTools.ts +39 -7
  91. package/src/redux/redux.ts +6 -2
  92. package/src/ref/Ref.ts +1 -1
  93. package/src/ref/core.ts +339 -345
  94. package/src/ref/customRef.ts +3 -3
  95. package/src/ref/rootRef.ts +100 -100
  96. package/src/rootStore/attachDetach.ts +89 -89
  97. package/src/rootStore/rootStore.ts +1 -1
  98. package/src/snapshot/SnapshotOf.ts +104 -104
  99. package/src/snapshot/SnapshotProcessingError.ts +45 -45
  100. package/src/snapshot/applySnapshot.ts +177 -181
  101. package/src/snapshot/cloneTreeValue.ts +30 -30
  102. package/src/snapshot/fromArraySnapshot.ts +27 -33
  103. package/src/snapshot/fromModelSnapshot.ts +70 -70
  104. package/src/snapshot/fromPlainObjectSnapshot.ts +47 -42
  105. package/src/snapshot/fromSnapshot.ts +198 -198
  106. package/src/snapshot/getSnapshot.ts +80 -79
  107. package/src/snapshot/index.ts +8 -8
  108. package/src/snapshot/internal.ts +230 -230
  109. package/src/snapshot/reconcileArraySnapshot.ts +70 -70
  110. package/src/snapshot/reconcileModelSnapshot.ts +155 -150
  111. package/src/snapshot/reconcilePlainObjectSnapshot.ts +72 -72
  112. package/src/snapshot/reconcileSnapshot.ts +88 -88
  113. package/src/standardActions/actions.ts +64 -64
  114. package/src/standardActions/objectActions.ts +60 -60
  115. package/src/transforms/ImmutableDate.ts +93 -93
  116. package/src/transforms/asMap.ts +50 -50
  117. package/src/transforms/asSet.ts +22 -22
  118. package/src/transforms/bigint.ts +20 -20
  119. package/src/transforms/date.ts +40 -40
  120. package/src/treeUtils/deepEquals.ts +55 -55
  121. package/src/treeUtils/sandbox.ts +6 -3
  122. package/src/tweaker/TweakerPriority.ts +9 -9
  123. package/src/tweaker/tweak.ts +4 -3
  124. package/src/tweaker/tweakArray.ts +530 -475
  125. package/src/tweaker/tweakFrozen.ts +42 -42
  126. package/src/tweaker/tweakModel.ts +1 -1
  127. package/src/tweaker/tweakPlainObject.ts +355 -355
  128. package/src/tweaker/typeChecking.ts +101 -101
  129. package/src/types/SnapshotTypeMismatchError.ts +46 -46
  130. package/src/types/TypeCheckError.ts +183 -184
  131. package/src/types/TypeChecker.ts +202 -185
  132. package/src/types/arrayBased/typesArray.ts +136 -137
  133. package/src/types/arrayBased/typesTuple.ts +138 -139
  134. package/src/types/createPerEntryCachedCheck.ts +166 -160
  135. package/src/types/index.ts +6 -6
  136. package/src/types/objectBased/typesArraySet.ts +133 -134
  137. package/src/types/objectBased/typesDataModelData.ts +203 -204
  138. package/src/types/objectBased/typesModel.ts +220 -221
  139. package/src/types/objectBased/typesObject.ts +308 -310
  140. package/src/types/objectBased/typesObjectMap.ts +142 -143
  141. package/src/types/objectBased/typesRecord.ts +156 -157
  142. package/src/types/objectBased/typesRef.ts +89 -89
  143. package/src/types/primitiveBased/typesEnum.ts +63 -63
  144. package/src/types/primitiveBased/typesPrimitive.ts +219 -220
  145. package/src/types/registerDefaultStandardTypeResolvers.ts +21 -21
  146. package/src/types/resolveTypeChecker.ts +78 -78
  147. package/src/types/schemas.ts +208 -208
  148. package/src/types/tProp.ts +277 -268
  149. package/src/types/typeCheck.ts +21 -21
  150. package/src/types/typeCheckErrorUtils.ts +23 -23
  151. package/src/types/types.ts +142 -142
  152. package/src/types/utility/typeToStoredData.ts +37 -37
  153. package/src/types/utility/typesBigInt.ts +15 -15
  154. package/src/types/utility/typesCodec.ts +41 -38
  155. package/src/types/utility/typesCodecCore.ts +178 -178
  156. package/src/types/utility/typesCodecSupport.ts +806 -806
  157. package/src/types/utility/typesDate.ts +27 -27
  158. package/src/types/utility/typesMap.ts +253 -222
  159. package/src/types/utility/typesOr.ts +263 -259
  160. package/src/types/utility/typesRefinement.ts +131 -125
  161. package/src/types/utility/typesSet.ts +110 -110
  162. package/src/types/utility/typesSkipCheck.ts +69 -70
  163. package/src/types/utility/typesTag.ts +88 -82
  164. package/src/types/utility/typesUnchecked.ts +40 -40
  165. package/src/utils/AnyFunction.ts +4 -4
  166. package/src/utils/ModelPool.ts +59 -59
  167. package/src/utils/chainFns.ts +18 -18
  168. package/src/utils/decorators.ts +274 -274
  169. package/src/utils/errorDiagnostics.ts +204 -204
  170. package/src/utils/index.ts +443 -372
  171. package/src/wrappers/ArraySet.ts +156 -156
  172. package/src/wrappers/ObjectMap.ts +155 -136
  173. package/src/wrappers/asMap.ts +65 -30
  174. package/src/wrappers/asSet.ts +3 -3
@@ -1,88 +1,88 @@
1
- import { set } from "mobx"
2
- import { modelIdKey, modelTypeKey } from "../model/metadata"
3
- import { isModel } from "../model/utils"
4
- import { fastGetParentPathIncludingDataObjects } from "../parent"
5
- import { isMap, isPrimitive, isSet } from "../utils"
6
- import type { ModelPool } from "../utils/ModelPool"
7
- import { getSnapshot } from "./getSnapshot"
8
- import { registerDefaultReconcilers } from "./registerDefaultReconcilers"
9
- import { SnapshotProcessingError } from "./SnapshotProcessingError"
10
-
11
- type Reconciler = (value: any, sn: any, modelPool: ModelPool, parent: any) => any
12
-
13
- const reconcilers: { priority: number; reconciler: Reconciler }[] = []
14
-
15
- /**
16
- * @internal
17
- */
18
- export function registerReconciler(priority: number, reconciler: Reconciler): void {
19
- reconcilers.push({ priority, reconciler })
20
- reconcilers.sort((a, b) => a.priority - b.priority)
21
- }
22
-
23
- /**
24
- * @internal
25
- */
26
- export function reconcileSnapshot(value: any, sn: any, modelPool: ModelPool, parent: any): any {
27
- if (isPrimitive(sn)) {
28
- return sn
29
- }
30
-
31
- // if the snapshot passed is exactly the same as the current one
32
- // then it is already reconciled
33
- if (getSnapshot(value) === sn) {
34
- return value
35
- }
36
-
37
- registerDefaultReconcilers()
38
-
39
- const reconcilersLen = reconcilers.length
40
- for (let i = 0; i < reconcilersLen; i++) {
41
- const { reconciler } = reconcilers[i]
42
- const ret = reconciler(value, sn, modelPool, parent)
43
- if (ret !== undefined) {
44
- return ret
45
- }
46
- }
47
-
48
- if (isMap(sn)) {
49
- throw new SnapshotProcessingError({
50
- message: "a snapshot must not contain maps",
51
- actualSnapshot: sn,
52
- })
53
- }
54
-
55
- if (isSet(sn)) {
56
- throw new SnapshotProcessingError({
57
- message: "a snapshot must not contain sets",
58
- actualSnapshot: sn,
59
- })
60
- }
61
-
62
- throw new SnapshotProcessingError({
63
- message: "unsupported snapshot",
64
- actualSnapshot: sn,
65
- })
66
- }
67
-
68
- /**
69
- * @internal
70
- */
71
- export function detachIfNeeded(newValue: any, oldValue: any, modelPool: ModelPool) {
72
- // edge case for when we are swapping models around the tree
73
-
74
- if (newValue === oldValue) {
75
- // already where it should be
76
- return
77
- }
78
-
79
- if (
80
- isModel(newValue) &&
81
- modelPool.findModelByTypeAndId(newValue[modelTypeKey], newValue[modelIdKey])
82
- ) {
83
- const parentPath = fastGetParentPathIncludingDataObjects(newValue, false)
84
- if (parentPath) {
85
- set(parentPath.parent, parentPath.path, null)
86
- }
87
- }
88
- }
1
+ import { set } from "mobx"
2
+ import { modelIdKey, modelTypeKey } from "../model/metadata"
3
+ import { isModel } from "../model/utils"
4
+ import { fastGetParentPathIncludingDataObjects } from "../parent"
5
+ import { isMap, isPrimitive, isSet } from "../utils"
6
+ import type { ModelPool } from "../utils/ModelPool"
7
+ import { getSnapshot } from "./getSnapshot"
8
+ import { registerDefaultReconcilers } from "./registerDefaultReconcilers"
9
+ import { SnapshotProcessingError } from "./SnapshotProcessingError"
10
+
11
+ type Reconciler = (value: any, sn: any, modelPool: ModelPool, parent: any) => any
12
+
13
+ const reconcilers: { priority: number; reconciler: Reconciler }[] = []
14
+
15
+ /**
16
+ * @internal
17
+ */
18
+ export function registerReconciler(priority: number, reconciler: Reconciler): void {
19
+ reconcilers.push({ priority, reconciler })
20
+ reconcilers.sort((a, b) => a.priority - b.priority)
21
+ }
22
+
23
+ /**
24
+ * @internal
25
+ */
26
+ export function reconcileSnapshot(value: any, sn: any, modelPool: ModelPool, parent: any): any {
27
+ if (isPrimitive(sn)) {
28
+ return sn
29
+ }
30
+
31
+ // if the snapshot passed is exactly the same as the current one
32
+ // then it is already reconciled
33
+ if (getSnapshot(value) === sn) {
34
+ return value
35
+ }
36
+
37
+ registerDefaultReconcilers()
38
+
39
+ const reconcilersLen = reconcilers.length
40
+ for (let i = 0; i < reconcilersLen; i++) {
41
+ const { reconciler } = reconcilers[i]
42
+ const ret = reconciler(value, sn, modelPool, parent)
43
+ if (ret !== undefined) {
44
+ return ret
45
+ }
46
+ }
47
+
48
+ if (isMap(sn)) {
49
+ throw new SnapshotProcessingError({
50
+ message: "a snapshot must not contain maps",
51
+ actualSnapshot: sn,
52
+ })
53
+ }
54
+
55
+ if (isSet(sn)) {
56
+ throw new SnapshotProcessingError({
57
+ message: "a snapshot must not contain sets",
58
+ actualSnapshot: sn,
59
+ })
60
+ }
61
+
62
+ throw new SnapshotProcessingError({
63
+ message: "unsupported snapshot",
64
+ actualSnapshot: sn,
65
+ })
66
+ }
67
+
68
+ /**
69
+ * @internal
70
+ */
71
+ export function detachIfNeeded(newValue: any, oldValue: any, modelPool: ModelPool) {
72
+ // edge case for when we are swapping models around the tree
73
+
74
+ if (newValue === oldValue) {
75
+ // already where it should be
76
+ return
77
+ }
78
+
79
+ if (
80
+ isModel(newValue) &&
81
+ modelPool.findModelByTypeAndId(newValue[modelTypeKey], newValue[modelIdKey])
82
+ ) {
83
+ const parentPath = fastGetParentPathIncludingDataObjects(newValue, false)
84
+ if (parentPath) {
85
+ set(parentPath.parent, parentPath.path, null)
86
+ }
87
+ }
88
+ }
@@ -1,64 +1,64 @@
1
- import { ActionContextActionType } from "../action/context"
2
- import { isModelAction } from "../action/isModelAction"
3
- import { flow, isModelFlow } from "../action/modelFlow"
4
- import { wrapInAction } from "../action/wrapInAction"
5
- import { assertIsTreeNode } from "../tweaker/core"
6
- import { assertIsFunction, failure, logWarning } from "../utils"
7
- import { AnyFunction } from "../utils/AnyFunction"
8
- import { copyFunctionMetadata } from "../utils/decorators"
9
-
10
- /**
11
- * A function with an object as target.
12
- */
13
- type TargetedAction = AnyFunction
14
-
15
- const standaloneActionRegistry = new Map<string, TargetedAction>()
16
-
17
- /**
18
- * @internal
19
- */
20
- export function getStandaloneAction(actionName: string) {
21
- return standaloneActionRegistry.get(actionName)
22
- }
23
-
24
- /**
25
- * @internal
26
- */
27
- export function addStandaloneAction(fullActionName: string, fn: TargetedAction, isFlow: boolean) {
28
- assertIsFunction(fn, fullActionName)
29
-
30
- if (standaloneActionRegistry.has(fullActionName)) {
31
- logWarning(
32
- "warn",
33
- `an standalone action with name "${fullActionName}" already exists (if you are using hot-reloading you may safely ignore this warning)`,
34
- `duplicateActionName - ${fullActionName}`
35
- )
36
- }
37
-
38
- if (isModelAction(fn)) {
39
- throw failure("the standalone action must not be previously marked as an action")
40
- }
41
- if (isModelFlow(fn)) {
42
- throw failure("the standalone action must not be previously marked as a flow action")
43
- }
44
-
45
- const wrappedAction = isFlow
46
- ? flow({ nameOrNameFn: fullActionName, generator: fn })
47
- : wrapInAction({
48
- nameOrNameFn: fullActionName,
49
- fn,
50
- actionType: ActionContextActionType.Sync,
51
- })
52
-
53
- const finalAction = (target: any, ...args: any[]) => {
54
- assertIsTreeNode(target, "target")
55
-
56
- // we need to put the target into this
57
- return wrappedAction.call(target, target, ...args)
58
- }
59
- // preserve user-provided metadata without leaking internal action/flow markers.
60
- copyFunctionMetadata(fn, finalAction)
61
-
62
- standaloneActionRegistry.set(fullActionName, finalAction)
63
- return finalAction
64
- }
1
+ import { ActionContextActionType } from "../action/context"
2
+ import { isModelAction } from "../action/isModelAction"
3
+ import { flow, isModelFlow } from "../action/modelFlow"
4
+ import { wrapInAction } from "../action/wrapInAction"
5
+ import { assertIsTreeNode } from "../tweaker/core"
6
+ import { assertIsFunction, failure, logWarning } from "../utils"
7
+ import type { AnyFunction } from "../utils/AnyFunction"
8
+ import { copyFunctionMetadata } from "../utils/decorators"
9
+
10
+ /**
11
+ * A function with an object as target.
12
+ */
13
+ type TargetedAction = AnyFunction
14
+
15
+ const standaloneActionRegistry = new Map<string, TargetedAction>()
16
+
17
+ /**
18
+ * @internal
19
+ */
20
+ export function getStandaloneAction(actionName: string) {
21
+ return standaloneActionRegistry.get(actionName)
22
+ }
23
+
24
+ /**
25
+ * @internal
26
+ */
27
+ export function addStandaloneAction(fullActionName: string, fn: TargetedAction, isFlow: boolean) {
28
+ assertIsFunction(fn, fullActionName)
29
+
30
+ if (standaloneActionRegistry.has(fullActionName)) {
31
+ logWarning(
32
+ "warn",
33
+ `an standalone action with name "${fullActionName}" already exists (if you are using hot-reloading you may safely ignore this warning)`,
34
+ `duplicateActionName - ${fullActionName}`
35
+ )
36
+ }
37
+
38
+ if (isModelAction(fn)) {
39
+ throw failure("the standalone action must not be previously marked as an action")
40
+ }
41
+ if (isModelFlow(fn)) {
42
+ throw failure("the standalone action must not be previously marked as a flow action")
43
+ }
44
+
45
+ const wrappedAction = isFlow
46
+ ? flow({ nameOrNameFn: fullActionName, generator: fn })
47
+ : wrapInAction({
48
+ nameOrNameFn: fullActionName,
49
+ fn,
50
+ actionType: ActionContextActionType.Sync,
51
+ })
52
+
53
+ const finalAction = (target: any, ...args: any[]) => {
54
+ assertIsTreeNode(target, "target")
55
+
56
+ // we need to put the target into this
57
+ return wrappedAction.call(target, target, ...args)
58
+ }
59
+ // preserve user-provided metadata without leaking internal action/flow markers.
60
+ copyFunctionMetadata(fn, finalAction)
61
+
62
+ standaloneActionRegistry.set(fullActionName, finalAction)
63
+ return finalAction
64
+ }
@@ -1,60 +1,60 @@
1
- import { isObservable, remove } from "mobx"
2
- import { toTreeNode } from "../tweaker/tweak"
3
- import { assertIsObject, namespace as ns } from "../utils"
4
- import { setIfDifferent } from "../utils/setIfDifferent"
5
- import { standaloneAction } from "./standaloneActions"
6
- import { AnyFunction } from "../utils/AnyFunction"
7
-
8
- const namespace = `${ns}/objectActions`
9
-
10
- export const objectActions = {
11
- set: standaloneAction(
12
- `${namespace}::set`,
13
- <T extends object, K extends keyof T>(target: T, key: K, value: T[K]): void => {
14
- if (isObservable(target)) {
15
- setIfDifferent(target, key, value)
16
- } else {
17
- target[key] = value
18
- }
19
- }
20
- ),
21
-
22
- assign: standaloneAction(
23
- `${namespace}::assign`,
24
- <T extends object>(target: T, partialObject: Partial<T>): void => {
25
- assertIsObject(partialObject, "partialObject")
26
- const keys = Object.keys(partialObject)
27
-
28
- if (isObservable(target)) {
29
- for (const key of keys) {
30
- const newValue = (partialObject as any)[key]
31
- setIfDifferent(target, key, newValue)
32
- }
33
- } else {
34
- for (const key of keys) {
35
- ;(target as any)[key] = (partialObject as any)[key]
36
- }
37
- }
38
- }
39
- ),
40
-
41
- delete: standaloneAction(
42
- `${namespace}::delete`,
43
- <T extends object, K extends keyof T>(target: T, key: K): boolean => {
44
- return remove(target, key as any)
45
- }
46
- ),
47
-
48
- call: standaloneAction(
49
- `${namespace}::call`,
50
- <T extends object, K extends keyof T>(
51
- target: T,
52
- methodName: K,
53
- ...args: T[K] extends AnyFunction ? Parameters<T[K]> : never
54
- ): T[K] extends AnyFunction ? ReturnType<T[K]> : never => {
55
- return (target as any)[methodName](...args)
56
- }
57
- ),
58
-
59
- create: <T extends object>(data: T): T => toTreeNode(data),
60
- }
1
+ import { isObservable, remove } from "mobx"
2
+ import { toTreeNode } from "../tweaker/tweak"
3
+ import { assertIsObject, namespace as ns } from "../utils"
4
+ import type { AnyFunction } from "../utils/AnyFunction"
5
+ import { setIfDifferent } from "../utils/setIfDifferent"
6
+ import { standaloneAction } from "./standaloneActions"
7
+
8
+ const namespace = `${ns}/objectActions`
9
+
10
+ export const objectActions = {
11
+ set: standaloneAction(
12
+ `${namespace}::set`,
13
+ <T extends object, K extends keyof T>(target: T, key: K, value: T[K]): void => {
14
+ if (isObservable(target)) {
15
+ setIfDifferent(target, key, value)
16
+ } else {
17
+ target[key] = value
18
+ }
19
+ }
20
+ ),
21
+
22
+ assign: standaloneAction(
23
+ `${namespace}::assign`,
24
+ <T extends object>(target: T, partialObject: Partial<T>): void => {
25
+ assertIsObject(partialObject, "partialObject")
26
+ const keys = Object.keys(partialObject)
27
+
28
+ if (isObservable(target)) {
29
+ for (const key of keys) {
30
+ const newValue = (partialObject as any)[key]
31
+ setIfDifferent(target, key, newValue)
32
+ }
33
+ } else {
34
+ for (const key of keys) {
35
+ ;(target as any)[key] = (partialObject as any)[key]
36
+ }
37
+ }
38
+ }
39
+ ),
40
+
41
+ delete: standaloneAction(
42
+ `${namespace}::delete`,
43
+ <T extends object, K extends keyof T>(target: T, key: K): boolean => {
44
+ return remove(target, key as any)
45
+ }
46
+ ),
47
+
48
+ call: standaloneAction(
49
+ `${namespace}::call`,
50
+ <T extends object, K extends keyof T>(
51
+ target: T,
52
+ methodName: K,
53
+ ...args: T[K] extends AnyFunction ? Parameters<T[K]> : never
54
+ ): T[K] extends AnyFunction ? ReturnType<T[K]> : never => {
55
+ return (target as any)[methodName](...args)
56
+ }
57
+ ),
58
+
59
+ create: <T extends object>(data: T): T => toTreeNode(data),
60
+ }
@@ -1,93 +1,93 @@
1
- import { failure } from "../utils"
2
-
3
- /**
4
- * @internal
5
- */
6
- export interface ImmutableDate
7
- extends Omit<
8
- Date,
9
- | "setTime"
10
- | "setMilliseconds"
11
- | "setUTCMilliseconds"
12
- | "setSeconds"
13
- | "setUTCSeconds"
14
- | "setMinutes"
15
- | "setUTCMinutes"
16
- | "setHours"
17
- | "setUTCHours"
18
- | "setDate"
19
- | "setUTCDate"
20
- | "setMonth"
21
- | "setUTCMonth"
22
- | "setFullYear"
23
- | "setUTCFullYear"
24
- > {}
25
-
26
- const errMessage = "this Date object is immutable"
27
-
28
- /**
29
- * @internal
30
- */
31
- export class ImmutableDate extends Date {
32
- // disable mutable methods
33
-
34
- setTime(): any {
35
- throw failure(errMessage)
36
- }
37
-
38
- setMilliseconds(): any {
39
- throw failure(errMessage)
40
- }
41
-
42
- setUTCMilliseconds(): any {
43
- throw failure(errMessage)
44
- }
45
-
46
- setSeconds(): any {
47
- throw failure(errMessage)
48
- }
49
-
50
- setUTCSeconds(): any {
51
- throw failure(errMessage)
52
- }
53
-
54
- setMinutes(): any {
55
- throw failure(errMessage)
56
- }
57
-
58
- setUTCMinutes(): any {
59
- throw failure(errMessage)
60
- }
61
-
62
- setHours(): any {
63
- throw failure(errMessage)
64
- }
65
-
66
- setUTCHours(): any {
67
- throw failure(errMessage)
68
- }
69
-
70
- setDate(): any {
71
- throw failure(errMessage)
72
- }
73
-
74
- setUTCDate(): any {
75
- throw failure(errMessage)
76
- }
77
-
78
- setMonth(): any {
79
- throw failure(errMessage)
80
- }
81
-
82
- setUTCMonth(): any {
83
- throw failure(errMessage)
84
- }
85
-
86
- setFullYear(): any {
87
- throw failure(errMessage)
88
- }
89
-
90
- setUTCFullYear(): any {
91
- throw failure(errMessage)
92
- }
93
- }
1
+ import { failure } from "../utils"
2
+
3
+ /**
4
+ * @internal
5
+ */
6
+ export interface ImmutableDate
7
+ extends Omit<
8
+ Date,
9
+ | "setTime"
10
+ | "setMilliseconds"
11
+ | "setUTCMilliseconds"
12
+ | "setSeconds"
13
+ | "setUTCSeconds"
14
+ | "setMinutes"
15
+ | "setUTCMinutes"
16
+ | "setHours"
17
+ | "setUTCHours"
18
+ | "setDate"
19
+ | "setUTCDate"
20
+ | "setMonth"
21
+ | "setUTCMonth"
22
+ | "setFullYear"
23
+ | "setUTCFullYear"
24
+ > {}
25
+
26
+ const errMessage = "this Date object is immutable"
27
+
28
+ /**
29
+ * @internal
30
+ */
31
+ export class ImmutableDate extends Date {
32
+ // disable mutable methods
33
+
34
+ setTime(): any {
35
+ throw failure(errMessage)
36
+ }
37
+
38
+ setMilliseconds(): any {
39
+ throw failure(errMessage)
40
+ }
41
+
42
+ setUTCMilliseconds(): any {
43
+ throw failure(errMessage)
44
+ }
45
+
46
+ setSeconds(): any {
47
+ throw failure(errMessage)
48
+ }
49
+
50
+ setUTCSeconds(): any {
51
+ throw failure(errMessage)
52
+ }
53
+
54
+ setMinutes(): any {
55
+ throw failure(errMessage)
56
+ }
57
+
58
+ setUTCMinutes(): any {
59
+ throw failure(errMessage)
60
+ }
61
+
62
+ setHours(): any {
63
+ throw failure(errMessage)
64
+ }
65
+
66
+ setUTCHours(): any {
67
+ throw failure(errMessage)
68
+ }
69
+
70
+ setDate(): any {
71
+ throw failure(errMessage)
72
+ }
73
+
74
+ setUTCDate(): any {
75
+ throw failure(errMessage)
76
+ }
77
+
78
+ setMonth(): any {
79
+ throw failure(errMessage)
80
+ }
81
+
82
+ setUTCMonth(): any {
83
+ throw failure(errMessage)
84
+ }
85
+
86
+ setFullYear(): any {
87
+ throw failure(errMessage)
88
+ }
89
+
90
+ setUTCFullYear(): any {
91
+ throw failure(errMessage)
92
+ }
93
+ }