UNPKG

4.14 kBJavaScriptView Raw
1var __assign = (this && this.__assign) || function () {
2 __assign = Object.assign || function(t) {
3 for (var s, i = 1, n = arguments.length; i < n; i++) {
4 s = arguments[i];
5 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6 t[p] = s[p];
7 }
8 return t;
9 };
10 return __assign.apply(this, arguments);
11};
12import { computed, onBecomeUnobserved, _isComputingDerivation, } from "mobx";
13import { invariant } from "./utils";
14/**
15 * Creates a function that maps an object to a view.
16 * The mapping is memoized.
17 *
18 * See the [transformer](#createtransformer-in-detail) section for more details.
19 *
20 * @param transformer A function which transforms instances of A into instances of B
21 * @param arg2 An optional cleanup function which is called when the transformation is no longer
22 * observed from a reactive context, or config options
23 * @returns The memoized transformer function
24 */
25export function createTransformer(transformer, arg2) {
26 invariant(typeof transformer === "function" && transformer.length < 2, "createTransformer expects a function that accepts one argument");
27 // Memoizes: object -> reactive view that applies transformer to the object
28 var views = new Map();
29 var onCleanup = undefined;
30 var keepAlive = false;
31 var debugNameGenerator = undefined;
32 if (typeof arg2 === "object") {
33 onCleanup = arg2.onCleanup;
34 keepAlive = arg2.keepAlive !== undefined ? arg2.keepAlive : false;
35 debugNameGenerator = arg2.debugNameGenerator;
36 }
37 else if (typeof arg2 === "function") {
38 onCleanup = arg2;
39 }
40 function createView(sourceObject) {
41 var latestValue;
42 var computedValueOptions = {};
43 if (typeof arg2 === "object") {
44 onCleanup = arg2.onCleanup;
45 debugNameGenerator = arg2.debugNameGenerator;
46 computedValueOptions = arg2;
47 }
48 else if (typeof arg2 === "function") {
49 onCleanup = arg2;
50 }
51 else {
52 onCleanup = undefined;
53 debugNameGenerator = undefined;
54 }
55 var sourceType = typeof sourceObject;
56 var prettifiedName = debugNameGenerator
57 ? debugNameGenerator(sourceObject)
58 : "Transformer-" + transformer.name + "-" + (sourceType === "string" || sourceType === "number" ? sourceObject : "object");
59 var expr = computed(function () {
60 return (latestValue = transformer(sourceObject));
61 }, __assign(__assign({}, computedValueOptions), { name: prettifiedName }));
62 if (!keepAlive) {
63 var disposer_1 = onBecomeUnobserved(expr, function () {
64 views.delete(sourceObject);
65 disposer_1();
66 if (onCleanup)
67 onCleanup(latestValue, sourceObject);
68 });
69 }
70 return expr;
71 }
72 var memoWarned = false;
73 return function (object) {
74 checkTransformableObject(object);
75 var reactiveView = views.get(object);
76 if (reactiveView)
77 return reactiveView.get();
78 if (!keepAlive && !_isComputingDerivation()) {
79 if (!memoWarned) {
80 console.warn("invoking a transformer from outside a reactive context won't memorized " +
81 "and is cleaned up immediately, unless keepAlive is set");
82 memoWarned = true;
83 }
84 var value = transformer(object);
85 if (onCleanup)
86 onCleanup(value, object);
87 return value;
88 }
89 // Not in cache; create a reactive view
90 reactiveView = createView(object);
91 views.set(object, reactiveView);
92 return reactiveView.get();
93 };
94}
95function checkTransformableObject(object) {
96 var objectType = typeof object;
97 if (object === null ||
98 (objectType !== "object" &&
99 objectType !== "function" &&
100 objectType !== "string" &&
101 objectType !== "number"))
102 throw new Error("[mobx-utils] transform expected an object, function, string or number, got: " + String(object));
103}