ar_sync 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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 {