1 | import { globalState, die } from "../internal"
|
2 |
|
3 |
|
4 | export const assign = Object.assign
|
5 | export const getDescriptor = Object.getOwnPropertyDescriptor
|
6 | export const defineProperty = Object.defineProperty
|
7 | export const objectPrototype = Object.prototype
|
8 |
|
9 | export const EMPTY_ARRAY = []
|
10 | Object.freeze(EMPTY_ARRAY)
|
11 |
|
12 | export const EMPTY_OBJECT = {}
|
13 | Object.freeze(EMPTY_OBJECT)
|
14 |
|
15 | export interface Lambda {
|
16 | (): void
|
17 | name?: string
|
18 | }
|
19 |
|
20 | const hasProxy = typeof Proxy !== "undefined"
|
21 | const plainObjectString = Object.toString()
|
22 |
|
23 | export function assertProxies() {
|
24 | if (!hasProxy) {
|
25 | die(
|
26 | __DEV__
|
27 | ? "`Proxy` objects are not available in the current environment. Please configure MobX to enable a fallback implementation.`"
|
28 | : "Proxy not available"
|
29 | )
|
30 | }
|
31 | }
|
32 |
|
33 | export function warnAboutProxyRequirement(msg: string) {
|
34 | if (__DEV__ && globalState.verifyProxies) {
|
35 | die(
|
36 | "MobX is currently configured to be able to run in ES5 mode, but in ES5 MobX won't be able to " +
|
37 | msg
|
38 | )
|
39 | }
|
40 | }
|
41 |
|
42 | export function getNextId() {
|
43 | return ++globalState.mobxGuid
|
44 | }
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | export function once(func: Lambda): Lambda {
|
50 | let invoked = false
|
51 | return function () {
|
52 | if (invoked) return
|
53 | invoked = true
|
54 | return (func as any).apply(this, arguments)
|
55 | }
|
56 | }
|
57 |
|
58 | export const noop = () => {}
|
59 |
|
60 | export function isFunction(fn: any): fn is Function {
|
61 | return typeof fn === "function"
|
62 | }
|
63 |
|
64 | export function isString(value: any): value is string {
|
65 | return typeof value === "string"
|
66 | }
|
67 |
|
68 | export function isStringish(value: any): value is string | number | symbol {
|
69 | const t = typeof value
|
70 | switch (t) {
|
71 | case "string":
|
72 | case "symbol":
|
73 | case "number":
|
74 | return true
|
75 | }
|
76 | return false
|
77 | }
|
78 |
|
79 | export function isObject(value: any): value is Object {
|
80 | return value !== null && typeof value === "object"
|
81 | }
|
82 |
|
83 | export function isPlainObject(value) {
|
84 | if (!isObject(value)) return false
|
85 | const proto = Object.getPrototypeOf(value)
|
86 | if (proto == null) return true
|
87 | return proto.constructor?.toString() === plainObjectString
|
88 | }
|
89 |
|
90 |
|
91 | export function isGenerator(obj: any): boolean {
|
92 | const constructor = obj?.constructor
|
93 | if (!constructor) return false
|
94 | if ("GeneratorFunction" === constructor.name || "GeneratorFunction" === constructor.displayName)
|
95 | return true
|
96 | return false
|
97 | }
|
98 |
|
99 | export function addHiddenProp(object: any, propName: PropertyKey, value: any) {
|
100 | defineProperty(object, propName, {
|
101 | enumerable: false,
|
102 | writable: true,
|
103 | configurable: true,
|
104 | value
|
105 | })
|
106 | }
|
107 |
|
108 | export function addHiddenFinalProp(object: any, propName: PropertyKey, value: any) {
|
109 | defineProperty(object, propName, {
|
110 | enumerable: false,
|
111 | writable: false,
|
112 | configurable: true,
|
113 | value
|
114 | })
|
115 | }
|
116 |
|
117 | export function createInstanceofPredicate<T>(
|
118 | name: string,
|
119 | theClass: new (...args: any[]) => T
|
120 | ): (x: any) => x is T {
|
121 | const propName = "isMobX" + name
|
122 | theClass.prototype[propName] = true
|
123 | return function (x) {
|
124 | return isObject(x) && x[propName] === true
|
125 | } as any
|
126 | }
|
127 |
|
128 | export function isES6Map(thing): boolean {
|
129 | return thing instanceof Map
|
130 | }
|
131 |
|
132 | export function isES6Set(thing): thing is Set<any> {
|
133 | return thing instanceof Set
|
134 | }
|
135 |
|
136 | const hasGetOwnPropertySymbols = typeof Object.getOwnPropertySymbols !== "undefined"
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | export function getPlainObjectKeys(object) {
|
142 | const keys = Object.keys(object)
|
143 |
|
144 | if (!hasGetOwnPropertySymbols) return keys
|
145 | const symbols = Object.getOwnPropertySymbols(object)
|
146 | if (!symbols.length) return keys
|
147 | return [...keys, ...symbols.filter(s => objectPrototype.propertyIsEnumerable.call(object, s))]
|
148 | }
|
149 |
|
150 |
|
151 |
|
152 | export const ownKeys: (target: any) => PropertyKey[] =
|
153 | typeof Reflect !== "undefined" && Reflect.ownKeys
|
154 | ? Reflect.ownKeys
|
155 | : hasGetOwnPropertySymbols
|
156 | ? obj => Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj) as any)
|
157 | : Object.getOwnPropertyNames
|
158 |
|
159 | export function stringifyKey(key: any): string {
|
160 | if (typeof key === "string") return key
|
161 | if (typeof key === "symbol") return key.toString()
|
162 | return new String(key).toString()
|
163 | }
|
164 |
|
165 | export function toPrimitive(value) {
|
166 | return value === null ? null : typeof value === "object" ? "" + value : value
|
167 | }
|
168 |
|
169 | export function hasProp(target: Object, prop: PropertyKey): boolean {
|
170 | return objectPrototype.hasOwnProperty.call(target, prop)
|
171 | }
|
172 |
|
173 |
|
174 | export const getOwnPropertyDescriptors =
|
175 | Object.getOwnPropertyDescriptors ||
|
176 | function getOwnPropertyDescriptors(target: any) {
|
177 |
|
178 | const res: any = {}
|
179 |
|
180 | ownKeys(target).forEach(key => {
|
181 | res[key] = getDescriptor(target, key)
|
182 | })
|
183 | return res
|
184 | }
|