// Note: Only handled objects and primitives are allowed to be set/pushed/mapped import { inspect } from 'node:util'; function load_descriptor({ type, value }, { storage, mutable }) { if (type === 'primitive') { return value; } else { throw new Error('not implemented'); } } const Record_Handler = { get(target, property, receiver) { const { storage, id } = target; return storage.get_record_property(id, property); }, set(target, property, value) { const { storage, id, mutable } = target; if (!mutable) { throw new Not_Mutable_Error({ storage, id, property, value }); } storage.set_record_property(id, property, value); return true; } }; class Storage { #pending_id = 1; #records = new Map(); create_record(data=undefined, mutable=true) { const id = this.acquire_new_id(); const property_bag = {}; const result = new Proxy({ storage: this, id, property_bag, mutable, }, Record_Handler); this.#records.set(id, property_bag); if (data !== undefined) { Object.assign(result, data); } return result; } get_record_property(item_id, property) { const property_bag = this.#records.get(item_id); if (property_bag === undefined) { throw new No_Such_Object_Index_Error({storage: this, id: item_id, property}); } return property_bag[property]; } set_record_property(item_id, property, value) { const descriptor = this.maybe_create_descriptor(value); if (!descriptor) { throw new Not_Storable_Error({ storage: this, id: item_id, property, value }); } const property_bag = this.#records.get(item_id); if (property_bag === undefined) { throw new No_Such_Object_Index_Error({storage: this, id: item_id, property}); } property_bag[property] = descriptor; } maybe_create_descriptor(value) { if (typeof value === 'string') { return { type: 'primitive', value }; } } can_be_stored(value) { if (typeof value === 'string') { return true; } else { return false; } } acquire_new_id() { return this.#pending_id++; } }; const s1 = new Storage(); const p1 = s1.create_record({stuff: 5n}, true); console.log(p1.blargh); console.log(s1.get_record_property(1, 'stuff')) //p1.stuff = ['hello', 'world'];