ar_sync 1.0.5 → 1.1.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.
data/core/ArSyncStore.js CHANGED
@@ -32,51 +32,55 @@ var __spreadArrays = (this && this.__spreadArrays) || function () {
32
32
  };
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
34
  var ArSyncApi_1 = require("./ArSyncApi");
35
- var ModelBatchRequest = {
36
- timer: null,
37
- apiRequests: {},
38
- fetch: function (api, query, id) {
35
+ var ModelBatchRequest = /** @class */ (function () {
36
+ function ModelBatchRequest() {
37
+ this.timer = null;
38
+ this.apiRequests = new Map();
39
+ }
40
+ ModelBatchRequest.prototype.fetch = function (api, query, id) {
39
41
  var _this = this;
40
42
  this.setTimer();
41
- return new Promise(function (resolve) {
43
+ return new Promise(function (resolve, reject) {
42
44
  var queryJSON = JSON.stringify(query);
43
- var apiRequest = _this.apiRequests[api] = _this.apiRequests[api] || {};
44
- var queryRequests = apiRequest[queryJSON] = apiRequest[queryJSON] || { query: query, requests: {} };
45
- var request = queryRequests.requests[id] = queryRequests.requests[id] || { id: id, callbacks: [] };
46
- request.callbacks.push(resolve);
45
+ var apiRequest = _this.apiRequests.get(api);
46
+ if (!apiRequest)
47
+ _this.apiRequests.set(api, apiRequest = new Map());
48
+ var queryRequests = apiRequest.get(queryJSON);
49
+ if (!queryRequests)
50
+ apiRequest.set(queryJSON, queryRequests = { query: query, requests: new Map() });
51
+ var request = queryRequests.requests.get(id);
52
+ if (!request)
53
+ queryRequests.requests.set(id, request = { id: id, callbacks: [] });
54
+ request.callbacks.push({ resolve: resolve, reject: reject });
47
55
  });
48
- },
49
- batchFetch: function () {
50
- var apiRequests = this.apiRequests;
51
- for (var api in apiRequests) {
52
- var apiRequest = apiRequests[api];
53
- var _loop_1 = function (query, requests) {
54
- var ids = Object.values(requests).map(function (_a) {
55
- var id = _a.id;
56
- return id;
57
- });
56
+ };
57
+ ModelBatchRequest.prototype.batchFetch = function () {
58
+ this.apiRequests.forEach(function (apiRequest, api) {
59
+ apiRequest.forEach(function (_a) {
60
+ var query = _a.query, requests = _a.requests;
61
+ var ids = Array.from(requests.keys());
58
62
  ArSyncApi_1.default.syncFetch({ api: api, query: query, params: { ids: ids } }).then(function (models) {
59
63
  for (var _i = 0, models_1 = models; _i < models_1.length; _i++) {
60
64
  var model = models_1[_i];
61
- requests[model.id].model = model;
62
- }
63
- for (var _a = 0, _b = Object.values(requests); _a < _b.length; _a++) {
64
- var _c = _b[_a], model = _c.model, callbacks = _c.callbacks;
65
- for (var _d = 0, callbacks_1 = callbacks; _d < callbacks_1.length; _d++) {
66
- var callback = callbacks_1[_d];
67
- callback(model);
68
- }
65
+ var req = requests.get(model.id);
66
+ if (req)
67
+ req.model = model;
69
68
  }
69
+ requests.forEach(function (_a) {
70
+ var model = _a.model, callbacks = _a.callbacks;
71
+ callbacks.forEach(function (cb) { return cb.resolve(model); });
72
+ });
73
+ }).catch(function (e) {
74
+ requests.forEach(function (_a) {
75
+ var callbacks = _a.callbacks;
76
+ callbacks.forEach(function (cb) { return cb.reject(e); });
77
+ });
70
78
  });
71
- };
72
- for (var _i = 0, _a = Object.values(apiRequest); _i < _a.length; _i++) {
73
- var _b = _a[_i], query = _b.query, requests = _b.requests;
74
- _loop_1(query, requests);
75
- }
76
- }
77
- this.apiRequests = {};
78
- },
79
- setTimer: function () {
79
+ });
80
+ });
81
+ this.apiRequests.clear();
82
+ };
83
+ ModelBatchRequest.prototype.setTimer = function () {
80
84
  var _this = this;
81
85
  if (this.timer)
82
86
  return;
@@ -84,8 +88,10 @@ var ModelBatchRequest = {
84
88
  _this.timer = null;
85
89
  _this.batchFetch();
86
90
  }, 20);
87
- }
88
- };
91
+ };
92
+ return ModelBatchRequest;
93
+ }());
94
+ var modelBatchRequest = new ModelBatchRequest;
89
95
  var ArSyncContainerBase = /** @class */ (function () {
90
96
  function ArSyncContainerBase() {
91
97
  this.listeners = [];
@@ -94,9 +100,14 @@ var ArSyncContainerBase = /** @class */ (function () {
94
100
  ArSyncContainerBase.prototype.initForReload = function (request) {
95
101
  var _this = this;
96
102
  this.networkSubscriber = ArSyncStore.connectionManager.subscribeNetwork(function (state) {
97
- if (state) {
98
- ArSyncApi_1.default.syncFetch(request).then(function (data) {
99
- if (_this.data) {
103
+ if (!state) {
104
+ if (_this.onConnectionChange)
105
+ _this.onConnectionChange(false);
106
+ return;
107
+ }
108
+ if (request.id != null) {
109
+ modelBatchRequest.fetch(request.api, request.query, request.id).then(function (data) {
110
+ if (_this.data && data) {
100
111
  _this.replaceData(data);
101
112
  if (_this.onConnectionChange)
102
113
  _this.onConnectionChange(true);
@@ -106,8 +117,17 @@ var ArSyncContainerBase = /** @class */ (function () {
106
117
  });
107
118
  }
108
119
  else {
109
- if (_this.onConnectionChange)
110
- _this.onConnectionChange(false);
120
+ ArSyncApi_1.default.syncFetch(request).then(function (data) {
121
+ if (_this.data && data) {
122
+ _this.replaceData(data);
123
+ if (_this.onConnectionChange)
124
+ _this.onConnectionChange(true);
125
+ if (_this.onChange)
126
+ _this.onChange([], _this.data);
127
+ }
128
+ }).catch(function (e) {
129
+ console.error("failed to reload. " + e);
130
+ });
111
131
  }
112
132
  });
113
133
  };
@@ -136,7 +156,7 @@ var ArSyncContainerBase = /** @class */ (function () {
136
156
  }
137
157
  this.listeners = [];
138
158
  };
139
- ArSyncContainerBase.compactQuery = function (query) {
159
+ ArSyncContainerBase.compactQueryAttributes = function (query) {
140
160
  function compactAttributes(attributes) {
141
161
  var attrs = {};
142
162
  var keys = [];
@@ -154,7 +174,7 @@ var ArSyncContainerBase = /** @class */ (function () {
154
174
  return [true, false];
155
175
  if (keys.length === 1)
156
176
  return [keys[0], false];
157
- return [keys];
177
+ return [keys, false];
158
178
  }
159
179
  var needsEscape = attrs['attributes'] || attrs['params'] || attrs['as'];
160
180
  if (keys.length === 0)
@@ -180,13 +200,10 @@ var ArSyncContainerBase = /** @class */ (function () {
180
200
  result.attributes = attributes;
181
201
  return result;
182
202
  }
183
- try {
184
- var result = compactQuery(query);
185
- return result === true ? {} : result;
186
- }
187
- catch (e) {
188
- throw JSON.stringify(query) + e.stack;
189
- }
203
+ var result = compactQuery(query);
204
+ if (typeof result === 'object' && 'attributes' in result)
205
+ return result.attributes;
206
+ return result === true ? {} : result;
190
207
  };
191
208
  ArSyncContainerBase.parseQuery = function (query, attrsonly) {
192
209
  var attributes = {};
@@ -232,14 +249,22 @@ var ArSyncContainerBase = /** @class */ (function () {
232
249
  ArSyncContainerBase._load = function (_a, root) {
233
250
  var api = _a.api, id = _a.id, params = _a.params, query = _a.query;
234
251
  var parsedQuery = ArSyncRecord.parseQuery(query);
235
- var compactQuery = ArSyncRecord.compactQuery(parsedQuery);
236
- if (id) {
237
- return ModelBatchRequest.fetch(api, compactQuery, id).then(function (data) { return new ArSyncRecord(parsedQuery, data, null, root); });
252
+ var compactQueryAttributes = ArSyncRecord.compactQueryAttributes(parsedQuery);
253
+ if (id != null) {
254
+ return modelBatchRequest.fetch(api, compactQueryAttributes, id).then(function (data) {
255
+ if (!data)
256
+ throw { retry: false };
257
+ var request = { api: api, id: id, query: compactQueryAttributes };
258
+ return new ArSyncRecord(parsedQuery, data, request, root);
259
+ });
238
260
  }
239
261
  else {
240
- var request_1 = { api: api, query: compactQuery, params: params };
262
+ var request_1 = { api: api, query: compactQueryAttributes, params: params };
241
263
  return ArSyncApi_1.default.syncFetch(request_1).then(function (response) {
242
- if (response.collection && response.order) {
264
+ if (!response) {
265
+ throw { retry: false };
266
+ }
267
+ else if (response.collection && response.order) {
243
268
  return new ArSyncCollection(response.sync_keys, 'collection', parsedQuery, response, request_1, root);
244
269
  }
245
270
  else if (response instanceof Array) {
@@ -278,16 +303,14 @@ var ArSyncRecord = /** @class */ (function (_super) {
278
303
  if (request)
279
304
  _this.initForReload(request);
280
305
  _this.query = query;
306
+ _this.queryAttributes = query.attributes || {};
281
307
  _this.data = {};
282
308
  _this.children = {};
283
309
  _this.replaceData(data);
284
310
  return _this;
285
311
  }
286
312
  ArSyncRecord.prototype.setSyncKeys = function (sync_keys) {
287
- this.sync_keys = sync_keys;
288
- if (!this.sync_keys) {
289
- this.sync_keys = [];
290
- }
313
+ this.sync_keys = sync_keys !== null && sync_keys !== void 0 ? sync_keys : [];
291
314
  };
292
315
  ArSyncRecord.prototype.replaceData = function (data) {
293
316
  this.setSyncKeys(data.sync_keys);
@@ -297,8 +320,8 @@ var ArSyncRecord = /** @class */ (function (_super) {
297
320
  this.data.id = data.id;
298
321
  }
299
322
  this.paths = [];
300
- for (var key in this.query.attributes) {
301
- var subQuery = this.query.attributes[key];
323
+ for (var key in this.queryAttributes) {
324
+ var subQuery = this.queryAttributes[key];
302
325
  var aliasName = subQuery.as || key;
303
326
  var subData = data[aliasName];
304
327
  var child = this.children[aliasName];
@@ -345,9 +368,9 @@ var ArSyncRecord = /** @class */ (function (_super) {
345
368
  }
346
369
  }
347
370
  }
348
- if (this.query.attributes['*']) {
371
+ if (this.queryAttributes['*']) {
349
372
  for (var key in data) {
350
- if (!this.query.attributes[key] && this.data[key] !== data[key]) {
373
+ if (!this.queryAttributes[key] && this.data[key] !== data[key]) {
351
374
  this.mark();
352
375
  this.data[key] = data[key];
353
376
  }
@@ -357,8 +380,8 @@ var ArSyncRecord = /** @class */ (function (_super) {
357
380
  };
358
381
  ArSyncRecord.prototype.onNotify = function (notifyData, path) {
359
382
  var _this = this;
360
- var action = notifyData.action, class_name = notifyData.class_name, id = notifyData.id;
361
- var query = path && this.query.attributes[path];
383
+ var action = notifyData.action, className = notifyData.class_name, id = notifyData.id;
384
+ var query = path && this.queryAttributes[path];
362
385
  var aliasName = (query && query.as) || path;
363
386
  if (action === 'remove') {
364
387
  var child = this.children[aliasName];
@@ -372,7 +395,7 @@ var ArSyncRecord = /** @class */ (function (_super) {
372
395
  else if (action === 'add') {
373
396
  if (this.data[aliasName] && this.data[aliasName].id === id)
374
397
  return;
375
- ModelBatchRequest.fetch(class_name, ArSyncRecord.compactQuery(query), id).then(function (data) {
398
+ modelBatchRequest.fetch(className, ArSyncRecord.compactQueryAttributes(query), id).then(function (data) {
376
399
  if (!data || !_this.data)
377
400
  return;
378
401
  var model = new ArSyncRecord(query, data, null, _this.root);
@@ -385,16 +408,21 @@ var ArSyncRecord = /** @class */ (function (_super) {
385
408
  model.parentModel = _this;
386
409
  model.parentKey = aliasName;
387
410
  _this.onChange([aliasName], model.data);
411
+ }).catch(function (e) {
412
+ console.error("failed to load " + className + ":" + id + " " + e);
388
413
  });
389
414
  }
390
415
  else {
391
416
  var field = notifyData.field;
392
417
  var query_2 = field ? this.patchQuery(field) : this.reloadQuery();
393
- if (query_2)
394
- ModelBatchRequest.fetch(class_name, query_2, id).then(function (data) {
395
- if (_this.data)
396
- _this.update(data);
397
- });
418
+ if (!query_2)
419
+ return;
420
+ modelBatchRequest.fetch(className, query_2, id).then(function (data) {
421
+ if (_this.data)
422
+ _this.update(data);
423
+ }).catch(function (e) {
424
+ console.error("failed to load patch " + className + ":" + id + " " + e);
425
+ });
398
426
  }
399
427
  };
400
428
  ArSyncRecord.prototype.subscribeAll = function () {
@@ -404,7 +432,7 @@ var ArSyncRecord = /** @class */ (function (_super) {
404
432
  var key = _a[_i];
405
433
  this.subscribe(key, callback);
406
434
  }
407
- var _loop_2 = function (path) {
435
+ var _loop_1 = function (path) {
408
436
  var pathCallback = function (data) { return _this.onNotify(data, path); };
409
437
  for (var _i = 0, _a = this_1.sync_keys; _i < _a.length; _i++) {
410
438
  var key = _a[_i];
@@ -414,48 +442,38 @@ var ArSyncRecord = /** @class */ (function (_super) {
414
442
  var this_1 = this;
415
443
  for (var _b = 0, _c = this.paths; _b < _c.length; _b++) {
416
444
  var path = _c[_b];
417
- _loop_2(path);
445
+ _loop_1(path);
418
446
  }
419
447
  };
420
448
  ArSyncRecord.prototype.patchQuery = function (key) {
421
- var val = this.query.attributes[key];
422
- if (!val)
423
- return;
424
- var attributes = val.attributes, as = val.as, params = val.params;
425
- if (attributes && Object.keys(val.attributes).length === 0)
426
- attributes = null;
427
- if (!attributes && !as && !params)
428
- return key;
429
- var result = {};
430
- if (attributes)
431
- result.attributes = attributes;
432
- if (as)
433
- result.as = as;
434
- if (params)
435
- result.params = params;
436
- return result;
449
+ var _a;
450
+ var subQuery = this.queryAttributes[key];
451
+ if (subQuery)
452
+ return _a = {}, _a[key] = subQuery, _a;
437
453
  };
438
454
  ArSyncRecord.prototype.reloadQuery = function () {
439
- var _a;
440
455
  if (this.reloadQueryCache)
441
456
  return this.reloadQueryCache;
442
- var reloadQuery = this.reloadQueryCache = { attributes: [] };
443
- for (var key in this.query.attributes) {
457
+ var arrayQuery = [];
458
+ var hashQuery = {};
459
+ for (var key in this.queryAttributes) {
444
460
  if (key === 'sync_keys')
445
461
  continue;
446
- var val = this.query.attributes[key];
462
+ var val = this.queryAttributes[key];
447
463
  if (!val || !val.attributes) {
448
- reloadQuery.attributes.push(key);
464
+ arrayQuery === null || arrayQuery === void 0 ? void 0 : arrayQuery.push(key);
465
+ hashQuery[key] = true;
449
466
  }
450
467
  else if (!val.params && Object.keys(val.attributes).length === 0) {
451
- reloadQuery.attributes.push((_a = {}, _a[key] = val, _a));
468
+ arrayQuery = null;
469
+ hashQuery[key] = val;
452
470
  }
453
471
  }
454
- return reloadQuery;
472
+ return this.reloadQueryCache = arrayQuery || hashQuery;
455
473
  };
456
474
  ArSyncRecord.prototype.update = function (data) {
457
475
  for (var key in data) {
458
- var subQuery = this.query.attributes[key];
476
+ var subQuery = this.queryAttributes[key];
459
477
  if (subQuery && subQuery.attributes && Object.keys(subQuery.attributes).length > 0)
460
478
  continue;
461
479
  if (this.data[key] === data[key])
@@ -483,42 +501,39 @@ var ArSyncCollection = /** @class */ (function (_super) {
483
501
  __extends(ArSyncCollection, _super);
484
502
  function ArSyncCollection(sync_keys, path, query, data, request, root) {
485
503
  var _this = _super.call(this) || this;
486
- _this.order = { limit: null, mode: 'asc', key: 'id' };
504
+ _this.ordering = { orderBy: 'id', direction: 'asc' };
487
505
  _this.aliasOrderKey = 'id';
488
506
  _this.root = root;
489
507
  _this.path = path;
490
508
  _this.query = query;
491
- _this.compactQuery = ArSyncRecord.compactQuery(query);
509
+ _this.queryAttributes = query.attributes || {};
510
+ _this.compactQueryAttributes = ArSyncRecord.compactQueryAttributes(query);
492
511
  if (request)
493
512
  _this.initForReload(request);
494
- if (query.params && (query.params.order || query.params.limit)) {
495
- _this.setOrdering(query.params.limit, query.params.order);
513
+ if (query.params) {
514
+ _this.setOrdering(query.params);
496
515
  }
497
516
  _this.data = [];
498
517
  _this.children = [];
499
518
  _this.replaceData(data, sync_keys);
500
519
  return _this;
501
520
  }
502
- ArSyncCollection.prototype.setOrdering = function (limit, order) {
503
- var mode = 'asc';
504
- var key = 'id';
505
- if (order === 'asc' || order === 'desc') {
506
- mode = order;
507
- }
508
- else if (typeof order === 'object' && order) {
509
- var keys = Object.keys(order);
510
- if (keys.length > 1)
511
- throw 'multiple order keys are not supported';
512
- if (keys.length === 1)
513
- key = keys[0];
514
- mode = order[key] === 'asc' ? 'asc' : 'desc';
515
- }
516
- var limitNumber = (typeof limit === 'number') ? limit : null;
517
- if (limitNumber !== null && key !== 'id')
518
- throw 'limit with custom order key is not supported';
519
- var subQuery = this.query.attributes[key];
520
- this.aliasOrderKey = (subQuery && subQuery.as) || key;
521
- this.order = { limit: limitNumber, mode: mode, key: key };
521
+ ArSyncCollection.prototype.setOrdering = function (ordering) {
522
+ var direction = 'asc';
523
+ var orderBy = 'id';
524
+ var first = undefined;
525
+ var last = undefined;
526
+ if (ordering.direction === 'desc')
527
+ direction = ordering.direction;
528
+ if (typeof ordering.orderBy === 'string')
529
+ orderBy = ordering.orderBy;
530
+ if (typeof ordering.first === 'number')
531
+ first = ordering.first;
532
+ if (typeof ordering.last === 'number')
533
+ last = ordering.last;
534
+ var subQuery = this.queryAttributes[orderBy];
535
+ this.aliasOrderKey = (subQuery && subQuery.as) || orderBy;
536
+ this.ordering = { first: first, last: last, direction: direction, orderBy: orderBy };
522
537
  };
523
538
  ArSyncCollection.prototype.setSyncKeys = function (sync_keys) {
524
539
  var _this = this;
@@ -531,31 +546,31 @@ var ArSyncCollection = /** @class */ (function (_super) {
531
546
  };
532
547
  ArSyncCollection.prototype.replaceData = function (data, sync_keys) {
533
548
  this.setSyncKeys(sync_keys);
534
- var existings = {};
549
+ var existings = new Map();
535
550
  for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
536
551
  var child = _a[_i];
537
- existings[child.data.id] = child;
552
+ existings.set(child.data.id, child);
538
553
  }
539
554
  var collection;
540
- if ('collection' in data && 'order' in data) {
541
- collection = data.collection;
542
- this.setOrdering(data.order.limit, data.order.mode);
555
+ if (Array.isArray(data)) {
556
+ collection = data;
543
557
  }
544
558
  else {
545
- collection = data;
559
+ collection = data.collection;
560
+ this.setOrdering(data.ordering);
546
561
  }
547
562
  var newChildren = [];
548
563
  var newData = [];
549
564
  for (var _b = 0, collection_1 = collection; _b < collection_1.length; _b++) {
550
565
  var subData = collection_1[_b];
551
- var model = null;
552
- if (typeof (subData) === 'object' && subData && 'id' in subData)
553
- model = existings[subData.id];
566
+ var model = undefined;
567
+ if (typeof (subData) === 'object' && subData && 'sync_keys' in subData)
568
+ model = existings.get(subData.id);
554
569
  var data_1 = subData;
555
570
  if (model) {
556
571
  model.replaceData(subData);
557
572
  }
558
- else if (subData.id) {
573
+ else if (subData.sync_keys) {
559
574
  model = new ArSyncRecord(this.query, subData, null, this.root);
560
575
  model.parentModel = this;
561
576
  model.parentKey = subData.id;
@@ -568,7 +583,7 @@ var ArSyncCollection = /** @class */ (function (_super) {
568
583
  }
569
584
  while (this.children.length) {
570
585
  var child = this.children.pop();
571
- if (!existings[child.data.id])
586
+ if (!existings.has(child.data.id))
572
587
  child.release();
573
588
  }
574
589
  if (this.data.length || newChildren.length)
@@ -587,63 +602,94 @@ var ArSyncCollection = /** @class */ (function (_super) {
587
602
  };
588
603
  ArSyncCollection.prototype.consumeAdd = function (className, id) {
589
604
  var _this = this;
605
+ var _a = this.ordering, first = _a.first, last = _a.last, direction = _a.direction;
606
+ var limit = first || last;
590
607
  if (this.data.findIndex(function (a) { return a.id === id; }) >= 0)
591
608
  return;
592
- if (this.order.limit === this.data.length) {
593
- if (this.order.mode === 'asc') {
594
- var last = this.data[this.data.length - 1];
595
- if (last && last.id < id)
596
- return;
609
+ if (limit && limit <= this.data.length) {
610
+ var lastItem = this.data[this.data.length - 1];
611
+ var firstItem = this.data[0];
612
+ if (direction === 'asc') {
613
+ if (first) {
614
+ if (lastItem && lastItem.id < id)
615
+ return;
616
+ }
617
+ else {
618
+ if (firstItem && id < firstItem.id)
619
+ return;
620
+ }
597
621
  }
598
622
  else {
599
- var last = this.data[this.data.length - 1];
600
- if (last && last.id > id)
601
- return;
623
+ if (first) {
624
+ if (lastItem && id < lastItem.id)
625
+ return;
626
+ }
627
+ else {
628
+ if (firstItem && firstItem.id < id)
629
+ return;
630
+ }
602
631
  }
603
632
  }
604
- ModelBatchRequest.fetch(className, this.compactQuery, id).then(function (data) {
633
+ modelBatchRequest.fetch(className, this.compactQueryAttributes, id).then(function (data) {
605
634
  if (!data || !_this.data)
606
635
  return;
607
636
  var model = new ArSyncRecord(_this.query, data, null, _this.root);
608
637
  model.parentModel = _this;
609
638
  model.parentKey = id;
610
- var overflow = _this.order.limit && _this.order.limit === _this.data.length;
639
+ var overflow = limit && limit <= _this.data.length;
611
640
  var rmodel;
612
641
  _this.mark();
613
642
  var orderKey = _this.aliasOrderKey;
614
- if (_this.order.mode === 'asc') {
615
- var last = _this.data[_this.data.length - 1];
616
- _this.children.push(model);
617
- _this.data.push(model.data);
618
- if (last && last[orderKey] > data[orderKey])
619
- _this.markAndSort();
620
- if (overflow) {
621
- rmodel = _this.children.shift();
622
- rmodel.release();
623
- _this.data.shift();
643
+ var firstItem = _this.data[0];
644
+ var lastItem = _this.data[_this.data.length - 1];
645
+ if (direction === 'asc') {
646
+ if (firstItem && data[orderKey] < firstItem[orderKey]) {
647
+ _this.children.unshift(model);
648
+ _this.data.unshift(model.data);
649
+ }
650
+ else {
651
+ var skipSort = lastItem && lastItem[orderKey] < data[orderKey];
652
+ _this.children.push(model);
653
+ _this.data.push(model.data);
654
+ if (!skipSort)
655
+ _this.markAndSort();
624
656
  }
625
657
  }
626
658
  else {
627
- var first = _this.data[0];
628
- _this.children.unshift(model);
629
- _this.data.unshift(model.data);
630
- if (first && first[orderKey] > data[orderKey])
631
- _this.markAndSort();
632
- if (overflow) {
659
+ if (firstItem && data[orderKey] > firstItem[orderKey]) {
660
+ _this.children.unshift(model);
661
+ _this.data.unshift(model.data);
662
+ }
663
+ else {
664
+ var skipSort = lastItem && lastItem[orderKey] > data[orderKey];
665
+ _this.children.push(model);
666
+ _this.data.push(model.data);
667
+ if (!skipSort)
668
+ _this.markAndSort();
669
+ }
670
+ }
671
+ if (overflow) {
672
+ if (first) {
633
673
  rmodel = _this.children.pop();
634
- rmodel.release();
635
674
  _this.data.pop();
636
675
  }
676
+ else {
677
+ rmodel = _this.children.shift();
678
+ _this.data.shift();
679
+ }
680
+ rmodel.release();
637
681
  }
638
682
  _this.onChange([model.id], model.data);
639
683
  if (rmodel)
640
684
  _this.onChange([rmodel.id], null);
685
+ }).catch(function (e) {
686
+ console.error("failed to load " + className + ":" + id + " " + e);
641
687
  });
642
688
  };
643
689
  ArSyncCollection.prototype.markAndSort = function () {
644
690
  this.mark();
645
691
  var orderKey = this.aliasOrderKey;
646
- if (this.order.mode === 'asc') {
692
+ if (this.ordering.direction === 'asc') {
647
693
  this.children.sort(function (a, b) { return a.data[orderKey] < b.data[orderKey] ? -1 : +1; });
648
694
  this.data.sort(function (a, b) { return a[orderKey] < b[orderKey] ? -1 : +1; });
649
695
  }
@@ -11,7 +11,7 @@ export default class ConnectionManager {
11
11
  unsubscribe: () => void;
12
12
  };
13
13
  subscribe(key: any, func: any): {
14
- unsubscribe: () => void;
14
+ unsubscribe(): void;
15
15
  };
16
16
  connect(key: any): any;
17
17
  disconnect(key: any): void;
@@ -40,6 +40,8 @@ var ConnectionManager = /** @class */ (function () {
40
40
  };
41
41
  ConnectionManager.prototype.subscribe = function (key, func) {
42
42
  var _this = this;
43
+ if (!this.networkStatus)
44
+ return { unsubscribe: function () { } };
43
45
  var subscription = this.connect(key);
44
46
  var id = subscription.serial++;
45
47
  subscription.ref++;