{"id":20564317,"url":"https://github.com/tarantool/node-tarantool-driver","last_synced_at":"2025-04-09T23:19:16.244Z","repository":{"id":29824805,"uuid":"33369333","full_name":"tarantool/node-tarantool-driver","owner":"tarantool","description":"Node driver for Tarantool 1.6+","archived":false,"fork":false,"pushed_at":"2024-09-05T13:25:00.000Z","size":355,"stargazers_count":66,"open_issues_count":12,"forks_count":21,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-02T21:09:28.941Z","etag":null,"topics":["javascript","tarantool"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tarantool.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2015-04-03T15:28:31.000Z","updated_at":"2024-12-06T09:58:41.000Z","dependencies_parsed_at":"2024-06-18T22:35:16.360Z","dependency_job_id":"ca4a0f0a-e12b-42fe-9a7a-03f10f3a68ed","html_url":"https://github.com/tarantool/node-tarantool-driver","commit_stats":{"total_commits":129,"total_committers":10,"mean_commits":12.9,"dds":0.4728682170542635,"last_synced_commit":"8274c300391efff728b3a4b651e54643ed7a5dc9"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fnode-tarantool-driver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fnode-tarantool-driver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fnode-tarantool-driver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tarantool%2Fnode-tarantool-driver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tarantool","download_url":"https://codeload.github.com/tarantool/node-tarantool-driver/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248125735,"owners_count":21051792,"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":["javascript","tarantool"],"created_at":"2024-11-16T04:25:35.633Z","updated_at":"2025-04-09T23:19:16.219Z","avatar_url":"https://github.com/tarantool.png","language":"JavaScript","readme":"# Node.js driver for tarantool 1.7+\n\n[![Build Status](https://travis-ci.org/tarantool/node-tarantool-driver.svg)](https://travis-ci.org/tarantool/node-tarantool-driver)\n\nNode tarantool driver for 1.7+ support Node.js v.4+.\n\nBased on [go-tarantool](https://github.com/tarantool/go-tarantool) and implements [Tarantool’s binary protocol](http://tarantool.org/doc/dev_guide/box-protocol.html), for more information you can read them or basic documentation at [Tarantool manual](http://tarantool.org/doc/).\n\nCode architecture and some features in version 3 borrowed from the [ioredis](https://github.com/luin/ioredis).\n\n[msgpack-lite](https://github.com/kawanet/msgpack-lite) package used as MsgPack encoder/decoder.\n\n\u003c!-- If you have a problem with connection it will be destroyed. You can subscribe on TarantoolConnection.socket.on('close') for retrieve information about closing connection or you can process rejected errors for you requests. --\u003e\n\n\n## Table of contents\n\n* [Installation](#installation)\n* [Configuration](#configuration)\n* [Usage example](#usage-example)\n* [Msgpack implementation](#msgpack-implementation)\n* [API reference](#api-reference)\n* [Debugging](#debugging)\n* [Contributions](#contributions)\n* [Changelog](#changelog)\n\n## Installation\n\n```Bash\nnpm install --save tarantool-driver\n```\n## Configuration\n\nnew Tarantool([port], [host], [options]) ⇐ \u003ccode\u003e[EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter)\u003c/code\u003e\u003c/dt\u003e\n\nCreates a Tarantool instance, extends [EventEmitter](http://nodejs.org/api/events.html#events_class_events_eventemitter).\n\nConnection related custom events:\n* \"reconnecting\" - emitted when the client try to reconnect, first argument is retry delay in ms.\n* \"connect\" - emitted when the client connected and auth passed (if username and password provided), first argument is an object with host and port of the Taranool server.\n* \"change_host\" - emitted when `nonWritableHostPolicy` option is set and write error occurs, first argument is the text of error which provoked the host to be changed.\n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| [port] | \u003ccode\u003enumber\u003c/code\u003e \\| \u003ccode\u003estring\u003c/code\u003e \\| \u003ccode\u003eObject\u003c/code\u003e | \u003ccode\u003e3301\u003c/code\u003e | Port of the Tarantool server, or a URI string (see the examples in [tarantool configuration doc](https://tarantool.org/en/doc/reference/configuration/index.html#uri)), or the `options` object(see the third argument). |\n| [host] | \u003ccode\u003estring\u003c/code\u003e \\| \u003ccode\u003eObject\u003c/code\u003e | \u003ccode\u003e\u0026quot;localhost\u0026quot;\u003c/code\u003e | Host of the Tarantool server, when the first argument is a URL string, this argument is an object represents the options. |\n| [path] | \u003ccode\u003estring\u003c/code\u003e \\| \u003ccode\u003eObject\u003c/code\u003e | \u003ccode\u003enull\u003c/code\u003e | Unix socket path of the Tarantool server. |\n| [options] | \u003ccode\u003eObject\u003c/code\u003e |  | Other options, including all from [net.createConnection](https://nodejs.org/api/net.html#netcreateconnection). |\n| [options.port] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e6379\u003c/code\u003e | Port of the Tarantool server. |\n| [options.host] | \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003e\u0026quot;localhost\u0026quot;\u003c/code\u003e | Host of the Tarantool server. |\n| [options.username] | \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003enull\u003c/code\u003e | If set, client will authenticate with the value of this option when connected. |\n| [options.password] | \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003enull\u003c/code\u003e | If set, client will authenticate with the value of this option when connected. |\n| [options.timeout] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e0\u003c/code\u003e | The milliseconds before a timeout occurs during the initial connection to the Tarantool server. |\n| [options.tls] | \u003ccode\u003eObject\u003c/code\u003e | \u003ccode\u003enull\u003c/code\u003e | If specified, forces to use `tls` module instead of the default `net`. In object properties you can specify any TLS-related options, e.g. from the [tls.createSecureContext()](https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions) |\n| [options.keepAlive] | \u003ccode\u003eboolean\u003c/code\u003e | \u003ccode\u003etrue\u003c/code\u003e | Enables keep-alive functionality (recommended). |\n| [options.noDelay] | \u003ccode\u003eboolean\u003c/code\u003e | \u003ccode\u003etrue\u003c/code\u003e | Disables the use of Nagle's algorithm (recommended). |\n| [options.lazyConnect] | \u003ccode\u003eboolean\u003c/code\u003e | \u003ccode\u003efalse\u003c/code\u003e | By default, When a new `Tarantool` instance is created, it will connect to Tarantool server automatically. If you want to keep disconnected util a command is called, you can pass the `lazyConnect` option to the constructor. |\n| [options.nonWritableHostPolicy] | \u003ccode\u003estring\u003c/code\u003e | \u003ccode\u003enull\u003c/code\u003e | What to do when Tarantool server rejects write operation, e.g. because of `box.cfg.read_only` set to `true` or during snapshot fetching. \u003cbr /\u003e Possible values are: \u003cbr /\u003e - `null`: just rejects Promise with an error \u003cbr /\u003e - `changeHost`: disconnect from the current host and connect to the next from `reserveHosts`. Pending Promise will be rejected. \u003cbr /\u003e - `changeAndRetry`: same as `changeHost`, but after reconnecting tries to run the command again in order to fullfil the Promise |\n| [options.maxRetriesPerRequest] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e5\u003c/code\u003e | Number of attempts to find the alive host if `nonWritableHostPolicy` is not null. |\n| [options.enableOfflineQueue] | \u003ccode\u003eboolean\u003c/code\u003e | \u003ccode\u003etrue\u003c/code\u003e | By default, if there is no active connection to the Tarantool server, commands are added to a queue and are executed once the connection is \"ready\", meaning the connection to the Tarantool server has been established and auth passed (`connect` event is also executed at this moment). If this option is false, when execute the command when the connection isn't ready, an error will be returned. |\n| [options.reserveHosts] | \u003ccode\u003earray\u003c/code\u003e | [] | Array of [strings](https://tarantool.org/en/doc/reference/configuration/index.html?highlight=uri#uri)  - reserve hosts. Client will try to connect to hosts from this array after loosing connection with current host and will do it cyclically. See example below.|\n| [options.beforeReserve] | \u003ccode\u003enumber\u003c/code\u003e | \u003ccode\u003e2\u003c/code\u003e | Number of attempts to reconnect before connect to next host from the \u003ccode\u003ereserveHosts\u003c/code\u003e |\n| [options.retryStrategy] | \u003ccode\u003efunction\u003c/code\u003e |  | See below |\n\n### Reserve hosts example:\n\n```javascript\nlet connection = new Tarantool({\n    host: 'mail.ru',\n    port: 33013,\n    username: 'user'\n    password: 'secret',\n    reserveHosts: [\n        'anotheruser:difficultpass@mail.ru:33033',\n        '127.0.0.1:3301'\n    ],\n    beforeReserve: 1\n})\n// connect to mail.ru:33013 -\u003e dead\n//                  ↓\n// trying connect to mail.ru:33033 -\u003e dead\n//                  ↓\n// trying connect to 127.0.0.1:3301 -\u003e dead\n//                  ↓\n// trying connect to mail.ru:33013 ...etc\n```\n\n### Retry strategy\n\nBy default, node-tarantool-driver client will try to reconnect when the connection to Tarantool is lost\nexcept when the connection is closed manually by `tarantool.disconnect()`.\n\nIt's very flexible to control how long to wait to reconnect after disconnection\nusing the `retryStrategy` option:\n\n```javascript\nvar tarantool = new Tarantool({\n  // This is the default value of `retryStrategy`\n  retryStrategy: function (times) {\n    var delay = Math.min(times * 50, 2000);\n    return delay;\n  }\n});\n```\n\n\n`retryStrategy` is a function that will be called when the connection is lost.\nThe argument `times` means this is the nth reconnection being made and\nthe return value represents how long (in ms) to wait to reconnect. When the\nreturn value isn't a number, node-tarantool-driver will stop trying to reconnect, and the connection\nwill be lost forever if the user doesn't call `tarantool.connect()` manually.\n\n**This feature is borrowed from the [ioredis](https://github.com/luin/ioredis)**\n\n## Usage example\n\nWe use TarantoolConnection instance and connect before other operations. Methods call return promise(https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise). Available methods with some testing: select, update, replace, insert, delete, auth, destroy.\n```javascript\nvar TarantoolConnection = require('tarantool-driver');\nvar conn = new TarantoolConnection('notguest:sesame@mail.ru:3301');\n\n// select arguments space_id, index_id, limit, offset, iterator, key\nconn.select(512, 0, 1, 0, 'eq', [50])\n    .then(funtion(results){\n        doSomeThingWithResults(results);\n    });\n```\n\n\n## Msgpack implementation\n\nYou can use any implementation that can be duck typing with next interface:\n\n```Javascript\n//msgpack implementation example\n/*\n    @interface\n    decode: (Buffer buf)\n    encode: (Object obj)\n */\nvar exampleCustomMsgpack = {\n    encode: function(obj){\n        return yourmsgpack.encode(obj);\n    },\n    decode: function(buf){\n        return yourmsgpack.decode(obj);\n    }\n};\n```\n\nBy default use msgpack-lite package.\n\n## API reference\n\n### tarantool.connect() ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nResolve if connected. Or reject if not.\n\n### tarantool._auth(login: String, password: String) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\n**An internal method. The connection should be established before invoking.**\n\nAuth with using [chap-sha1](http://tarantool.org/doc/book/box/box_space.html). About authenthication more here: [authentication](http://tarantool.org/doc/book/box/authentication.html)\n\n### tarantool.packUuid(uuid: String)\n\n**Method for converting [UUID values](https://www.tarantool.io/ru/doc/latest/concepts/data_model/value_store/#uuid) to Tarantool-compatible format.**\n\nIf passing UUID without converion via this method, server will accept it as simple String.\n\n### tarantool.packDecimal(numberToConvert: Number)\n\n**Method for converting Numbers (Float or Integer) to Tarantool [Decimal](https://www.tarantool.io/ru/doc/latest/concepts/data_model/value_store/#decimal) type.**\n\nIf passing number without converion via this method, server will accept it as Integer or Double (for JS Float type).\n\n### tarantool.packInteger(numberToConvert: Number)\n\n**Method for safely passing numbers up to int64 to bind params**\n\nOtherwise msgpack will encode anything bigger than int32 as a double number.\n\n### tarantool.select(spaceId: Number or String, indexId: Number or String, limit: Number, offset: Number, iterator: Iterator,  key: tuple) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\n[Iterators](http://tarantool.org/doc/book/box/box_index.html). Available iterators: 'eq', 'req', 'all', 'lt', 'le', 'ge', 'gt', 'bitsAllSet', 'bitsAnySet', 'bitsAllNotSet'.\n\nIt's just select. Promise resolve array of tuples.\n\nSome examples:\n\n```Javascript\nconn.select(512, 0, 1, 0, 'eq', [50]);\n//same as\nconn.select('test', 'primary', 1, 0, 'eq', [50]);\n```\n\nYou can use space name or index name instead of id, but this way some requests will be made to get and cache metadata. This stored information will be actual for delete, replace, insert, update too.\n\nFor tests, we will create a Space named 'users' on the Tarantool server-side, where the 'id' index is of UUID type:\n\n```lua\n-- example schema of such space\nbox.schema.space.create(\"users\", {engine = 'memtx'})\nbox.space.users:format({\n    {name = 'id', type = 'uuid', is_nullable = false},\n    {name = 'username', type = 'string', is_nullable = false}\n})\n```\nAnd then select some tuples on a client side:\n```Javascript\nconn.select('users', 'id', 1, 0, 'eq', [conn.packUuid('550e8400-e29b-41d4-a716-446655440000')]);\n```\n\n### tarantool.selectCb(spaceId: Number or String, indexId: Number or String, limit: Number, offset: Number, iterator: Iterator,  key: tuple, callback: function(success), callback: function(error))\n\nSame as [tarantool.select](#select) but with callbacks.\n\n### tarantool.delete(spaceId: Number or String, indexId: Number or String, key: tuple) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nPromise resolve an array of deleted tuples.\n\n### tarantool.update(spaceId: Number or String, indexId: Number or String, key: tuple, ops) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\n[Possible operators.](https://tarantool.org/doc/book/box/box_space.html#lua-function.space_object.update)\n\nPromise resolve an array of updated tuples.\n\n### tarantool.insert(spaceId: Number or String, tuple) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nMore you can read here: [Insert](https://tarantool.org/doc/book/box/box_space.html#lua-function.space_object.insert)\n\nPromise resolve a new tuple.\n\n### tarantool.upsert(spaceId: Number or String, ops: array of operations, tuple: tuple) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nAbout operation: [Upsert](http://tarantool.org/doc/book/box/box_space.html#lua-function.space_object.upsert)\n\n[Possible operators.](https://tarantool.org/doc/book/box/box_space.html#lua-function.space_object.update)\n\nPromise resolve nothing.\n\n### tarantool.replace(spaceId: Number or String, tuple: tuple) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nMore you can read here: [Replace](https://tarantool.org/doc/book/box/box_space.html#lua-function.space_object.replace)\n\nPromise resolve a new or replaced tuple.\n\n### tarantool.call(functionName: String, args...) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nCall a function with arguments.\n\nYou can create function on tarantool side:\n```Lua\nfunction myget(id)\n    val = box.space.batched:select{id}\n    return val[1]\nend\n```\n\nAnd then use something like this:\n```Javascript\nconn.call('myget', 4)\n    .then(function(value){\n        console.log(value);\n    });\n```\n\nIf you have a 2 arguments function just send a second arguments in this way:\n```Javascript\nconn.call('my2argumentsfunc', 'first', 'second argument')\n```\nAnd etc like this.\n\nBecause lua support a multiple return it's always return array or undefined.\n\n### tarantool.eval(expression: String) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nEvaluate and execute the expression in Lua-string. [Eval](https://tarantool.org/doc/reference/reference_lua/net_box.html?highlight=eval#lua-function.conn.eval)\n\nPromise resolve result:any.\n\nExample:\n\n\n```Javascript\nconn.eval('return box.session.user()')\n    .then(function(res){\n        console.log('current user is:' res[0])\n    })\n```\n\n### tarantool.sql(query: String, bindParams: Array) ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nIt's accessible only in 2.1 tarantool.\n\nYou can use SQL query that is like sqlite dialect to query a tarantool database.\n\nYou can insert or select or create database.\n\nMore about it [here](https://www.tarantool.io/en/doc/2.1/tutorials/sql_tutorial/).\n\nExample:\n\n```Javascript\nawait connection.insert('tags', ['tag_1', 1])\nawait connection.insert('tags', ['tag_2', 50])\nconnection.sql('select * from \"tags\"')\n.then((res) =\u003e {\n  console.log('Successful get tags', res);\n})\n.catch((error) =\u003e {\n  console.log(error);\n});\n```\n\nP.S. If you using lowercase in your space name you need to use a double quote for their name.\n\nIt doesn't work for space without format.\n\n### tarantool.pipeline().\u003c...\u003e.exec()\n\nQueue some commands in memory and then send them simultaneously to the server in a single (or several, if request body is too big) network call(s). \nThis way the performance is significantly improved by more than 300% (depending on the number of pipelined commands - the bigger, the better)\n\nExample:\n\n```Javascript\ntarantool.pipeline()\n.insert('tags', ['tag_1', 1])\n.insert('tags', ['tag_2', 50])\n.sql('update \"tags\" set \"amount\" = 10 where \"tag_id\" = \\'tag_1\\'')\n.update('tags', 'tag_id', ['tag_2'], [['=', 'amount', 30]])\n.sql('select * from \"tags\"')\n.call('truncateTags')\n.exec()\n```\n\n### tarantool.ping() ⇒ \u003ccode\u003ePromise\u003c/code\u003e\n\nPromise resolve true.\n\n### ~~tarantool.destroy(interupt: Boolean) ⇒ \u003ccode\u003ePromise\u003c/code\u003e~~\n***Deprecated***\n### tarantool.disconnect()\nDisconnect from Tarantool.\n\nThis method closes the connection immediately,\nand may lose some pending replies that haven't written to client.\n\n## Debugging\n\nSet environment variable \"DEBUG\" to \"tarantool-driver:*\"\n\n## Contributions\n\nIt's ok you can do whatever you need. I add log options for some technical information it can be help for you. If i don't answer i just miss email :( it's a lot emails from github so please write me to newbiecraft@gmail.com directly if i don't answer in one day.\n\n## Changelog\n\n### 3.1.0\n\n- Added 3 new msgpack extensions: UUID, Datetime, Decimal.\n- Connection object now accepts all options of `net.createConnection()`, including Unix socket path.\n- New `nonWritableHostPolicy` and related options, which improves a high availability capabilities without any 3rd parties.\n- Ability to disable the offline queue.\n- Fixed [bug with int32](https://github.com/tarantool/node-tarantool-driver/issues/48) numbers when it was encoded as floating. Use method `packInteger()` to solve this.\n- `selectCb()` now also accepts `spaceId` and `indexId` as their String names, not only their IDs.\n- Some performance improvements by caching internal values.\n- TLS (SSL) support.\n- New `pipeline()`+`exec()` methods kindly borrowed from the [ioredis](https://github.com/redis/ioredis?tab=readme-ov-file#pipelining), which lets you to queue some commands in memory and then send them simultaneously to the server in a single (or several, if request body is too big) network call(s). Thanks to the Tarantool, which [made this possible](https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/format/#packet-structure).\nThis way the performance is significantly improved by 500-1600% - you can check it yourself by running `npm run benchmark-read` or `npm run benchmark-write`.\nNote that this feature doesn't replaces the Transaction model, which has some level of isolation.\n- Changed `const` declaration to `var` in order to support old Node.JS versions.\n\n### 3.0.7\n\nFix in header decoding to support latest Tarantool versions. Update to tests to support latest Tarantool versions.\n\n### 3.0.6\n\nRemove let for support old nodejs version\n\n### 3.0.5\n\nAdd support SQL\n\n### 3.0.4\n\nFix eval and call\n\n### 3.0.3\n\nIncrease request id limit to SMI Maximum\n\n### 3.0.2\n\nFix parser thx @tommiv\n\n### 3.0.0\n\nNew version with reconnect in alpha.\n\n### 1.0.0\n\nFix test for call changes and remove unuse upsert parameter (critical change API for upsert)\n\n### 0.4.1\n\nAdd clear schema cache on change schema id\n\n### 0.4.0\n\nChange msgpack5 to msgpack-lite(thx to @arusakov).\nAdd msgpack as option for connection.\nBump msgpack5 for work at new version.\n\n### 0.3.0\nAdd upsert operation.\nKey is now can be just a number.\n\n## ToDo\n\n1. Streams\n2. Events and subscriptions\n3. Graceful shutdown protocol\n4. Prepared SQL statements","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarantool%2Fnode-tarantool-driver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftarantool%2Fnode-tarantool-driver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftarantool%2Fnode-tarantool-driver/lists"}