From 961bbd2e5ab76d04fefa91e150a4805351e99783 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Dec 2025 21:26:41 +0000 Subject: [PATCH] fix: allow primitive values in EventQL query results The isStreamRow function was incorrectly requiring payload to be a Record (object). This caused runEventQlQuery to fail with "Failed to run EventQL query" when the query returned primitive values (boolean, number, string) instead of objects. Fixes #304 --- src/runEventQlQuery.test.ts | 65 +++++++++++++++++++++++++++++++++++++ src/stream/isStreamRow.ts | 3 +- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/runEventQlQuery.test.ts b/src/runEventQlQuery.test.ts index b792040..13a7b25 100644 --- a/src/runEventQlQuery.test.ts +++ b/src/runEventQlQuery.test.ts @@ -68,4 +68,69 @@ suite('runEventQlQuery', { timeout: 30_000 }, () => { assert.equal(secondRow.id, '1'); assert.equal(secondRow.data.value, 42); }); + + test('reads rows with primitive number values.', async (): Promise => { + const client = container.getClient(); + + const event: EventCandidate = { + source: 'https://www.eventsourcingdb.io', + subject: '/test', + type: 'io.eventsourcingdb.test', + data: { value: 42 }, + }; + + await client.writeEvents([event]); + + const rowsRead: unknown[] = []; + for await (const row of client.runEventQlQuery('FROM e IN events PROJECT INTO e.data.value')) { + rowsRead.push(row); + } + + assert.equal(rowsRead.length, 1); + assert.equal(rowsRead[0], 42); + }); + + test('reads rows with primitive boolean values.', async (): Promise => { + const client = container.getClient(); + + const event: EventCandidate = { + source: 'https://www.eventsourcingdb.io', + subject: '/test', + type: 'io.eventsourcingdb.test', + data: { value: 42 }, + }; + + await client.writeEvents([event]); + + const rowsRead: unknown[] = []; + for await (const row of client.runEventQlQuery( + 'FROM e IN events PROJECT INTO e.data.value > 0', + )) { + rowsRead.push(row); + } + + assert.equal(rowsRead.length, 1); + assert.equal(rowsRead[0], true); + }); + + test('reads rows with primitive string values.', async (): Promise => { + const client = container.getClient(); + + const event: EventCandidate = { + source: 'https://www.eventsourcingdb.io', + subject: '/test', + type: 'io.eventsourcingdb.test', + data: { name: 'hello' }, + }; + + await client.writeEvents([event]); + + const rowsRead: unknown[] = []; + for await (const row of client.runEventQlQuery('FROM e IN events PROJECT INTO e.data.name')) { + rowsRead.push(row); + } + + assert.equal(rowsRead.length, 1); + assert.equal(rowsRead[0], 'hello'); + }); }); diff --git a/src/stream/isStreamRow.ts b/src/stream/isStreamRow.ts index 944bb09..8a1214f 100644 --- a/src/stream/isStreamRow.ts +++ b/src/stream/isStreamRow.ts @@ -1,11 +1,10 @@ -import { isRecord } from 'src/types/isRecord.js'; import { hasShapeOf } from '../types/hasShapeOf.js'; import type { StreamRow } from './StreamRow.js'; const isStreamRow = (line: unknown): line is StreamRow => { return hasShapeOf(line, { type: value => value === 'row', - payload: isRecord, + payload: (value: unknown): value is unknown => value !== undefined, }); };