From a9bb8e6680d9d2a1e2e9deadcc8f608b66187f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikael=20L=C3=B6vqvist?= Date: Sat, 4 Apr 2026 07:08:37 +0200 Subject: [PATCH] Initial commit --- .gitignore | 2 + Makefile | 8 +++ experiments/os1.mjs | 121 ++++++++++++++++++++++++++++++++++++++++++ package-manifest.yaml | 6 +++ 4 files changed, 137 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 experiments/os1.mjs create mode 100644 package-manifest.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..81a4951 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +pnpm-workspace.yaml \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f443eb0 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +build/: + mkdir -p build + rsync -aP source/ build/ + +clean: + rm -rf build + +.PHONY: clean \ No newline at end of file diff --git a/experiments/os1.mjs b/experiments/os1.mjs new file mode 100644 index 0000000..de08e13 --- /dev/null +++ b/experiments/os1.mjs @@ -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']; \ No newline at end of file diff --git a/package-manifest.yaml b/package-manifest.yaml new file mode 100644 index 0000000..99cad4f --- /dev/null +++ b/package-manifest.yaml @@ -0,0 +1,6 @@ +packages: + object-graph-storage: + path: source/object-graph-storage + documentation: documentation/object-graph-storage + description: Lightweight persistent storage for structured data. + version: 0.1.0