UNPKG

17.1 kBTypeScriptView Raw
1import { IAnyStateTreeNode, IType, IAnyModelType, IStateTreeNode, IJsonPatch, IDisposer, IAnyType, ReferenceIdentifier, TypeOfValue, IActionContext, IAnyComplexType } from "../internal";
2/** @hidden */
3export declare type TypeOrStateTreeNodeToStateTreeNode<T extends IAnyType | IAnyStateTreeNode> = T extends IType<any, any, infer TT> ? TT & IStateTreeNode<T> : T;
4/**
5 * Returns the _actual_ type of the given tree node. (Or throws)
6 *
7 * @param object
8 * @returns
9 */
10export declare function getType(object: IAnyStateTreeNode): IAnyComplexType;
11/**
12 * Returns the _declared_ type of the given sub property of an object, array or map.
13 * In the case of arrays and maps the property name is optional and will be ignored.
14 *
15 * Example:
16 * ```ts
17 * const Box = types.model({ x: 0, y: 0 })
18 * const box = Box.create()
19 *
20 * console.log(getChildType(box, "x").name) // 'number'
21 * ```
22 *
23 * @param object
24 * @param propertyName
25 * @returns
26 */
27export declare function getChildType(object: IAnyStateTreeNode, propertyName?: string): IAnyType;
28/**
29 * Registers a function that will be invoked for each mutation that is applied to the provided model instance, or to any of its children.
30 * See [patches](https://github.com/mobxjs/mobx-state-tree#patches) for more details. onPatch events are emitted immediately and will not await the end of a transaction.
31 * Patches can be used to deep observe a model tree.
32 *
33 * @param target the model instance from which to receive patches
34 * @param callback the callback that is invoked for each patch. The reversePatch is a patch that would actually undo the emitted patch
35 * @returns function to remove the listener
36 */
37export declare function onPatch(target: IAnyStateTreeNode, callback: (patch: IJsonPatch, reversePatch: IJsonPatch) => void): IDisposer;
38/**
39 * Registers a function that is invoked whenever a new snapshot for the given model instance is available.
40 * The listener will only be fire at the end of the current MobX (trans)action.
41 * See [snapshots](https://github.com/mobxjs/mobx-state-tree#snapshots) for more details.
42 *
43 * @param target
44 * @param callback
45 * @returns
46 */
47export declare function onSnapshot<S>(target: IStateTreeNode<IType<any, S, any>>, callback: (snapshot: S) => void): IDisposer;
48/**
49 * Applies a JSON-patch to the given model instance or bails out if the patch couldn't be applied
50 * See [patches](https://github.com/mobxjs/mobx-state-tree#patches) for more details.
51 *
52 * Can apply a single past, or an array of patches.
53 *
54 * @param target
55 * @param patch
56 * @returns
57 */
58export declare function applyPatch(target: IAnyStateTreeNode, patch: IJsonPatch | ReadonlyArray<IJsonPatch>): void;
59export interface IPatchRecorder {
60 patches: ReadonlyArray<IJsonPatch>;
61 inversePatches: ReadonlyArray<IJsonPatch>;
62 reversedInversePatches: ReadonlyArray<IJsonPatch>;
63 readonly recording: boolean;
64 stop(): void;
65 resume(): void;
66 replay(target?: IAnyStateTreeNode): void;
67 undo(target?: IAnyStateTreeNode): void;
68}
69/**
70 * Small abstraction around `onPatch` and `applyPatch`, attaches a patch listener to a tree and records all the patches.
71 * Returns an recorder object with the following signature:
72 *
73 * Example:
74 * ```ts
75 * export interface IPatchRecorder {
76 * // the recorded patches
77 * patches: IJsonPatch[]
78 * // the inverse of the recorded patches
79 * inversePatches: IJsonPatch[]
80 * // true if currently recording
81 * recording: boolean
82 * // stop recording patches
83 * stop(): void
84 * // resume recording patches
85 * resume(): void
86 * // apply all the recorded patches on the given target (the original subject if omitted)
87 * replay(target?: IAnyStateTreeNode): void
88 * // reverse apply the recorded patches on the given target (the original subject if omitted)
89 * // stops the recorder if not already stopped
90 * undo(): void
91 * }
92 * ```
93 *
94 * The optional filter function allows to skip recording certain patches.
95 *
96 * @param subject
97 * @param filter
98 * @returns
99 */
100export declare function recordPatches(subject: IAnyStateTreeNode, filter?: (patch: IJsonPatch, inversePatch: IJsonPatch, actionContext: IActionContext | undefined) => boolean): IPatchRecorder;
101/**
102 * The inverse of `unprotect`.
103 *
104 * @param target
105 */
106export declare function protect(target: IAnyStateTreeNode): void;
107/**
108 * By default it is not allowed to directly modify a model. Models can only be modified through actions.
109 * However, in some cases you don't care about the advantages (like replayability, traceability, etc) this yields.
110 * For example because you are building a PoC or don't have any middleware attached to your tree.
111 *
112 * In that case you can disable this protection by calling `unprotect` on the root of your tree.
113 *
114 * Example:
115 * ```ts
116 * const Todo = types.model({
117 * done: false
118 * }).actions(self => ({
119 * toggle() {
120 * self.done = !self.done
121 * }
122 * }))
123 *
124 * const todo = Todo.create()
125 * todo.done = true // throws!
126 * todo.toggle() // OK
127 * unprotect(todo)
128 * todo.done = false // OK
129 * ```
130 */
131export declare function unprotect(target: IAnyStateTreeNode): void;
132/**
133 * Returns true if the object is in protected mode, @see protect
134 */
135export declare function isProtected(target: IAnyStateTreeNode): boolean;
136/**
137 * Applies a snapshot to a given model instances. Patch and snapshot listeners will be invoked as usual.
138 *
139 * @param target
140 * @param snapshot
141 * @returns
142 */
143export declare function applySnapshot<C>(target: IStateTreeNode<IType<C, any, any>>, snapshot: C): void;
144/**
145 * Calculates a snapshot from the given model instance. The snapshot will always reflect the latest state but use
146 * structural sharing where possible. Doesn't require MobX transactions to be completed.
147 *
148 * @param target
149 * @param applyPostProcess If true (the default) then postProcessSnapshot gets applied.
150 * @returns
151 */
152export declare function getSnapshot<S>(target: IStateTreeNode<IType<any, S, any>>, applyPostProcess?: boolean): S;
153/**
154 * Given a model instance, returns `true` if the object has a parent, that is, is part of another object, map or array.
155 *
156 * @param target
157 * @param depth How far should we look upward? 1 by default.
158 * @returns
159 */
160export declare function hasParent(target: IAnyStateTreeNode, depth?: number): boolean;
161/**
162 * Returns the immediate parent of this object, or throws.
163 *
164 * Note that the immediate parent can be either an object, map or array, and
165 * doesn't necessarily refer to the parent model.
166 *
167 * Please note that in child nodes access to the root is only possible
168 * once the `afterAttach` hook has fired.
169 *
170 * @param target
171 * @param depth How far should we look upward? 1 by default.
172 * @returns
173 */
174export declare function getParent<IT extends IAnyStateTreeNode | IAnyComplexType>(target: IAnyStateTreeNode, depth?: number): TypeOrStateTreeNodeToStateTreeNode<IT>;
175/**
176 * Given a model instance, returns `true` if the object has a parent of given type, that is, is part of another object, map or array
177 *
178 * @param target
179 * @param type
180 * @returns
181 */
182export declare function hasParentOfType(target: IAnyStateTreeNode, type: IAnyComplexType): boolean;
183/**
184 * Returns the target's parent of a given type, or throws.
185 *
186 * @param target
187 * @param type
188 * @returns
189 */
190export declare function getParentOfType<IT extends IAnyComplexType>(target: IAnyStateTreeNode, type: IT): IT["Type"];
191/**
192 * Given an object in a model tree, returns the root object of that tree.
193 *
194 * Please note that in child nodes access to the root is only possible
195 * once the `afterAttach` hook has fired.
196 *
197 * @param target
198 * @returns
199 */
200export declare function getRoot<IT extends IAnyComplexType | IAnyStateTreeNode>(target: IAnyStateTreeNode): TypeOrStateTreeNodeToStateTreeNode<IT>;
201/**
202 * Returns the path of the given object in the model tree
203 *
204 * @param target
205 * @returns
206 */
207export declare function getPath(target: IAnyStateTreeNode): string;
208/**
209 * Returns the path of the given object as unescaped string array.
210 *
211 * @param target
212 * @returns
213 */
214export declare function getPathParts(target: IAnyStateTreeNode): string[];
215/**
216 * Returns true if the given object is the root of a model tree.
217 *
218 * @param target
219 * @returns
220 */
221export declare function isRoot(target: IAnyStateTreeNode): boolean;
222/**
223 * Resolves a path relatively to a given object.
224 * Returns undefined if no value can be found.
225 *
226 * @param target
227 * @param path escaped json path
228 * @returns
229 */
230export declare function resolvePath(target: IAnyStateTreeNode, path: string): any;
231/**
232 * Resolves a model instance given a root target, the type and the identifier you are searching for.
233 * Returns undefined if no value can be found.
234 *
235 * @param type
236 * @param target
237 * @param identifier
238 * @returns
239 */
240export declare function resolveIdentifier<IT extends IAnyModelType>(type: IT, target: IAnyStateTreeNode, identifier: ReferenceIdentifier): IT["Type"] | undefined;
241/**
242 * Returns the identifier of the target node.
243 * This is the *string normalized* identifier, which might not match the type of the identifier attribute
244 *
245 * @param target
246 * @returns
247 */
248export declare function getIdentifier(target: IAnyStateTreeNode): string | null;
249/**
250 * Tests if a reference is valid (pointing to an existing node and optionally if alive) and returns such reference if it the check passes,
251 * else it returns undefined.
252 *
253 * @param getter Function to access the reference.
254 * @param checkIfAlive true to also make sure the referenced node is alive (default), false to skip this check.
255 * @returns
256 */
257export declare function tryReference<N extends IAnyStateTreeNode>(getter: () => N | null | undefined, checkIfAlive?: boolean): N | undefined;
258/**
259 * Tests if a reference is valid (pointing to an existing node and optionally if alive) and returns if the check passes or not.
260 *
261 * @param getter Function to access the reference.
262 * @param checkIfAlive true to also make sure the referenced node is alive (default), false to skip this check.
263 * @returns
264 */
265export declare function isValidReference<N extends IAnyStateTreeNode>(getter: () => N | null | undefined, checkIfAlive?: boolean): boolean;
266/**
267 * Try to resolve a given path relative to a given node.
268 *
269 * @param target
270 * @param path
271 * @returns
272 */
273export declare function tryResolve(target: IAnyStateTreeNode, path: string): any;
274/**
275 * Given two state tree nodes that are part of the same tree,
276 * returns the shortest jsonpath needed to navigate from the one to the other
277 *
278 * @param base
279 * @param target
280 * @returns
281 */
282export declare function getRelativePath(base: IAnyStateTreeNode, target: IAnyStateTreeNode): string;
283/**
284 * Returns a deep copy of the given state tree node as new tree.
285 * Short hand for `snapshot(x) = getType(x).create(getSnapshot(x))`
286 *
287 * _Tip: clone will create a literal copy, including the same identifiers. To modify identifiers etc during cloning, don't use clone but take a snapshot of the tree, modify it, and create new instance_
288 *
289 * @param source
290 * @param keepEnvironment indicates whether the clone should inherit the same environment (`true`, the default), or not have an environment (`false`). If an object is passed in as second argument, that will act as the environment for the cloned tree.
291 * @returns
292 */
293export declare function clone<T extends IAnyStateTreeNode>(source: T, keepEnvironment?: boolean | any): T;
294/**
295 * Removes a model element from the state tree, and let it live on as a new state tree
296 */
297export declare function detach<T extends IAnyStateTreeNode>(target: T): T;
298/**
299 * Removes a model element from the state tree, and mark it as end-of-life; the element should not be used anymore
300 */
301export declare function destroy(target: IAnyStateTreeNode): void;
302/**
303 * Returns true if the given state tree node is not killed yet.
304 * This means that the node is still a part of a tree, and that `destroy`
305 * has not been called. If a node is not alive anymore, the only thing one can do with it
306 * is requesting it's last path and snapshot
307 *
308 * @param target
309 * @returns
310 */
311export declare function isAlive(target: IAnyStateTreeNode): boolean;
312/**
313 * Use this utility to register a function that should be called whenever the
314 * targeted state tree node is destroyed. This is a useful alternative to managing
315 * cleanup methods yourself using the `beforeDestroy` hook.
316 *
317 * This methods returns the same disposer that was passed as argument.
318 *
319 * Example:
320 * ```ts
321 * const Todo = types.model({
322 * title: types.string
323 * }).actions(self => ({
324 * afterCreate() {
325 * const autoSaveDisposer = reaction(
326 * () => getSnapshot(self),
327 * snapshot => sendSnapshotToServerSomehow(snapshot)
328 * )
329 * // stop sending updates to server if this
330 * // instance is destroyed
331 * addDisposer(self, autoSaveDisposer)
332 * }
333 * }))
334 * ```
335 *
336 * @param target
337 * @param disposer
338 * @returns The same disposer that was passed as argument
339 */
340export declare function addDisposer(target: IAnyStateTreeNode, disposer: IDisposer): IDisposer;
341/**
342 * Returns the environment of the current state tree. For more info on environments,
343 * see [Dependency injection](https://github.com/mobxjs/mobx-state-tree#dependency-injection)
344 *
345 * Please note that in child nodes access to the root is only possible
346 * once the `afterAttach` hook has fired
347 *
348 * Returns an empty environment if the tree wasn't initialized with an environment
349 *
350 * @param target
351 * @returns
352 */
353export declare function getEnv<T = any>(target: IAnyStateTreeNode): T;
354/**
355 * Performs a depth first walk through a tree.
356 */
357export declare function walk(target: IAnyStateTreeNode, processor: (item: IAnyStateTreeNode) => void): void;
358export interface IModelReflectionPropertiesData {
359 name: string;
360 properties: {
361 [K: string]: IAnyType;
362 };
363}
364/**
365 * Returns a reflection of the model type properties and name for either a model type or model node.
366 *
367 * @param typeOrNode
368 * @returns
369 */
370export declare function getPropertyMembers(typeOrNode: IAnyModelType | IAnyStateTreeNode): IModelReflectionPropertiesData;
371export interface IModelReflectionData extends IModelReflectionPropertiesData {
372 actions: string[];
373 views: string[];
374 volatile: string[];
375}
376/**
377 * Returns a reflection of the model node, including name, properties, views, volatile and actions.
378 *
379 * @param target
380 * @returns
381 */
382export declare function getMembers(target: IAnyStateTreeNode): IModelReflectionData;
383export declare function cast<O extends string | number | boolean | null | undefined = never>(snapshotOrInstance: O): O;
384export declare function cast<O = never>(snapshotOrInstance: TypeOfValue<O>["CreationType"] | TypeOfValue<O>["SnapshotType"] | TypeOfValue<O>["Type"]): O;
385/**
386 * Casts a node instance type to an snapshot type so it can be assigned to a type snapshot (e.g. to be used inside a create call).
387 * Note that this is just a cast for the type system, this is, it won't actually convert an instance to a snapshot,
388 * but just fool typescript into thinking so.
389 *
390 * Example:
391 * ```ts
392 * const ModelA = types.model({
393 * n: types.number
394 * }).actions(self => ({
395 * setN(aNumber: number) {
396 * self.n = aNumber
397 * }
398 * }))
399 *
400 * const ModelB = types.model({
401 * innerModel: ModelA
402 * })
403 *
404 * const a = ModelA.create({ n: 5 });
405 * // this will allow the compiler to use a model as if it were a snapshot
406 * const b = ModelB.create({ innerModel: castToSnapshot(a)})
407 * ```
408 *
409 * @param snapshotOrInstance Snapshot or instance
410 * @returns The same object casted as an input (creation) snapshot
411 */
412export declare function castToSnapshot<I>(snapshotOrInstance: I): Extract<I, IAnyStateTreeNode> extends never ? I : TypeOfValue<I>["CreationType"];
413/**
414 * Casts a node instance type to a reference snapshot type so it can be assigned to a refernence snapshot (e.g. to be used inside a create call).
415 * Note that this is just a cast for the type system, this is, it won't actually convert an instance to a refererence snapshot,
416 * but just fool typescript into thinking so.
417 *
418 * Example:
419 * ```ts
420 * const ModelA = types.model({
421 * id: types.identifier,
422 * n: types.number
423 * }).actions(self => ({
424 * setN(aNumber: number) {
425 * self.n = aNumber
426 * }
427 * }))
428 *
429 * const ModelB = types.model({
430 * refA: types.reference(ModelA)
431 * })
432 *
433 * const a = ModelA.create({ id: 'someId', n: 5 });
434 * // this will allow the compiler to use a model as if it were a reference snapshot
435 * const b = ModelB.create({ refA: castToReferenceSnapshot(a)})
436 * ```
437 *
438 * @param instance Instance
439 * @returns The same object casted as an reference snapshot (string or number)
440 */
441export declare function castToReferenceSnapshot<I>(instance: I): Extract<I, IAnyStateTreeNode> extends never ? I : ReferenceIdentifier;
442/**
443 * Returns the unique node id (not to be confused with the instance identifier) for a
444 * given instance.
445 * This id is a number that is unique for each instance.
446 *
447 * @export
448 * @param target
449 * @returns
450 */
451export declare function getNodeId(target: IAnyStateTreeNode): number;