Skip to content

Instantly share code, notes, and snippets.

@3AHAT0P
Created April 19, 2018 20:35
Show Gist options
  • Save 3AHAT0P/281f16fc3a84b32cdd0074bf9fcf3e7f to your computer and use it in GitHub Desktop.
Save 3AHAT0P/281f16fc3a84b32cdd0074bf9fcf3e7f to your computer and use it in GitHub Desktop.
(async () => {
const relation = (ModelClass, deserialize, serialize) => {
return (target, key, descriptor) => {
const proto = Reflect.getPrototypeOf(target);
if (!target.hasOwnProperty(Symbol.for('#meta'))) {
if (proto.hasOwnProperty(Symbol.for('#meta'))) {
Reflect.defineProperty(target, Symbol.for('#meta'), {value: {...proto[Symbol.for('#meta')]}});
} else {
Reflect.defineProperty(target, Symbol.for('#meta'), {value: {}});
}
}
if (target[Symbol.for('#meta')].attributes == null) target[Symbol.for('#meta')].attributes = {};
if (target[Symbol.for('#meta')].attributes[key] == null) target[Symbol.for('#meta')].attributes[key] = {};
target[Symbol.for('#meta')].attributes[key].deserialize = deserialize;
target[Symbol.for('#meta')].attributes[key].serialize = serialize;
target[Symbol.for('#meta')].attributes[key].relatedKey = key.replace(/Id$/i, '');
return {
enumerable: descriptor.enumerable,
configurable: true,
get() {
target[Symbol.for('#meta')].attributes[key].store = ModelClass.getStore();
target[Symbol.for('#meta')].attributes[key].relatedId = this.id;
const _descriptor = {
enumerable: descriptor.enumerable,
configurable: descriptor.configurable,
writable: descriptor.writable
};
if (descriptor.value && descriptor.value.constructor.name === 'Function') {
_descriptor.value = descriptor.value();
} else if (descriptor.initializer && descriptor.initializer.constructor.name === 'Function') {
_descriptor.value = descriptor.initializer();
if (_descriptor.value && _descriptor.value.constructor.name === 'Function') {
_descriptor.value = _descriptor.value();
}
}
Reflect.defineProperty(this, key, _descriptor);
}
};
};
};
const deserialize = async (value, meta) => {
debugger
return await meta.store.getMany({[meta.relatedKey]: meta.relatedId});
};
const hasManyRelation = (ModelClass) => {
return relation(ModelClass, deserialize, () => void 0);
};
let i = 0;
const uuid = () => i++;
const attribute = (deserialize, serialize) => {
return (target, key, descriptor) => {
const proto = Reflect.getPrototypeOf(target);
if (!target.hasOwnProperty(Symbol.for('#meta'))) {
if (proto.hasOwnProperty(Symbol.for('#meta'))) {
Reflect.defineProperty(target, Symbol.for('#meta'), {value: {...proto[Symbol.for('#meta')]}});
} else {
Reflect.defineProperty(target, Symbol.for('#meta'), {value: {}});
}
}
if (target[Symbol.for('#meta')].attributes == null) target[Symbol.for('#meta')].attributes = {};
if (target[Symbol.for('#meta')].attributes[key] == null) target[Symbol.for('#meta')].attributes[key] = {};
target[Symbol.for('#meta')].attributes[key].deserialize = deserialize;
target[Symbol.for('#meta')].attributes[key].serialize = serialize;
return {
enumerable: descriptor.enumerable,
configurable: true,
get() {
const _descriptor = {
enumerable: descriptor.enumerable,
configurable: descriptor.configurable,
writable: descriptor.writable
};
if (descriptor.value && descriptor.value.constructor.name === 'Function') {
_descriptor.value = descriptor.value();
} else if (descriptor.initializer && descriptor.initializer.constructor.name === 'Function') {
_descriptor.value = descriptor.initializer();
if (_descriptor.value && _descriptor.value.constructor.name === 'Function') {
_descriptor.value = _descriptor.value();
}
}
Reflect.defineProperty(this, key, _descriptor);
}
};
};
};
const stringAttr = () => {
return attribute(String, String.valueOf);
};
class AbstractStore {
getMany() {
return [];
}
}
class TurnStore {
getMany() {
return [];
}
}
class ActionStore {
getMany() {
debugger
return [new ActionModel({turnId: 1}), new ActionModel({turnId: 1})];
}
}
class AbstractModel {
_data = {};
@stringAttr()
id = uuid;
constructor(data = {}) {
// this[Symbol.for('#meta')] = {};
// this.id;
if (data.id != null) this.id = data.id;
setTimeout(this.deserialize.bind(this,data));
}
deserialize(data) {
// debugger;
for (const [key, {deserialize}] of Object.entries(this[Symbol.for('#meta')].attributes)) {
this[key];
if (key === 'id' && data.id == null) continue;
this[key] = this._data[key] = deserialize(data[key], this[Symbol.for('#meta')].attributes[key]);
}
return this;
}
serialize() {
const data = {};
for (const [key, {serialize}] of Object.entries(this[Symbol.for('#meta')].attributes)) {
data[key] = this._data[key] = serialize(this[key], this[Symbol.for('#meta')].attributes[key]);
}
return data;
}
}
class ActionModel extends AbstractModel {
@stringAttr()
turnId = null;
static getStore() {
// debugger
return new ActionStore();
}
}
class TurnModel extends AbstractModel {
@hasManyRelation(ActionModel)
actions = [];
addAction() {
}
}
const turn = new TurnModel();
console.log(turn);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment