@joystick.js/db-canary 0.0.0-canary.2252 → 0.0.0-canary.2253

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- const i=(c,t,e={})=>({admin_action:c,database:t,...e}),n=(c,t,e,a={})=>({admin_action:c,database:t,collection:e,...a}),s=async(c,t)=>c.send_request("admin",t);class r{constructor(t,e){this.client=t,this.database_name=e}collection(t){const e=this.client.constructor.Collection;return new e(this.client,this.database_name,t)}async list_collections(){const t=i("list_collections",this.database_name);return s(this.client,t)}async get_stats(){const t=i("get_database_stats",this.database_name);return s(this.client,t)}async drop_database(){const t=i("drop_database",this.database_name);return s(this.client,t)}async create_collection(t,e={}){const a=n("create_collection",this.database_name,t,{options:e});return s(this.client,a)}async list_documents(t){const e=n("list_documents",this.database_name,t);return s(this.client,e)}async get_document(t,e){const a=n("get_document",this.database_name,t,{document_id:e});return s(this.client,a)}async query_documents(t,e){const a=n("query_documents",this.database_name,t,{filter:e});return s(this.client,a)}async insert_document(t,e){const a=n("insert_document",this.database_name,t,{document:e});return s(this.client,a)}async update_document(t,e,a){const d=n("update_document",this.database_name,t,{document_id:e,update:a});return s(this.client,d)}async delete_document(t,e){const a=n("delete_document",this.database_name,t,{document_id:e});return s(this.client,a)}}var _=r;export{_ as default};
1
+ const r=(c,t,e={})=>({admin_action:c,database:t,...e}),n=(c,t,e,s={})=>({admin_action:c,database:t,collection:e,...s}),a=async(c,t)=>c.send_request("admin",t);class _{constructor(t,e){this.client=t,this.database_name=e}collection(t){const e=this.client.constructor.Collection;return new e(this.client,this.database_name,t)}async list_collections(){const t=r("list_collections",this.database_name);return a(this.client,t)}async get_stats(){const t=r("get_database_stats",this.database_name);return a(this.client,t)}async drop_database(){const t=r("drop_database",this.database_name);return a(this.client,t)}async create_collection(t,e={}){const s=n("create_collection",this.database_name,t,{options:e});return a(this.client,s)}async list_documents(t){const e=n("list_documents",this.database_name,t);return a(this.client,e)}async get_document(t,e){const s=n("get_document",this.database_name,t,{document_id:e});return a(this.client,s)}async query_documents(t,e){const s=n("query_documents",this.database_name,t,{filter:e});return a(this.client,s)}async insert_document(t,e){const s=n("insert_document",this.database_name,t,{document:e});return a(this.client,s)}async update_document(t,e,s){const i=n("update_document",this.database_name,t,{document_id:e,update:s});return a(this.client,i)}async delete_document(t,e){const s=n("delete_document",this.database_name,t,{document_id:e});return a(this.client,s)}async stats(){return this.client.get_stats()}async ping(){return this.client.ping()}async backup_now(){return this.client.backup_now()}async list_backups(){return this.client.list_backups()}async restore_backup(t){return this.client.restore_backup(t)}async get_replication_status(){return this.client.get_replication_status()}async add_secondary(t){return this.client.add_secondary(t)}async remove_secondary(t){return this.client.remove_secondary(t)}async sync_secondaries(){return this.client.sync_secondaries()}async get_secondary_health(){return this.client.get_secondary_health()}async get_forwarder_status(){return this.client.get_forwarder_status()}async get_auto_index_stats(){return this.client.get_auto_index_stats()}async reload(){return this.client.reload()}}var o=_;export{o as default};
@@ -1 +1 @@
1
- import h from"net";import{EventEmitter as l}from"events";import{encode as m,decode as p}from"msgpackr";import f from"./database.js";const _=()=>({useFloat32:!1,int64AsType:"number",mapsAsObjects:!0}),g=s=>{const e=m(s,_()),t=Buffer.allocUnsafe(4);return t.writeUInt32BE(e.length,0),Buffer.concat([t,e])},q=(s,e)=>{const t=s.slice(0,e),n=s.slice(e);try{return{message:p(t,_()),buffer:n}}catch(i){throw new Error(`Invalid message format: ${i.message}`)}},y=s=>{if(s.length<4)return{expected_length:null,buffer:s};const e=s.readUInt32BE(0),t=s.slice(4);return{expected_length:e,buffer:t}},b=()=>{let s=Buffer.alloc(0),e=null;return{parse_messages:i=>{s=Buffer.concat([s,i]);const r=[];for(;s.length>0;){if(e===null){const a=y(s);if(e=a.expected_length,s=a.buffer,e===null)break}if(s.length<e)break;const c=q(s,e);r.push(c.message),s=c.buffer,e=null}return r},reset:()=>{s=Buffer.alloc(0),e=null}}},w=(s,e)=>Math.min(e*Math.pow(2,s-1),3e4),k=(s={})=>({host:s.host||"localhost",port:s.port||1983,password:s.password||null,timeout:s.timeout||5e3,reconnect:s.reconnect!==!1,max_reconnect_attempts:s.max_reconnect_attempts||10,reconnect_delay:s.reconnect_delay||1e3,auto_connect:s.auto_connect!==!1}),x=(s,e,t)=>setTimeout(()=>{s&&!s.destroyed&&(s.destroy(),e(new Error("Connection timeout")))},t),E=(s,e,t)=>setTimeout(()=>{const n=s.get(e);n&&(s.delete(e),n.reject(new Error("Request timeout")))},t),u=(s,e)=>{for(const[t,{reject:n,timeout:i}]of s)clearTimeout(i),n(new Error(e));s.clear()},T=s=>s.ok===1||s.ok===!0,v=s=>s.ok===0||s.ok===!1,B=s=>typeof s.error=="string"?s.error:JSON.stringify(s.error)||"Operation failed";class d extends l{constructor(e={}){super();const t=k(e);this.host=t.host,this.port=t.port,this.password=t.password,this.timeout=t.timeout,this.reconnect=t.reconnect,this.max_reconnect_attempts=t.max_reconnect_attempts,this.reconnect_delay=t.reconnect_delay,this.socket=null,this.message_parser=null,this.is_connected=!1,this.is_authenticated=!1,this.is_connecting=!1,this.reconnect_attempts=0,this.reconnect_timeout=null,this.pending_requests=new Map,this.request_id_counter=0,this.request_queue=[],t.auto_connect&&this.connect()}connect(){if(this.is_connecting||this.is_connected)return;this.is_connecting=!0,this.socket=new h.Socket,this.message_parser=b();const e=x(this.socket,this.handle_connection_error.bind(this),this.timeout);this.setup_socket_handlers(e),this.socket.connect(this.port,this.host,()=>{this.handle_successful_connection(e)})}setup_socket_handlers(e){this.socket.on("data",t=>{this.handle_incoming_data(t)}),this.socket.on("error",t=>{clearTimeout(e),this.handle_connection_error(t)}),this.socket.on("close",()=>{clearTimeout(e),this.handle_disconnect()})}handle_successful_connection(e){clearTimeout(e),this.is_connected=!0,this.is_connecting=!1,this.reconnect_attempts=0,this.emit("connect"),this.password?this.authenticate():this.handle_authentication_complete()}handle_authentication_complete(){this.is_authenticated=!0,this.emit("authenticated"),this.process_request_queue()}handle_incoming_data(e){try{const t=this.message_parser.parse_messages(e);for(const n of t)this.handle_message(n)}catch(t){this.emit("error",new Error(`Message parsing failed: ${t.message}`))}}async authenticate(){if(!this.password){this.emit("error",new Error('Password required for authentication. Provide password in client options: joystickdb.client({ password: "your_password" })')),this.disconnect();return}try{if((await this.send_request("authentication",{password:this.password})).ok===1)this.handle_authentication_complete();else throw new Error("Authentication failed")}catch(e){this.emit("error",new Error(`Authentication error: ${e.message}`)),this.disconnect()}}handle_message(e){this.pending_requests.size>0?this.handle_pending_request_response(e):this.emit("response",e)}handle_pending_request_response(e){const[t,{resolve:n,reject:i,timeout:r}]=this.pending_requests.entries().next().value;if(clearTimeout(r),this.pending_requests.delete(t),T(e))n(e);else if(v(e)){const c=B(e);i(new Error(c))}else n(e)}handle_connection_error(e){this.reset_connection_state(),u(this.pending_requests,"Connection lost"),this.emit("error",e),this.should_attempt_reconnect()?this.schedule_reconnect():this.emit("disconnect")}handle_disconnect(){this.reset_connection_state(),u(this.pending_requests,"Connection closed"),this.should_attempt_reconnect()?this.schedule_reconnect():this.emit("disconnect")}reset_connection_state(){this.is_connecting=!1,this.is_connected=!1,this.is_authenticated=!1,this.socket&&(this.socket.removeAllListeners(),this.socket.destroy(),this.socket=null),this.message_parser&&this.message_parser.reset()}should_attempt_reconnect(){return this.reconnect&&this.reconnect_attempts<this.max_reconnect_attempts}schedule_reconnect(){this.reconnect_attempts++;const e=w(this.reconnect_attempts,this.reconnect_delay);this.emit("reconnecting",{attempt:this.reconnect_attempts,delay:e}),this.reconnect_timeout=setTimeout(()=>{this.connect()},e)}send_request(e,t={},n=!0){return new Promise((i,r)=>{const c=++this.request_id_counter,o={message:{op:e,data:t},resolve:i,reject:r,request_id:c};if(this.should_queue_request(e,n)){this.request_queue.push(o);return}this.send_request_now(o)})}should_queue_request(e,t){const i=!["authentication","setup","ping"].includes(e);return(!this.is_connected||i&&!this.is_authenticated)&&t}send_request_now(e){const{message:t,resolve:n,reject:i,request_id:r}=e,c=E(this.pending_requests,r,this.timeout);this.pending_requests.set(r,{resolve:n,reject:i,timeout:c});try{const a=g(t);this.socket.write(a)}catch(a){clearTimeout(c),this.pending_requests.delete(r),i(a)}}process_request_queue(){for(;this.request_queue.length>0&&this.is_connected&&this.is_authenticated;){const e=this.request_queue.shift();this.send_request_now(e)}}disconnect(){this.reconnect=!1,this.reconnect_timeout&&(clearTimeout(this.reconnect_timeout),this.reconnect_timeout=null),this.socket&&this.socket.end()}async backup_now(){return this.send_request("admin",{admin_action:"backup_now"})}async list_backups(){return this.send_request("admin",{admin_action:"list_backups"})}async restore_backup(e){return this.send_request("admin",{admin_action:"restore_backup",backup_name:e})}async get_replication_status(){return this.send_request("admin",{admin_action:"get_replication_status"})}async add_secondary(e){return this.send_request("admin",{admin_action:"add_secondary",...e})}async remove_secondary(e){return this.send_request("admin",{admin_action:"remove_secondary",secondary_id:e})}async sync_secondaries(){return this.send_request("admin",{admin_action:"sync_secondaries"})}async get_secondary_health(){return this.send_request("admin",{admin_action:"get_secondary_health"})}async get_forwarder_status(){return this.send_request("admin",{admin_action:"get_forwarder_status"})}async ping(){return this.send_request("ping",{},!1)}async reload(){return this.send_request("reload")}async get_auto_index_stats(){return this.send_request("admin",{admin_action:"get_auto_index_stats"})}async setup(){const e=await this.send_request("setup",{},!1);return e.data&&e.data.instructions&&console.log(e.data.instructions),e}async delete_many(e,t={},n={}){return this.send_request("delete_many",{collection:e,filter:t,options:n})}db(e){return new f(this,e)}async list_databases(){return this.send_request("admin",{admin_action:"list_databases"})}}class j{constructor(e,t,n){this.client=e,this.database_name=t,this.collection_name=n}async insert_one(e,t={}){return this.client.send_request("insert_one",{database:this.database_name,collection:this.collection_name,document:e,options:t})}async find_one(e={},t={}){return(await this.client.send_request("find_one",{database:this.database_name,collection:this.collection_name,filter:e,options:t})).document}async find(e={},t={}){return(await this.client.send_request("find",{database:this.database_name,collection:this.collection_name,filter:e,options:t})).documents||[]}async update_one(e,t,n={}){return this.client.send_request("update_one",{database:this.database_name,collection:this.collection_name,filter:e,update:t,options:n})}async delete_one(e,t={}){return this.client.send_request("delete_one",{database:this.database_name,collection:this.collection_name,filter:e,options:t})}async delete_many(e={},t={}){return this.client.send_request("delete_many",{database:this.database_name,collection:this.collection_name,filter:e,options:t})}async bulk_write(e,t={}){return this.client.send_request("bulk_write",{database:this.database_name,collection:this.collection_name,operations:e,options:t})}async create_index(e,t={}){return this.client.send_request("create_index",{database:this.database_name,collection:this.collection_name,field:e,options:t})}async upsert_index(e,t={}){return this.client.send_request("create_index",{database:this.database_name,collection:this.collection_name,field:e,options:{...t,upsert:!0}})}async drop_index(e){return this.client.send_request("drop_index",{database:this.database_name,collection:this.collection_name,field:e})}async get_indexes(){return this.client.send_request("get_indexes",{database:this.database_name,collection:this.collection_name})}}d.Collection=j;const C={client:s=>new d(s)};var P=C;export{P as default};
1
+ import h from"net";import{EventEmitter as l}from"events";import{encode as m,decode as p}from"msgpackr";import f from"./database.js";const _=()=>({useFloat32:!1,int64AsType:"number",mapsAsObjects:!0}),g=s=>{const e=m(s,_()),t=Buffer.allocUnsafe(4);return t.writeUInt32BE(e.length,0),Buffer.concat([t,e])},q=(s,e)=>{const t=s.slice(0,e),n=s.slice(e);try{return{message:p(t,_()),buffer:n}}catch(i){throw new Error(`Invalid message format: ${i.message}`)}},y=s=>{if(s.length<4)return{expected_length:null,buffer:s};const e=s.readUInt32BE(0),t=s.slice(4);return{expected_length:e,buffer:t}},b=()=>{let s=Buffer.alloc(0),e=null;return{parse_messages:i=>{s=Buffer.concat([s,i]);const r=[];for(;s.length>0;){if(e===null){const a=y(s);if(e=a.expected_length,s=a.buffer,e===null)break}if(s.length<e)break;const c=q(s,e);r.push(c.message),s=c.buffer,e=null}return r},reset:()=>{s=Buffer.alloc(0),e=null}}},w=(s,e)=>Math.min(e*Math.pow(2,s-1),3e4),k=(s={})=>({host:s.host||"localhost",port:s.port||1983,password:s.password||null,timeout:s.timeout||5e3,reconnect:s.reconnect!==!1,max_reconnect_attempts:s.max_reconnect_attempts||10,reconnect_delay:s.reconnect_delay||1e3,auto_connect:s.auto_connect!==!1}),x=(s,e,t)=>setTimeout(()=>{s&&!s.destroyed&&(s.destroy(),e(new Error("Connection timeout")))},t),E=(s,e,t)=>setTimeout(()=>{const n=s.get(e);n&&(s.delete(e),n.reject(new Error("Request timeout")))},t),u=(s,e)=>{for(const[t,{reject:n,timeout:i}]of s)clearTimeout(i),n(new Error(e));s.clear()},T=s=>s.ok===1||s.ok===!0,v=s=>s.ok===0||s.ok===!1,B=s=>typeof s.error=="string"?s.error:JSON.stringify(s.error)||"Operation failed";class d extends l{constructor(e={}){super();const t=k(e);this.host=t.host,this.port=t.port,this.password=t.password,this.timeout=t.timeout,this.reconnect=t.reconnect,this.max_reconnect_attempts=t.max_reconnect_attempts,this.reconnect_delay=t.reconnect_delay,this.socket=null,this.message_parser=null,this.is_connected=!1,this.is_authenticated=!1,this.is_connecting=!1,this.reconnect_attempts=0,this.reconnect_timeout=null,this.pending_requests=new Map,this.request_id_counter=0,this.request_queue=[],t.auto_connect&&this.connect()}connect(){if(this.is_connecting||this.is_connected)return;this.is_connecting=!0,this.socket=new h.Socket,this.message_parser=b();const e=x(this.socket,this.handle_connection_error.bind(this),this.timeout);this.setup_socket_handlers(e),this.socket.connect(this.port,this.host,()=>{this.handle_successful_connection(e)})}setup_socket_handlers(e){this.socket.on("data",t=>{this.handle_incoming_data(t)}),this.socket.on("error",t=>{clearTimeout(e),this.handle_connection_error(t)}),this.socket.on("close",()=>{clearTimeout(e),this.handle_disconnect()})}handle_successful_connection(e){clearTimeout(e),this.is_connected=!0,this.is_connecting=!1,this.reconnect_attempts=0,this.emit("connect"),this.password?this.authenticate():this.handle_authentication_complete()}handle_authentication_complete(){this.is_authenticated=!0,this.emit("authenticated"),this.process_request_queue()}handle_incoming_data(e){try{const t=this.message_parser.parse_messages(e);for(const n of t)this.handle_message(n)}catch(t){this.emit("error",new Error(`Message parsing failed: ${t.message}`))}}async authenticate(){if(!this.password){this.emit("error",new Error('Password required for authentication. Provide password in client options: joystickdb.client({ password: "your_password" })')),this.disconnect();return}try{if((await this.send_request("authentication",{password:this.password})).ok===1)this.handle_authentication_complete();else throw new Error("Authentication failed")}catch(e){this.emit("error",new Error(`Authentication error: ${e.message}`)),this.disconnect()}}handle_message(e){this.pending_requests.size>0?this.handle_pending_request_response(e):this.emit("response",e)}handle_pending_request_response(e){const[t,{resolve:n,reject:i,timeout:r}]=this.pending_requests.entries().next().value;if(clearTimeout(r),this.pending_requests.delete(t),T(e))n(e);else if(v(e)){const c=B(e);i(new Error(c))}else n(e)}handle_connection_error(e){this.reset_connection_state(),u(this.pending_requests,"Connection lost"),this.emit("error",e),this.should_attempt_reconnect()?this.schedule_reconnect():this.emit("disconnect")}handle_disconnect(){this.reset_connection_state(),u(this.pending_requests,"Connection closed"),this.should_attempt_reconnect()?this.schedule_reconnect():this.emit("disconnect")}reset_connection_state(){this.is_connecting=!1,this.is_connected=!1,this.is_authenticated=!1,this.socket&&(this.socket.removeAllListeners(),this.socket.destroy(),this.socket=null),this.message_parser&&this.message_parser.reset()}should_attempt_reconnect(){return this.reconnect&&this.reconnect_attempts<this.max_reconnect_attempts}schedule_reconnect(){this.reconnect_attempts++;const e=w(this.reconnect_attempts,this.reconnect_delay);this.emit("reconnecting",{attempt:this.reconnect_attempts,delay:e}),this.reconnect_timeout=setTimeout(()=>{this.connect()},e)}send_request(e,t={},n=!0){return new Promise((i,r)=>{const c=++this.request_id_counter,o={message:{op:e,data:t},resolve:i,reject:r,request_id:c};if(this.should_queue_request(e,n)){this.request_queue.push(o);return}this.send_request_now(o)})}should_queue_request(e,t){const i=!["authentication","setup","ping"].includes(e);return(!this.is_connected||i&&!this.is_authenticated)&&t}send_request_now(e){const{message:t,resolve:n,reject:i,request_id:r}=e,c=E(this.pending_requests,r,this.timeout);this.pending_requests.set(r,{resolve:n,reject:i,timeout:c});try{const a=g(t);this.socket.write(a)}catch(a){clearTimeout(c),this.pending_requests.delete(r),i(a)}}process_request_queue(){for(;this.request_queue.length>0&&this.is_connected&&this.is_authenticated;){const e=this.request_queue.shift();this.send_request_now(e)}}disconnect(){this.reconnect=!1,this.reconnect_timeout&&(clearTimeout(this.reconnect_timeout),this.reconnect_timeout=null),this.socket&&this.socket.end()}async backup_now(){return this.send_request("admin",{admin_action:"backup_now"})}async list_backups(){return this.send_request("admin",{admin_action:"list_backups"})}async restore_backup(e){return this.send_request("admin",{admin_action:"restore_backup",backup_name:e})}async get_replication_status(){return this.send_request("admin",{admin_action:"get_replication_status"})}async add_secondary(e){return this.send_request("admin",{admin_action:"add_secondary",...e})}async remove_secondary(e){return this.send_request("admin",{admin_action:"remove_secondary",secondary_id:e})}async sync_secondaries(){return this.send_request("admin",{admin_action:"sync_secondaries"})}async get_secondary_health(){return this.send_request("admin",{admin_action:"get_secondary_health"})}async get_forwarder_status(){return this.send_request("admin",{admin_action:"get_forwarder_status"})}async ping(){return this.send_request("ping",{},!1)}async reload(){return this.send_request("reload")}async get_auto_index_stats(){return this.send_request("admin",{admin_action:"get_auto_index_stats"})}async setup(){const e=await this.send_request("setup",{},!1);return e.data&&e.data.instructions&&console.log(e.data.instructions),e}async delete_many(e,t={},n={}){return this.send_request("delete_many",{collection:e,filter:t,options:n})}db(e){return new f(this,e)}async list_databases(){return this.send_request("admin",{admin_action:"list_databases"})}async get_stats(){return this.send_request("admin",{admin_action:"stats"})}}class j{constructor(e,t,n){this.client=e,this.database_name=t,this.collection_name=n}async insert_one(e,t={}){return this.client.send_request("insert_one",{database:this.database_name,collection:this.collection_name,document:e,options:t})}async find_one(e={},t={}){return(await this.client.send_request("find_one",{database:this.database_name,collection:this.collection_name,filter:e,options:t})).document}async find(e={},t={}){return{documents:(await this.client.send_request("find",{database:this.database_name,collection:this.collection_name,filter:e,options:t})).documents||[]}}async update_one(e,t,n={}){return this.client.send_request("update_one",{database:this.database_name,collection:this.collection_name,filter:e,update:t,options:n})}async delete_one(e,t={}){return this.client.send_request("delete_one",{database:this.database_name,collection:this.collection_name,filter:e,options:t})}async delete_many(e={},t={}){return this.client.send_request("delete_many",{database:this.database_name,collection:this.collection_name,filter:e,options:t})}async bulk_write(e,t={}){return this.client.send_request("bulk_write",{database:this.database_name,collection:this.collection_name,operations:e,options:t})}async create_index(e,t={}){return this.client.send_request("create_index",{database:this.database_name,collection:this.collection_name,field:e,options:t})}async upsert_index(e,t={}){return this.client.send_request("create_index",{database:this.database_name,collection:this.collection_name,field:e,options:{...t,upsert:!0}})}async drop_index(e){return this.client.send_request("drop_index",{database:this.database_name,collection:this.collection_name,field:e})}async get_indexes(){return this.client.send_request("get_indexes",{database:this.database_name,collection:this.collection_name})}}d.Collection=j;const C={client:s=>new d(s)};var P=C;export{P as default};
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@joystick.js/db-canary",
3
3
  "type": "module",
