Skip to content
This repository was archived by the owner on Sep 11, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
40 changes: 40 additions & 0 deletions sdk/assemblyscript/src/assembly/__tests__/database.spec.ts
Original file line number Diff line number Diff line change
@@ -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. <[email protected]>
* 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<Point>(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<Location>(json);
expect(location.longitude).toBe(1);
expect(location.latitude).toBe(2);
});

run();
38 changes: 20 additions & 18 deletions sdk/assemblyscript/src/assembly/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export function queryScalar<T>(
*
* Note that this class is identical to the Location class, but uses different field names.
*/
@json
export class Point {
constructor(
public x: f64,
Expand All @@ -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];
Expand All @@ -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,
Expand All @@ -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];
Expand Down
16 changes: 16 additions & 0 deletions sdk/assemblyscript/src/tests/database.run.ts
Original file line number Diff line number Diff line change
@@ -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. <[email protected]>
* 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: {},
});