{"id":47845287,"url":"https://github.com/dolphindb/api-javascript","last_synced_at":"2026-04-03T21:10:08.224Z","repository":{"id":37678489,"uuid":"450848699","full_name":"dolphindb/api-javascript","owner":"dolphindb","description":"DolphinDB JavaScript API is a JavaScript library that encapsulates the ability to operate the DolphinDB database, such as: connecting to the database, executing scripts, calling functions, uploading variables, etc.","archived":false,"fork":false,"pushed_at":"2026-03-31T05:49:36.000Z","size":3842,"stargazers_count":12,"open_issues_count":0,"forks_count":1,"subscribers_count":6,"default_branch":"main","last_synced_at":"2026-03-31T07:52:28.296Z","etag":null,"topics":["dolphindb","dolphindb-api","javascript","nodejs","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dolphindb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-01-22T14:59:13.000Z","updated_at":"2026-03-31T05:49:39.000Z","dependencies_parsed_at":"2024-01-23T08:28:55.065Z","dependency_job_id":"87f65907-de6f-455c-a131-e0f34641fc1a","html_url":"https://github.com/dolphindb/api-javascript","commit_stats":{"total_commits":677,"total_committers":9,"mean_commits":75.22222222222223,"dds":0.2496307237813885,"last_synced_commit":"399c0b5c462a6c5f1adab88103fc566ad645561f"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/dolphindb/api-javascript","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dolphindb%2Fapi-javascript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dolphindb%2Fapi-javascript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dolphindb%2Fapi-javascript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dolphindb%2Fapi-javascript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dolphindb","download_url":"https://codeload.github.com/dolphindb/api-javascript/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dolphindb%2Fapi-javascript/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31377619,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T17:53:18.093Z","status":"ssl_error","status_checked_at":"2026-04-03T17:53:17.617Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["dolphindb","dolphindb-api","javascript","nodejs","typescript"],"created_at":"2026-04-03T21:10:07.656Z","updated_at":"2026-04-03T21:10:08.209Z","avatar_url":"https://github.com/dolphindb.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DolphinDB JavaScript API\n\n\u003cp align='center'\u003e\n    \u003cimg src='./ddb.svg' alt='DolphinDB' width='256'\u003e\n\u003c/p\u003e\n\n\u003cp align='center'\u003e\n    \u003ca href='https://www.npmjs.com/package/dolphindb' target='_blank'\u003e\n        \u003cimg alt='npm version' src='https://img.shields.io/npm/v/dolphindb.svg?style=flat-square\u0026color=brightgreen' /\u003e\n    \u003c/a\u003e\n    \u003ca href='https://www.npmjs.com/package/dolphindb' target='_blank'\u003e\n        \u003cimg alt='npm downloads' src='https://img.shields.io/npm/dt/dolphindb?style=flat-square\u0026color=brightgreen' /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n## English | [中文](./README.zh.md)\n\n## Overview\nThe DolphinDB JavaScript API is a JavaScript library that encapsulates interactions with the DolphinDB database, such as connecting to the database, executing scripts, calling functions, uploading variables, etc.\n\nhttps://www.npmjs.com/package/dolphindb\n\n## Features\n\n- Communicates with the DolphinDB database using WebSocket and exchanges data in binary format, supporting real-time streaming data.\n- Supports running in both browser and Node.js environments.\n- Uses TypedArray in JavaScript such as Int32Array to handle binary data.\n- Supports serialized upload of up to 2 GB of data in a single call, with no limit on the amount of downloaded data.\n\n## Usage\n\n### Connecting to DolphinDB\n\n#### Method 1: Use the built CDN version directly in the browser\n\nSave the following content to an `example.html` file and open it with a browser to run it. Press F12 to open the debug console and check the logs.\n\n```html\n\u003c!doctype html\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eDolphinDB\u003c/title\u003e\n        \u003cmeta charset='utf-8' /\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003cscript type=\"module\"\u003e\n            import { DDB } from 'https://cdn.dolphindb.cn/assets/api.js'\n            \n            let ddb = new DDB('ws://127.0.0.1:8848')\n            \n            await ddb.connect()\n            \n            console.log(\n                await ddb.execute('1 + 1')\n            )\n            \n            console.log(\n                await ddb.invoke('add', [1, 1])\n            )\n        \u003c/script\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### Method 2: Install the npm package and import to the project\n\n##### 1. Installation\n\n1.1. Install the latest version of Node.js and browser on your machine.\n- Windows: https://nodejs.org/en/download/prebuilt-installer/current\n- Linux: https://github.com/nodesource/distributions?tab=readme-ov-file#debian-and-ubuntu-based-distributions\n\n1.2. (Optional) Create a new project using the following command. Skip this step if you already have a project.\n\n```bash\nmkdir dolphindb-example\ncd dolphindb-example\nnpm init --yes\n```\n\n1.3. Open the `package.json` file with an editor and add a line `\"type\": \"module\"` below `\"main\": \"./index.js\"` to enable ECMAScript modules. In the following code, you can use `import { DDB } from 'dolphindb'` to import npm package.\n\n1.4. Install the npm package in the project.\n\n```bash\nnpm install dolphindb\n```\n\n##### 2. Usage\n\n```ts\n// 2.1 import in the browser environment\nimport { DDB } from 'dolphindb/browser.js'\n\n// 2.1 import in the Node.js environment\n// import { DDB } from 'dolphindb'\n// For existing projects using CommonJS modules, import as follows: const { DDB } = await import('dolphindb')\n\n// 2.2 Initialize the instance to connect to DolphinDB using the WebSocket URL (no actual network connection is established)\nlet ddb = new DDB('ws://127.0.0.1:8848')\n\n// Use HTTPS encryption\n// let ddb = new DDB('wss://dolphindb.com')\n\n// 2.3 Call the DolphinDB add function, automatically connecting to the database (requires DolphinDB version 1.30.16 or 2.00.4 or higher)\nconsole.log(await ddb.invoke('add', [1, 2])) // Output 3\n\n// 2.4 Disconnect after use to release resources\nddb.disconnect()\n```\n\n#### Code completion and function prompt\n\nSee https://cdn.dolphindb.cn/assets/docs.en.json  \nor https://cdn.dolphindb.cn/assets/docs.zh.json\n\n#### Connection options\n\n```ts\nlet ddb = new DDB('ws://127.0.0.1:8848', {\n    // Whether to automatically log in after establishing a connection, default is true\n    autologin: true,\n    \n    // DolphinDB login username, default is 'admin'\n    username: 'admin',\n    \n    // DolphinDB login password, default is '123456'\n    password: '123456',\n    \n    // Set python session flag, default is false\n    python: false,\n    \n    // Set the SQL standard to execute in the current session, use the SqlStandard enum, default is DolphinDB\n    // sql: SqlStandard.MySQL,\n    // sql: SqlStandard.Oracle,\n    \n    // Set this option for the database connection to be used only for streaming data, see `5. Streaming Data` for details\n    streaming: undefined\n})\n```\n\n### Calling functions\n#### `invoke` method\n##### Code example\n\n```ts\nconst result = await ddb.invoke('add', [1, 1])\n// TypeScript: const result = await ddb.invoke\u003cnumber\u003e('add', [1, 1])\n\nconsole.log(result === 2)  // true\n```\n\nIn the example above, two parameters 1 (corresponding to the int type in DolphinDB) are uploaded to the DolphinDB database as parameters of the `add` function, and the result of the function call is received in `result`.\n\n`\u003cnumber\u003e` is used for TypeScript to infer the type of the return value.\n\n##### Method declaration\n\n```ts\n/** Call a dolphindb function, passing in a native JS array as parameters, and return a native JS object or value (result after calling DdbObj.data()) */\nasync invoke \u003cTResult = any\u003e (\n    /** Function name */\n    func: string, \n    \n    /** `[ ]` Call parameters, can be a native JS array */\n    args?: any[], \n    \n    /** Call options */\n    options?: {\n        /** Urgent flag. Use urgent worker to execute, preventing being blocked by other jobs */\n        urgent?: boolean\n        \n        /** When setting node alias, send to the corresponding node in the cluster to execute (using DolphinDB's rpc method) */\n        node?: string\n        \n        /** When setting multiple node aliases, send to the corresponding multiple nodes in the cluster to execute (using DolphinDB's pnodeRun method) */\n        nodes?: string[]\n        \n        /** Required when setting the node parameter and the parameter array is empty, specify the function type, not passed in other cases */\n        func_type?: DdbFunctionType\n        \n        /** Optionally passed when setting the nodes parameter, not passed in other cases */\n        add_node_alias?: boolean\n        \n        /** Handle messages (DdbMessage) during this rpc */\n        listener?: DdbMessageListener\n    } = { }\n): Promise\u003cTResult\u003e\n```\n\n#### `call` method\n\n##### Code example\n\n```ts\nimport { DdbInt } from 'dolphindb'\n\nconst result = await ddb.call('add', [new DdbInt(1), new DdbInt(1)])\n// TypeScript: const result = await ddb.call\u003cDdbInt\u003e('add', [new DdbInt(1), new DdbInt(1)])\n\nconsole.log(result.value === 2)  // true\n```\n\n###### Using DdbObj objects to represent data types in DolphinDB\n\nIn the example above, two parameters `new DdbInt(1)`, corresponding to the INT type in DolphinDB, are uploaded to the DolphinDB database as arguments of the `add` function, and the result of the function call is received in `result`.\n\n\u003cDdbInt\u003e is used by TypeScript to infer the type of the return value\n\n- result is a DdbInt, which is also a DdbObj\u003cnumber\u003e\n- result.form is a DdbForm.scalar\n- result.type is a DdbType.int\n- result.value is data of number type in JavaScript (the value range and precision of INT can be accurately represented by JavaScript number type)\n\nIt is recommended to first understand the concepts related to TypedArray in JavaScript, you can refer to:\n\n- https://stackoverflow.com/questions/42416783/where-to-use-arraybuffer-vs-typed-array-in-javascript\n- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray\n\n```ts\n/** Can represent all data types in DolphinDB databases */\nclass DdbObj \u003cT extends DdbValue = DdbValue\u003e {\n    /** is it little endian */\n    le: boolean\n    \n    /** DolphinDB data form */\n    form: DdbForm\n    \n    /** DolphinDB data type */\n    type: DdbType\n    \n    /** consumed length in buf parsed */\n    length: number\n    \n    /** table name / column name */\n    name?: string\n    \n    /**\n        Lowest dimension\n        - vector: rows = n, cols = 1\n        - pair:   rows = 2, cols = 1\n        - matrix: rows = n, cols = m\n        - set:    the same as vector\n        - dict:   include keys, values vector\n        - table:  the same as matrix\n    */\n    rows?: number\n    \n    /** 2nd dimension */\n    cols?: number\n    \n    /** the actual data. Different DdbForm, DdbType use different types in DdbValue to represent actual data */\n    value: T\n    \n    /** raw binary data, only top-level objects generated by parse_message when parse_object is false have this attribute */\n    buffer?: Uint8Array\n    \n    constructor (data: Partial\u003cDdbObj\u003e \u0026 { form: DdbForm, type: DdbType, length: number }) {\n        Object.assign(this, data)\n    }\n}\n\nclass DdbInt extends DdbObj\u003cnumber\u003e {\n    constructor (value: number) {\n        super({\n            form: DdbForm.scalar,\n            type: DdbType.int,\n            length: 4,\n            value\n        })\n    }\n}\n\n// ... There are also many utility classes, such as DdbString, DdbLong, DdbDouble, DdbVectorDouble, DdbVectorAny, etc.\n\ntype DdbValue = \n    null | boolean | number | [number, number] | bigint | string | string[] | \n    Uint8Array | Int16Array | Int32Array | Float32Array | Float64Array | BigInt64Array | Uint8Array[] | \n    DdbObj[] | DdbFunctionDefValue | DdbSymbolExtendedValue\n    \n\nenum DdbForm {\n    scalar = 0,\n    vector = 1,\n    pair = 2,\n    matrix = 3,\n    set = 4,\n    dict = 5,\n    table = 6,\n    chart = 7,\n    chunk = 8,\n}\n\n\nenum DdbType {\n    void = 0,\n    bool = 1,\n    char = 2,\n    short = 3,\n    int = 4,\n    long = 5,\n    // ...\n    timestamp = 12,\n    // ...\n    double = 16,\n    symbol = 17,\n    string = 18,\n    // ...\n}\n```\n\n##### Specifying form and type to manually create a DdbObj object\n\nIf there is no shortcut class, you can also specify form and type to manually create a DdbObj object:\n\n```ts\n// Created by the DdbDateTime shortcut class\nnew DdbDateTime(1644573600)\n\n// Equivalent to manually creating an object of form = scalar, type = datetime through DdbObj\nconst obj = new DdbObj({\n     form: DdbForm.scalar,\n     type: DdbType.datetime,\n     value: 1644573600,\n     length: 0\n})\n\n\n// The corresponding type and value of value in js can refer to the result returned by ddb.eval (see the `eval` method declaration below)\nconst obj = await ddb.eval('2022.02.11 10:00:00')\nconsole.log(obj.form === DdbForm.scalar)\nconsole.log(obj.type === DdbType.datetime)\nconsole.log(obj.value)\n\n// Another example is to create a set\n// refer to ddb.eval\n// const obj = await ddb.eval('set([1, 2, 3])')\n// console.log(obj.value)\nconst obj = new DdbObj({\n     form: DdbForm.set,\n     type: DdbType.int,\n     value: Int32Array.of(1, 2, 3),\n     length: 0\n})\n\n// easier to use shortcut classes\nconst obj = new DdbSetInt(\n     new Set([1, 2, 3])\n)\n```\n\n##### NULL object in scalar\n\nFor the NULL object in the form of scalar, the value corresponding to DdbObj is null in JavaScript：\n\n```ts\n;(await ddb.eval('double()')).value === null\n\n// create NULL object\nnew DdbInt(null)\nnew DdbDouble(null)\n```\n\n##### Method declaration\n\n```ts\nasync call \u003cT extends DdbObj\u003e (\n    /** function name */\n    func: string,\n    \n    /** function arguments (The incoming native string and boolean will be automatically converted to DdbObj\u003cstring\u003e and DdbObj\u003cboolean\u003e) */\n    args?: (DdbObj | string | boolean)[] = [ ],\n    \n    /** calling options */\n    options?: {\n        /** Urgent flag. Use urgent worker to execute to prevent being blocked by other jobs */\n        urgent?: boolean\n        \n        /** When the node alias is set, the function is sent to the corresponding node in the cluster for execution (using the rpc method in DolphinDB) */\n        node?: string\n        \n        /** When setting multiple node aliases, send them to the corresponding multiple nodes in the cluster for execution (using the pnodeRun method in DolphinDB) */\n        nodes?: string[]\n        \n        /** It must be passed when setting the node parameter, the function type needs to be specified, and it is not passed in other cases */\n        func_type?: DdbFunctionType\n        \n        /** It may be  passed when setting the nodes parameter, otherwise may not be passed */\n        add_node_alias?: boolean\n    } = { }\n): Promise\u003cT\u003e\n```\n\n### Executing scripts\n\n#### `execute` method\n##### Code example\n\n```ts\nconst result = await ddb.eval(\n    'def foo (a, b) {\\n' +\n    '    return a + b\\n' +\n    '}\\n' +\n    'foo(1l, 1l)\\n'\n)\n\n// TypeScript:\n// import type { DdbLong } from 'dolphindb'\n// const result = await ddb.eval\u003cDdbLong\u003e(...)\n\nconsole.log(result.value === 2n)  // true\n```\n\nIn the preceding example, a script is uploaded through a string to the DolphinDB database for execution, and the execution result of the last statement `foo(1l, 1l)` is received.\n\n`\u003cDdbLong\u003e` is used by TypeScript to infer the type of the return value\n\n- result is a `DdbLong`, which is also a `DdbObj\u003cbigint\u003e`\n- result.form is `DdbForm.scalar`\n- result.type is `DdbType.long`\n- result.value is the native `bigint` in JavaScript (the precision of long cannot be accurately represented by JavaScript number, but it can be represented by bigint)\n\nAs long as the WebSocket connection is not disconnected, the custom function `foo` will always exist in the subsequent session and can be reused, for example, you can use `await ddb.call\u003cDdbInt\u003e('foo', [new DdbInt(1), new DdbInt(1)])` to call this custom function\n\n##### Method declaration\n\n```ts\n/** Execute DolphinDB script and return a native JS object or value (result after calling DdbObj.data()) */\nasync execute \u003cTResult = any\u003e (\n    /** Script to execute */\n    script: string, \n    \n    /** Execution options */\n    options?: {\n        /** Urgent flag, ensure the submitted script is processed using an urgent worker to prevent blocking by other jobs */\n        urgent?: boolean\n        /** listener?: Handle messages (DdbMessage) during this rpc */\n        listener?: DdbMessageListener\n    }\n): Promise\u003cTResult\u003e\n```\n\n#### `eval` Method\n\n##### Code example\n```ts\nconst result = await ddb.eval(\n    'def foo (a, b) {\\n' +\n    '    return a + b\\n' +\n    '}\\n' +\n    'foo(1l, 1l)\\n'\n)\n\n// TypeScript:\n// import type { DdbLong } from 'dolphindb'\n// const result = await ddb.eval\u003cDdbLong\u003e(...)\n\nconsole.log(result.value === 2n)  // true\n```\n\nIn the example above, a script is uploaded as a string to the DolphinDB database for execution, and the result of the last statement `foo(1l, 1l)` is received in `result`.\n\n`\u003cDdbLong\u003e` is used for TypeScript to infer the return value type.\n\n- result is a `DdbLong`, also `DdbObj\u003cbigint\u003e`\n- result.form is `DdbForm.scalar`\n- result.type is `DdbType.long`\n- result.value is a native `bigint` in JavaScript (the precision of long cannot be accurately represented by JavaScript's number, but can be represented by bigint)\n\n##### Method declaration\n\n```ts\n/** Execute DolphinDB script and return a DdbObj object */\nasync eval \u003cT extends DdbObj\u003e (\n    /** Script to execute */\n    script: string,\n    \n    /** Execution options */\n    options: {\n        /** Urgent flag, ensure the submitted script is processed using an urgent worker to prevent blocking by other jobs */\n        urgent?: boolean\n    } = { }\n): Promise\u003cT\u003e\n```\n\n### Upload Variables\n#### Code example\n\n```ts\nimport { DdbVectorDouble } from 'dolphindb'\n\nlet a = new Array(10000)\na.fill(1.0)\n\nddb.upload(['bar1', 'bar2'], [new DdbVectorDouble(a), new DdbVectorDouble(a)])\n```\n\nIn the example above, two variables `bar1` and `bar2` are uploaded, with values being double vectors of length 10000.\n\nAs long as the WebSocket connection is not disconnected, these variables `bar1` and `bar2` will always exist in subsequent sessions and can be reused.\n\n#### Method declaration\n\n```ts\nasync upload (\n    /** Variable names to upload */\n    vars: string[],\n    \n    /** Variable values to upload */\n    args: (DdbObj | string | boolean)[]\n): Promise\u003cvoid\u003e\n```\n\n\n### Upload and insert data into the table\n```ts\n// Load or create a table in the session corresponding to the connection\nawait ddb.execute('t = table(1..10 as id, take([\"A001\", \"B001\"], 10) as sym, rand(10.0, 10) as val)')\n// await ddb.execute('t = loadTable(database(\"dfs://path-to-db\"), \"table_name\")')\n\nconsole.log(\n    'Number of rows inserted:',\n    // Use tableInsert to insert data\n    await ddb.invoke\u003cnumber\u003e(\n        'tableInsert',\n        [\n            't',\n            \n            // Data\n            new DdbTable([\n                // First column\n                new DdbVectorInt([1, 2, 3]),\n                \n                // Second column\n                new DdbVectorSymbol(['a', 'b', 'c']),\n                \n                // The third column\n                new DdbVectorDouble([1.1, 1.2, 1.3]),\n            ])\n        ]\n    )\n)\n```\n\n### Close the connection\n```ts\nddb.disconnect()\n```\n\n\n### Other Examples\n\n```ts\nimport { nulls, DdbInt, timestamp2str, DdbVectorSymbol, DdbTable, DdbVectorDouble } from 'dolphindb'\n\n// Format timestamp in DolphinDB to string\ntimestamp2str(\n    (\n        await ddb.call('now', [false])\n        // TypeScript: await ddb.call\u003cDdbObj\u003cbigint\u003e\u003e('now', [false])\n    ).value\n) === '2022.02.23 17:23:13.494'\n\n// Create symbol vector\nnew DdbVectorSymbol(['aaa', 'aaa', 'aaa', 'aaa', 'aaa', 'bbb'])\n\n// Create double vector with NULL values using native JavaScript array\nnew DdbVectorDouble([0.1, null, 0.3])\n\n// Create double vector more efficiently and memory-saving using JavaScript TypedArray\nlet av = new Float64Array(3)\nav[0] = 0.1\nav[1] = nulls.double\nav[2] = 0.3\nnew DdbVectorDouble(av)\n\n// Create DdbTable\nnew DdbTable(\n    [\n        new DdbVectorDouble([0.1, 0.2, null], 'col0'),\n        new DdbVectorSymbol(['a', 'b', 'c'], 'col1')\n    ],\n    'mytable'\n)\n```\n\n### Streaming Data\n\n```ts\n// Create new streaming data connection configuration\nlet sddb = new DDB('ws://192.168.0.43:8800', {\n    autologin: true,\n    username: 'admin',\n    password: '123456',\n    streaming: {\n        table: 'name of the stream table to subscribe to',\n        \n        // Stream data processing callback, message type is StreamingMessage\n        handler (message) {\n            console.log(message)\n        }\n    }\n})\n\n// Establish connection\nawait sddb.connect()\n```\n\nAfter the connection is established, the received streaming data will be called as the `message` parameter of the `handler`, and the message type is `StreamingMessage`, as follows:\n\n```ts\nexport interface StreamingParams {\n    table: string\n    action?: string\n    \n    handler (message: StreamingMessage): any\n}\n\nexport interface StreamingMessage \u003cTRows = any\u003e extends StreamingParams {\n    /** The time when the server sends the message (nano seconds since epoch)\n        std::chrono::system_clock::now().time_since_epoch() / std::chrono::nanoseconds(1) */\n    time: bigint\n    \n    /** Message ID */\n    id: bigint\n    \n    /** Subscription topic, i.e., the name of a subscription.\n        It is a string composed of the alias of the node where the subscription table is located, the name of the stream table, and the name of the subscription task (if actionName is specified), separated by `/` */\n    topic: string\n    \n    /** Streaming data */\n    data: DdbTableData\u003cTRows\u003e\n    \n    window: {\n        /** Offset from the start of the connection, starting at 0, and increasing as the window moves */\n        offset: number\n        \n        /** Historical data */\n        data: TRows[]\n        \n        /** Array of objects received each time */\n        objs: DdbObj\u003cDdbVectorObj[]\u003e[]\n    }\n    \n    /** If there is an error in parsing the message pushed after the successful subscription, the error is set and the handler is called */\n    error?: Error\n}\n```\n\nTo close streaming data subscription, use the following two methods to disconnect:\n- Automatically disconnect by closing the browser page\n- Manually disconnect by calling `sddb.disconnect()`\n\n\n### Development method\n\n```shell\n# Install the latest version of nodejs (see above)\n\n# Install the pnpm package manager\nnpm install -g pnpm\n\ngit clone https://github.com/dolphindb/api-javascript.git\n\ncd api-javascript\n\n# Install project dependencies\npnpm install\n\n# Copy .vscode/settings.template.json to .vscode/settings.json\ncp .vscode/settings.template.json .vscode/settings.json\n\n# Refer to scripts in package.json\n\n# Build\npnpm run build\n\n# Format code and automatically fix code errors\npnpm run fix\n\n# Test\npnpm run test\n\n# Scan entries\npnpm run scan\n# Manually complete untranslated entries\n# Run scan again to update the dictionary file dict.json\npnpm run scan\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdolphindb%2Fapi-javascript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdolphindb%2Fapi-javascript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdolphindb%2Fapi-javascript/lists"}