@epam/uui-db 4.9.1 → 4.10.0-rc.1

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.
package/index.js CHANGED
@@ -1,408 +1,54 @@
1
- module.exports =
2
- /******/ (function(modules) { // webpackBootstrap
3
- /******/ // The module cache
4
- /******/ var installedModules = {};
5
- /******/
6
- /******/ // The require function
7
- /******/ function __webpack_require__(moduleId) {
8
- /******/
9
- /******/ // Check if module is in cache
10
- /******/ if(installedModules[moduleId]) {
11
- /******/ return installedModules[moduleId].exports;
12
- /******/ }
13
- /******/ // Create a new module (and put it into the cache)
14
- /******/ var module = installedModules[moduleId] = {
15
- /******/ i: moduleId,
16
- /******/ l: false,
17
- /******/ exports: {}
18
- /******/ };
19
- /******/
20
- /******/ // Execute the module function
21
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22
- /******/
23
- /******/ // Flag the module as loaded
24
- /******/ module.l = true;
25
- /******/
26
- /******/ // Return the exports of the module
27
- /******/ return module.exports;
28
- /******/ }
29
- /******/
30
- /******/
31
- /******/ // expose the modules object (__webpack_modules__)
32
- /******/ __webpack_require__.m = modules;
33
- /******/
34
- /******/ // expose the module cache
35
- /******/ __webpack_require__.c = installedModules;
36
- /******/
37
- /******/ // define getter function for harmony exports
38
- /******/ __webpack_require__.d = function(exports, name, getter) {
39
- /******/ if(!__webpack_require__.o(exports, name)) {
40
- /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41
- /******/ }
42
- /******/ };
43
- /******/
44
- /******/ // define __esModule on exports
45
- /******/ __webpack_require__.r = function(exports) {
46
- /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47
- /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48
- /******/ }
49
- /******/ Object.defineProperty(exports, '__esModule', { value: true });
50
- /******/ };
51
- /******/
52
- /******/ // create a fake namespace object
53
- /******/ // mode & 1: value is a module id, require it
54
- /******/ // mode & 2: merge all properties of value into the ns
55
- /******/ // mode & 4: return value when already ns object
56
- /******/ // mode & 8|1: behave like require
57
- /******/ __webpack_require__.t = function(value, mode) {
58
- /******/ if(mode & 1) value = __webpack_require__(value);
59
- /******/ if(mode & 8) return value;
60
- /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61
- /******/ var ns = Object.create(null);
62
- /******/ __webpack_require__.r(ns);
63
- /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64
- /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65
- /******/ return ns;
66
- /******/ };
67
- /******/
68
- /******/ // getDefaultExport function for compatibility with non-harmony modules
69
- /******/ __webpack_require__.n = function(module) {
70
- /******/ var getter = module && module.__esModule ?
71
- /******/ function getDefault() { return module['default']; } :
72
- /******/ function getModuleExports() { return module; };
73
- /******/ __webpack_require__.d(getter, 'a', getter);
74
- /******/ return getter;
75
- /******/ };
76
- /******/
77
- /******/ // Object.prototype.hasOwnProperty.call
78
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79
- /******/
80
- /******/ // __webpack_public_path__
81
- /******/ __webpack_require__.p = "/";
82
- /******/
83
- /******/
84
- /******/ // Load entry module and return exports
85
- /******/ return __webpack_require__(__webpack_require__.s = 0);
86
- /******/ })
87
- /************************************************************************/
88
- /******/ ({
1
+ import shallowEqual from 'shallowequal';
2
+ import zip from 'lodash.zip';
3
+ import transform from 'lodash.transform';
4
+ import isEqual from 'lodash.isequal';
5
+ import * as I from 'immutable';
6
+ import { Seq } from 'immutable';
7
+ import { getFilterPredicate, getSearchFilter, getOrderComparer, batch } from '@epam/uui-core';
8
+ import groupBy from 'lodash.groupby';
9
+ import map from 'lodash.map';
10
+ import merge from 'lodash.merge';
11
+ import countBy from 'lodash.countby';
12
+ import filter from 'lodash.filter';
13
+ import forEach from 'lodash.foreach';
14
+ import pick from 'lodash.pick';
15
+ import isEmpty from 'lodash.isempty';
16
+ import { createContext, useContext, useState, useMemo, useEffect } from 'react';
89
17
 
90
- /***/ "../node_modules/tslib/tslib.es6.js":
91
- /*!******************************************!*\
92
- !*** ../node_modules/tslib/tslib.es6.js ***!
93
- \******************************************/
94
- /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __createBinding, __exportStar, __values, __read, __spread, __spreadArrays, __spreadArray, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault, __classPrivateFieldGet, __classPrivateFieldSet, __classPrivateFieldIn */
95
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
96
-
97
- "use strict";
98
- __webpack_require__.r(__webpack_exports__);
99
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__extends", function() { return __extends; });
100
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__assign", function() { return __assign; });
101
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__rest", function() { return __rest; });
102
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__decorate", function() { return __decorate; });
103
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__param", function() { return __param; });
104
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; });
105
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; });
106
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; });
107
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__createBinding", function() { return __createBinding; });
108
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; });
109
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; });
110
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; });
111
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spread", function() { return __spread; });
112
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spreadArrays", function() { return __spreadArrays; });
113
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spreadArray", function() { return __spreadArray; });
114
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__await", function() { return __await; });
115
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncGenerator", function() { return __asyncGenerator; });
116
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncDelegator", function() { return __asyncDelegator; });
117
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncValues", function() { return __asyncValues; });
118
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__makeTemplateObject", function() { return __makeTemplateObject; });
119
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importStar", function() { return __importStar; });
120
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importDefault", function() { return __importDefault; });
121
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldGet", function() { return __classPrivateFieldGet; });
122
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldSet", function() { return __classPrivateFieldSet; });
123
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldIn", function() { return __classPrivateFieldIn; });
124
- /******************************************************************************
125
- Copyright (c) Microsoft Corporation.
126
-
127
- Permission to use, copy, modify, and/or distribute this software for any
128
- purpose with or without fee is hereby granted.
129
-
130
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
131
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
132
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
133
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
134
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
135
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
136
- PERFORMANCE OF THIS SOFTWARE.
137
- ***************************************************************************** */
138
- /* global Reflect, Promise */
139
-
140
- var extendStatics = function(d, b) {
141
- extendStatics = Object.setPrototypeOf ||
142
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
143
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
144
- return extendStatics(d, b);
145
- };
146
-
147
- function __extends(d, b) {
148
- if (typeof b !== "function" && b !== null)
149
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
150
- extendStatics(d, b);
151
- function __() { this.constructor = d; }
152
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
153
- }
154
-
155
- var __assign = function() {
156
- __assign = Object.assign || function __assign(t) {
157
- for (var s, i = 1, n = arguments.length; i < n; i++) {
158
- s = arguments[i];
159
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
160
- }
161
- return t;
162
- }
163
- return __assign.apply(this, arguments);
164
- }
165
-
166
- function __rest(s, e) {
167
- var t = {};
168
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
169
- t[p] = s[p];
170
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
171
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
172
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
173
- t[p[i]] = s[p[i]];
174
- }
175
- return t;
176
- }
177
-
178
- function __decorate(decorators, target, key, desc) {
179
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
180
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
181
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
182
- return c > 3 && r && Object.defineProperty(target, key, r), r;
183
- }
184
-
185
- function __param(paramIndex, decorator) {
186
- return function (target, key) { decorator(target, key, paramIndex); }
187
- }
188
-
189
- function __metadata(metadataKey, metadataValue) {
190
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
191
- }
192
-
193
- function __awaiter(thisArg, _arguments, P, generator) {
194
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
195
- return new (P || (P = Promise))(function (resolve, reject) {
196
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
197
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
198
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
199
- step((generator = generator.apply(thisArg, _arguments || [])).next());
200
- });
201
- }
202
-
203
- function __generator(thisArg, body) {
204
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
205
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
206
- function verb(n) { return function (v) { return step([n, v]); }; }
207
- function step(op) {
208
- if (f) throw new TypeError("Generator is already executing.");
209
- while (_) try {
210
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
211
- if (y = 0, t) op = [op[0] & 2, t.value];
212
- switch (op[0]) {
213
- case 0: case 1: t = op; break;
214
- case 4: _.label++; return { value: op[1], done: false };
215
- case 5: _.label++; y = op[1]; op = [0]; continue;
216
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
217
- default:
218
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
219
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
220
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
221
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
222
- if (t[2]) _.ops.pop();
223
- _.trys.pop(); continue;
224
- }
225
- op = body.call(thisArg, _);
226
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
227
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
228
- }
229
- }
230
-
231
- var __createBinding = Object.create ? (function(o, m, k, k2) {
232
- if (k2 === undefined) k2 = k;
233
- var desc = Object.getOwnPropertyDescriptor(m, k);
234
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
235
- desc = { enumerable: true, get: function() { return m[k]; } };
236
- }
237
- Object.defineProperty(o, k2, desc);
238
- }) : (function(o, m, k, k2) {
239
- if (k2 === undefined) k2 = k;
240
- o[k2] = m[k];
241
- });
242
-
243
- function __exportStar(m, o) {
244
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
245
- }
246
-
247
- function __values(o) {
248
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
249
- if (m) return m.call(o);
250
- if (o && typeof o.length === "number") return {
251
- next: function () {
252
- if (o && i >= o.length) o = void 0;
253
- return { value: o && o[i++], done: !o };
254
- }
255
- };
256
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
257
- }
258
-
259
- function __read(o, n) {
260
- var m = typeof Symbol === "function" && o[Symbol.iterator];
261
- if (!m) return o;
262
- var i = m.call(o), r, ar = [], e;
263
- try {
264
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
265
- }
266
- catch (error) { e = { error: error }; }
267
- finally {
268
- try {
269
- if (r && !r.done && (m = i["return"])) m.call(i);
270
- }
271
- finally { if (e) throw e.error; }
272
- }
273
- return ar;
274
- }
275
-
276
- /** @deprecated */
277
- function __spread() {
278
- for (var ar = [], i = 0; i < arguments.length; i++)
279
- ar = ar.concat(__read(arguments[i]));
280
- return ar;
281
- }
282
-
283
- /** @deprecated */
284
- function __spreadArrays() {
285
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
286
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
287
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
288
- r[k] = a[j];
289
- return r;
290
- }
291
-
292
- function __spreadArray(to, from, pack) {
293
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
294
- if (ar || !(i in from)) {
295
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
296
- ar[i] = from[i];
297
- }
298
- }
299
- return to.concat(ar || Array.prototype.slice.call(from));
300
- }
301
-
302
- function __await(v) {
303
- return this instanceof __await ? (this.v = v, this) : new __await(v);
304
- }
305
-
306
- function __asyncGenerator(thisArg, _arguments, generator) {
307
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
308
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
309
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
310
- function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
311
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
312
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
313
- function fulfill(value) { resume("next", value); }
314
- function reject(value) { resume("throw", value); }
315
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
316
- }
317
-
318
- function __asyncDelegator(o) {
319
- var i, p;
320
- return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
321
- function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
322
- }
323
-
324
- function __asyncValues(o) {
325
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
326
- var m = o[Symbol.asyncIterator], i;
327
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
328
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
329
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
330
- }
331
-
332
- function __makeTemplateObject(cooked, raw) {
333
- if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
334
- return cooked;
335
- };
336
-
337
- var __setModuleDefault = Object.create ? (function(o, v) {
338
- Object.defineProperty(o, "default", { enumerable: true, value: v });
339
- }) : function(o, v) {
340
- o["default"] = v;
341
- };
342
-
343
- function __importStar(mod) {
344
- if (mod && mod.__esModule) return mod;
345
- var result = {};
346
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
347
- __setModuleDefault(result, mod);
348
- return result;
349
- }
350
-
351
- function __importDefault(mod) {
352
- return (mod && mod.__esModule) ? mod : { default: mod };
353
- }
354
-
355
- function __classPrivateFieldGet(receiver, state, kind, f) {
356
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
357
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
358
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
359
- }
360
-
361
- function __classPrivateFieldSet(receiver, state, value, kind, f) {
362
- if (kind === "m") throw new TypeError("Private method is not writable");
363
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
364
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
365
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
366
- }
367
-
368
- function __classPrivateFieldIn(state, receiver) {
369
- if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object");
370
- return typeof state === "function" ? receiver === state : state.has(receiver);
371
- }
372
-
373
-
374
- /***/ }),
375
-
376
- /***/ "./index.tsx":
377
- /*!*******************!*\
378
- !*** ./index.tsx ***!
379
- \*******************/
380
- /*! no static exports found */
381
- /***/ (function(module, exports, __webpack_require__) {
382
-
383
- "use strict";
384
-
385
- Object.defineProperty(exports, "__esModule", { value: true });
386
- const tslib_1 = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
387
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./src */ "./src/index.ts"), exports);
388
-
389
-
390
- /***/ }),
391
-
392
- /***/ "./src/Db.ts":
393
- /*!*******************!*\
394
- !*** ./src/Db.ts ***!
395
- \*******************/
396
- /*! no static exports found */
397
- /***/ (function(module, exports, __webpack_require__) {
18
+ var DbRelationType;
19
+ (function (DbRelationType) {
20
+ DbRelationType[DbRelationType["Aggregation"] = 0] = "Aggregation";
21
+ DbRelationType[DbRelationType["Association"] = 1] = "Association";
22
+ })(DbRelationType || (DbRelationType = {}));
398
23
 
399
- "use strict";
24
+ // TBD: New typescript would contain better typing for this. Remove this hack after update.
25
+ let objectKeys = Object.keys;
26
+ function defaultCompareViewDependencies(prev, next) {
27
+ if (Array.isArray(prev) && Array.isArray(next)) {
28
+ if (prev.length === next.length) {
29
+ return zip(prev, next).every(([p, n]) => shallowEqual(p, n));
30
+ }
31
+ return false;
32
+ }
33
+ return shallowEqual(prev, next);
34
+ }
35
+ /**
36
+ * Deep diff between two object, using lodash
37
+ * @param {Object} object Object compared
38
+ * @param {Object} base Object to compare with
39
+ * @return {Object} Return a new object who represent the diff
40
+ */
41
+ function difference(object, base) {
42
+ function changes(object, base) {
43
+ return transform(object, function (result, value, key) {
44
+ if (!isEqual(value, base[key])) {
45
+ result[key] = (typeof value === "object" && typeof base[key] === "object") ? changes(value, base[key]) : value;
46
+ }
47
+ });
48
+ }
49
+ return changes(object, base);
50
+ }
400
51
 
401
- Object.defineProperty(exports, "__esModule", { value: true });
402
- exports.Db = void 0;
403
- const tslib_1 = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
404
- const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
405
- const lodash_isequal_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.isequal */ "lodash.isequal"));
406
52
  class Db {
407
53
  constructor(tables, reusedCache) {
408
54
  this.tables = tables;
@@ -424,7 +70,7 @@ class Db {
424
70
  }
425
71
  with(patch) {
426
72
  return this.update(db => {
427
- (0, utils_1.objectKeys)(db.tables).forEach(entityName => {
73
+ objectKeys(db.tables).forEach(entityName => {
428
74
  if (patch[entityName]) {
429
75
  db.tables[entityName] = db.tables[entityName].with(patch[entityName]);
430
76
  }
@@ -450,7 +96,7 @@ class Db {
450
96
  let shouldUpdate = this !== cacheItem.computedOnDb;
451
97
  let dependencies = this.valueAbsent;
452
98
  if (view.getDependencies) {
453
- const compare = view.compareDependencies || utils_1.defaultCompareViewDependencies;
99
+ const compare = view.compareDependencies || defaultCompareViewDependencies;
454
100
  dependencies = view.getDependencies(this, params);
455
101
  shouldUpdate = !compare(cacheItem.dependencies, dependencies);
456
102
  }
@@ -459,10 +105,10 @@ class Db {
459
105
  cacheItem.dependencies = dependencies;
460
106
  let newValue = view.compute(this, params, dependencies);
461
107
  cacheItem.computedOnDb = this;
462
- let compareResults = view.compareResults || lodash_isequal_1.default;
108
+ let compareResults = view.compareResults || isEqual;
463
109
  if (!compareResults(previousValue, newValue)) {
464
110
  if (view.traceDiff) {
465
- console.debug((0, utils_1.difference)(previousValue, newValue));
111
+ console.debug(difference(previousValue, newValue));
466
112
  }
467
113
  cacheItem.currentValue = newValue;
468
114
  }
@@ -470,268 +116,83 @@ class Db {
470
116
  return cacheItem.currentValue;
471
117
  }
472
118
  }
473
- exports.Db = Db;
474
-
475
-
476
- /***/ }),
477
-
478
- /***/ "./src/DbRef.ts":
479
- /*!**********************!*\
480
- !*** ./src/DbRef.ts ***!
481
- \**********************/
482
- /*! no static exports found */
483
- /***/ (function(module, exports, __webpack_require__) {
484
119
 
485
- "use strict";
120
+ /******************************************************************************
121
+ Copyright (c) Microsoft Corporation.
122
+
123
+ Permission to use, copy, modify, and/or distribute this software for any
124
+ purpose with or without fee is hereby granted.
125
+
126
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
127
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
128
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
129
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
130
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
131
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
132
+ PERFORMANCE OF THIS SOFTWARE.
133
+ ***************************************************************************** */
134
+
135
+ function __rest(s, e) {
136
+ var t = {};
137
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
138
+ t[p] = s[p];
139
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
140
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
141
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
142
+ t[p[i]] = s[p[i]];
143
+ }
144
+ return t;
145
+ }
146
+
147
+ function __awaiter(thisArg, _arguments, P, generator) {
148
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
149
+ return new (P || (P = Promise))(function (resolve, reject) {
150
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
151
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
152
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
153
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
154
+ });
155
+ }
486
156
 
487
- Object.defineProperty(exports, "__esModule", { value: true });
488
- exports.DbRef = void 0;
489
- const tslib_1 = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
490
- const patchHelpers_1 = __webpack_require__(/*! ./patchHelpers */ "./src/patchHelpers.ts");
491
- const tempIds_1 = __webpack_require__(/*! ./tempIds */ "./src/tempIds.tsx");
492
- const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
493
- const lodash_isempty_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.isempty */ "lodash.isempty"));
494
- const Loader_1 = __webpack_require__(/*! ./Loader */ "./src/Loader.ts");
495
- const uui_core_1 = __webpack_require__(/*! @epam/uui-core */ "@epam/uui-core");
496
- const SimpleLoadingTracker_1 = __webpack_require__(/*! ./SimpleLoadingTracker */ "./src/SimpleLoadingTracker.ts");
497
- const ListLoadingTracker_1 = __webpack_require__(/*! ./ListLoadingTracker */ "./src/ListLoadingTracker.ts");
498
- class DbRef {
499
- constructor(blank) {
500
- this.blank = blank;
501
- this.log = [];
502
- this.autoSave = true;
503
- this.savedPoint = 0;
504
- this.throttleSaveMs = 1000;
505
- /* Update subscriptions (aka live views) */
506
- this.lastSubscriptionId = 1;
507
- this.subscriptions = new Map();
508
- this.updateHandlers = [];
509
- /* Error Subscriptions */
510
- this.saveErrorHandlers = [];
511
- /* Save scheduling */
512
- this.enqueueSave = (0, uui_core_1.batch)(() => (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
513
- const cumulativePatch = this.makeCumulativePatch();
514
- const lastLogEntry = this.log.length;
515
- if ((0, lodash_isempty_1.default)(cumulativePatch)) {
516
- return;
517
- }
518
- try {
519
- const response = yield this.savePatch(cumulativePatch);
520
- this.applyResponse(response, lastLogEntry);
521
- this.update();
522
- }
523
- catch (error) {
524
- this.saveError(cumulativePatch, error);
525
- this.update();
526
- throw error;
527
- }
528
- }));
529
- this.handleBeforeUnload = (e) => {
530
- if (this.enqueueSave.isBusy) {
531
- e.returnValue = false;
532
- return false;
533
- }
534
- };
535
- this.loaders = [];
536
- this.db = blank;
537
- this.base = blank;
538
- this.tempIdMap = new tempIds_1.TempIdMap(blank);
539
- this.idMap = this.tempIdMap;
540
- window.addEventListener('beforeunload', this.handleBeforeUnload);
157
+ class DbTable {
158
+ constructor(schema, state, q) {
159
+ this.schema = schema;
160
+ this.state = state;
161
+ this.q = q;
162
+ if (!state) {
163
+ const indexes = (schema.indexes || []).map(indexDef => {
164
+ return {
165
+ field: indexDef,
166
+ map: I.Map(),
167
+ };
168
+ });
169
+ this.state = { pk: I.Map(), indexes };
170
+ }
171
+ if (!q) {
172
+ this.q = {};
173
+ }
541
174
  }
542
- /** Saves all committed patches. Useful only if autoSave is off. */
543
- save() {
544
- return this.enqueueSave();
175
+ keyToImmutable(id) {
176
+ if (Array.isArray(id)) {
177
+ return I.List(id);
178
+ }
179
+ else {
180
+ return id;
181
+ }
545
182
  }
546
- getAutoSave() {
547
- return this.autoSave;
183
+ byId(id) {
184
+ return this.state.pk.get(this.keyToImmutable(id));
548
185
  }
549
- setAutoSave(val) {
550
- if (this.autoSave != val) {
551
- this.autoSave = val;
552
- this.autoSave && this.enqueueSave();
553
- this.update();
186
+ getId(entity) {
187
+ if (Array.isArray(this.schema.primaryKey)) {
188
+ return this.schema.primaryKey.map((key) => entity[key]);
554
189
  }
190
+ return entity[this.schema.primaryKey];
555
191
  }
556
- revert() {
557
- this.db = this.base;
558
- this.log = this.log.slice(0, this.savedPoint);
559
- this.update();
560
- }
561
- /** Concrete DbRef instances should override and implement their save logic in this method */
562
- savePatch(patch) {
563
- return Promise.resolve({ submit: {} });
564
- }
565
- /* Db Update logic */
566
- commit(patch) {
567
- const dbBeforeUpdate = this.db.with(patch);
568
- patch = this.beforeUpdate(patch, dbBeforeUpdate.tables, this.db.tables);
569
- patch = (0, patchHelpers_1.mergeEntityPatches)(this.db.tables, patch);
570
- this.log.push({ patch });
571
- this.db = this.db.with(patch);
572
- this.autoSave && this.enqueueSave(null, { throttleMs: this.throttleSaveMs });
573
- this.update();
574
- }
575
- beforeUpdate(patch, tables, prevTables) {
576
- let patchAndDependencies = {};
577
- (0, utils_1.objectKeys)(tables).filter(entityName => patch[entityName] && !tables[entityName].schema.beforeUpdate).forEach(entityName => {
578
- patchAndDependencies[entityName] = patch[entityName];
579
- });
580
- (0, utils_1.objectKeys)(tables).filter(entityName => patch[entityName] && tables[entityName].schema.beforeUpdate).forEach(entityName => {
581
- const schema = tables[entityName].schema;
582
- const { beforeUpdate } = schema;
583
- let context = {
584
- clientIdsMap: this.tempIdMap,
585
- schema,
586
- tables,
587
- prevTables,
588
- };
589
- const results = patch[entityName].map(e => beforeUpdate(e, context));
590
- const updatedPatch = { [entityName]: results.map(result => result.entity) };
591
- const dependentEntityPatchesForUpdate = (0, patchHelpers_1.unionPatches)(results.filter(result => result.dependentEntities).map(result => result.dependentEntities));
592
- const dependentEntityPatches = this.beforeUpdate(dependentEntityPatchesForUpdate, tables, prevTables);
593
- patchAndDependencies = (0, patchHelpers_1.mergeEntityPatches)(tables, (0, patchHelpers_1.unionPatches)([patchAndDependencies, updatedPatch, dependentEntityPatches]));
594
- });
595
- return patchAndDependencies;
596
- }
597
- commitFetch(patch) {
598
- patch = this.tempIdMap.serverToClientPatch(patch);
599
- this.rebase(this.base.with(patch));
600
- this.update();
601
- }
602
- rebase(newBase) {
603
- this.base = newBase;
604
- this.db = newBase;
605
- for (let n = this.savedPoint; n < this.log.length; n++) {
606
- this.db = this.db.with(this.log[n].patch);
607
- }
608
- }
609
- makeCumulativePatch() {
610
- const lastLogEntry = this.log.length;
611
- const logEntriesToSave = this.log.slice(this.savedPoint, lastLogEntry);
612
- let cumulativePatch = (0, patchHelpers_1.makeCumulativePatch)(this.db, logEntriesToSave.map(t => t.patch), this.tempIdMap);
613
- cumulativePatch = this.tempIdMap.clientToServerPatch(cumulativePatch);
614
- return cumulativePatch;
615
- }
616
- applyResponse(response, newSavedPoint) {
617
- this.tempIdMap.appendServerMapping(response);
618
- let serverPatch = (0, patchHelpers_1.flattenResponse)(response.submit, this.db.tables);
619
- serverPatch = (0, patchHelpers_1.mergeEntityPatches)(this.db.tables, serverPatch);
620
- this.savedPoint = newSavedPoint;
621
- this.base = this.db;
622
- this.commitFetch(serverPatch);
623
- }
624
- subscribe(view, params, onUpdate) {
625
- const id = this.lastSubscriptionId++;
626
- const subscription = {
627
- update: (params) => {
628
- subscription.currentParams = params;
629
- subscription.currentValue = this.db.runView(view, params);
630
- return subscription.currentValue;
631
- },
632
- currentParams: null,
633
- currentValue: null,
634
- onUpdate,
635
- unsubscribe: () => { this.subscriptions.delete(id); },
636
- };
637
- subscription.update(params);
638
- this.subscriptions.set(id, subscription);
639
- return subscription;
640
- }
641
- onUpdate(handler) {
642
- this.subscribe({
643
- compute: db => db,
644
- compareResults: (a, b) => a === b,
645
- }, null, handler);
646
- }
647
- update() {
648
- this.subscriptions.forEach(subscription => {
649
- const previousValue = subscription.currentValue;
650
- subscription.update(subscription.currentParams);
651
- if (subscription.currentValue !== previousValue && subscription.onUpdate) {
652
- subscription.onUpdate(subscription.currentValue);
653
- }
654
- });
655
- }
656
- onSaveError(handler) {
657
- this.saveErrorHandlers.push(handler);
658
- }
659
- saveError(request, error) {
660
- this.saveErrorHandlers.forEach(handler => handler(request, error));
661
- }
662
- makeLoader(options) {
663
- const loader = new Loader_1.Loader(this, () => new SimpleLoadingTracker_1.SimpleLoadingTracker(), options);
664
- this.loaders.push(loader);
665
- return loader;
666
- }
667
- makeListLoader(options) {
668
- const loader = new Loader_1.Loader(this, () => new ListLoadingTracker_1.ListLoadingTracker(), options);
669
- this.loaders.push(loader);
670
- return loader;
671
- }
672
- reload() {
673
- this.loaders = [];
674
- }
675
- }
676
- exports.DbRef = DbRef;
677
-
678
-
679
- /***/ }),
680
-
681
- /***/ "./src/DbTable.ts":
682
- /*!************************!*\
683
- !*** ./src/DbTable.ts ***!
684
- \************************/
685
- /*! no static exports found */
686
- /***/ (function(module, exports, __webpack_require__) {
687
-
688
- "use strict";
689
-
690
- Object.defineProperty(exports, "__esModule", { value: true });
691
- exports.DbTable = void 0;
692
- const tslib_1 = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
693
- const I = (0, tslib_1.__importStar)(__webpack_require__(/*! immutable */ "immutable"));
694
- const uui_core_1 = __webpack_require__(/*! @epam/uui-core */ "@epam/uui-core");
695
- const immutable_1 = __webpack_require__(/*! immutable */ "immutable");
696
- class DbTable {
697
- constructor(schema, state, q) {
698
- this.schema = schema;
699
- this.state = state;
700
- this.q = q;
701
- if (!state) {
702
- const indexes = (schema.indexes || []).map(indexDef => {
703
- return {
704
- field: indexDef,
705
- map: I.Map(),
706
- };
707
- });
708
- this.state = { pk: I.Map(), indexes };
709
- }
710
- if (!q) {
711
- this.q = {};
712
- }
713
- }
714
- keyToImmutable(id) {
715
- if (Array.isArray(id)) {
716
- return I.List(id);
717
- }
718
- else {
719
- return id;
720
- }
721
- }
722
- byId(id) {
723
- return this.state.pk.get(this.keyToImmutable(id));
724
- }
725
- getId(entity) {
726
- if (Array.isArray(this.schema.primaryKey)) {
727
- return this.schema.primaryKey.map((key) => entity[key]);
728
- }
729
- return entity[this.schema.primaryKey];
730
- }
731
- update(mutate) {
732
- const clone = new this.constructor(this.schema, this.state, this.q);
733
- mutate(clone);
734
- return clone;
192
+ update(mutate) {
193
+ const clone = new this.constructor(this.schema, this.state, this.q);
194
+ mutate(clone);
195
+ return clone;
735
196
  }
736
197
  /* Mutation */
737
198
  with(patch) {
@@ -749,7 +210,7 @@ class DbTable {
749
210
  }
750
211
  return { id, immId, patch: entityPatch, existing, updated, isNew: !existing, isDeleted };
751
212
  });
752
- const idVal = immutable_1.Seq.Keyed(updates.map(entity => [entity.immId, entity.updated]));
213
+ const idVal = Seq.Keyed(updates.map(entity => [entity.immId, entity.updated]));
753
214
  let newPk = this.state.pk.merge(idVal);
754
215
  // TBD: replace with deleteAll after migrating to immutable 4
755
216
  updates.filter(u => u.isDeleted).forEach(u => {
@@ -820,13 +281,13 @@ class DbTable {
820
281
  for (let n = 0; n < indexes.length; n++) {
821
282
  const index = indexes[n];
822
283
  if (index.field in filter) {
823
- const _a = filter, _b = index.field, condition = _a[_b], rest = (0, tslib_1.__rest)(_a, [typeof _b === "symbol" ? _b : _b + ""]);
284
+ const _a = filter, _b = index.field, condition = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
824
285
  let conditionValues = null;
825
286
  if (condition != null && typeof condition === "object") {
826
287
  // Attempt to use index for 'in' and 'isNull' criteria.
827
288
  // We need to be very conservative here, indexed field should work the same way as getPatternPredicate. So
828
289
  // - it's better to leave corner cases to getPatternPredicate
829
- const _c = condition, { in: inCriteria, isNull: nullCriteria } = _c, restCriteria = (0, tslib_1.__rest)(_c, ["in", "isNull"]);
290
+ const _c = condition, { in: inCriteria, isNull: nullCriteria } = _c, restCriteria = __rest(_c, ["in", "isNull"]);
830
291
  if (inCriteria && Array.isArray(inCriteria)) {
831
292
  conditionValues = inCriteria;
832
293
  }
@@ -873,15 +334,15 @@ class DbTable {
873
334
  result = this.state.pk.toArray();
874
335
  }
875
336
  if (filter) {
876
- let predicate = (0, uui_core_1.getFilterPredicate)(q.filter);
337
+ let predicate = getFilterPredicate(q.filter);
877
338
  result = result.filter(predicate);
878
339
  }
879
340
  if (q.search) {
880
- let searchFilter = (0, uui_core_1.getSearchFilter)(q.search);
341
+ let searchFilter = getSearchFilter(q.search);
881
342
  result = result.filter(item => searchFilter(this.schema.searchBy.map(field => item[field])));
882
343
  }
883
344
  if (q.sorting) {
884
- let comparer = (0, uui_core_1.getOrderComparer)(q.sorting);
345
+ let comparer = getOrderComparer(q.sorting);
885
346
  result = result.sort(comparer);
886
347
  }
887
348
  if (q.range) {
@@ -890,360 +351,86 @@ class DbTable {
890
351
  return result;
891
352
  }
892
353
  }
893
- exports.DbTable = DbTable;
894
-
895
-
896
- /***/ }),
897
354
 
898
- /***/ "./src/ListLoadingTracker.ts":
899
- /*!***********************************!*\
900
- !*** ./src/ListLoadingTracker.ts ***!
901
- \***********************************/
902
- /*! no static exports found */
903
- /***/ (function(module, exports, __webpack_require__) {
904
-
905
- "use strict";
906
-
907
- Object.defineProperty(exports, "__esModule", { value: true });
908
- exports.ListLoadingTracker = void 0;
909
- const tslib_1 = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
910
- class ListLoadingTracker {
911
- constructor(options) {
912
- this.options = options;
913
- this.cache = new Map();
914
- this.extractList = (options === null || options === void 0 ? void 0 : options.extractList) || ((r) => r);
915
- }
916
- prepare(request) {
917
- const { filter, sorting, search, range } = request, unknownFields = (0, tslib_1.__rest)(request, ["filter", "sorting", "search", "range"]);
918
- const options = {};
919
- if (filter) {
920
- options.filter = filter;
921
- }
922
- if (sorting) {
923
- options.sorting = sorting;
924
- }
925
- if (search) {
926
- options.search = search;
927
- }
928
- let keyObject = Object.assign(Object.assign({}, options), unknownFields);
929
- const key = JSON.stringify(keyObject);
930
- let entry = this.cache.get(key);
931
- if (!entry) {
932
- entry = { options, count: 0, maxCount: null, isComplete: false };
933
- this.cache.set(key, entry);
934
- }
935
- return { options, range, unknownFields, entry };
355
+ function unionPatches(patches) {
356
+ const result = {};
357
+ patches.forEach(patch => {
358
+ objectKeys(patch).forEach(tableName => {
359
+ result[tableName] = result[tableName] ? [...result[tableName], ...patch[tableName]] : patch[tableName];
360
+ });
361
+ });
362
+ return result;
363
+ }
364
+ function mergeEntityPatches(tables, patch) {
365
+ const result = {};
366
+ objectKeys(patch).forEach(key => {
367
+ const table = tables[key];
368
+ const groupedEntities = groupBy(patch[key], item => table.getId(item));
369
+ const tablePatch = map(groupedEntities, entities => {
370
+ const result = merge({}, ...entities);
371
+ if (process.env.NODE_ENV !== 'production') {
372
+ const props = objectKeys(result).filter(prop => Object.keys(countBy(entities.filter(entity => entity[prop] !== undefined), entity => entity[prop])).length > 1);
373
+ if (props.length) {
374
+ console.warn('mergeEntityPatches: Different property values found for the same entity.\nProperty names:\n', props, '\nEntities:\n', ...entities);
375
+ }
376
+ }
377
+ return result;
378
+ });
379
+ result[key] = tablePatch;
380
+ });
381
+ return result;
382
+ }
383
+ function flattenResponseHelper(result, object, tablesByTypeName) {
384
+ if (Array.isArray(object)) {
385
+ object.forEach(item => flattenResponseHelper(result, item, tablesByTypeName));
936
386
  }
937
- diff(request) {
938
- const { options, range, unknownFields, entry } = this.prepare(request);
939
- if (entry.isComplete) {
940
- return null;
941
- }
942
- if (!request.range) {
943
- return request;
944
- }
945
- else {
946
- const requestedMax = request.range.from + request.range.count;
947
- let missingCount = requestedMax - entry.count;
948
- if (entry.maxCount) {
949
- missingCount = Math.min(missingCount, entry.maxCount);
387
+ else if (typeof object === 'object') {
388
+ const clone = {};
389
+ let tableKey;
390
+ let fields = {};
391
+ if ('__typename' in object) {
392
+ const table = tablesByTypeName[object.__typename];
393
+ if (table) {
394
+ tableKey = table.schema.tableName;
395
+ fields = table.schema.fields;
950
396
  }
951
- if (missingCount > 0) {
952
- return Object.assign(Object.assign(Object.assign({}, options), unknownFields), { range: { from: entry.count, count: requestedMax - entry.count } });
397
+ }
398
+ for (let key in object) {
399
+ const value = object[key];
400
+ const field = fields[key];
401
+ if ((field && !!field.disableFlatten)
402
+ || typeof value !== 'object'
403
+ || value === null
404
+ || (Array.isArray(value) && value.every(item => typeof item !== 'object'))) {
405
+ clone[key] = value;
953
406
  }
954
407
  else {
955
- return null;
408
+ flattenResponseHelper(result, value, tablesByTypeName);
956
409
  }
957
410
  }
958
- }
959
- count(request) {
960
- const { entry } = this.prepare(request);
961
- return { knownCount: Math.max(entry.count, entry.maxCount), exactCount: entry.maxCount };
962
- }
963
- append(request, response) {
964
- const { options, range, unknownFields, entry } = this.prepare(request);
965
- if (response) {
966
- const list = this.extractList(response);
967
- if (list.count) {
968
- entry.maxCount = list.count;
969
- }
970
- if (!range) {
971
- entry.count = list.items.length;
972
- entry.maxCount = list.items.length;
973
- entry.isComplete = true;
974
- }
975
- else {
976
- const from = (list.from == null) ? range.from : list.from;
977
- if (list.items.length > 0) {
978
- entry.count = Math.max(entry.count, from + list.items.length);
979
- }
980
- if (list.items.length < range.count) {
981
- entry.maxCount = from + list.items.length;
982
- entry.count = entry.maxCount;
983
- entry.isComplete = true;
984
- }
985
- }
986
- }
987
- else {
988
- if (range) {
989
- entry.count = Math.max(entry.count, request.range.from + request.range.count);
990
- }
991
- else {
992
- entry.isComplete = true;
993
- }
994
- }
995
- }
996
- }
997
- exports.ListLoadingTracker = ListLoadingTracker;
998
-
999
-
1000
- /***/ }),
1001
-
1002
- /***/ "./src/Loader.ts":
1003
- /*!***********************!*\
1004
- !*** ./src/Loader.ts ***!
1005
- \***********************/
1006
- /*! no static exports found */
1007
- /***/ (function(module, exports, __webpack_require__) {
1008
-
1009
- "use strict";
1010
-
1011
- Object.defineProperty(exports, "__esModule", { value: true });
1012
- exports.Loader = void 0;
1013
- class Loader {
1014
- constructor(dbRef, getTracker, options) {
1015
- this.dbRef = dbRef;
1016
- this.getTracker = getTracker;
1017
- this.options = options;
1018
- this.currentRequests = new Set();
1019
- this.load = (inputRequest) => {
1020
- const result = {
1021
- isComplete: this.loaded.diff(inputRequest) == null,
1022
- isLoading: false,
1023
- request: inputRequest,
1024
- missing: this.loadedAndLoading.diff(inputRequest),
1025
- promise: null,
1026
- reload: null,
1027
- };
1028
- result.reload = () => {
1029
- result.missing = inputRequest;
1030
- this.loadImpl(result);
1031
- };
1032
- if (result.isComplete) {
1033
- // Everything requested is already loaded
1034
- result.isComplete = true;
1035
- result.isLoading = false;
1036
- result.promise = Promise.resolve();
1037
- return result;
1038
- }
1039
- else {
1040
- if (result.missing == null) {
1041
- // Everything requested is either loaded already, or being loaded
1042
- result.isComplete = false;
1043
- result.isLoading = true;
1044
- // There's no good way to tell which of current requests is querying requested data - there actually can be 2 of them.
1045
- // So we track all running requests, and await all of them in such case.
1046
- result.promise = Promise.all(this.currentRequests.entries()).then(() => { });
1047
- return result;
1048
- }
1049
- else {
1050
- // Something requested is not loaded, nor being loaded. Need to perform a new request.
1051
- this.loadImpl(result);
1052
- return result;
1053
- }
1054
- }
1055
- };
1056
- this.loaded = getTracker();
1057
- this.loadedAndLoading = getTracker();
1058
- }
1059
- loadImpl(state) {
1060
- this.loadedAndLoading.append(state.missing);
1061
- state.isLoading = true;
1062
- let serverRequest = state.missing;
1063
- if (this.options.clientToServerRequest) {
1064
- serverRequest = this.options.clientToServerRequest(serverRequest);
1065
- }
1066
- state.promise = this.options.api(serverRequest).then(result => {
1067
- this.loaded.append(state.missing, result);
1068
- this.loadedAndLoading.append(state.missing, result);
1069
- state.missing = null;
1070
- state.isLoading = false;
1071
- state.isComplete = true;
1072
- state.promise = Promise.resolve();
1073
- const flatten = this.options.convertToPatch(result);
1074
- this.options.postProcess && this.options.postProcess(flatten);
1075
- this.dbRef.commitFetch(flatten);
1076
- });
1077
- this.currentRequests.add(state.promise);
1078
- state.promise.finally(() => {
1079
- this.currentRequests.delete(state.promise);
1080
- });
1081
- return state.promise;
1082
- }
1083
- }
1084
- exports.Loader = Loader;
1085
-
1086
-
1087
- /***/ }),
1088
-
1089
- /***/ "./src/SimpleLoadingTracker.ts":
1090
- /*!*************************************!*\
1091
- !*** ./src/SimpleLoadingTracker.ts ***!
1092
- \*************************************/
1093
- /*! no static exports found */
1094
- /***/ (function(module, exports, __webpack_require__) {
1095
-
1096
- "use strict";
1097
-
1098
- Object.defineProperty(exports, "__esModule", { value: true });
1099
- exports.SimpleLoadingTracker = void 0;
1100
- class SimpleLoadingTracker {
1101
- constructor() {
1102
- this.set = new Set();
1103
- }
1104
- getKey(request) {
1105
- return JSON.stringify(request);
1106
- }
1107
- diff(request) {
1108
- return this.set.has(this.getKey(request)) ? null : request;
1109
- }
1110
- append(request, result) {
1111
- this.set.add(this.getKey(request));
1112
- }
1113
- }
1114
- exports.SimpleLoadingTracker = SimpleLoadingTracker;
1115
-
1116
-
1117
- /***/ }),
1118
-
1119
- /***/ "./src/index.ts":
1120
- /*!**********************!*\
1121
- !*** ./src/index.ts ***!
1122
- \**********************/
1123
- /*! no static exports found */
1124
- /***/ (function(module, exports, __webpack_require__) {
1125
-
1126
- "use strict";
1127
-
1128
- Object.defineProperty(exports, "__esModule", { value: true });
1129
- const tslib_1 = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
1130
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./types */ "./src/types.ts"), exports);
1131
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./Db */ "./src/Db.ts"), exports);
1132
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./DbTable */ "./src/DbTable.ts"), exports);
1133
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./DbRef */ "./src/DbRef.ts"), exports);
1134
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./tempIds */ "./src/tempIds.tsx"), exports);
1135
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./utils */ "./src/utils.ts"), exports);
1136
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./patchHelpers */ "./src/patchHelpers.ts"), exports);
1137
- (0, tslib_1.__exportStar)(__webpack_require__(/*! ./reactHooks */ "./src/reactHooks.ts"), exports);
1138
-
1139
-
1140
- /***/ }),
1141
-
1142
- /***/ "./src/patchHelpers.ts":
1143
- /*!*****************************!*\
1144
- !*** ./src/patchHelpers.ts ***!
1145
- \*****************************/
1146
- /*! no static exports found */
1147
- /***/ (function(module, exports, __webpack_require__) {
1148
-
1149
- "use strict";
1150
-
1151
- Object.defineProperty(exports, "__esModule", { value: true });
1152
- exports.getEntityParentDependencies = exports.getParentEntities = exports.hasServerFields = exports.isNew = exports.getId = exports.isClientOnly = exports.makeCumulativePatch = exports.isPatchBlank = exports.flattenResponse = exports.mergeEntityPatches = exports.unionPatches = void 0;
1153
- const tslib_1 = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
1154
- const types_1 = __webpack_require__(/*! ./types */ "./src/types.ts");
1155
- const I = (0, tslib_1.__importStar)(__webpack_require__(/*! immutable */ "immutable"));
1156
- const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
1157
- const lodash_groupby_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.groupby */ "lodash.groupby"));
1158
- const lodash_map_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.map */ "lodash.map"));
1159
- const lodash_merge_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.merge */ "lodash.merge"));
1160
- const lodash_countby_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.countby */ "lodash.countby"));
1161
- const lodash_filter_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.filter */ "lodash.filter"));
1162
- const lodash_foreach_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.foreach */ "lodash.foreach"));
1163
- const lodash_pick_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.pick */ "lodash.pick"));
1164
- function unionPatches(patches) {
1165
- const result = {};
1166
- patches.forEach(patch => {
1167
- (0, utils_1.objectKeys)(patch).forEach(tableName => {
1168
- result[tableName] = result[tableName] ? [...result[tableName], ...patch[tableName]] : patch[tableName];
1169
- });
1170
- });
1171
- return result;
1172
- }
1173
- exports.unionPatches = unionPatches;
1174
- function mergeEntityPatches(tables, patch) {
1175
- const result = {};
1176
- (0, utils_1.objectKeys)(patch).forEach(key => {
1177
- const table = tables[key];
1178
- const groupedEntities = (0, lodash_groupby_1.default)(patch[key], item => table.getId(item));
1179
- const tablePatch = (0, lodash_map_1.default)(groupedEntities, entities => {
1180
- const result = (0, lodash_merge_1.default)({}, ...entities);
1181
- if (true) {
1182
- const props = (0, utils_1.objectKeys)(result).filter(prop => Object.keys((0, lodash_countby_1.default)(entities.filter(entity => entity[prop] !== undefined), entity => entity[prop])).length > 1);
1183
- if (props.length) {
1184
- console.warn('mergeEntityPatches: Different property values found for the same entity.\nProperty names:\n', props, '\nEntities:\n', ...entities);
1185
- }
1186
- }
1187
- return result;
1188
- });
1189
- result[key] = tablePatch;
1190
- });
1191
- return result;
1192
- }
1193
- exports.mergeEntityPatches = mergeEntityPatches;
1194
- function flattenResponseHelper(result, object, tablesByTypeName) {
1195
- if (Array.isArray(object)) {
1196
- object.forEach(item => flattenResponseHelper(result, item, tablesByTypeName));
1197
- }
1198
- else if (typeof object === 'object') {
1199
- const clone = {};
1200
- let tableKey;
1201
- let fields = {};
1202
- if ('__typename' in object) {
1203
- const table = tablesByTypeName[object.__typename];
1204
- if (table) {
1205
- tableKey = table.schema.tableName;
1206
- fields = table.schema.fields;
1207
- }
1208
- }
1209
- for (let key in object) {
1210
- const value = object[key];
1211
- const field = fields[key];
1212
- if ((field && !!field.disableFlatten)
1213
- || typeof value !== 'object'
1214
- || value === null
1215
- || (Array.isArray(value) && value.every(item => typeof item !== 'object'))) {
1216
- clone[key] = value;
1217
- }
1218
- else {
1219
- flattenResponseHelper(result, value, tablesByTypeName);
1220
- }
1221
- }
1222
- if (tableKey) {
1223
- result[tableKey].push(clone);
1224
- }
411
+ if (tableKey) {
412
+ result[tableKey].push(clone);
413
+ }
1225
414
  }
1226
415
  }
