{"id":13672729,"url":"https://github.com/boilingdata/node-boilingdata","last_synced_at":"2025-04-27T22:32:47.842Z","repository":{"id":38850068,"uuid":"484148475","full_name":"boilingdata/node-boilingdata","owner":"boilingdata","description":"BoilingData JS client (NodeJS and Browsers)","archived":false,"fork":false,"pushed_at":"2024-04-02T07:24:11.000Z","size":654,"stargazers_count":19,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-24T10:34:00.131Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/boilingdata.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-04-21T17:41:16.000Z","updated_at":"2024-04-15T22:14:32.000Z","dependencies_parsed_at":"2023-02-09T16:45:31.203Z","dependency_job_id":"4725c03e-c1d9-479c-898d-cdf1fb418918","html_url":"https://github.com/boilingdata/node-boilingdata","commit_stats":{"total_commits":58,"total_committers":3,"mean_commits":"19.333333333333332","dds":0.06896551724137934,"last_synced_commit":"02dcd8b351380ad79eae0dd8ec00afa77b3f8d9e"},"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boilingdata%2Fnode-boilingdata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boilingdata%2Fnode-boilingdata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boilingdata%2Fnode-boilingdata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boilingdata%2Fnode-boilingdata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boilingdata","download_url":"https://codeload.github.com/boilingdata/node-boilingdata/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251219600,"owners_count":21554444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T09:01:45.687Z","updated_at":"2025-04-27T22:32:42.817Z","avatar_url":"https://github.com/boilingdata.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# BoilingData WebSocket client JS/TS SDK\n\n![CI](https://github.com/boilingdata/node-boilingdata/workflows/CI/badge.svg?branch=main)\n![BuiltBy](https://img.shields.io/badge/TypeScript-Lovers-black.svg \"img.shields.io\")\n\nYou can use this SDK both on browser and with NodeJS.\n\n\u003e See also BoilingData command line client tool: [https://github.com/boilingdata/boilingdata-bdcli](https://github.com/boilingdata/boilingdata-bdcli).\n\n## Installing the SDK\n\n```shell\nyarn add @boilingdata/node-boilingdata\n```\n\n## Browser\n\nCopy and add `browser/boilingdata.min.js` script to your HTML.\n\n```html\n\u003cscript src=\"boilingdata.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  const bdInstance = new BoilingData({ username: \"myUsername\", password: \"myPw\" });\n  let isConnected = false;\n  async function connectAndRunQuery() {\n    if (!isConnected) {\n      await bdInstance.connect();\n      isConnected = true;\n    }\n    const rows = await bdInstance.execQueryPromise({ sql: \"SELECT 42;\" });\n    console.log({ rows });\n  }\n  connectAndRunQuery();\n\u003c/script\u003e\n```\n\n## Basic Examples\n\n`execQueryPromise()` method can be used to await for the results directly.\n\n```shell\nyarn install @boilingdata/node-boilingdata\n# copy paste the example to example.mjs file.\nBD_USERNAME=\u003cyourBoilingEmail\u003e BD_PASSWORD=\u003cyourBoilingPw\u003e node example.mjs\n```\n\n```typescript\nimport { BoilingData } from \"@boilingdata/node-boilingdata\";\n\nasync function main() {\n  const bdInstance = new BoilingData({ username: process.env[\"BD_USERNAME\"], password: process.env[\"BD_PASSWORD\"] });\n  await bdInstance.connect();\n  const start = Date.now();\n  const sql = `SELECT COUNT(*) FROM parquet_scan('s3://boilingdata-demo/demo.parquet');`;\n  const rows = await bdInstance.execQueryPromise({ sql });\n  const stop = Date.now();\n  console.log(JSON.parse(JSON.stringify(rows)));\n  console.log(\"Query time measured from this script (ms):\", stop - start);\n  await bdInstance.close();\n}\n\nmain();\n```\n\n`execQuery()` uses callbacks.\n\n```typescript\nimport { BoilingData, isDataResponse } from \"@boilingdata/node-boilingdata\";\n\nasync function main() {\n  const bdInstance = new BoilingData({ username: process.env[\"BD_USERNAME\"], password: process.env[\"BD_PASSWORD\"] });\n  await bdInstance.connect();\n  const sql = `SELECT COUNT(*) FROM parquet_scan('s3://boilingdata-demo/demo.parquet');`;\n  const rows = await new Promise\u003cany[]\u003e((resolve, reject) =\u003e {\n    let r: any[] = [];\n    bdInstance.execQuery({\n      sql,\n      callbacks: {\n        onData: (data: IBDDataResponse | unknown) =\u003e {\n          if (isDataResponse(data)) data.data.map(row =\u003e r.push(row));\n        },\n        onQueryFinished: () =\u003e resolve(r),\n        onLogError: (data: any) =\u003e reject(data),\n      },\n    });\n  });\n  console.log(rows);\n  await bdInstance.close();\n}\n```\n\n`getTapClientToken()` method can be used to fetch [Data Taps client token](https://www.taps.boilingdata.com/). You need fresh token when sending data to a Data Tap shared to you (or with your own Data Tap too). This API call does not require `connect()` method to be called as the request goes through via REST API rather than WebSocket API.\n\n```typescript\nconst bdInstance = new BoilingData({ username: process.env[\"BD_USERNAME\"], password: process.env[\"BD_PASSWORD\"] });\n// first argument is token lifetime, max \"24h\", 2nd argument is the sharing user (unless your own Tap). Both arguments are optional.\nconst tapClientToken = await bdInstance.getTapClientToken(\"24h\", \"dforsber@gmail.com\");\n```\n\nThis repository contains JS/TS BoilingData client SDK that can be used both with NodeJS and in browser. Please see the integration tests on `tests/query.test.ts` for for more examples.\n\n### Callbacks\n\nThe SDK uses the BoilingData Websocket API in the background, meaning that events can arrive at any time. We use a range of global and query-specific callbacks to allow you to hook into the events that you care about.\n\nAll callbacks work in both the global scope and the query scope; i.e. global callbacks will always be executed when a message arrives, query callbacks will only be executed when messages relating to that query arrive.\n\n- onRequest - This event happens when your application sends a request to BoilingData\n- onData - Query data response. A single query may have many onData events as processing is parallelised in the background.\n- onQueryFinished - The processing of data has completed, and you should not expect any further onData events (although more info messages may arrive)\n- onLambdaEvent - the status of your datasets, i.e. warm, warmingUp, shutdown\n- onSocketOpen - executed when the socket API successfully opens (so it is safe to start sending SQL queries)\n- onSocketClose - executed when the socket API has closed (intentionally or not)\n- onInfo - information about a query - connection time, query time, execution time, etc.\n- onLogError - Log Errors, such as SQL syntax errors.\n- onLogWarn - Log warning messages\n- onLogInfo - Log info messages\n- onLogDebug - Log debug messsages\n\n#### Setting Global Callbacks\n\nGlobal callbacks can be set when creating the BoilingData instance.\n\n```typescript\nnew BoilingData({\n  username,\n  password,\n  globalCallbacks: {\n    onRequest: req =\u003e {\n      console.log(\"A new request has been made with ID\", req.requestId);\n    },\n    onQueryFinished: req =\u003e {\n      console.log(\"Request complete!\", req.requestId);\n    },\n    onLogError: message =\u003e {\n      console.error(\"LogError\", message);\n    },\n    onSocketOpen: socketInstance =\u003e {\n      console.log(\"The socket has opened!\");\n    },\n    onLambdaEvent: message =\u003e {\n      console.log(\"Change in status of dataset: \", message);\n    },\n  },\n});\n```\n\n#### Setting Query-level Callbacks\n\nQuery callbacks are set when creating the query\n\n```typescript\nbdInstance.execQuery({\n  sql: `SELECT COUNT(*) AS count FROM parquet_scan('s3://boilingdata-demo/demo2.parquet');`,\n  callbacks: {\n    onData: data =\u003e {\n      console.log(\"Some data for this query arrived\", data);\n    },\n    onQueryFinished: () =\u003e resolve(r),\n    onLogError: (data: any) =\u003e reject(data),\n  },\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboilingdata%2Fnode-boilingdata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboilingdata%2Fnode-boilingdata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboilingdata%2Fnode-boilingdata/lists"}