1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | import * as array from './array.js'
|
8 | import * as object from './object.js'
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | export const callAll = (fs, args, i = 0) => {
|
17 | try {
|
18 | for (; i < fs.length; i++) {
|
19 | fs[i](...args)
|
20 | }
|
21 | } finally {
|
22 | if (i < fs.length) {
|
23 | callAll(fs, args, i + 1)
|
24 | }
|
25 | }
|
26 | }
|
27 |
|
28 | export const nop = () => {}
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | export const apply = f => f()
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | export const id = a => a
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | export const equalityStrict = (a, b) => a === b
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 | export const equalityFlat = (a, b) => a === b || (a != null && b != null && a.constructor === b.constructor && ((array.isArray(a) && array.equalFlat(a, (b))) || (typeof a === 'object' && object.equalFlat(a, b))))
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 | export const equalityDeep = (a, b) => {
|
71 | if (a == null || b == null) {
|
72 | return equalityStrict(a, b)
|
73 | }
|
74 | if (a.constructor !== b.constructor) {
|
75 | return false
|
76 | }
|
77 | if (a === b) {
|
78 | return true
|
79 | }
|
80 | switch (a.constructor) {
|
81 | case ArrayBuffer:
|
82 | a = new Uint8Array(a)
|
83 | b = new Uint8Array(b)
|
84 |
|
85 | case Uint8Array: {
|
86 | if (a.byteLength !== b.byteLength) {
|
87 | return false
|
88 | }
|
89 | for (let i = 0; i < a.length; i++) {
|
90 | if (a[i] !== b[i]) {
|
91 | return false
|
92 | }
|
93 | }
|
94 | break
|
95 | }
|
96 | case Set: {
|
97 | if (a.size !== b.size) {
|
98 | return false
|
99 | }
|
100 | for (const value of a) {
|
101 | if (!b.has(value)) {
|
102 | return false
|
103 | }
|
104 | }
|
105 | break
|
106 | }
|
107 | case Map: {
|
108 | if (a.size !== b.size) {
|
109 | return false
|
110 | }
|
111 | for (const key of a.keys()) {
|
112 | if (!b.has(key) || !equalityDeep(a.get(key), b.get(key))) {
|
113 | return false
|
114 | }
|
115 | }
|
116 | break
|
117 | }
|
118 | case Object:
|
119 | if (object.length(a) !== object.length(b)) {
|
120 | return false
|
121 | }
|
122 | for (const key in a) {
|
123 | if (!object.hasProperty(a, key) || !equalityDeep(a[key], b[key])) {
|
124 | return false
|
125 | }
|
126 | }
|
127 | break
|
128 | case Array:
|
129 | if (a.length !== b.length) {
|
130 | return false
|
131 | }
|
132 | for (let i = 0; i < a.length; i++) {
|
133 | if (!equalityDeep(a[i], b[i])) {
|
134 | return false
|
135 | }
|
136 | }
|
137 | break
|
138 | default:
|
139 | return false
|
140 | }
|
141 | return true
|
142 | }
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 | export const isOneOf = (value, options) => options.includes(value)
|
153 |
|
154 |
|
155 | export const isArray = array.isArray
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 | export const isString = (s) => s && s.constructor === String
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 | export const isNumber = n => n != null && n.constructor === Number
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 | export const is = (n, T) => n && n.constructor === T
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | export const isTemplate = (T) =>
|
182 | |
183 |
|
184 |
|
185 |
|
186 | n => n && n.constructor === T
|