Skip to content

Commit

Permalink
Merge branch 'main' into 71-dictvalues-does-not-work-with-referenced-…
Browse files Browse the repository at this point in the history
…znsocket-objects
  • Loading branch information
PythonFZ committed Nov 8, 2024
2 parents ef269da + 884916a commit db801f1
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 12 deletions.
48 changes: 43 additions & 5 deletions js/dict.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,52 @@ export class Dict {

async values() {
const values = await this._client.hVals(this._key);
return values.map((x) => JSON.parse(x)); // Parse the values
return values.map((x) => {
const value = JSON.parse(x);
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;
});
}

async entries() { // Renamed from items to entries
async entries() {
const entries = await this._client.hGetAll(this._key);
return Object.entries(entries).map(
([key, value]) => [key, JSON.parse(value)]
);
return Object.entries(entries).map(([key, value]) => {
const parsedValue = JSON.parse(value);

if (typeof parsedValue === "string") {
if (parsedValue.startsWith("znsocket.List:")) {
const refKey = parsedValue.split(/:(.+)/)[1];
return [key, new ZnSocketList({ client: this._client, socket: this._socket, key: refKey })];
} else if (parsedValue.startsWith("znsocket.Dict:")) {
const refKey = parsedValue.split(/:(.+)/)[1];
return [key, new Dict({ client: this._client, socket: this._socket, key: refKey })];
}
}

return [key, parsedValue];
});
}

async toObject() {
const entries = await this.entries();
// go through all and if one of them is a Dict or List, call toObject on it
const obj = {};
for (const [key, value] of entries) {
if (value instanceof Dict || value instanceof ZnSocketList) {
obj[key] = await value.toObject();
} else {
obj[key] = value;
}
}
return obj;
}

onRefresh(callback) {
Expand Down
3 changes: 2 additions & 1 deletion js/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ export class Dict {
clear(): Promise<any>;
keys(): Promise<string[]>;
values(): Promise<any[]>;
entries(): Promise<[string, any][]>; // Renamed from items to entries
entries(): Promise<[string, any][]>;
toObject(): Promise<Record<string, any>>;

onRefresh(callback: (data: { keys?: string[]; indices?: number[] }) => void): void;
offRefresh(): void;
Expand Down
14 changes: 14 additions & 0 deletions js_tests/native.dict.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,17 @@ test("native_dict_with_list", async () => {
expect(await listInstance.get(0)).toBe("A");
expect(await listInstance.get(1)).toBe("B");
});


test("native_dict_to_object", 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);

// convert to object
const obj = await dct2.toObject();
expect(obj).toEqual({ dict: { Hello: "World" } });

});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "znsocket",
"version": "0.2.5",
"version": "0.2.6",
"description": "JS interface for the python znsocket package",
"main": "js/index.js",
"types": "js/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "znsocket"
version = "0.2.5"
version = "0.2.6"
description = "Python implementation of a Redis-compatible API using websockets."
authors = ["Fabian Zills <[email protected]>"]
license = "Apache-2.0"
Expand Down
25 changes: 21 additions & 4 deletions znsocket/objects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ def __init__(
callbacks: dict[str, Callable]
optional function callbacks for methods
which modify the database.
repr_type: str
repr_type: DictRepr
Control the `repr` appearance of the object.
Reduce for better performance.
Expand Down Expand Up @@ -374,7 +374,7 @@ def __getitem__(self, key: str) -> t.Any:
value = List(r=self.redis, key=key)
elif value.startswith("znsocket.Dict:"):
key = value.split(":", 1)[1]
value = Dict(r=self.redis, key=key)
value = Dict(r=self.redis, key=key, repr_type=self.repr_type)
return value

def __setitem__(self, key: str, value: t.Any) -> None:
Expand Down Expand Up @@ -415,13 +415,30 @@ def keys(self) -> list[str]:
def values(self) -> list[t.Any]:
response = []
for v in self.redis.hvals(self.key):
response.append(_decode(self, v))
value = _decode(self, v)
if isinstance(value, str):
if value.startswith("znsocket.List:"):
key = value.split(":", 1)[1]
value = List(r=self.redis, key=key)
elif value.startswith("znsocket.Dict:"):
key = value.split(":", 1)[1]
value = Dict(r=self.redis, key=key, repr_type=self.repr_type)
response.append(value)
return response

def items(self) -> list[t.Tuple[str, t.Any]]:
response = []
for k, v in self.redis.hgetall(self.key).items():
response.append((k, _decode(self, v)))
value = _decode(self, v)
if isinstance(value, str):
if value.startswith("znsocket.List:"):
key = value.split(":", 1)[1]
value = List(r=self.redis, key=key)
elif value.startswith("znsocket.Dict:"):
key = value.split(":", 1)[1]
value = Dict(r=self.redis, key=key, repr_type=self.repr_type)

response.append((k, value))
return response

def __contains__(self, key: str) -> bool:
Expand Down

0 comments on commit db801f1

Please sign in to comment.