Created
June 7, 2025 22:48
-
-
Save clinuxrulz/3ece6b38a15508188dc4eb3e49772321 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export function projectMutableOverAutomergeDocV2<T extends object>( | |
| json: any, | |
| updateJson: (cb: (json: any) => any) => void, | |
| typeSchema: TypeSchema<T> | |
| ): T { | |
| if (typeof typeSchema != "object" || typeSchema.type != "Object") { | |
| throw new Error("Expected object."); | |
| } | |
| let properties = typeSchema.properties; | |
| let result = new Proxy<T>( | |
| {} as T, | |
| { | |
| defineProperty(target, property, attributes) { | |
| console.log("defineProperty", target, property, attributes); | |
| return Reflect.defineProperty(target, property, attributes); | |
| }, | |
| deleteProperty(target, p) { | |
| console.log("deleteProperty", target, p); | |
| return Reflect.deleteProperty(target, p); | |
| }, | |
| getOwnPropertyDescriptor(target, p) { | |
| console.log("getOwnPropertyDescriptor", target, p); | |
| if ((properties as any)[p] != undefined) { | |
| let r = Reflect.getOwnPropertyDescriptor(properties, p); | |
| if (r == undefined) { | |
| return; | |
| } | |
| r = { ...r, }; | |
| r.value = (result as any)[p]; | |
| return r; | |
| } | |
| return Reflect.getOwnPropertyDescriptor(target, p); | |
| }, | |
| getPrototypeOf(target) { | |
| console.log("getPrototypeOf", target); | |
| return Reflect.getPrototypeOf(target); | |
| }, | |
| has(target, p) { | |
| console.log("has", target); | |
| if ((properties as any)[p] != undefined) { | |
| return true; | |
| } | |
| return Reflect.has(target, p); | |
| }, | |
| isExtensible(target) { | |
| console.log("isExtendable", target); | |
| return Reflect.isExtensible(target); | |
| }, | |
| ownKeys(target) { | |
| console.log("ownKeys", target); | |
| return [ | |
| ...Reflect.ownKeys(properties), | |
| ...Reflect.ownKeys(target), | |
| ]; | |
| }, | |
| preventExtensions(target) { | |
| console.log("preventExtensions", target); | |
| return Reflect.preventExtensions(target); | |
| }, | |
| setPrototypeOf(target, v) { | |
| console.log("setPrototypeOf", target, v); | |
| return Reflect.setPrototypeOf(target, v); | |
| }, | |
| get(target, p, receiver) { | |
| if (typeof p == "symbol") { | |
| return (target as any)[p]; | |
| } | |
| if (typeof p == "string") { | |
| let propertySchema = (properties as any)[p] as TypeSchema<any>; | |
| if (propertySchema != undefined) { | |
| if ((propertySchema as any).type == "Object") { | |
| return projectMutableOverAutomergeDocV2( | |
| json[p], | |
| (cb) => updateJson((json2) => cb(json2[p])), | |
| propertySchema, | |
| ); | |
| } else if ((propertySchema as any).type == "Array") { | |
| return projectMutableOverAutomergeDocArrayV2( | |
| json[p], | |
| (cb) => updateJson((json2) => cb(json2[p])), | |
| propertySchema, | |
| ); | |
| } | |
| let r = loadFromJsonViaTypeSchema( | |
| propertySchema as any, | |
| json[p] | |
| ); | |
| if (r.type == "Err") { | |
| return makeDefaultViaTypeSchema(propertySchema as any); | |
| } | |
| return r.value; | |
| } | |
| } | |
| return Reflect.get(target, p, receiver); | |
| }, | |
| set(target, p, newValue, receiver) { | |
| if (typeof p == "symbol") { | |
| (target as any)[p] = newValue; | |
| return true; | |
| } | |
| if (typeof p == "string") { | |
| let propertySchema = (properties as any)[p] as TypeSchema<any>; | |
| if (propertySchema != undefined) { | |
| let r = saveToJsonViaTypeSchema(propertySchema, newValue); | |
| updateJson((json2) => json2[p] = r); | |
| return true; | |
| } | |
| } | |
| return Reflect.set(target, p, newValue, receiver); | |
| }, | |
| }, | |
| ); | |
| return result; | |
| } | |
| export function projectMutableOverAutomergeDocArrayV2<T extends object>( | |
| json: any, | |
| updateJson: (cb: (json: any) => any) => void, | |
| typeSchema: TypeSchema<T> | |
| ): T { | |
| if (typeof typeSchema != "object" || typeSchema.type != "Array") { | |
| throw new Error("Expected object."); | |
| } | |
| let elementSchema = typeSchema.element; | |
| let iterator = function*() { | |
| for (let i = 0; i < json.length; ++i) { | |
| yield (result as any)[i]; | |
| } | |
| }; | |
| let result = new Proxy<T>( | |
| [undefined] as T, | |
| { | |
| defineProperty(target, property, attributes) { | |
| console.log("defineProperty", target, property, attributes); | |
| return Reflect.defineProperty(target, property, attributes); | |
| }, | |
| deleteProperty(target, p) { | |
| console.log("deleteProperty", target, p); | |
| return Reflect.deleteProperty(target, p); | |
| }, | |
| getOwnPropertyDescriptor(target, p) { | |
| console.log("getOwnPropertyDescriptor", target, p); | |
| let idx = (typeof p == "string") ? Number.parseInt(p) : undefined; | |
| if (Number.isNaN(idx)) { | |
| idx = undefined; | |
| } | |
| if (idx != undefined) { | |
| let r = Reflect.getOwnPropertyDescriptor(target, 0); | |
| if (r == undefined) { | |
| return; | |
| } | |
| r = { ...r, }; | |
| r.value = (result as any)[p]; | |
| return r; | |
| } | |
| return Reflect.getOwnPropertyDescriptor(target, p); | |
| }, | |
| getPrototypeOf(target) { | |
| console.log("getPrototypeOf", target); | |
| return Reflect.getPrototypeOf(target); | |
| }, | |
| has(target, p) { | |
| console.log("has", target); | |
| let idx = (typeof p == "string") ? Number.parseInt(p) : undefined; | |
| if (Number.isNaN(idx)) { | |
| idx = undefined; | |
| } | |
| if (idx != undefined) { | |
| return 0 <= idx && idx < json.length; | |
| } | |
| return Reflect.has(target, p); | |
| }, | |
| isExtensible(target) { | |
| console.log("isExtendable", target); | |
| return Reflect.isExtensible(target); | |
| }, | |
| ownKeys(target) { | |
| console.log("ownKeys", target); | |
| return [ | |
| ...Array(json.length).fill(undefined).map((_,idx) => idx.toString()), | |
| ...Reflect.ownKeys(target).filter((key) => key != "0"), | |
| ]; | |
| }, | |
| preventExtensions(target) { | |
| console.log("preventExtensions", target); | |
| return Reflect.preventExtensions(target); | |
| }, | |
| setPrototypeOf(target, v) { | |
| console.log("setPrototypeOf", target, v); | |
| return Reflect.setPrototypeOf(target, v); | |
| }, | |
| get(target, p, receiver) { | |
| if (p == Symbol.iterator) { | |
| return iterator; | |
| } | |
| if (typeof p == "symbol") { | |
| return (target as any)[p]; | |
| } | |
| if (typeof p == "string") { | |
| let idx = (typeof p == "string") ? Number.parseInt(p) : undefined; | |
| if (Number.isNaN(idx)) { | |
| idx = undefined; | |
| } | |
| if (idx != undefined && 0 <= idx && idx < json.length) { | |
| if ((elementSchema as any).type == "Object") { | |
| return projectMutableOverAutomergeDocV2( | |
| json[idx], | |
| (cb) => updateJson((json2) => cb(json2[p])), | |
| elementSchema as any, | |
| ); | |
| } else if ((elementSchema as any).type == "Array") { | |
| return projectMutableOverAutomergeDocArrayV2( | |
| json[idx], | |
| (cb) => updateJson((json2) => cb(json2[p])), | |
| elementSchema as any, | |
| ); | |
| } | |
| let r = loadFromJsonViaTypeSchema( | |
| elementSchema as any, | |
| json[idx] | |
| ); | |
| if (r.type == "Err") { | |
| return makeDefaultViaTypeSchema(elementSchema as any); | |
| } | |
| return r.value; | |
| } | |
| } | |
| return Reflect.get(target, p, receiver); | |
| }, | |
| set(target, p, newValue, receiver) { | |
| if (typeof p == "symbol") { | |
| (target as any)[p] = newValue; | |
| return true; | |
| } | |
| if (typeof p == "string") { | |
| let idx = (typeof p == "string") ? Number.parseInt(p) : undefined; | |
| if (Number.isNaN(idx)) { | |
| idx = undefined; | |
| } | |
| if (idx != undefined) { | |
| let r = saveToJsonViaTypeSchema(elementSchema as any, newValue); | |
| updateJson((json2) => json2[p] = r); | |
| return true; | |
| } | |
| } | |
| return Reflect.set(target, p, newValue, receiver); | |
| }, | |
| }, | |
| ); | |
| return result; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment