From 867b028ca2fec4d9031d478eb7a4dcc2e2215171 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Mar 2026 21:06:25 +0000 Subject: [PATCH 1/2] Fix fromDataView: enumerable, complete comment, optional setter, readonly inference Agent-Logs-Url: https://github.com/rotu/structview/sessions/a3098295-1c79-476e-9dae-b1e34e5b1ba1 Co-authored-by: rotu <119948+rotu@users.noreply.github.com> --- fields.ts | 29 ++++++++++++++++++++++++++--- mod_test.ts | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/fields.ts b/fields.ts index 61df69f..eaf0a40 100644 --- a/fields.ts +++ b/fields.ts @@ -273,13 +273,36 @@ export function bool(fieldOffset: number): StructPropertyDescriptor { /** * Define a descriptor based on a dataview of the struct - * @param fieldGetter function which, given a dataview, returns - * @returns + * @param fieldGetter function which, given a dataview, returns the field value + * @param fieldSetter optional function which, given a dataview and a value, sets the field value + * @returns an enumerable property descriptor; readonly if no setter is provided */ export function fromDataView( fieldGetter: (dv: DataView) => T, -): StructPropertyDescriptor & ReadOnlyAccessorDescriptor { + fieldSetter: (dv: DataView, value: T) => void, +): StructPropertyDescriptor +export function fromDataView( + fieldGetter: (dv: DataView) => T, +): StructPropertyDescriptor & ReadOnlyAccessorDescriptor +export function fromDataView( + fieldGetter: (dv: DataView) => T, + fieldSetter?: (dv: DataView, value: T) => void, +): StructPropertyDescriptor { + if (fieldSetter !== undefined) { + return { + enumerable: true, + get() { + const dv = structDataView(this) + return fieldGetter(dv) + }, + set(value) { + const dv = structDataView(this) + fieldSetter(dv, value) + }, + } + } return { + enumerable: true, get() { const dv = structDataView(this) return fieldGetter(dv) diff --git a/mod_test.ts b/mod_test.ts index b68ad09..77b457b 100644 --- a/mod_test.ts +++ b/mod_test.ts @@ -5,6 +5,7 @@ import { f16, f32, f64, + fromDataView, i16, i32, i64, @@ -449,3 +450,49 @@ Deno.test("alloc", () => { // ensure correct typing (that alloc doesn't return a bare Struct) const _zz: Sized = z }) + +Deno.test("fromDataView getter-only is readonly and enumerable", () => { + class S extends defineStruct({ + val: fromDataView((dv) => dv.getUint8(0)), + }) {} + const buf = new Uint8Array([42]) + const obj = new S(buf) + assertEquals(obj.val, 42) + + // type test: val is readonly + assertThrows(() => { + // @ts-expect-error assigning to readonly property + obj.val = 1 + }) + + // the descriptor should be enumerable + const keys: string[] = [] + for (const k in S.prototype) { + keys.push(k) + } + assert(keys.includes("val")) +}) + +Deno.test("fromDataView with setter is writable and enumerable", () => { + class S extends defineStruct({ + val: fromDataView( + (dv) => dv.getUint8(0), + (dv, v) => dv.setUint8(0, v), + ), + }) {} + const buf = new Uint8Array([0]) + const obj = new S(buf) + obj.val = 99 + assertEquals(obj.val, 99) + assertEquals(buf[0], 99) + + // type test: val is writable (no @ts-expect-error needed) + const _: number = obj.val + + // the descriptor should be enumerable + const keys: string[] = [] + for (const k in S.prototype) { + keys.push(k) + } + assert(keys.includes("val")) +}) From 653534e14c5c2e26e89c5b4f03004693de21213c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Mar 2026 07:40:51 +0000 Subject: [PATCH 2/2] Bump minor version to 0.15.0 Agent-Logs-Url: https://github.com/rotu/structview/sessions/efb92433-db0a-46bd-9a9d-ad2cbf60cf75 Co-authored-by: rotu <119948+rotu@users.noreply.github.com> --- deno.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deno.json b/deno.json index b43e9e5..277077a 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@rotu/structview", - "version": "0.14.1", + "version": "0.15.0", "license": "MIT", "tasks": { "dev": "deno test --watch",