diff --git a/src/aw-client.ts b/src/aw-client.ts index 23e29e6..eefa344 100644 --- a/src/aw-client.ts +++ b/src/aw-client.ts @@ -343,31 +343,50 @@ export class AWClient { // If all results were cached, return them if (cacheResults.every((r) => r !== null)) { + //console.debug("Returning fully cached query results"); return cacheResults; } - - // Otherwise, query with remaining timeperiods - data.timeperiods = data.timeperiods.filter( - (_, i) => cacheResults[i] === null, - ); } - const queryResults = await this._post("/0/query/", data); + const timeperiodsNotCached = data.timeperiods.filter( + (_, i) => cacheResults[i] === null, + ); + + // Otherwise, query with remaining timeperiods + const queryResults = await this._post("/0/query/", { + ...data, + timeperiods: timeperiodsNotCached, + }); if (params.cache) { + /* + if (cacheResults.every((r) => r === null)) { + console.debug("Returning uncached query results"); + } else if ( + cacheResults.some((r) => r === null) && + cacheResults.some((r) => r !== null) + ) { + console.debug("Returning partially cached query results"); + } + */ + // Cache results for (const [i, result] of queryResults.entries()) { const cacheKey = JSON.stringify({ - timeperiod: data.timeperiods[i], + timeperiod: timeperiodsNotCached[i], query, }); this.queryCache[cacheKey] = result; } - // Return all results - return cacheResults.map( - (r: any, i: number) => r ?? queryResults[i], - ); + // Return all results from cache + return timeperiods.map((_, i) => { + const cacheKey = JSON.stringify({ + timeperiod: data.timeperiods[i], + query, + }); + return this.queryCache[cacheKey]; + }); } else { return queryResults; } diff --git a/src/test/test.ts b/src/test/test.ts index fa0b2cd..f640d9c 100644 --- a/src/test/test.ts +++ b/src/test/test.ts @@ -155,10 +155,15 @@ describe("Basic API usage", () => { }); it("Query", async () => { - const e1 = { ...testevent, timestamp: new Date("2022-01-01") }; - const e2 = { ...testevent, timestamp: new Date("2022-01-02") }; + const d1 = new Date("2022-01-01"); + const d2 = new Date("2022-01-02"); + const d3 = new Date("2022-01-03"); + const e1 = { ...testevent, timestamp: d1 }; + const e2 = { ...testevent, timestamp: d2 }; + const e3 = { ...testevent, timestamp: d3 }; await awc.heartbeat(bucketId, 5, e1); await awc.heartbeat(bucketId, 5, e2); + await awc.heartbeat(bucketId, 5, e3); // Both these are valid timeperiod specs const timeperiods = [ @@ -178,7 +183,20 @@ describe("Basic API usage", () => { e2.timestamp.toISOString(), new Date(resp_e1.timestamp).toISOString(), ); - assert.equal(e2.data.label, resp[0][0].data.label); + assert.equal(e2.data.label, resp_e1.data.label); + + // Run query again and check that the results are the same (correctly cached) + const resp2: IEvent[][] = await awc.query(timeperiods, query); + assert.deepEqual(resp, resp2); + + // Add a timeperiod and query again, to check that partial cache works + const timeperiods2 = [ + { start: d1, end: d2 }, + { start: d2, end: d3 }, + ]; + const resp3: IEvent[][] = await awc.query(timeperiods2, query); + assert.equal(2, resp3[0].length); + assert.equal(2, resp3[1].length); }); });