1227
416
  function flattenResponse(response, tables) {
1228
417
  const result = {};
1229
418
  let tablesByTypeName = {};
1230
419
  Object.values(tables).forEach(table => tablesByTypeName[table.schema.typeName] = table);
1231
- (0, utils_1.objectKeys)(tables).forEach(tableName => tablesByTypeName);
1232
- (0, utils_1.objectKeys)(tables).forEach(key => result[key] = []);
420
+ objectKeys(tables).forEach(tableName => tablesByTypeName);
421
+ objectKeys(tables).forEach(key => result[key] = []);
1233
422
  flattenResponseHelper(result, response, tablesByTypeName);
1234
423
  return result;
1235
424
  }
1236
- exports.flattenResponse = flattenResponse;
1237
425
  function isPatchBlank(patch) {
1238
- return !(0, utils_1.objectKeys)(patch).some(key => patch[key].length > 0);
426
+ return !objectKeys(patch).some(key => patch[key].length > 0);
1239
427
  }
1240
- exports.isPatchBlank = isPatchBlank;
1241
428
  /**
1242
429
  * Given several patches, creates a new single patch with all fields from all entities in all patches.
1243
430
  */
1244
431
  function makeCumulativePatch(updatedDb, patches, clientIdsMap) {
1245
432
  const result = {};
1246
- (0, utils_1.objectKeys)(updatedDb.tables).forEach(entityName => {
433
+ objectKeys(updatedDb.tables).forEach(entityName => {
1247
434
  const table = updatedDb.tables[entityName];
1248
435
  const schema = table.schema;
1249
436
  let ids = I.Set();
@@ -1261,47 +448,42 @@ function makeCumulativePatch(updatedDb, patches, clientIdsMap) {
1261
448
  });
1262
449
  return result;
1263
450
  }
1264
- exports.makeCumulativePatch = makeCumulativePatch;
1265
451
  function isClientOnly(entity, schema) {
1266
452
  if (typeof schema.isClientOnly === 'function') {
1267
453
  return schema.isClientOnly(entity);
1268
454
  }
1269
455
  return !!schema.isClientOnly;
1270
456
  }
1271
- exports.isClientOnly = isClientOnly;
1272
457
  function getId(entity, schema) {
1273
458
  if (typeof schema.primaryKey == 'string') {
1274
459
  return entity[schema.primaryKey];
1275
460
  }
1276
461
  const result = [];
1277
- (0, lodash_foreach_1.default)((0, lodash_pick_1.default)(entity, schema.primaryKey), (value) => {
462
+ forEach(pick(entity, schema.primaryKey), (value) => {
1278
463
  result.push(value);
1279
464
  });
1280
465
  return result;
1281
466
  }
1282
- exports.getId = getId;
1283
467
  function isNew(entity, schema, clientIdsMap) {
1284
468
  const id = getId(entity, schema);
1285
469
  return !clientIdsMap.clientToServer(id);
1286
470
  }
1287
- exports.isNew = isNew;
1288
471
  function hasServerFields(entity, schema, clientIdsMap, tables) {
1289
472
  const fullEntity = Object.assign(Object.assign({}, tables[schema.tableName].byId(entity.id) || {}), entity);
1290
473
  if (isClientOnly(fullEntity, schema)) {
1291
474
  return false;
1292
475
  }
1293
- return (0, utils_1.objectKeys)(entity).some(fieldName => {
476
+ return objectKeys(entity).some(fieldName => {
1294
477
  const fieldSchema = schema.fields[fieldName];
1295
478
  return !fieldSchema || !(fieldSchema.isClientOnly || fieldSchema.isReadOnly || (fieldSchema.isGenerated && !isNew(entity, schema, clientIdsMap)));
1296
479
  });
1297
480
  }
1298
- exports.hasServerFields = hasServerFields;
1299
481
  function getParentEntities(patch, tables) {
1300
482
  const dependenciesPatch = {};
1301
- (0, utils_1.objectKeys)(patch).forEach(key => {
483
+ objectKeys(patch).forEach(key => {
1302
484
  const table = tables[key];
1303
485
  const tableSchema = table.schema;
1304
- const fields = (0, lodash_filter_1.default)((0, lodash_map_1.default)(tableSchema.fields, (field, name) => (Object.assign(Object.assign({}, field), { name }))), field => field.fk && field.fk.relationType == types_1.DbRelationType.Aggregation);
486
+ const fields = filter(map(tableSchema.fields, (field, name) => (Object.assign(Object.assign({}, field), { name }))), field => field.fk && field.fk.relationType == DbRelationType.Aggregation);
1305
487
  const tablePatch = patch[key];
1306
488
  fields.forEach(field => {
1307
489
  const { fk: { tableName }, name } = field;
@@ -1309,7 +491,7 @@ function getParentEntities(patch, tables) {
1309
491
  const actualTableName = (typeof tableName == 'function' ? tableName(entity) : tableName);
1310
492
  const dbEntity = table.byId(table.getId(entity));
1311
493
  const parentEntity = tables[actualTableName].byId(dbEntity[name]);
1312
- const idFields = (0, lodash_pick_1.default)(parentEntity, tables[actualTableName].schema.primaryKey);
494
+ const idFields = pick(parentEntity, tables[actualTableName].schema.primaryKey);
1313
495
  if (parentEntity) {
1314
496
  dependenciesPatch[actualTableName] = dependenciesPatch[actualTableName] || [];
1315
497
  dependenciesPatch[actualTableName].push(idFields);
@@ -1319,7 +501,6 @@ function getParentEntities(patch, tables) {
1319
501
  });
1320
502
  return dependenciesPatch;
1321
503
  }
1322
- exports.getParentEntities = getParentEntities;
1323
504
  function getEntityParentDependencies(entity, entityName, tables) {
1324
505
  let patch = { [entityName]: [entity] };
1325
506
  const resultPatches = [];
@@ -1335,64 +516,14 @@ function getEntityParentDependencies(entity, entityName, tables) {
1335
516
  result = mergeEntityPatches(tables, result);
1336
517
  return result;
1337
518
  }
1338
- exports.getEntityParentDependencies = getEntityParentDependencies;
1339
-
1340
-
1341
- /***/ }),
1342
-
1343
- /***/ "./src/reactHooks.ts":
1344
- /*!***************************!*\
1345
- !*** ./src/reactHooks.ts ***!
1346
- \***************************/
1347
- /*! no static exports found */
1348
- /***/ (function(module, exports, __webpack_require__) {
1349
-
1350
- "use strict";
1351
-
1352
- Object.defineProperty(exports, "__esModule", { value: true });
1353
- exports.useDbView = exports.useDbRef = exports.DbContext = void 0;
1354
- const react_1 = __webpack_require__(/*! react */ "react");
1355
- exports.DbContext = (0, react_1.createContext)(null);
1356
- function useDbRef() {
1357
- return (0, react_1.useContext)(exports.DbContext);
1358
- }
1359
- exports.useDbRef = useDbRef;
1360
- function useDbView(fn, params, options) {
1361
- const dbRef = useDbRef();
1362
- const [state, setState] = (0, react_1.useState)();
1363
- const subscription = (0, react_1.useMemo)(() => dbRef.subscribe(Object.assign({ compute: fn }, options), params, setState), []);
1364
- subscription.update(params);
1365
- (0, react_1.useEffect)(() => {
1366
- return () => subscription.unsubscribe();
1367
- }, []);
1368
- return subscription.currentValue;
1369
- }
1370
- exports.useDbView = useDbView;
1371
-
1372
519
 
1373
- /***/ }),
1374
-
1375
- /***/ "./src/tempIds.tsx":
1376
- /*!*************************!*\
1377
- !*** ./src/tempIds.tsx ***!
1378
- \*************************/
1379
- /*! no static exports found */
1380
- /***/ (function(module, exports, __webpack_require__) {
1381
-
1382
- "use strict";
1383
-
1384
- Object.defineProperty(exports, "__esModule", { value: true });
1385
- exports.TempIdMap = exports.isTempId = exports.getTempId = void 0;
1386
- const utils_1 = __webpack_require__(/*! ./utils */ "./src/utils.ts");
1387
520
  let lastTempId = -1;
1388
521
  function getTempId() {
1389
522
  return --lastTempId;
1390
523
  }
1391
- exports.getTempId = getTempId;
1392
524
  function isTempId(val) {
1393
525
  return typeof val === 'number' && val < 0;
1394
526
  }
1395
- exports.isTempId = isTempId;
1396
527
  class TempIdMap {
1397
528
  constructor(db) {
1398
529
  this.db = db;
@@ -1440,7 +571,7 @@ class TempIdMap {
1440
571
  }
1441
572
  copyPatch(patch) {
1442
573
  const newPatch = Object.assign({}, patch);
1443
- (0, utils_1.objectKeys)(patch).forEach(tableName => {
574
+ objectKeys(patch).forEach(tableName => {
1444
575
  let tablePatch = patch[tableName].map(entityPatch => (Object.assign({}, entityPatch)));
1445
576
  newPatch[tableName] = tablePatch;
1446
577
  });
@@ -1448,9 +579,9 @@ class TempIdMap {
1448
579
  }
1449
580
  // Iterate thru every field in every patch for every table, matching certain field criteria. The patch is mutated!
1450
581
  mapFields(patch, filter, callback) {
1451
- (0, utils_1.objectKeys)(patch).forEach(tableName => {
582
+ objectKeys(patch).forEach(tableName => {
1452
583
  const schema = this.db.tables[tableName].schema;
1453
- const fields = (0, utils_1.objectKeys)(schema.fields || [])
584
+ const fields = objectKeys(schema.fields || [])
1454
585
  .map(fieldName => {
1455
586
  const fieldSchema = schema.fields[fieldName];
1456
587
  if (filter(fieldSchema, fieldName)) {
@@ -1537,7 +668,7 @@ class TempIdMap {
1537
668
  return patch;
1538
669
  }
1539
670
  appendServerMapping(response) {
1540
- (0, utils_1.objectKeys)(response.submit).forEach(tableName => {
671
+ objectKeys(response.submit).forEach(tableName => {
1541
672
  if (this.db.tables[tableName]) {
1542
673
  const tablePatch = response.submit[tableName];
1543
674
  if (tablePatch) {
@@ -1556,256 +687,375 @@ class TempIdMap {
1556
687
  });
1557
688
  }
1558
689
  }
1559
- exports.TempIdMap = TempIdMap;
1560
-
1561
690
 
1562
- /***/ }),
1563
-
1564
- /***/ "./src/types.ts":
1565
- /*!**********************!*\
1566
- !*** ./src/types.ts ***!
1567
- \**********************/
1568
- /*! no static exports found */
1569
- /***/ (function(module, exports, __webpack_require__) {
1570
-
1571
- "use strict";
1572
-
1573
- Object.defineProperty(exports, "__esModule", { value: true });
1574
- exports.DbRelationType = void 0;
1575
- var DbRelationType;
1576
- (function (DbRelationType) {
1577
- DbRelationType[DbRelationType["Aggregation"] = 0] = "Aggregation";
1578
- DbRelationType[DbRelationType["Association"] = 1] = "Association";
1579
- })(DbRelationType = exports.DbRelationType || (exports.DbRelationType = {}));
1580
-
1581
-
1582
- /***/ }),
1583
-
1584
- /***/ "./src/utils.ts":
1585
- /*!**********************!*\
1586
- !*** ./src/utils.ts ***!
1587
- \**********************/
1588
- /*! no static exports found */
1589
- /***/ (function(module, exports, __webpack_require__) {
1590
-
1591
- "use strict";
1592
-
1593
- Object.defineProperty(exports, "__esModule", { value: true });
1594
- exports.difference = exports.defaultCompareViewDependencies = exports.objectKeys = void 0;
1595
- const tslib_1 = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
1596
- const shallowequal_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! shallowequal */ "shallowequal"));
1597
- const lodash_zip_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.zip */ "lodash.zip"));
1598
- const lodash_transform_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.transform */ "lodash.transform"));
1599
- const lodash_isequal_1 = (0, tslib_1.__importDefault)(__webpack_require__(/*! lodash.isequal */ "lodash.isequal"));
1600
- // TBD: New typescript would contain better typing for this. Remove this hack after update.
1601
- exports.objectKeys = Object.keys;
1602
- function defaultCompareViewDependencies(prev, next) {
1603
- if (Array.isArray(prev) && Array.isArray(next)) {
1604
- if (prev.length === next.length) {
1605
- return (0, lodash_zip_1.default)(prev, next).every(([p, n]) => (0, shallowequal_1.default)(p, n));
1606
- }
1607
- return false;
1608
- }
1609
- return (0, shallowequal_1.default)(prev, next);
1610
- }
1611
- exports.defaultCompareViewDependencies = defaultCompareViewDependencies;
1612
- /**
1613
- * Deep diff between two object, using lodash
1614
- * @param {Object} object Object compared
1615
- * @param {Object} base Object to compare with
1616
- * @return {Object} Return a new object who represent the diff
1617
- */
1618
- function difference(object, base) {
1619
- function changes(object, base) {
1620
- return (0, lodash_transform_1.default)(object, function (result, value, key) {
1621
- if (!(0, lodash_isequal_1.default)(value, base[key])) {
1622
- result[key] = (typeof value === "object" && typeof base[key] === "object") ? changes(value, base[key]) : value;
691
+ class Loader {
692
+ constructor(dbRef, getTracker, options) {
693
+ this.dbRef = dbRef;
694
+ this.getTracker = getTracker;
695
+ this.options = options;
696
+ this.currentRequests = new Set();
697
+ this.load = (inputRequest) => {
698
+ const result = {
699
+ isComplete: this.loaded.diff(inputRequest) == null,
700
+ isLoading: false,
701
+ request: inputRequest,
702
+ missing: this.loadedAndLoading.diff(inputRequest),
703
+ promise: null,
704
+ reload: null,
705
+ };
706
+ result.reload = () => {
707
+ result.missing = inputRequest;
708
+ this.loadImpl(result);
709
+ };
710
+ if (result.isComplete) {
711
+ // Everything requested is already loaded
712
+ result.isComplete = true;
713
+ result.isLoading = false;
714
+ result.promise = Promise.resolve();
715
+ return result;
1623
716
  }
1624
- });
1625
- }
1626
- return changes(object, base);
1627
- }
1628
- exports.difference = difference;
1629
-
1630
-
1631
- /***/ }),
1632
-
1633
- /***/ 0:
1634
- /*!*************************!*\
1635
- !*** multi ./index.tsx ***!
1636
- \*************************/
1637
- /*! no static exports found */
1638
- /***/ (function(module, exports, __webpack_require__) {
1639
-
1640
- module.exports = __webpack_require__(/*! /Users/Aliaksei_Manetau/WebstormProjects/uui/uui-db/index.tsx */"./index.tsx");
1641
-
1642
-
1643
- /***/ }),
1644
-
1645
- /***/ "@epam/uui-core":
1646
- /*!*********************************!*\
1647
- !*** external "@epam/uui-core" ***!
1648
- \*********************************/
1649
- /*! no static exports found */
1650
- /***/ (function(module, exports) {
1651
-
1652
- module.exports = require("@epam/uui-core");
1653
-
1654
- /***/ }),
1655
-
1656
- /***/ "immutable":
1657
- /*!****************************!*\
1658
- !*** external "immutable" ***!
1659
- \****************************/
1660
- /*! no static exports found */
1661
- /***/ (function(module, exports) {
1662
-
1663
- module.exports = require("immutable");
1664
-
1665
- /***/ }),
1666
-
1667
- /***/ "lodash.countby":
1668
- /*!*********************************!*\
1669
- !*** external "lodash.countby" ***!
1670
- \*********************************/
1671
- /*! no static exports found */
1672
- /***/ (function(module, exports) {
1673
-
1674
- module.exports = require("lodash.countby");
1675
-
1676
- /***/ }),
1677
-
1678
- /***/ "lodash.filter":
1679
- /*!********************************!*\
1680
- !*** external "lodash.filter" ***!
1681
- \********************************/
1682
- /*! no static exports found */
1683
- /***/ (function(module, exports) {
1684
-
1685
- module.exports = require("lodash.filter");
1686
-
1687
- /***/ }),
1688
-
1689
- /***/ "lodash.foreach":
1690
- /*!*********************************!*\
1691
- !*** external "lodash.foreach" ***!
1692
- \*********************************/
1693
- /*! no static exports found */
1694
- /***/ (function(module, exports) {
1695
-
1696
- module.exports = require("lodash.foreach");
1697
-
1698
- /***/ }),
1699
-
1700
- /***/ "lodash.groupby":
1701
- /*!*********************************!*\
1702
- !*** external "lodash.groupby" ***!
1703
- \*********************************/
1704
- /*! no static exports found */
1705
- /***/ (function(module, exports) {
1706
-
1707
- module.exports = require("lodash.groupby");
1708
-
1709
- /***/ }),
1710
-
1711
- /***/ "lodash.isempty":
1712
- /*!*********************************!*\
1713
- !*** external "lodash.isempty" ***!
1714
- \*********************************/
1715
- /*! no static exports found */
1716
- /***/ (function(module, exports) {
1717
-
1718
- module.exports = require("lodash.isempty");
1719
-
1720
- /***/ }),
1721
-
1722
- /***/ "lodash.isequal":
1723
- /*!*********************************!*\
1724
- !*** external "lodash.isequal" ***!
1725
- \*********************************/
1726
- /*! no static exports found */
1727
- /***/ (function(module, exports) {
1728
-
1729
- module.exports = require("lodash.isequal");
1730
-
1731
- /***/ }),
1732
-
1733
- /***/ "lodash.map":
1734
- /*!*****************************!*\
1735
- !*** external "lodash.map" ***!
1736
- \*****************************/
1737
- /*! no static exports found */
1738
- /***/ (function(module, exports) {
1739
-
1740
- module.exports = require("lodash.map");
1741
-
1742
- /***/ }),
1743
-
1744
- /***/ "lodash.merge":
1745
- /*!*******************************!*\
1746
- !*** external "lodash.merge" ***!
1747
- \*******************************/
1748
- /*! no static exports found */
1749
- /***/ (function(module, exports) {
1750
-
1751
- module.exports = require("lodash.merge");
1752
-
1753
- /***/ }),
1754
-
1755
- /***/ "lodash.pick":
1756
- /*!******************************!*\
1757
- !*** external "lodash.pick" ***!
1758
- \******************************/
1759
- /*! no static exports found */
1760
- /***/ (function(module, exports) {
1761
-
1762
- module.exports = require("lodash.pick");
1763
-
1764
- /***/ }),
1765
-
1766
- /***/ "lodash.transform":
1767
- /*!***********************************!*\
1768
- !*** external "lodash.transform" ***!
1769
- \***********************************/
1770
- /*! no static exports found */
1771
- /***/ (function(module, exports) {
1772
-
1773
- module.exports = require("lodash.transform");
1774
-
1775
- /***/ }),
1776
-
1777
- /***/ "lodash.zip":
1778
- /*!*****************************!*\
1779
- !*** external "lodash.zip" ***!
1780
- \*****************************/
1781
- /*! no static exports found */
1782
- /***/ (function(module, exports) {
1783
-
1784
- module.exports = require("lodash.zip");
1785
-
1786
- /***/ }),
1787
-
1788
- /***/ "react":
1789
- /*!************************!*\
1790
- !*** external "react" ***!
1791
- \************************/
1792
- /*! no static exports found */
1793
- /***/ (function(module, exports) {
1794
-
1795
- module.exports = require("react");
717
+ else {
718
+ if (result.missing == null) {
719
+ // Everything requested is either loaded already, or being loaded
720
+ result.isComplete = false;
721
+ result.isLoading = true;
722
+ // There's no good way to tell which of current requests is querying requested data - there actually can be 2 of them.
723
+ // So we track all running requests, and await all of them in such case.
724
+ result.promise = Promise.all(this.currentRequests.entries()).then(() => { });
725
+ return result;
726
+ }
727
+ else {
728
+ // Something requested is not loaded, nor being loaded. Need to perform a new request.
729
+ this.loadImpl(result);
730
+ return result;
731
+ }
732
+ }
733
+ };
734
+ this.loaded = getTracker();
735
+ this.loadedAndLoading = getTracker();
736
+ }
737
+ loadImpl(state) {
738
+ this.loadedAndLoading.append(state.missing);
739
+ state.isLoading = true;
740
+ let serverRequest = state.missing;
741
+ if (this.options.clientToServerRequest) {
742
+ serverRequest = this.options.clientToServerRequest(serverRequest);
743
+ }
744
+ state.promise = this.options.api(serverRequest).then(result => {
745
+ this.loaded.append(state.missing, result);
746
+ this.loadedAndLoading.append(state.missing, result);
747
+ state.missing = null;
748
+ state.isLoading = false;
749
+ state.isComplete = true;
750
+ state.promise = Promise.resolve();
751
+ const flatten = this.options.convertToPatch(result);
752
+ this.options.postProcess && this.options.postProcess(flatten);
753
+ this.dbRef.commitFetch(flatten);
754
+ });
755
+ this.currentRequests.add(state.promise);
756
+ state.promise.finally(() => {
757
+ this.currentRequests.delete(state.promise);
758
+ });
759
+ return state.promise;
760
+ }
761
+ }
1796
762
 
1797
- /***/ }),
763
+ class SimpleLoadingTracker {
764
+ constructor() {
765
+ this.set = new Set();
766
+ }
767
+ getKey(request) {
768
+ return JSON.stringify(request);
769
+ }
770
+ diff(request) {
771
+ return this.set.has(this.getKey(request)) ? null : request;
772
+ }
773
+ append(request, result) {
774
+ this.set.add(this.getKey(request));
775
+ }
776
+ }
1798
777
 
1799
- /***/ "shallowequal":
1800
- /*!*******************************!*\
1801
- !*** external "shallowequal" ***!
1802
- \*******************************/
1803
- /*! no static exports found */
1804
- /***/ (function(module, exports) {
778
+ class ListLoadingTracker {
779
+ constructor(options) {
780
+ this.options = options;
781
+ this.cache = new Map();
782
+ this.extractList = (options === null || options === void 0 ? void 0 : options.extractList) || ((r) => r);
783
+ }
784
+ prepare(request) {
785
+ const { filter, sorting, search, range } = request, unknownFields = __rest(request, ["filter", "sorting", "search", "range"]);
786
+ const options = {};
787
+ if (filter) {
788
+ options.filter = filter;
789
+ }
790
+ if (sorting) {
791
+ options.sorting = sorting;
792
+ }
793
+ if (search) {
794
+ options.search = search;
795
+ }
796
+ let keyObject = Object.assign(Object.assign({}, options), unknownFields);
797
+ const key = JSON.stringify(keyObject);
798
+ let entry = this.cache.get(key);
799
+ if (!entry) {
800
+ entry = { options, count: 0, maxCount: null, isComplete: false };
801
+ this.cache.set(key, entry);
802
+ }
803
+ return { options, range, unknownFields, entry };
804
+ }
805
+ diff(request) {
806
+ const { options, range, unknownFields, entry } = this.prepare(request);
807
+ if (entry.isComplete) {
808
+ return null;
809
+ }
810
+ if (!request.range) {
811
+ return request;
812
+ }
813
+ else {
814
+ const requestedMax = request.range.from + request.range.count;
815
+ let missingCount = requestedMax - entry.count;
816
+ if (entry.maxCount) {
817
+ missingCount = Math.min(missingCount, entry.maxCount);
818
+ }
819
+ if (missingCount > 0) {
820
+ return Object.assign(Object.assign(Object.assign({}, options), unknownFields), { range: { from: entry.count, count: requestedMax - entry.count } });
821
+ }
822
+ else {
823
+ return null;
824
+ }
825
+ }
826
+ }
827
+ count(request) {
828
+ const { entry } = this.prepare(request);
829
+ return { knownCount: Math.max(entry.count, entry.maxCount), exactCount: entry.maxCount };
830
+ }
831
+ append(request, response) {
832
+ const { options, range, unknownFields, entry } = this.prepare(request);
833
+ if (response) {
834
+ const list = this.extractList(response);
835
+ if (list.count) {
836
+ entry.maxCount = list.count;
837
+ }
838
+ if (!range) {
839
+ entry.count = list.items.length;
840
+ entry.maxCount = list.items.length;
841
+ entry.isComplete = true;
842
+ }
843
+ else {
844
+ const from = (list.from == null) ? range.from : list.from;
845
+ if (list.items.length > 0) {
846
+ entry.count = Math.max(entry.count, from + list.items.length);
847
+ }
848
+ if (list.items.length < range.count) {
849
+ entry.maxCount = from + list.items.length;
850
+ entry.count = entry.maxCount;
851
+ entry.isComplete = true;
852
+ }
853
+ }
854
+ }
855
+ else {
856
+ if (range) {
857
+ entry.count = Math.max(entry.count, request.range.from + request.range.count);
858
+ }
859
+ else {
860
+ entry.isComplete = true;
861
+ }
862
+ }
863
+ }
864
+ }
1805
865
 
1806
- module.exports = require("shallowequal");
866
+ class DbRef {
867
+ constructor(blank) {
868
+ this.blank = blank;
869
+ this.log = [];
870
+ this.autoSave = true;
871
+ this.savedPoint = 0;
872
+ this.throttleSaveMs = 1000;
873
+ /* Update subscriptions (aka live views) */
874
+ this.lastSubscriptionId = 1;
875
+ this.subscriptions = new Map();
876
+ this.updateHandlers = [];
877
+ /* Error Subscriptions */
878
+ this.saveErrorHandlers = [];
879
+ /* Save scheduling */
880
+ this.enqueueSave = batch(() => __awaiter(this, void 0, void 0, function* () {
881
+ const cumulativePatch = this.makeCumulativePatch();
882
+ const lastLogEntry = this.log.length;
883
+ if (isEmpty(cumulativePatch)) {
884
+ return;
885
+ }
886
+ try {
887
+ const response = yield this.savePatch(cumulativePatch);
888
+ this.applyResponse(response, lastLogEntry);
889
+ this.update();
890
+ }
891
+ catch (error) {
892
+ this.saveError(cumulativePatch, error);
893
+ this.update();
894
+ throw error;
895
+ }
896
+ }));
897
+ this.handleBeforeUnload = (e) => {
898
+ if (this.enqueueSave.isBusy) {
899
+ e.returnValue = false;
900
+ return false;
901
+ }
902
+ };
903
+ this.loaders = [];
904
+ this.db = blank;
905
+ this.base = blank;
906
+ this.tempIdMap = new TempIdMap(blank);
907
+ this.idMap = this.tempIdMap;
908
+ window.addEventListener('beforeunload', this.handleBeforeUnload);
909
+ }
910
+ /** Saves all committed patches. Useful only if autoSave is off. */
911
+ save() {
912
+ return this.enqueueSave();
913
+ }
914
+ getAutoSave() {
915
+ return this.autoSave;
916
+ }
917
+ setAutoSave(val) {
918
+ if (this.autoSave != val) {
919
+ this.autoSave = val;
920
+ this.autoSave && this.enqueueSave();
921
+ this.update();
922
+ }
923
+ }
924
+ revert() {
925
+ this.db = this.base;
926
+ this.log = this.log.slice(0, this.savedPoint);
927
+ this.update();
928
+ }
929
+ /** Concrete DbRef instances should override and implement their save logic in this method */
930
+ savePatch(patch) {
931
+ return Promise.resolve({ submit: {} });
932
+ }
933
+ /* Db Update logic */
934
+ commit(patch) {
935
+ const dbBeforeUpdate = this.db.with(patch);
936
+ patch = this.beforeUpdate(patch, dbBeforeUpdate.tables, this.db.tables);
937
+ patch = mergeEntityPatches(this.db.tables, patch);
938
+ this.log.push({ patch });
939
+ this.db = this.db.with(patch);
940
+ this.autoSave && this.enqueueSave(null, { throttleMs: this.throttleSaveMs });
941
+ this.update();
942
+ }
943
+ beforeUpdate(patch, tables, prevTables) {
944
+ let patchAndDependencies = {};
945
+ objectKeys(tables).filter(entityName => patch[entityName] && !tables[entityName].schema.beforeUpdate).forEach(entityName => {
946
+ patchAndDependencies[entityName] = patch[entityName];
947
+ });
948
+ objectKeys(tables).filter(entityName => patch[entityName] && tables[entityName].schema.beforeUpdate).forEach(entityName => {
949
+ const schema = tables[entityName].schema;
950
+ const { beforeUpdate } = schema;
951
+ let context = {
952
+ clientIdsMap: this.tempIdMap,
953
+ schema,
954
+ tables,
955
+ prevTables,
956
+ };
957
+ const results = patch[entityName].map(e => beforeUpdate(e, context));
958
+ const updatedPatch = { [entityName]: results.map(result => result.entity) };
959
+ const dependentEntityPatchesForUpdate = unionPatches(results.filter(result => result.dependentEntities).map(result => result.dependentEntities));
960
+ const dependentEntityPatches = this.beforeUpdate(dependentEntityPatchesForUpdate, tables, prevTables);
961
+ patchAndDependencies = mergeEntityPatches(tables, unionPatches([patchAndDependencies, updatedPatch, dependentEntityPatches]));
962
+ });
963
+ return patchAndDependencies;
964
+ }
965
+ commitFetch(patch) {
966
+ patch = this.tempIdMap.serverToClientPatch(patch);
967
+ this.rebase(this.base.with(patch));
968
+ this.update();
969
+ }
970
+ rebase(newBase) {
971
+ this.base = newBase;
972
+ this.db = newBase;
973
+ for (let n = this.savedPoint; n < this.log.length; n++) {
974
+ this.db = this.db.with(this.log[n].patch);
975
+ }
976
+ }
977
+ makeCumulativePatch() {
978
+ const lastLogEntry = this.log.length;
979
+ const logEntriesToSave = this.log.slice(this.savedPoint, lastLogEntry);
980
+ let cumulativePatch = makeCumulativePatch(this.db, logEntriesToSave.map(t => t.patch), this.tempIdMap);
981
+ cumulativePatch = this.tempIdMap.clientToServerPatch(cumulativePatch);
982
+ return cumulativePatch;
983
+ }
984
+ applyResponse(response, newSavedPoint) {
985
+ this.tempIdMap.appendServerMapping(response);
986
+ let serverPatch = flattenResponse(response.submit, this.db.tables);
987
+ serverPatch = mergeEntityPatches(this.db.tables, serverPatch);
988
+ this.savedPoint = newSavedPoint;
989
+ this.base = this.db;
990
+ this.commitFetch(serverPatch);
991
+ }
992
+ subscribe(view, params, onUpdate) {
993
+ const id = this.lastSubscriptionId++;
994
+ const subscription = {
995
+ update: (params) => {
996
+ subscription.currentParams = params;
997
+ subscription.currentValue = this.db.runView(view, params);
998
+ return subscription.currentValue;
999
+ },
1000
+ currentParams: null,
1001
+ currentValue: null,
1002
+ onUpdate,
1003
+ unsubscribe: () => { this.subscriptions.delete(id); },
1004
+ };
1005
+ subscription.update(params);
1006
+ this.subscriptions.set(id, subscription);
1007
+ return subscription;
1008
+ }
1009
+ onUpdate(handler) {
1010
+ this.subscribe({
1011
+ compute: db => db,
1012
+ compareResults: (a, b) => a === b,
1013
+ }, null, handler);
1014
+ }
1015
+ update() {
1016
+ this.subscriptions.forEach(subscription => {
1017
+ const previousValue = subscription.currentValue;
1018
+ subscription.update(subscription.currentParams);
1019
+ if (subscription.currentValue !== previousValue && subscription.onUpdate) {
1020
+ subscription.onUpdate(subscription.currentValue);
1021
+ }
1022
+ });
1023
+ }
1024
+ onSaveError(handler) {
1025
+ this.saveErrorHandlers.push(handler);
1026
+ }
1027
+ saveError(request, error) {
1028
+ this.saveErrorHandlers.forEach(handler => handler(request, error));
1029
+ }
1030
+ makeLoader(options) {
1031
+ const loader = new Loader(this, () => new SimpleLoadingTracker(), options);
1032
+ this.loaders.push(loader);
1033
+ return loader;
1034
+ }
1035
+ makeListLoader(options) {
1036
+ const loader = new Loader(this, () => new ListLoadingTracker(), options);
1037
+ this.loaders.push(loader);
1038
+ return loader;
1039
+ }
1040
+ reload() {
1041
+ this.loaders = [];
1042
+ }
1043
+ }
1807
1044
 
1808
- /***/ })
1045
+ const DbContext = createContext(null);
1046
+ function useDbRef() {
1047
+ return useContext(DbContext);
1048
+ }
1049
+ function useDbView(fn, params, options) {
1050
+ const dbRef = useDbRef();
1051
+ const [state, setState] = useState();
1052
+ const subscription = useMemo(() => dbRef.subscribe(Object.assign({ compute: fn }, options), params, setState), []);
1053
+ subscription.update(params);
1054
+ useEffect(() => {
1055
+ return () => subscription.unsubscribe();
1056
+ }, []);
1057
+ return subscription.currentValue;
1058
+ }
1809
1059
 
1810
- /******/ });
1811
- //# sourceMappingURL=index.js.map
1060
+ export { Db, DbContext, DbRef, DbRelationType, DbTable, TempIdMap, defaultCompareViewDependencies, difference, flattenResponse, getEntityParentDependencies, getId, getParentEntities, getTempId, hasServerFields, isClientOnly, isNew, isPatchBlank, isTempId, makeCumulativePatch, mergeEntityPatches, objectKeys, unionPatches, useDbRef, useDbView };
1061
+ //# sourceMappingURL=index.js.map