Skip to content

Commit f1b0d97

Browse files
fix: refactor queries
1 parent c4c6d0c commit f1b0d97

10 files changed

+227
-69
lines changed

packages/sdk/src/__example__/index.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export const schema: MockSchemaType = {
5151
durability: 0,
5252
},
5353
},
54-
} as MockSchemaType;
54+
};
5555

5656
async function exampleUsage() {
5757
const db = await init<MockSchemaType>(
@@ -70,9 +70,8 @@ async function exampleUsage() {
7070
player: {
7171
$: {
7272
where: {
73-
// done does not exisst and no warning is thrown
74-
name: { $eq: "Alice" },
75-
score: { $gt: 10 },
73+
name: { $is: "Alice" },
74+
score: { $is: 10 },
7675
},
7776
},
7877
},

packages/sdk/src/__tests__/convertQueryToClause.test.ts

+18-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe("convertQueryToClause", () => {
1313
},
1414
};
1515

16-
const result = convertQueryToClause(query);
16+
const result = convertQueryToClause(query, schema);
1717

1818
expect(result).toEqual({
1919
Composite: {
@@ -70,7 +70,7 @@ describe("convertQueryToClause", () => {
7070
},
7171
};
7272

73-
const result = convertQueryToClause(query);
73+
const result = convertQueryToClause(query, schema);
7474

7575
expect(result).toEqual({
7676
Composite: {
@@ -105,7 +105,7 @@ describe("convertQueryToClause", () => {
105105
},
106106
};
107107

108-
const result = convertQueryToClause(query);
108+
const result = convertQueryToClause(query, schema);
109109

110110
expect(result).toEqual({
111111
Composite: {
@@ -141,7 +141,7 @@ describe("convertQueryToClause", () => {
141141
},
142142
};
143143

144-
const result = convertQueryToClause(query);
144+
const result = convertQueryToClause(query, schema);
145145

146146
expect(result).toEqual({
147147
Composite: {
@@ -167,12 +167,17 @@ describe("convertQueryToClause", () => {
167167
$: { where: { score: { $gt: 100 } } },
168168
},
169169
item: {
170-
$: { where: { durability: { $lt: 50 } } },
170+
$: {
171+
where: {
172+
durability: { $lt: 50 },
173+
type: { $is: "diamond" },
174+
},
175+
},
171176
},
172177
},
173178
};
174179

175-
const result = convertQueryToClause(query);
180+
const result = convertQueryToClause(query, schema);
176181

177182
expect(result).toEqual({
178183
Composite: {
@@ -186,6 +191,13 @@ describe("convertQueryToClause", () => {
186191
value: { Primitive: { U32: 100 } },
187192
},
188193
},
194+
{
195+
Keys: {
196+
keys: [undefined, "diamond", undefined],
197+
pattern_matching: "VariableLen",
198+
models: ["world-item"],
199+
},
200+
},
189201
{
190202
Member: {
191203
model: "world-item",

packages/sdk/src/__tests__/convertQueryToEntityKeyClauses.test.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ describe("convertQueryToEntityKeyClauses", () => {
103103
it("should handle queries with entityIds", () => {
104104
const query: QueryType<MockSchemaType> = {
105105
world: {
106-
player: {
107-
$: {},
106+
item: {
107+
$: {
108+
where: {
109+
type: { $is: "sword" },
110+
},
111+
},
108112
},
109113
},
110114
};
@@ -113,9 +117,9 @@ describe("convertQueryToEntityKeyClauses", () => {
113117
const expected: torii.EntityKeysClause[] = [
114118
{
115119
Keys: {
116-
keys: Array(3).fill(undefined), // ['id', 'name', 'score']
120+
keys: [undefined, "sword", undefined], // ['id', 'type']
117121
pattern_matching: "VariableLen",
118-
models: ["world-player"],
122+
models: ["world-item"],
119123
},
120124
},
121125
];

packages/sdk/src/convertQueryToEntityKeyClauses.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as torii from "@dojoengine/torii-client";
2-
import { SchemaType, QueryType } from "./types";
2+
import { SchemaType, SubscriptionQueryType } from "./types";
33

44
/**
55
* Converts a subscription query to an array of EntityKeysClause.
@@ -10,7 +10,7 @@ import { SchemaType, QueryType } from "./types";
1010
* @returns An array of EntityKeysClause.
1111
*/
1212
export function convertQueryToEntityKeyClauses<T extends SchemaType>(
13-
query: QueryType<T>,
13+
query: SubscriptionQueryType<T>,
1414
schema: T
1515
): torii.EntityKeysClause[] {
1616
if (!query) {
@@ -25,6 +25,17 @@ export function convertQueryToEntityKeyClauses<T extends SchemaType>(
2525
clauses.push({ HashedKeys: entityIds });
2626
}
2727

28+
clauses.push(...convertQueryToKeysClause(namespaces, schema));
29+
30+
return clauses;
31+
}
32+
33+
export function convertQueryToKeysClause<T extends SchemaType>(
34+
namespaces: Omit<SubscriptionQueryType<T>, "entityIds">,
35+
schema: T
36+
): torii.EntityKeysClause[] {
37+
const clauses: torii.EntityKeysClause[] = [];
38+
2839
Object.entries(namespaces).forEach(([namespace, models]) => {
2940
if (models && typeof models === "object") {
3041
Object.entries(models).forEach(([model, value]) => {
@@ -106,6 +117,7 @@ function createClauseFromWhere(
106117
whereOptions?: Record<
107118
string,
108119
{
120+
$is?: any;
109121
$eq?: any;
110122
$neq?: any;
111123
$gt?: any;
@@ -136,6 +148,9 @@ function createClauseFromWhere(
136148
const index = fieldOrder.indexOf(field);
137149
if (index !== -1) {
138150
// Assign value without operator prefixes
151+
if (condition.$is !== undefined) {
152+
keys[index] = condition.$is.toString();
153+
}
139154
if (condition.$eq !== undefined) {
140155
keys[index] = condition.$eq.toString();
141156
}

packages/sdk/src/convertQuerytoClause.ts

+118-30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as torii from "@dojoengine/torii-client";
2-
import { SchemaType, QueryType } from "./types";
2+
import { SchemaType, QueryType, SubscriptionQueryType } from "./types";
3+
import { convertQueryToKeysClause } from "./convertQueryToEntityKeyClauses";
34

45
/**
56
* Converts a query object into a Torii clause.
@@ -26,7 +27,7 @@ import { SchemaType, QueryType } from "./types";
2627
*/
2728
export function convertQueryToClause<T extends SchemaType>(
2829
query: QueryType<T>,
29-
operator: torii.LogicalOperator = "And"
30+
schema: T
3031
): torii.Clause {
3132
const clauses: torii.Clause[] = [];
3233

@@ -50,50 +51,137 @@ export function convertQueryToClause<T extends SchemaType>(
5051
) {
5152
const whereClause = conditions.where;
5253
if (whereClause && typeof whereClause === "object") {
53-
for (const [member, memberValue] of Object.entries(
54-
whereClause
55-
)) {
56-
if (
57-
typeof memberValue === "object" &&
58-
memberValue !== null
59-
) {
60-
for (const [op, val] of Object.entries(
61-
memberValue
62-
)) {
54+
// Separate $is conditions from other conditions
55+
const hasIsClause = Object.values(whereClause).some(
56+
(condition: any) => "$is" in condition
57+
);
58+
59+
if (hasIsClause) {
60+
// Extract $is conditions for Keys clause
61+
const isConditions: any = {};
62+
const otherConditions: any = {};
63+
for (const [
64+
member,
65+
memberValue,
66+
] of Object.entries(whereClause)) {
67+
if (
68+
typeof memberValue === "object" &&
69+
memberValue !== null &&
70+
"$is" in memberValue
71+
) {
72+
isConditions[member] = memberValue;
73+
} else {
74+
otherConditions[member] = memberValue;
75+
}
76+
}
77+
78+
// Build Keys clause using existing function
79+
const keyClauses = convertQueryToKeysClause(
80+
{
81+
[namespace]: {
82+
[model]: {
83+
$: {
84+
where: isConditions,
85+
},
86+
},
87+
},
88+
} as Omit<
89+
SubscriptionQueryType<T>,
90+
"entityIds"
91+
>,
92+
schema
93+
);
94+
clauses.push(...(keyClauses as any));
95+
96+
// Process other conditions as Member clauses
97+
for (const [
98+
member,
99+
memberValue,
100+
] of Object.entries(otherConditions)) {
101+
if (
102+
typeof memberValue === "object" &&
103+
memberValue !== null
104+
) {
105+
for (const [op, val] of Object.entries(
106+
memberValue
107+
)) {
108+
clauses.push({
109+
Member: {
110+
model: namespaceModel,
111+
member,
112+
operator:
113+
convertOperator(op),
114+
value: convertToPrimitive(
115+
val
116+
),
117+
},
118+
});
119+
}
120+
} else {
121+
// Assume equality condition
63122
clauses.push({
64123
Member: {
65124
model: namespaceModel,
66125
member,
67-
operator: convertOperator(op),
68-
value: convertToPrimitive(val),
126+
operator: "Eq",
127+
value: convertToPrimitive(
128+
memberValue
129+
),
130+
},
131+
});
132+
}
133+
}
134+
} else {
135+
// No $is conditions, process all as Member clauses
136+
for (const [
137+
member,
138+
memberValue,
139+
] of Object.entries(whereClause)) {
140+
if (
141+
typeof memberValue === "object" &&
142+
memberValue !== null
143+
) {
144+
for (const [op, val] of Object.entries(
145+
memberValue
146+
)) {
147+
clauses.push({
148+
Member: {
149+
model: namespaceModel,
150+
member,
151+
operator:
152+
convertOperator(op),
153+
value: convertToPrimitive(
154+
val
155+
),
156+
},
157+
});
158+
}
159+
} else {
160+
// Assume equality condition
161+
clauses.push({
162+
Member: {
163+
model: namespaceModel,
164+
member,
165+
operator: "Eq",
166+
value: convertToPrimitive(
167+
memberValue
168+
),
69169
},
70170
});
71171
}
72-
} else {
73-
clauses.push({
74-
Member: {
75-
model: namespaceModel,
76-
member,
77-
operator: "Eq", // Default to Eq
78-
value: convertToPrimitive(
79-
memberValue
80-
),
81-
},
82-
});
83172
}
84173
}
85174
}
86175
}
87176
} else {
88177
// Handle the case where there are no conditions
89-
90-
return {
178+
clauses.push({
91179
Keys: {
92180
keys: [undefined],
93181
pattern_matching: "FixedLen",
94182
models: [namespaceModel],
95183
},
96-
};
184+
});
97185
}
98186
}
99187
}
@@ -103,7 +191,7 @@ export function convertQueryToClause<T extends SchemaType>(
103191
if (clauses.length > 0) {
104192
return {
105193
Composite: {
106-
operator: operator,
194+
operator: "And",
107195
clauses: clauses,
108196
},
109197
};
@@ -112,7 +200,7 @@ export function convertQueryToClause<T extends SchemaType>(
112200
// If there are no clauses, return an empty Composite
113201
return {
114202
Composite: {
115-
operator: operator,
203+
operator: "And",
116204
clauses: [],
117205
},
118206
};

packages/sdk/src/getEntities.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import * as torii from "@dojoengine/torii-client";
2929
export async function getEntities<T extends SchemaType>(
3030
client: torii.ToriiClient,
3131
query: QueryType<T>,
32+
schema: T,
3233
callback: (response: {
3334
data?: StandardizedQueryResult<T>;
3435
error?: Error;
@@ -37,7 +38,7 @@ export async function getEntities<T extends SchemaType>(
3738
offset: number = 0, // Default offset
3839
options?: { logging?: boolean } // Logging option
3940
): Promise<StandardizedQueryResult<T>> {
40-
const clause = convertQueryToClause(query);
41+
const clause = convertQueryToClause(query, schema);
4142

4243
let cursor = offset;
4344
let continueFetching = true;

0 commit comments

Comments
 (0)