Initial commit
This commit is contained in:
121
experiments/os1.mjs
Normal file
121
experiments/os1.mjs
Normal file
@@ -0,0 +1,121 @@
|
||||
// Note: Only handled objects and primitives are allowed to be set/pushed/mapped
|
||||
|
||||
import { inspect } from 'node:util';
|
||||
|
||||
class Not_Storable_Error extends Error {
|
||||
constructor({ storage, value, prop, id }) {
|
||||
const type = value === null ? 'null' : typeof value;
|
||||
const location = prop ? `property "${prop}" of record #${id}` : `record #${id}`;
|
||||
super(`Cannot store value of type "${type}" in ${location}: ${inspect(value)}`);
|
||||
this.name = 'Not_Storable_Error';
|
||||
this.storage = storage;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
class Not_Mutable_Error extends Error {
|
||||
constructor({ storage, value, prop, id }) {
|
||||
const type = value === null ? 'null' : typeof value;
|
||||
const location = prop ? `property "${prop}" of record #${id}` : `record #${id}`;
|
||||
super(`Cannot set ${location}: record is immutable (tried to store value of type "${type}": ${inspect(value)})`);
|
||||
this.name = 'Not_Mutable_Error';
|
||||
this.storage = storage;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function load_descriptor({ type, value }, { storage, mutable }) {
|
||||
if (type === 'primitive') {
|
||||
return value;
|
||||
} else {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
const Record_Handler = {
|
||||
|
||||
get(target, prop, receiver) {
|
||||
const { storage, id, mutable } = target;
|
||||
|
||||
const result_descriptor = storage.get_record_property(id, prop);
|
||||
if (result_descriptor) {
|
||||
return load_descriptor(result_descriptor, { storage, mutable });
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
|
||||
set(target, prop, value) {
|
||||
const { storage, id, mutable } = target;
|
||||
|
||||
if (!mutable) {
|
||||
throw new Not_Mutable_Error({ storage, id, prop, value });
|
||||
}
|
||||
|
||||
if (!storage.can_be_stored(value)) {
|
||||
throw new Not_Storable_Error({ storage, id, prop, value });
|
||||
}
|
||||
|
||||
storage.set_record_property(id, prop, 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) {
|
||||
console.log("Should get record property", { item_id, property });
|
||||
return { type: 'primitive', value: 'Hello' };
|
||||
}
|
||||
|
||||
set_record_property(item_id, property, value) {
|
||||
console.log("Should set record property", { item_id, property, 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: 'hello'}, true);
|
||||
console.log(p1.blargh);
|
||||
|
||||
//p1.stuff = ['hello', 'world'];
|
||||
Reference in New Issue
Block a user