This package provides a small asynchronous Node.js client for talking to an ONQL TCP server. It implements a simple framed protocol and a friendly async API so you can send requests and receive matching responses concurrently.
Install from npm:
npm install onql
Basic usage — create a client, send a request, then close the connection. This package uses ES Modules.
import { ONQLClient } from "onql";
async function main() {
const client = await ONQLClient.create("localhost", 5656);
try {
const resp = await client.sendRequest("onql or keyword", "query or data here", 5000);
console.log("Response:", resp);
} catch (err) {
console.error("Request failed:", err.message);
} finally {
await client.close();
}
}
main();
The client supports a simple subscription flow where a request ID (rid) is used as the subscription handle. The server may send multiple frames with that same rid — the client delivers them to the callback you provide.
import { ONQLClient } from "onql";
async function onEvent(rid, keyword, payload) {
console.log(`SUBSCRIPTION ${rid} -> ${keyword}:`, payload);
}
async function main() {
const client = await ONQLClient.create();
const rid = await client.subscribe("", "SELECT ...", onEvent);
console.log(`Started subscription with rid: ${rid}`);
// Let the subscription run for a bit...
await new Promise(resolve => setTimeout(resolve, 10000));
// later:
await client.unsubscribe(rid);
await client.close();
}
main();
ONQLClient.create(host = "localhost", port = 5656) -> Promise<ONQLClient>
- Connects and returns a ready-to-use client instance.
sendRequest(keyword, payload, timeoutMs = 10000) -> Promise<object>
- Sends a framed request and awaits the matching response.
payload
can be a string or an object (which will be JSON-stringified).
- Sends a framed request and awaits the matching response.
subscribe(onquery, query, callback) -> Promise<string>
- Opens a streaming subscription and returns the subscription
rid
. The callback(rid, keyword, payload) => {}
will be invoked for each message.
- Opens a streaming subscription and returns the subscription
unsubscribe(rid) -> Promise<void>
- Stops a subscription locally and sends a best-effort notification to the server.
close() -> Promise<void>
- Closes the connection and cleans up pending requests.
onLog = (level, msg) => {}
- An optional callback property for logging. Example:
client.onLog = (lvl, m) => console.log(
[${lvl}] ${m});
- An optional callback property for logging. Example:
The client uses a very small custom framing protocol to multiplex requests and responses on a single TCP connection. Important details:
- Socket type: TCP (
net.Socket
) — the client connects withnet.createConnection({ host, port })
. - End-of-message marker (EOM): ASCII
0x04
(EOT). Every frame ends with this byte so the reader can detect message boundaries. - Field delimiter: ASCII
0x1E
(record separator). Each frame is composed of three fields separated by this delimiter:request_id
,keyword
, andpayload
.
Frame layout (UTF-8 encoded, then appended with EOM byte):
<request_id><DELIM><keyword><DELIM><payload><EOM>
Example bytes for a request asking keyword get
for payload my-key
:
b"abcd1234\x1Eget\x1Emy-key" + b"\x04"
Responses use the same framing; the client matches responses to the
original request by the request_id
(rid). This design lets you make many
concurrent requests over a single long-lived TCP connection.
- If
create()
fails, ensure the server is reachable on the host/port and your firewall allows outbound TCP to that port. - If
sendRequest
rejects with a timeout error, try increasing thetimeoutMs
parameter or inspect the server logs to verify it is producing replies.