From 11c212c9058c2acc214f8207f12cb7c8b249d70b Mon Sep 17 00:00:00 2001 From: sha256 Date: Thu, 21 Dec 2023 01:57:10 +0600 Subject: [PATCH] Use proxy instead of Reflect.defineProperty to track changed fields. This shows actual field values in console log output. --- src/model.ts | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/model.ts b/src/model.ts index 62517b6..65a5cfc 100644 --- a/src/model.ts +++ b/src/model.ts @@ -17,21 +17,10 @@ export abstract class Factory { } function defineModelProperty(target: any, key: string, value: any) { - let _value = value; - Reflect.defineProperty(target, key, { - get: () => _value, - set: newVal => { - if(!target[kNew] && newVal != _value){ - target[kDirtyFields].add(key) - } - _value = newVal - }, - enumerable: true, - configurable: true - }) + target[key] = value } -function init(_this: KeyValue, payload: KeyValue = {}, hasId: boolean = true, isNew: boolean = true) { +function init(_this: KeyValue, payload: KeyValue = {}, hasId: boolean = true, isNew: boolean = true): any { const fieldProperties: PropertiesMeta = Reflect.getMetadata(kFieldPropertiesMeta, _this.constructor) || {} const nonFieldProperties = Object.keys(payload).reduce((acc, key) => key in fieldProperties ? acc : [...acc, key], [] as string[]) @@ -84,7 +73,15 @@ function init(_this: KeyValue, payload: KeyValue = {}, hasId: boolean = true, is } } - return _this + return new Proxy(_this, { + set(target: KeyValue, p: string | symbol, newValue: any): boolean { + if(!target[kNew] && newValue != target[p]){ + target[kDirtyFields].add(p) + } + target[p] = newValue + return true + } + }) } function savableRef(item: any){ @@ -164,12 +161,13 @@ export function model(options?: ModelOptions) { const bulkOpBuilder = new BulkOpBuilder(klass.name) const modelMeta = new ModelMeta(collectionName, klass.name) - const newClass = class ModelClass extends klass { + const newClass = class Model extends klass { constructor(...args: any[]) { super(); - init(this, args[0], args[1]) - this._ob = this + const proxy = init(this, args[0], args[1]) + this._ob = proxy + return proxy } [kDirtyFields]: Set = new Set(); @@ -184,7 +182,7 @@ export function model(options?: ModelOptions) { this[kNew] = false } else { const updateDoc: any = toObject(this, true, false, fields ? new Set(fields as any) : this[kDirtyFields]) - await ModelClass.find({_id: this._id}).update({$set: updateDoc}).one() + await Model.find({_id: this._id}).update({$set: updateDoc}).one() this[kDirtyFields].clear() } return this