Skip to content

Commit

Permalink
support nested structures on the JS side. (#57)
Browse files Browse the repository at this point in the history
* support nested structures on the JS side.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
PythonFZ and pre-commit-ci[bot] authored Nov 4, 2024
1 parent 44007c0 commit 720b010
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 5 deletions.
30 changes: 29 additions & 1 deletion js/dict.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Client as ZnSocketClient } from "./client.js";
import {List as ZnSocketList} from "./list.js";


export class Dict {
Expand Down Expand Up @@ -45,6 +46,13 @@ export class Dict {
data: { keys: [key] },
});
}

if (value instanceof ZnSocketList) {
value = `znsocket.List:${value._key}`;
} else if (value instanceof Dict) {
value = `znsocket.Dict:${value._key}`;
}

return this._client.hSet(this._key, key, JSON.stringify(value));
}

Expand All @@ -59,6 +67,16 @@ export class Dict {
});
}

// iterate over the entries and check if the value is a List or Dict
Object.entries(dict).forEach(([key, value]) => {
if (value instanceof ZnSocketList) {
dict[key] = `znsocket.List:${value._key}`;
} else if (value instanceof Dict) {
dict[key] = `znsocket.Dict:${value._key}`;
}
}
);

const entries = Object.entries(dict).map(([key, value]) => [
key,
JSON.stringify(value),
Expand All @@ -71,7 +89,17 @@ export class Dict {
if (value === null) {
return null;
}
return JSON.parse(value); // Parse the value
value = JSON.parse(value); // Parse the value
if (typeof value === "string") {
if (value.startsWith("znsocket.List:")) {
const refKey = value.split(/:(.+)/)[1];
return new ZnSocketList({ client: this._client,socket: this._socket , key: refKey});
} else if (value.startsWith("znsocket.Dict:")) {
const refKey = value.split(/:(.+)/)[1];
return new Dict({ client: this._client, socket: this._socket , key: refKey});
}
}
return value;
});
}

Expand Down
25 changes: 23 additions & 2 deletions js/list.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Client as ZnSocketClient } from "./client.js";
import { Dict as ZnSocketDict } from "./dict.js";

export class List {
constructor({ client, key, socket, callbacks }) {
Expand Down Expand Up @@ -52,6 +53,11 @@ export class List {
data: { start: await this.length() },
});
}
if (value instanceof List) {
value = `znsocket.List:${value._key}`;
} else if (value instanceof ZnSocketDict) {
value = `znsocket.Dict:${value._key}`;
}
return this._client.rPush(this._key, JSON.stringify(value));
}

Expand All @@ -65,6 +71,11 @@ export class List {
data: { indices: [index] },
});
}
if (value instanceof List) {
value = `znsocket.List:${value._key}`;
} else if (value instanceof ZnSocketDict) {
value = `znsocket.Dict:${value._key}`;
}
return this._client.lSet(this._key, index, JSON.stringify(value));
}

Expand All @@ -82,11 +93,21 @@ export class List {
}

async get(index) { // Renamed from getitem to get
const value = await this._client.lIndex(this._key, index);
let value = await this._client.lIndex(this._key, index);
if (value === null) {
return null;
}
return JSON.parse(value);
value = JSON.parse(value); // Parse the value
if (typeof value === "string") {
if (value.startsWith("znsocket.List:")) {
const refKey = value.split(/:(.+)/)[1];
return new List({ client: this._client,socket: this._socket , key: refKey});
} else if (value.startsWith("znsocket.Dict:")) {
const refKey = value.split(/:(.+)/)[1];
return new ZnSocketDict({ client: this._client, socket: this._socket , key: refKey});
}
}
return value;
}

onRefresh(callback) {
Expand Down
43 changes: 42 additions & 1 deletion js_tests/native.dict.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createClient, Dict } from "znsocket";
import { createClient, Dict, List } from "znsocket";

const ZNSOCKET_URL = "http://127.0.0.1:4748";
let client;
Expand Down Expand Up @@ -210,3 +210,44 @@ test("native_dict_json_test", async () => {
// expect(await dct.entries()).toEqual([[5, 5], [6, "6"], [7, 7], [8, "8"]]);
// expect(await dct.entries()).toEqual([["5", 5], ["6", "6"], ["7", 7], ["8", "8"]]); // WRONG! but what we get right now
});


test("native_dict_in_dict", async () => {
let dct1 = new Dict({ client: client, key: "dict:test:1" });
let dct2 = new Dict({ client: client, key: "dict:test:2" });

await dct1.set("Hello", "World");
await dct2.set("dict", dct1);

const dictInstance = await dct2.get("dict");
expect(dictInstance).toBeInstanceOf(Dict);
expect(dictInstance._key).toBe(dct1._key);
const helloValue = await dictInstance.get("Hello");
expect(helloValue).toBe("World");

await dct1.update({ "dct2": dct2 });

const dictInstance2 = await dct1.get("dct2");
expect(dictInstance2).toBeInstanceOf(Dict);
expect(dictInstance2._key).toBe(dct2._key);
const dictValue = await dictInstance2.get("dict");
expect(dictValue).toBeInstanceOf(Dict);
expect(dictValue._key).toBe(dct1._key);
const helloValue2 = await dictValue.get("Hello");
expect(helloValue2).toBe("World");
});

test("native_dict_with_list", async () => {
let lst = new List({ client: client, key: "list:test" });
let dct = new Dict({ client: client, key: "dict:test" });

await lst.push("A");
await lst.push("B");
await dct.set("list", lst);

const listInstance = await dct.get("list");
expect(listInstance).toBeInstanceOf(List);
expect(listInstance._key).toBe(lst._key);
expect(await listInstance.get(0)).toBe("A");
expect(await listInstance.get(1)).toBe("B");
});
34 changes: 33 additions & 1 deletion js_tests/native.list.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createClient, List } from "znsocket";
import { createClient, List, Dict } from "znsocket";

const ZNSOCKET_URL = "http://127.0.0.1:4748";
let client;
Expand Down Expand Up @@ -253,3 +253,35 @@ test("native_list_slice", async () => {
expect(sliced).toEqual(["item2", "item3"]);

});


test("native_list_in_list", async () => {
let lst1 = new List({ client: client, key: "list:test:1" });
let lst2 = new List({ client: client, key: "list:test:2" });

lst1.push(1);
lst2.push(lst1);

await new Promise(resolve => setTimeout(resolve, 100));

let item = await lst2.get(0);
expect(item).toBeInstanceOf(List);
expect(await item.get(0)).toBe(1);
});

test("native_list_with_dict", async () => {
let lst = new List({ client: client, key: "list:test" });
let dct = new Dict({ client: client, key: "dict:test" });

await dct.set("a", "A5");
await dct.set("b", "A6");

await lst.push(dct);

await new Promise(resolve => setTimeout(resolve, 100));

let item = await lst.get(0);
expect(item).toBeInstanceOf(Dict);
expect(await item.get("a")).toBe("A5");
expect(await item.get("b")).toBe("A6");
});

0 comments on commit 720b010

Please sign in to comment.