ar_sync 1.1.1 → 1.1.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c13bb4ca3915637f310817c9b5c689c12c05f0140cfe2d982da653bc251bf7e
4
- data.tar.gz: 447f9877703f3ba4cee8d590b6f63d91bc09486a86d2a709169ac245bcd592be
3
+ metadata.gz: '096573e72fb5d4dc465e79c9bf8b39617fb423d7d779534f4ce30768dda2b5b1'
4
+ data.tar.gz: c590f23a76420db7e056733ca895e56991cdcca8cfbd9908a503dc5ce57ab2f7
5
5
  SHA512:
6
- metadata.gz: dd149d8f9b3ee83ba0e72cc0924bffdcaa9fc144c29a25b544ed9959f270ab65514fb7f18d0410ed1afc88d9db59b2b3f1c964b1005b6eae3057c2d4416d7174
7
- data.tar.gz: c54c4e3b427c7f4bfec039bc4cacab491a413cc8e29a47307a4078e56266e7473c1171ed99bd5f3281b9afd509db298f293c9625250e040a7ef53f93c6d2f5ed
6
+ metadata.gz: 47d42249688cfef025fd2b9ea927d81962a786eded059a694ac5d069e7a0b0a48ca9bcc0d59a8d198bc4bb701cd86d4b98acc5c2c3de5b3018ac78f4b9487566
7
+ data.tar.gz: 88e61169ef8968905d8e9f341108f2c926ac23436ce30ad5e8f2ca7872a6e4e2644f24ff44769c5561589ba1954367325001675c2014b838053ccb6b1848ace9
@@ -5,13 +5,14 @@ jobs:
5
5
  strategy:
6
6
  fail-fast: false
7
7
  matrix:
8
- ruby: [ '2.7', '3.0', '3.1' ]
8
+ ruby: [ '3.1', '3.2', '3.3' ]
9
9
  gemfiles:
10
10
  - gemfiles/Gemfile-rails-6
11
- - gemfiles/Gemfile-rails-7
11
+ - gemfiles/Gemfile-rails-7-0
12
+ - gemfiles/Gemfile-rails-7-1
12
13
  runs-on: ubuntu-latest
13
14
  steps:
14
- - uses: actions/checkout@v2
15
+ - uses: actions/checkout@v4
15
16
  - uses: ruby/setup-ruby@v1
16
17
  with:
17
18
  ruby-version: ${{ matrix.ruby }}