4
- "version": "0.0.0-canary.2252",
5
- "canary_version": "0.0.0-canary.2251",
4
+ "version": "0.0.0-canary.2253",
5
+ "canary_version": "0.0.0-canary.2252",
6
6
  "description": "JoystickDB - A minimalist database server for the Joystick framework",
7
7
  "main": "./dist/server/index.js",
8
8
  "scripts": {
@@ -134,6 +134,59 @@ class Database {
134
134
  );
135
135
  return send_admin_request(this.client, request_data);
136
136
  }
137
+
138
+ // NOTE: Admin method delegations to client
139
+ async stats() {
140
+ return this.client.get_stats();
141
+ }
142
+
143
+ async ping() {
144
+ return this.client.ping();
145
+ }
146
+
147
+ async backup_now() {
148
+ return this.client.backup_now();
149
+ }
150
+
151
+ async list_backups() {
152
+ return this.client.list_backups();
153
+ }
154
+
155
+ async restore_backup(backup_name) {
156
+ return this.client.restore_backup(backup_name);
157
+ }
158
+
159
+ async get_replication_status() {
160
+ return this.client.get_replication_status();
161
+ }
162
+
163
+ async add_secondary(secondary) {
164
+ return this.client.add_secondary(secondary);
165
+ }
166
+
167
+ async remove_secondary(secondary_id) {
168
+ return this.client.remove_secondary(secondary_id);
169
+ }
170
+
171
+ async sync_secondaries() {
172
+ return this.client.sync_secondaries();
173
+ }
174
+
175
+ async get_secondary_health() {
176
+ return this.client.get_secondary_health();
177
+ }
178
+
179
+ async get_forwarder_status() {
180
+ return this.client.get_forwarder_status();
181
+ }
182
+
183
+ async get_auto_index_stats() {
184
+ return this.client.get_auto_index_stats();
185
+ }
186
+
187
+ async reload() {
188
+ return this.client.reload();
189
+ }
137
190
  }
138
191
 
139
192
  export default Database;
@@ -602,6 +602,11 @@ class JoystickDBClient extends EventEmitter {
602
602
  async list_databases() {
603
603
  return this.send_request('admin', { admin_action: 'list_databases' });
604
604
  }
605
+
606
+ // NOTE: Statistics Operations.
607
+ async get_stats() {
608
+ return this.send_request('admin', { admin_action: 'stats' });
609
+ }
605
610
  }
606
611
 
607
612
  /**
@@ -641,7 +646,7 @@ class Collection {
641
646
  filter,
642
647
  options
643
648
  });
644
- return result.documents || [];
649
+ return { documents: result.documents || [] };
645
650
  }
646
651
 
647
652
  async update_one(filter, update, options = {}) {