From af159b97eeb1341676992d842f3a32f36d3e74a9 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Thu, 22 May 2025 14:31:38 -0700 Subject: [PATCH 1/2] fix point and location serialization --- .../src/assembly/__tests__/database.spec.ts | 40 +++++++++++++++++++ sdk/assemblyscript/src/assembly/database.ts | 38 +++++++++--------- sdk/assemblyscript/src/tests/database.run.ts | 16 ++++++++ 3 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 sdk/assemblyscript/src/assembly/__tests__/database.spec.ts create mode 100644 sdk/assemblyscript/src/tests/database.run.ts diff --git a/sdk/assemblyscript/src/assembly/__tests__/database.spec.ts b/sdk/assemblyscript/src/assembly/__tests__/database.spec.ts new file mode 100644 index 000000000..1c3f2b9ca --- /dev/null +++ b/sdk/assemblyscript/src/assembly/__tests__/database.spec.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2025 Hypermode Inc. + * Licensed under the terms of the Apache License, Version 2.0 + * See the LICENSE file that accompanied this code for further details. + * + * SPDX-FileCopyrightText: 2025 Hypermode Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { expect, it, run } from "as-test"; +import { JSON } from "json-as"; +import { Point, Location } from "../database"; + +it("should serialize a Point object", () => { + const point = new Point(1, 2); + const json = JSON.stringify(point); + expect(json).toBe(`"(1.0,2.0)"`); +}); + +it("should deserialize a Point object", () => { + const json = `"(1.0,2.0)"`; + const point = JSON.parse(json); + expect(point.x).toBe(1); + expect(point.y).toBe(2); +}); + +it("should serialize a Location object", () => { + const location = new Location(1, 2); + const json = JSON.stringify(location); + expect(json).toBe(`"(1.0,2.0)"`); +}); + +it("should deserialize a Location object", () => { + const json = `"(1.0,2.0)"`; + const location = JSON.parse(json); + expect(location.longitude).toBe(1); + expect(location.latitude).toBe(2); +}); + +run(); diff --git a/sdk/assemblyscript/src/assembly/database.ts b/sdk/assemblyscript/src/assembly/database.ts index 17a7aa5a8..c6d726b54 100644 --- a/sdk/assemblyscript/src/assembly/database.ts +++ b/sdk/assemblyscript/src/assembly/database.ts @@ -171,6 +171,7 @@ export function queryScalar( * * Note that this class is identical to the Location class, but uses different field names. */ +@json export class Point { constructor( public x: f64, @@ -189,27 +190,27 @@ export class Point { return new Point(p[0], p[1]); } - // The following methods are required for custom JSON serialization - // This is used in lieu of the @json decorator, so that the class can be - // serialized to a string in SQL format. @serializer private serialize(self: Point): string { - return self.toString(); + return `"${self}"`; } @deserializer - private deserialize(data: string): Point | null { + private deserialize(data: string): Point { if ( data.length < 7 || data.charAt(0) != '"' || data.charAt(data.length - 1) != '"' - ) - return null; + ) { + throw new Error("Invalid Point string"); + } const p = parsePointString(data.substring(1, data.length - 1)); - if (p.length == 0) return null; + if (p.length == 0) { + throw new Error("Invalid Point string"); + } this.x = p[0]; this.y = p[1]; @@ -223,6 +224,7 @@ export class Point { * * Note that this class is identical to the `Point` class, but uses different field names. */ +@json export class Location { constructor( public longitude: f64, @@ -233,35 +235,35 @@ export class Location { return `(${this.longitude},${this.latitude})`; } - public static fromString(data: string): Point | null { + public static fromString(data: string): Location | null { const p = parsePointString(data); if (p.length == 0) { return null; } - return new Point(p[0], p[1]); + return new Location(p[0], p[1]); } - // The following methods are required for custom JSON serialization - // This is used in lieu of the @json decorator, so that the class can be - // serialized to a string in SQL format. @serializer private serialize(self: Location): string { - return '"' + self.toString() + '"'; + return `"${self}"`; } @deserializer - private deserialize(data: string): Location | null { + private deserialize(data: string): Location { if ( data.length < 7 || data.charAt(0) != '"' || data.charAt(data.length - 1) != '"' - ) - return null; + ) { + throw new Error("Invalid Location string"); + } const p = parsePointString(data.substring(1, data.length - 1)); - if (p.length == 0) return null; + if (p.length == 0) { + throw new Error("Invalid Location string"); + } this.longitude = p[0]; this.latitude = p[1]; diff --git a/sdk/assemblyscript/src/tests/database.run.ts b/sdk/assemblyscript/src/tests/database.run.ts new file mode 100644 index 000000000..12d2f4e68 --- /dev/null +++ b/sdk/assemblyscript/src/tests/database.run.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2025 Hypermode Inc. + * Licensed under the terms of the Apache License, Version 2.0 + * See the LICENSE file that accompanied this code for further details. + * + * SPDX-FileCopyrightText: 2025 Hypermode Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { readFileSync } from "fs"; +import { instantiate } from "../build/database.spec.js"; +const binary = readFileSync("./build/database.spec.wasm"); +const module = new WebAssembly.Module(binary); +instantiate(module, { + env: {}, +}); From e1d385ecff2dc6df63a3232c8edd6d9c6cfd603e Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Thu, 22 May 2025 14:32:50 -0700 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c71de290..e5344b1cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - fix: omit parallel_tool_calls in Go OpenAI SDK if it is set to true [#849](https://github.com/hypermodeinc/modus/pull/849) - feat: use embedded postgres on Windows [#851](https://github.com/hypermodeinc/modus/pull/851) - feat: add functions for parsing chat messages [#853](https://github.com/hypermodeinc/modus/pull/853) +- fix: fix serialization of Point and Location types [#854](https://github.com/hypermodeinc/modus/pull/854) ## 2025-05-19 - Go SDK 0.18.0-alpha.2