data/.gitignore CHANGED
@@ -7,7 +7,9 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /test/*.sqlite3
10
+ /test/*.sqlite3-*
10
11
  /test/generated_*
11
12
  .ruby-version
12
13
  /node_modules/
13
14
  tsconfig.tsbuildinfo
15
+ Gemfile.lock
data/Gemfile CHANGED
@@ -4,4 +4,5 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in ar_sync.gemspec
6
6
  gemspec
7
+ gem 'sqlite3', '~> 1.4'
7
8
  gem 'ar_serializer'
data/ar_sync.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_dependency 'activerecord'
24
24
  spec.add_dependency 'ar_serializer'
25
- %w[rake pry sqlite3 activerecord-import].each do |gem_name|
25
+ %w[rake sqlite3 activerecord-import].each do |gem_name|
26
26
  spec.add_development_dependency gem_name
27
27
  end
28
28
  end
data/bin/console CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  require 'bundler/setup'
4
4
  require 'ar_sync'
5
- require 'pry'
5
+ require 'irb'
6
6
  require_relative '../test/model'
7
7
  ArSync.on_notification do |events|
8
8
  puts "\e[1m#{events.inspect}\e[m"
9
9
  end
10
10
 
11
- Pry.start
11
+ IRB.start
@@ -1,9 +1,5 @@
1
+ import { ArSyncStore, Request } from './ArSyncStore';
1
2
  import ConnectionAdapter from './ConnectionAdapter';
2
- interface Request {
3
- api: string;
4
- query: any;
5
- params?: any;
6
- }
7
3
  declare type Path = Readonly<(string | number)[]>;
8
4
  interface Change {
9
5
  path: Path;
@@ -12,8 +8,14 @@ interface Change {
12
8
  declare type ChangeCallback = (change: Change) => void;
13
9
  declare type LoadCallback = () => void;
14
10
  declare type ConnectionCallback = (status: boolean) => void;
15
- declare type SubscriptionType = 'load' | 'change' | 'connection';
11
+ declare type SubscriptionType = 'load' | 'change' | 'connection' | 'destroy';
16
12
  declare type SubscriptionCallback = ChangeCallback | LoadCallback | ConnectionCallback;
13
+ declare type ArSyncModelRef = {
14
+ key: string;
15
+ count: number;
16
+ timer: number | null;
17
+ model: ArSyncStore;
18
+ };
17
19
  declare type PathFirst<P extends Readonly<any[]>> = ((...args: P) => void) extends (first: infer First, ...other: any) => void ? First : never;
18
20
  declare type PathRest<U> = U extends Readonly<any[]> ? ((...args: U) => any) extends (head: any, ...args: infer T) => any ? U extends Readonly<[any, any, ...any[]]> ? T : never : never : never;
19
21
  declare type DigResult<Data, P extends Readonly<any[]>> = Data extends null | undefined ? Data : PathFirst<P> extends never ? Data : PathFirst<P> extends keyof Data ? (Data extends Readonly<any[]> ? undefined : never) | {
@@ -26,6 +28,7 @@ export default class ArSyncModel<T> {
26
28
  private _listeners;
27
29
  complete: boolean;
28
30
  notfound?: boolean;
31
+ destroyed: boolean;
29
32
  connected: boolean;
30
33
  data: T | null;
31
34
  static _cache: {
@@ -52,12 +55,7 @@ export default class ArSyncModel<T> {
52
55
  release(): void;
53
56
  static retrieveRef(request: Request, option?: {
54
57
  immutable: boolean;
55
- }): {
56
- key: string;
57
- count: number;
58
- timer: number | null;
59
- model: any;
60
- };
58
+ }): ArSyncModelRef;
61
59
  static _detach(ref: any): void;
62
60
  private static _attach;
63
61
  static setConnectionAdapter(adapter: ConnectionAdapter): void;
data/core/ArSyncModel.js CHANGED
@@ -5,19 +5,22 @@ var ConnectionManager_1 = require("./ConnectionManager");
5
5
  var ArSyncModel = /** @class */ (function () {
6
6
  function ArSyncModel(request, option) {
7
7
  var _this = this;
8
+ this.complete = false;
9
+ this.destroyed = false;
8
10
  this._ref = ArSyncModel.retrieveRef(request, option);
9
11
  this._listenerSerial = 0;
10
12
  this._listeners = {};
11
- this.complete = false;
12
- this.connected = ArSyncStore_1.default.connectionManager.networkStatus;
13
+ this.connected = ArSyncStore_1.ArSyncStore.connectionManager.networkStatus;
13
14
  var setData = function () {
14
15
  _this.data = _this._ref.model.data;
15
16
  _this.complete = _this._ref.model.complete;
16
17
  _this.notfound = _this._ref.model.notfound;
18
+ _this.destroyed = _this._ref.model.destroyed;
17
19
  };
18
20
  setData();
19
21
  this.subscribe('load', setData);
20
22
  this.subscribe('change', setData);
23
+ this.subscribe('destroy', setData);
21
24
  this.subscribe('connection', function (status) {
22
25
  _this.connected = status;
23
26
  });
@@ -81,13 +84,12 @@ var ArSyncModel = /** @class */ (function () {
81
84
  this._listeners[id].unsubscribe();
82
85
  this._listeners = {};
83
86
  ArSyncModel._detach(this._ref);
84
- this._ref = null;
85
87
  };
86
88
  ArSyncModel.retrieveRef = function (request, option) {
87
89
  var key = JSON.stringify([request, option]);
88
90
  var ref = this._cache[key];
89
91
  if (!ref) {
90
- var model = new ArSyncStore_1.default(request, option);
92
+ var model = new ArSyncStore_1.ArSyncStore(request, option);
91
93
  ref = this._cache[key] = { key: key, count: 0, timer: null, model: model };
92
94
  }
93
95
  this._attach(ref);
@@ -116,7 +118,7 @@ var ArSyncModel = /** @class */ (function () {
116
118
  clearTimeout(ref.timer);
117
119
  };
118
120
  ArSyncModel.setConnectionAdapter = function (adapter) {
119
- ArSyncStore_1.default.connectionManager = new ConnectionManager_1.default(adapter);
121
+ ArSyncStore_1.ArSyncStore.connectionManager = new ConnectionManager_1.default(adapter);
120
122
  };
121
123
  ArSyncModel.waitForLoad = function () {
122
124
  var models = [];
@@ -1,20 +1,28 @@
1
- export default class ArSyncStore {
1
+ export declare type Request = {
2
+ api: string;
3
+ query: any;
4
+ params?: any;
5
+ id?: any;
6
+ };
7
+ export declare class ArSyncStore {
2
8
  immutable: boolean;
3
9
  markedForFreezeObjects: any[];
4
10
  changes: any;
5
11
  eventListeners: any;
6
12
  markForRelease: true | undefined;
7
13
  container: any;
8
- request: any;
14
+ request: Request;
9
15
  complete: boolean;
10
16
  notfound?: boolean;
17
+ destroyed: boolean;
11
18
  data: any;
12
19
  changesBufferTimer: number | undefined | null;
13
20
  retryLoadTimer: number | undefined | null;
14
21
  static connectionManager: any;
15
- constructor(request: any, { immutable }?: {
22
+ constructor(request: Request, { immutable }?: {
16
23
  immutable?: boolean | undefined;
17
24
  });
25
+ handleDestroy(): void;
18
26
  load(retryCount: number): void;
19
27
  setChangesBufferTimer(): void;
20
28
  subscribe(event: any, callback: any): {
data/core/ArSyncStore.js CHANGED
@@ -31,6 +31,7 @@ var __spreadArrays = (this && this.__spreadArrays) || function () {
31
31
  return r;
32
32
  };
33
33
  Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.ArSyncStore = void 0;
34
35
  var ArSyncApi_1 = require("./ArSyncApi");
35
36
  var ModelBatchRequest = /** @class */ (function () {
36
37
  function ModelBatchRequest() {
@@ -62,7 +63,7 @@ var ModelBatchRequest = /** @class */ (function () {
62
63
  ArSyncApi_1.default.syncFetch({ api: api, query: query, params: { ids: ids } }).then(function (models) {
63
64
  for (var _i = 0, models_1 = models; _i < models_1.length; _i++) {
64
65
  var model = models_1[_i];
65
- var req = requests.get(model.id);
66
+ var req = requests.get(model._sync.id);
66
67
  if (req)
67
68
  req.model = model;
68
69
  }
@@ -95,8 +96,9 @@ var modelBatchRequest = new ModelBatchRequest;
95
96
  var ArSyncContainerBase = /** @class */ (function () {
96
97
  function ArSyncContainerBase() {
97
98
  this.listeners = [];
99
+ this.parentModel = null;
98
100
  }
99
- ArSyncContainerBase.prototype.replaceData = function (_data, _sync_keys) { };
101
+ ArSyncContainerBase.prototype.replaceData = function (_data, _parentSyncKeys) { };
100
102
  ArSyncContainerBase.prototype.initForReload = function (request) {
101
103
  var _this = this;
102
104
  this.networkSubscriber = ArSyncStore.connectionManager.subscribeNetwork(function (state) {
@@ -246,7 +248,7 @@ var ArSyncContainerBase = /** @class */ (function () {
246
248
  return attributes;
247
249
  return { attributes: attributes, as: column, params: params };
248
250
  };
249
- ArSyncContainerBase._load = function (_a, root) {
251
+ ArSyncContainerBase.load = function (_a, root) {
250
252
  var api = _a.api, id = _a.id, params = _a.params, query = _a.query;
251
253
  var parsedQuery = ArSyncRecord.parseQuery(query);
252
254
  var compactQueryAttributes = ArSyncRecord.compactQueryAttributes(parsedQuery);
@@ -255,7 +257,7 @@ var ArSyncContainerBase = /** @class */ (function () {
255
257
  if (!data)
256
258
  throw { retry: false };
257
259
  var request = { api: api, id: id, query: compactQueryAttributes };
258
- return new ArSyncRecord(parsedQuery, data, request, root);
260
+ return new ArSyncRecord(parsedQuery, data, request, root, null, null);
259
261
  });
260
262
  }
261
263
  else {
@@ -264,41 +266,25 @@ var ArSyncContainerBase = /** @class */ (function () {
264
266
  if (!response) {
265
267
  throw { retry: false };
266
268
  }
267
- else if (response.collection && response.order) {
268
- return new ArSyncCollection(response.sync_keys, 'collection', parsedQuery, response, request_1, root);
269
+ else if (response.collection && response.order && response._sync) {
270
+ return new ArSyncCollection(response._sync.keys, 'collection', parsedQuery, response, request_1, root, null, null);
269
271
  }
270
272
  else if (response instanceof Array) {
271
- return new ArSyncCollection([], '', parsedQuery, response, request_1, root);
273
+ return new ArSyncCollection([], '', parsedQuery, response, request_1, root, null, null);
272
274
  }
273
275
  else {
274
- return new ArSyncRecord(parsedQuery, response, request_1, root);
276
+ return new ArSyncRecord(parsedQuery, response, request_1, root, null, null);
275
277
  }
276
278
  });
277
279
  }
278
280
  };
279
- ArSyncContainerBase.load = function (apiParams, root) {
280
- var _this = this;
281
- if (!(apiParams instanceof Array))
282
- return this._load(apiParams, root);
283
- return new Promise(function (resolve, _reject) {
284
- var resultModels = [];
285
- var countdown = apiParams.length;
286
- apiParams.forEach(function (param, i) {
287
- _this._load(param, root).then(function (model) {
288
- resultModels[i] = model;
289
- countdown--;
290
- if (countdown === 0)
291
- resolve(resultModels);
292
- });
293
- });
294
- });
295
- };
296
281
  return ArSyncContainerBase;
297
282
  }());
298
283
  var ArSyncRecord = /** @class */ (function (_super) {
299
284
  __extends(ArSyncRecord, _super);
300
- function ArSyncRecord(query, data, request, root) {
285
+ function ArSyncRecord(query, data, request, root, parentModel, parentKey) {
301
286
  var _this = _super.call(this) || this;
287
+ _this.fetching = new Set();
302
288
  _this.root = root;
303
289
  if (request)
304
290
  _this.initForReload(request);
@@ -306,54 +292,49 @@ var ArSyncRecord = /** @class */ (function (_super) {
306
292
  _this.queryAttributes = query.attributes || {};
307
293
  _this.data = {};
308
294
  _this.children = {};
295
+ _this.rootRecord = !parentModel;
296
+ _this.id = data._sync.id;
297
+ _this.syncKeys = data._sync.keys;
309
298
  _this.replaceData(data);
299
+ _this.parentModel = parentModel;
300
+ _this.parentKey = parentKey;
310
301
  return _this;
311
302
  }
312
- ArSyncRecord.prototype.setSyncKeys = function (sync_keys) {
313
- this.sync_keys = sync_keys !== null && sync_keys !== void 0 ? sync_keys : [];
314
- };
315
303
  ArSyncRecord.prototype.replaceData = function (data) {
316
- this.setSyncKeys(data.sync_keys);
304
+ this.id = data._sync.id;
305
+ this.syncKeys = data._sync.keys;
317
306
  this.unsubscribeAll();
318
- if (this.data.id !== data.id) {
319
- this.mark();
320
- this.data.id = data.id;
321
- }
322
307
  this.paths = [];
323
308
  for (var key in this.queryAttributes) {
324
309
  var subQuery = this.queryAttributes[key];
325
310
  var aliasName = subQuery.as || key;
326
311
  var subData = data[aliasName];
327
312
  var child = this.children[aliasName];
328
- if (key === 'sync_keys')
313
+ if (key === '_sync')
329
314
  continue;
330
- if (subData instanceof Array || (subData && subData.collection && subData.order)) {
315
+ if (subData instanceof Array || (subData && subData.collection && subData.order && subData._sync)) {
331
316
  if (child) {
332
- child.replaceData(subData, this.sync_keys);
317
+ child.replaceData(subData, this.syncKeys);
333
318
  }
334
319
  else {
335
- var collection = new ArSyncCollection(this.sync_keys, key, subQuery, subData, null, this.root);
320
+ var collection = new ArSyncCollection(this.syncKeys, key, subQuery, subData, null, this.root, this, aliasName);
336
321
  this.mark();
337
322
  this.children[aliasName] = collection;
338
323
  this.data[aliasName] = collection.data;
339
- collection.parentModel = this;
340
- collection.parentKey = aliasName;
341
324
  }
342
325
  }
343
326
  else {
344
327
  if (subQuery.attributes && Object.keys(subQuery.attributes).length > 0)
345
328
  this.paths.push(key);
346
- if (subData && subData.sync_keys) {
329
+ if (subData && subData._sync) {
347
330
  if (child) {
348
331
  child.replaceData(subData);
349
332
  }
350
333
  else {
351
- var model = new ArSyncRecord(subQuery, subData, null, this.root);
334
+ var model = new ArSyncRecord(subQuery, subData, null, this.root, this, aliasName);
352
335
  this.mark();
353
336
  this.children[aliasName] = model;
354
337
  this.data[aliasName] = model.data;
355
- model.parentModel = this;
356
- model.parentKey = aliasName;
357
338
  }
358
339
  }
359
340
  else {
@@ -370,6 +351,8 @@ var ArSyncRecord = /** @class */ (function (_super) {
370
351
  }
371
352
  if (this.queryAttributes['*']) {
372
353
  for (var key in data) {
354
+ if (key === '_sync')
355
+ continue;
373
356
  if (!this.queryAttributes[key] && this.data[key] !== data[key]) {
374
357
  this.mark();
375
358
  this.data[key] = data[key];
@@ -380,11 +363,12 @@ var ArSyncRecord = /** @class */ (function (_super) {
380
363
  };
381
364
  ArSyncRecord.prototype.onNotify = function (notifyData, path) {
382
365
  var _this = this;
383
- var action = notifyData.action, className = notifyData.class_name, id = notifyData.id;
366
+ var action = notifyData.action, className = notifyData.class, id = notifyData.id;
384
367
  var query = path && this.queryAttributes[path];
385
368
  var aliasName = (query && query.as) || path;
386
369
  if (action === 'remove') {
387
370
  var child = this.children[aliasName];
371
+ this.fetching.delete(aliasName + ":" + id); // To cancel consumeAdd
388
372
  if (child)
389
373
  child.release();
390
374
  this.children[aliasName] = null;
@@ -393,20 +377,25 @@ var ArSyncRecord = /** @class */ (function (_super) {
393
377
  this.onChange([aliasName], null);
394
378
  }
395
379
  else if (action === 'add') {
396
- if (this.data[aliasName] && this.data[aliasName].id === id)
380
+ var child = this.children[aliasName];
381
+ if (child instanceof ArSyncRecord && child.id === id)
397
382
  return;
383
+ var fetchKey_1 = aliasName + ":" + id;
384
+ this.fetching.add(fetchKey_1);
398
385
  modelBatchRequest.fetch(className, ArSyncRecord.compactQueryAttributes(query), id).then(function (data) {
386
+ // Record already removed
387
+ if (!_this.fetching.has(fetchKey_1))
388
+ return;
389
+ _this.fetching.delete(fetchKey_1);
399
390
  if (!data || !_this.data)
400
391
  return;
401
- var model = new ArSyncRecord(query, data, null, _this.root);
392
+ var model = new ArSyncRecord(query, data, null, _this.root, _this, aliasName);
402
393
  var child = _this.children[aliasName];
403
394
  if (child)
404
395
  child.release();
405
396
  _this.children[aliasName] = model;
406
397
  _this.mark();
407
398
  _this.data[aliasName] = model.data;
408
- model.parentModel = _this;
409
- model.parentKey = aliasName;
410
399
  _this.onChange([aliasName], model.data);
411
400
  }).catch(function (e) {
412
401
  console.error("failed to load " + className + ":" + id + " " + e);
@@ -428,13 +417,13 @@ var ArSyncRecord = /** @class */ (function (_super) {
428
417
  ArSyncRecord.prototype.subscribeAll = function () {
429
418
  var _this = this;
430
419
  var callback = function (data) { return _this.onNotify(data); };
431
- for (var _i = 0, _a = this.sync_keys; _i < _a.length; _i++) {
420
+ for (var _i = 0, _a = this.syncKeys; _i < _a.length; _i++) {
432
421
  var key = _a[_i];
433
422
  this.subscribe(key, callback);
434
423
  }
435
424
  var _loop_1 = function (path) {
436
425
  var pathCallback = function (data) { return _this.onNotify(data, path); };
437
- for (var _i = 0, _a = this_1.sync_keys; _i < _a.length; _i++) {
426
+ for (var _i = 0, _a = this_1.syncKeys; _i < _a.length; _i++) {
438
427
  var key = _a[_i];
439
428
  this_1.subscribe(key + path, pathCallback);
440
429
  }
@@ -444,6 +433,11 @@ var ArSyncRecord = /** @class */ (function (_super) {
444
433
  var path = _c[_b];
445
434
  _loop_1(path);
446
435
  }
436
+ if (this.rootRecord) {
437
+ var key = this.syncKeys[0];
438
+ if (key)
439
+ this.subscribe(key + '_destroy', function () { return _this.root.handleDestroy(); });
440
+ }
447
441
  };
448
442
  ArSyncRecord.prototype.patchQuery = function (key) {
449
443
  var _a;
@@ -457,7 +451,7 @@ var ArSyncRecord = /** @class */ (function (_super) {
457
451
  var arrayQuery = [];
458
452
  var hashQuery = {};
459
453
  for (var key in this.queryAttributes) {
460
- if (key === 'sync_keys')
454
+ if (key === '_sync')
461
455
  continue;
462
456
  var val = this.queryAttributes[key];
463
457
  if (!val || !val.attributes) {
@@ -473,6 +467,8 @@ var ArSyncRecord = /** @class */ (function (_super) {
473
467
  };
474
468
  ArSyncRecord.prototype.update = function (data) {
475
469
  for (var key in data) {
470
+ if (key === '_sync')
471
+ continue;
476
472
  var subQuery = this.queryAttributes[key];
477
473
  if (subQuery && subQuery.attributes && Object.keys(subQuery.attributes).length > 0)
478
474
  continue;
@@ -492,17 +488,18 @@ var ArSyncRecord = /** @class */ (function (_super) {
492
488
  return;
493
489
  this.data = __assign({}, this.data);
494
490
  this.root.mark(this.data);
495
- if (this.parentModel)
491
+ if (this.parentModel && this.parentKey)
496
492
  this.parentModel.markAndSet(this.parentKey, this.data);
497
493
  };
498
494
  return ArSyncRecord;
499
495
  }(ArSyncContainerBase));
500
496
  var ArSyncCollection = /** @class */ (function (_super) {
501
497
  __extends(ArSyncCollection, _super);
502
- function ArSyncCollection(sync_keys, path, query, data, request, root) {
498
+ function ArSyncCollection(parentSyncKeys, path, query, data, request, root, parentModel, parentKey) {
503
499
  var _this = _super.call(this) || this;
504
500
  _this.ordering = { orderBy: 'id', direction: 'asc' };
505
501
  _this.aliasOrderKey = 'id';
502
+ _this.fetching = new Set();
506
503
  _this.root = root;
507
504
  _this.path = path;
508
505
  _this.query = query;
@@ -515,7 +512,9 @@ var ArSyncCollection = /** @class */ (function (_super) {
515
512
  }
516
513
  _this.data = [];
517
514
  _this.children = [];
518
- _this.replaceData(data, sync_keys);
515
+ _this.replaceData(data, parentSyncKeys);
516
+ _this.parentModel = parentModel;
517
+ _this.parentKey = parentKey;
519
518
  return _this;
520
519
  }
521
520
  ArSyncCollection.prototype.setOrdering = function (ordering) {
@@ -535,21 +534,21 @@ var ArSyncCollection = /** @class */ (function (_super) {
535
534
  this.aliasOrderKey = (subQuery && subQuery.as) || orderBy;
536
535
  this.ordering = { first: first, last: last, direction: direction, orderBy: orderBy };
537
536
  };
538
- ArSyncCollection.prototype.setSyncKeys = function (sync_keys) {
537
+ ArSyncCollection.prototype.setSyncKeys = function (parentSyncKeys) {
539
538
  var _this = this;
540
- if (sync_keys) {
541
- this.sync_keys = sync_keys.map(function (key) { return key + _this.path; });
539
+ if (parentSyncKeys) {
540
+ this.syncKeys = parentSyncKeys.map(function (key) { return key + _this.path; });
542
541
  }
543
542
  else {
544
- this.sync_keys = [];
543
+ this.syncKeys = [];
545
544
  }
546
545
  };
547
- ArSyncCollection.prototype.replaceData = function (data, sync_keys) {
548
- this.setSyncKeys(sync_keys);
546
+ ArSyncCollection.prototype.replaceData = function (data, parentSyncKeys) {
547
+ this.setSyncKeys(parentSyncKeys);
549
548
  var existings = new Map();
550
549
  for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
551
550
  var child = _a[_i];
552
- existings.set(child.data.id, child);
551
+ existings.set(child.id, child);
553
552
  }
554
553
  var collection;
555
554
  if (Array.isArray(data)) {
@@ -564,16 +563,14 @@ var ArSyncCollection = /** @class */ (function (_super) {
564
563
  for (var _b = 0, collection_1 = collection; _b < collection_1.length; _b++) {
565
564
  var subData = collection_1[_b];
566
565
  var model = undefined;
567
- if (typeof (subData) === 'object' && subData && 'sync_keys' in subData)
568
- model = existings.get(subData.id);
566
+ if (typeof (subData) === 'object' && subData && '_sync' in subData)
567
+ model = existings.get(subData._sync.id);
569
568
  var data_1 = subData;
570
569
  if (model) {
571
570
  model.replaceData(subData);
572
571
  }
573
- else if (subData.sync_keys) {
574
- model = new ArSyncRecord(this.query, subData, null, this.root);
575
- model.parentModel = this;
576
- model.parentKey = subData.id;
572
+ else if (subData._sync) {
573
+ model = new ArSyncRecord(this.query, subData, null, this.root, this, subData._sync.id);
577
574
  }
578
575
  if (model) {
579
576
  newChildren.push(model);
@@ -583,7 +580,7 @@ var ArSyncCollection = /** @class */ (function (_super) {
583
580
  }
584
581
  while (this.children.length) {
585
582
  var child = this.children.pop();
586
- if (!existings.has(child.data.id))
583
+ if (!existings.has(child.id))
587
584
  child.release();
588
585
  }
589
586
  if (this.data.length || newChildren.length)
@@ -604,11 +601,11 @@ var ArSyncCollection = /** @class */ (function (_super) {
604
601
  var _this = this;
605
602
  var _a = this.ordering, first = _a.first, last = _a.last, direction = _a.direction;
606
603
  var limit = first || last;
607
- if (this.data.findIndex(function (a) { return a.id === id; }) >= 0)
604
+ if (this.children.find(function (a) { return a.id === id; }))
608
605
  return;
609
- if (limit && limit <= this.data.length) {
610
- var lastItem = this.data[this.data.length - 1];
611
- var firstItem = this.data[0];
606
+ if (limit && limit <= this.children.length) {
607
+ var lastItem = this.children[this.children.length - 1];
608
+ var firstItem = this.children[0];
612
609
  if (direction === 'asc') {
613
610
  if (first) {
614
611
  if (lastItem && lastItem.id < id)
@@ -630,12 +627,15 @@ var ArSyncCollection = /** @class */ (function (_super) {
630
627
  }
631
628
  }
632
629
  }
630
+ this.fetching.add(id);
633
631
  modelBatchRequest.fetch(className, this.compactQueryAttributes, id).then(function (data) {
632
+ // Record already removed
633
+ if (!_this.fetching.has(id))
634
+ return;
635
+ _this.fetching.delete(id);
634
636
  if (!data || !_this.data)
635
637
  return;
636
- var model = new ArSyncRecord(_this.query, data, null, _this.root);
637
- model.parentModel = _this;
638
- model.parentKey = id;
638
+ var model = new ArSyncRecord(_this.query, data, null, _this.root, _this, id);
639
639
  var overflow = limit && limit <= _this.data.length;
640
640
  var rmodel;
641
641
  _this.mark();
@@ -699,7 +699,8 @@ var ArSyncCollection = /** @class */ (function (_super) {
699
699
  }
700
700
  };
701
701
  ArSyncCollection.prototype.consumeRemove = function (id) {
702
- var idx = this.data.findIndex(function (a) { return a.id === id; });
702
+ var idx = this.children.findIndex(function (a) { return a.id === id; });
703
+ this.fetching.delete(id); // To cancel consumeAdd
703
704
  if (idx < 0)
704
705
  return;
705
706
  this.mark();
@@ -710,7 +711,7 @@ var ArSyncCollection = /** @class */ (function (_super) {
710
711
  };
711
712
  ArSyncCollection.prototype.onNotify = function (notifyData) {
712
713
  if (notifyData.action === 'add') {
713
- this.consumeAdd(notifyData.class_name, notifyData.id);
714
+ this.consumeAdd(notifyData.class, notifyData.id);
714
715
  }
715
716
  else if (notifyData.action === 'remove') {
716
717
  this.consumeRemove(notifyData.id);
@@ -719,7 +720,7 @@ var ArSyncCollection = /** @class */ (function (_super) {
719
720
  ArSyncCollection.prototype.subscribeAll = function () {
720
721
  var _this = this;
721
722
  var callback = function (data) { return _this.onNotify(data); };
722
- for (var _i = 0, _a = this.sync_keys; _i < _a.length; _i++) {
723
+ for (var _i = 0, _a = this.syncKeys; _i < _a.length; _i++) {
723
724
  var key = _a[_i];
724
725
  this.subscribe(key, callback);
725
726
  }
@@ -731,7 +732,7 @@ var ArSyncCollection = /** @class */ (function (_super) {
731
732
  };
732
733
  ArSyncCollection.prototype.markAndSet = function (id, data) {
733
734
  this.mark();
734
- var idx = this.data.findIndex(function (a) { return a.id === id; });
735
+ var idx = this.children.findIndex(function (a) { return a.id === id; });
735
736
  if (idx >= 0)
736
737
  this.data[idx] = data;
737
738
  };
@@ -740,7 +741,7 @@ var ArSyncCollection = /** @class */ (function (_super) {
740
741
  return;
741
742
  this.data = __spreadArrays(this.data);
742
743
  this.root.mark(this.data);
743
- if (this.parentModel)
744
+ if (this.parentModel && this.parentKey)
744
745
  this.parentModel.markAndSet(this.parentKey, this.data);
745
746
  };
746
747
  return ArSyncCollection;
@@ -748,15 +749,22 @@ var ArSyncCollection = /** @class */ (function (_super) {
748
749
  var ArSyncStore = /** @class */ (function () {
749
750
  function ArSyncStore(request, _a) {
750
751
  var immutable = (_a === void 0 ? {} : _a).immutable;
752
+ this.complete = false;
753
+ this.destroyed = false;
751
754
  this.immutable = !!immutable;
752
755
  this.markedForFreezeObjects = [];
753
756
  this.changes = [];
754
757
  this.eventListeners = { events: {}, serial: 0 };
755
758
  this.request = request;
756
- this.complete = false;
757
759
  this.data = null;
758
760
  this.load(0);
759
761
  }
762
+ ArSyncStore.prototype.handleDestroy = function () {
763
+ this.release();
764
+ this.data = null;
765
+ this.destroyed = true;
766
+ this.trigger('destroy');
767
+ };
760
768
  ArSyncStore.prototype.load = function (retryCount) {
761
769
  var _this = this;
762
770
  ArSyncContainerBase.load(this.request, this).then(function (container) {
@@ -854,4 +862,4 @@ var ArSyncStore = /** @class */ (function () {
854
862
  };
855
863
  return ArSyncStore;
856
864
  }());
857
- exports.default = ArSyncStore;
865
+ exports.ArSyncStore = ArSyncStore;
data/core/hooks.d.ts CHANGED
@@ -15,6 +15,7 @@ interface ModelStatus {
15
15
  complete: boolean;
16
16
  notfound?: boolean;
17
17
  connected: boolean;
18
+ destroyed: boolean;
18
19
  }
19
20
  export declare type DataAndStatus<T> = [T | null, ModelStatus];
20
21
  export interface Request {