Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model self destroy #143

Merged
merged 2 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions core/ArSyncModel.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { ArSyncStore, Request } from './ArSyncStore';
import ConnectionAdapter from './ConnectionAdapter';
interface Request {
api: string;
query: any;
params?: any;
}
declare type Path = Readonly<(string | number)[]>;
interface Change {
path: Path;
Expand All @@ -12,8 +8,14 @@ interface Change {
declare type ChangeCallback = (change: Change) => void;
declare type LoadCallback = () => void;
declare type ConnectionCallback = (status: boolean) => void;
declare type SubscriptionType = 'load' | 'change' | 'connection';
declare type SubscriptionType = 'load' | 'change' | 'connection' | 'destroy';
declare type SubscriptionCallback = ChangeCallback | LoadCallback | ConnectionCallback;
declare type ArSyncModelRef = {
key: string;
count: number;
timer: number | null;
model: ArSyncStore;
};
declare type PathFirst<P extends Readonly<any[]>> = ((...args: P) => void) extends (first: infer First, ...other: any) => void ? First : never;
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;
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) | {
Expand All @@ -26,6 +28,7 @@ export default class ArSyncModel<T> {
private _listeners;
complete: boolean;
notfound?: boolean;
destroyed: boolean;
connected: boolean;
data: T | null;
static _cache: {
Expand All @@ -52,12 +55,7 @@ export default class ArSyncModel<T> {
release(): void;
static retrieveRef(request: Request, option?: {
immutable: boolean;
}): {
key: string;
count: number;
timer: number | null;
model: any;
};
}): ArSyncModelRef;
static _detach(ref: any): void;
private static _attach;
static setConnectionAdapter(adapter: ConnectionAdapter): void;
Expand Down
12 changes: 7 additions & 5 deletions core/ArSyncModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ var ConnectionManager_1 = require("./ConnectionManager");
var ArSyncModel = /** @class */ (function () {
function ArSyncModel(request, option) {
var _this = this;
this.complete = false;
this.destroyed = false;
this._ref = ArSyncModel.retrieveRef(request, option);
this._listenerSerial = 0;
this._listeners = {};
this.complete = false;
this.connected = ArSyncStore_1.default.connectionManager.networkStatus;
this.connected = ArSyncStore_1.ArSyncStore.connectionManager.networkStatus;
var setData = function () {
_this.data = _this._ref.model.data;
_this.complete = _this._ref.model.complete;
_this.notfound = _this._ref.model.notfound;
_this.destroyed = _this._ref.model.destroyed;
};
setData();
this.subscribe('load', setData);
this.subscribe('change', setData);
this.subscribe('destroy', setData);
this.subscribe('connection', function (status) {
_this.connected = status;
});
Expand Down Expand Up @@ -81,13 +84,12 @@ var ArSyncModel = /** @class */ (function () {
this._listeners[id].unsubscribe();
this._listeners = {};
ArSyncModel._detach(this._ref);
this._ref = null;
};
ArSyncModel.retrieveRef = function (request, option) {
var key = JSON.stringify([request, option]);
var ref = this._cache[key];
if (!ref) {
var model = new ArSyncStore_1.default(request, option);
var model = new ArSyncStore_1.ArSyncStore(request, option);
ref = this._cache[key] = { key: key, count: 0, timer: null, model: model };
}
this._attach(ref);
Expand Down Expand Up @@ -116,7 +118,7 @@ var ArSyncModel = /** @class */ (function () {
clearTimeout(ref.timer);
};
ArSyncModel.setConnectionAdapter = function (adapter) {
ArSyncStore_1.default.connectionManager = new ConnectionManager_1.default(adapter);
ArSyncStore_1.ArSyncStore.connectionManager = new ConnectionManager_1.default(adapter);
};
ArSyncModel.waitForLoad = function () {
var models = [];
Expand Down
14 changes: 11 additions & 3 deletions core/ArSyncStore.d.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
export default class ArSyncStore {
export declare type Request = {
api: string;
query: any;
params?: any;
id?: any;
};
export declare class ArSyncStore {
immutable: boolean;
markedForFreezeObjects: any[];
changes: any;
eventListeners: any;
markForRelease: true | undefined;
container: any;
request: any;
request: Request;
complete: boolean;
notfound?: boolean;
destroyed: boolean;
data: any;
changesBufferTimer: number | undefined | null;
retryLoadTimer: number | undefined | null;
static connectionManager: any;
constructor(request: any, { immutable }?: {
constructor(request: Request, { immutable }?: {
immutable?: boolean | undefined;
});
handleDestroy(): void;
load(retryCount: number): void;
setChangesBufferTimer(): void;
subscribe(event: any, callback: any): {
Expand Down
80 changes: 37 additions & 43 deletions core/ArSyncStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ var __spreadArrays = (this && this.__spreadArrays) || function () {
return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArSyncStore = void 0;
var ArSyncApi_1 = require("./ArSyncApi");
var ModelBatchRequest = /** @class */ (function () {
function ModelBatchRequest() {
Expand Down Expand Up @@ -95,6 +96,7 @@ var modelBatchRequest = new ModelBatchRequest;
var ArSyncContainerBase = /** @class */ (function () {
function ArSyncContainerBase() {
this.listeners = [];
this.parentModel = null;
}
ArSyncContainerBase.prototype.replaceData = function (_data, _sync_keys) { };
ArSyncContainerBase.prototype.initForReload = function (request) {
Expand Down Expand Up @@ -246,7 +248,7 @@ var ArSyncContainerBase = /** @class */ (function () {
return attributes;
return { attributes: attributes, as: column, params: params };
};
ArSyncContainerBase._load = function (_a, root) {
ArSyncContainerBase.load = function (_a, root) {
var api = _a.api, id = _a.id, params = _a.params, query = _a.query;
var parsedQuery = ArSyncRecord.parseQuery(query);
var compactQueryAttributes = ArSyncRecord.compactQueryAttributes(parsedQuery);
Expand All @@ -255,7 +257,7 @@ var ArSyncContainerBase = /** @class */ (function () {
if (!data)
throw { retry: false };
var request = { api: api, id: id, query: compactQueryAttributes };
return new ArSyncRecord(parsedQuery, data, request, root);
return new ArSyncRecord(parsedQuery, data, request, root, null, null);
});
}
else {
Expand All @@ -265,39 +267,22 @@ var ArSyncContainerBase = /** @class */ (function () {
throw { retry: false };
}
else if (response.collection && response.order) {
return new ArSyncCollection(response.sync_keys, 'collection', parsedQuery, response, request_1, root);
return new ArSyncCollection(response.sync_keys, 'collection', parsedQuery, response, request_1, root, null, null);
}
else if (response instanceof Array) {
return new ArSyncCollection([], '', parsedQuery, response, request_1, root);
return new ArSyncCollection([], '', parsedQuery, response, request_1, root, null, null);
}
else {
return new ArSyncRecord(parsedQuery, response, request_1, root);
return new ArSyncRecord(parsedQuery, response, request_1, root, null, null);
}
});
}
};
ArSyncContainerBase.load = function (apiParams, root) {
var _this = this;
if (!(apiParams instanceof Array))
return this._load(apiParams, root);
return new Promise(function (resolve, _reject) {
var resultModels = [];
var countdown = apiParams.length;
apiParams.forEach(function (param, i) {
_this._load(param, root).then(function (model) {
resultModels[i] = model;
countdown--;
if (countdown === 0)
resolve(resultModels);
});
});
});
};
return ArSyncContainerBase;
}());
var ArSyncRecord = /** @class */ (function (_super) {
__extends(ArSyncRecord, _super);
function ArSyncRecord(query, data, request, root) {
function ArSyncRecord(query, data, request, root, parentModel, parentKey) {
var _this = _super.call(this) || this;
_this.fetching = new Set();
_this.root = root;
Expand All @@ -307,7 +292,10 @@ var ArSyncRecord = /** @class */ (function (_super) {
_this.queryAttributes = query.attributes || {};
_this.data = {};
_this.children = {};
_this.rootRecord = !parentModel;
_this.replaceData(data);
_this.parentModel = parentModel;
_this.parentKey = parentKey;
return _this;
}
ArSyncRecord.prototype.setSyncKeys = function (sync_keys) {
Expand All @@ -333,12 +321,10 @@ var ArSyncRecord = /** @class */ (function (_super) {
child.replaceData(subData, this.sync_keys);
}
else {
var collection = new ArSyncCollection(this.sync_keys, key, subQuery, subData, null, this.root);
var collection = new ArSyncCollection(this.sync_keys, key, subQuery, subData, null, this.root, this, aliasName);
this.mark();
this.children[aliasName] = collection;
this.data[aliasName] = collection.data;
collection.parentModel = this;
collection.parentKey = aliasName;
}
}
else {
Expand All @@ -349,12 +335,10 @@ var ArSyncRecord = /** @class */ (function (_super) {
child.replaceData(subData);
}
else {
var model = new ArSyncRecord(subQuery, subData, null, this.root);
var model = new ArSyncRecord(subQuery, subData, null, this.root, this, aliasName);
this.mark();
this.children[aliasName] = model;
this.data[aliasName] = model.data;
model.parentModel = this;
model.parentKey = aliasName;
}
}
else {
Expand Down Expand Up @@ -406,15 +390,13 @@ var ArSyncRecord = /** @class */ (function (_super) {
_this.fetching.delete(fetchKey_1);
if (!data || !_this.data)
return;
var model = new ArSyncRecord(query, data, null, _this.root);
var model = new ArSyncRecord(query, data, null, _this.root, _this, aliasName);
var child = _this.children[aliasName];
if (child)
child.release();
_this.children[aliasName] = model;
_this.mark();
_this.data[aliasName] = model.data;
model.parentModel = _this;
model.parentKey = aliasName;
_this.onChange([aliasName], model.data);
}).catch(function (e) {
console.error("failed to load " + className + ":" + id + " " + e);
Expand Down Expand Up @@ -452,6 +434,13 @@ var ArSyncRecord = /** @class */ (function (_super) {
var path = _c[_b];
_loop_1(path);
}
if (this.rootRecord) {
var destroyCallback = function () { return _this.root.handleDestroy(); };
for (var _d = 0, _e = this.sync_keys; _d < _e.length; _d++) {
var key = _e[_d];
this.subscribe(key + '_destroy', destroyCallback);
}
}
};
ArSyncRecord.prototype.patchQuery = function (key) {
var _a;
Expand Down Expand Up @@ -500,14 +489,14 @@ var ArSyncRecord = /** @class */ (function (_super) {
return;
this.data = __assign({}, this.data);
this.root.mark(this.data);
if (this.parentModel)
if (this.parentModel && this.parentKey)
this.parentModel.markAndSet(this.parentKey, this.data);
};
return ArSyncRecord;
}(ArSyncContainerBase));
var ArSyncCollection = /** @class */ (function (_super) {
__extends(ArSyncCollection, _super);
function ArSyncCollection(sync_keys, path, query, data, request, root) {
function ArSyncCollection(sync_keys, path, query, data, request, root, parentModel, parentKey) {
var _this = _super.call(this) || this;
_this.ordering = { orderBy: 'id', direction: 'asc' };
_this.aliasOrderKey = 'id';
Expand All @@ -525,6 +514,8 @@ var ArSyncCollection = /** @class */ (function (_super) {
_this.data = [];
_this.children = [];
_this.replaceData(data, sync_keys);
_this.parentModel = parentModel;
_this.parentKey = parentKey;
return _this;
}
ArSyncCollection.prototype.setOrdering = function (ordering) {
Expand Down Expand Up @@ -580,9 +571,7 @@ var ArSyncCollection = /** @class */ (function (_super) {
model.replaceData(subData);
}
else if (subData.sync_keys) {
model = new ArSyncRecord(this.query, subData, null, this.root);
model.parentModel = this;
model.parentKey = subData.id;
model = new ArSyncRecord(this.query, subData, null, this.root, this, subData.id);
}
if (model) {
newChildren.push(model);
Expand Down Expand Up @@ -647,9 +636,7 @@ var ArSyncCollection = /** @class */ (function (_super) {
_this.fetching.delete(id);
if (!data || !_this.data)
return;
var model = new ArSyncRecord(_this.query, data, null, _this.root);
model.parentModel = _this;
model.parentKey = id;
var model = new ArSyncRecord(_this.query, data, null, _this.root, _this, id);
var overflow = limit && limit <= _this.data.length;
var rmodel;
_this.mark();
Expand Down Expand Up @@ -755,23 +742,30 @@ var ArSyncCollection = /** @class */ (function (_super) {
return;
this.data = __spreadArrays(this.data);
this.root.mark(this.data);
if (this.parentModel)
if (this.parentModel && this.parentKey)
this.parentModel.markAndSet(this.parentKey, this.data);
};
return ArSyncCollection;
}(ArSyncContainerBase));
var ArSyncStore = /** @class */ (function () {
function ArSyncStore(request, _a) {
var immutable = (_a === void 0 ? {} : _a).immutable;
this.complete = false;
this.destroyed = false;
this.immutable = !!immutable;
this.markedForFreezeObjects = [];
this.changes = [];
this.eventListeners = { events: {}, serial: 0 };
this.request = request;
this.complete = false;
this.data = null;
this.load(0);
}
ArSyncStore.prototype.handleDestroy = function () {
this.release();
this.data = null;
this.destroyed = true;
this.trigger('destroy');
};
ArSyncStore.prototype.load = function (retryCount) {
var _this = this;
ArSyncContainerBase.load(this.request, this).then(function (container) {
Expand Down Expand Up @@ -869,4 +863,4 @@ var ArSyncStore = /** @class */ (function () {
};
return ArSyncStore;
}());
exports.default = ArSyncStore;
exports.ArSyncStore = ArSyncStore;
1 change: 1 addition & 0 deletions core/hooks.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface ModelStatus {
complete: boolean;
notfound?: boolean;
connected: boolean;
destroyed: boolean;
}
export declare type DataAndStatus<T> = [T | null, ModelStatus];
export interface Request {
Expand Down
Loading
Loading