blob: 47acaa2dc21442fb6cab132b2658c6fe63fd82d0 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* 'License'); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import Connection, { ConnectionOptions } from './connection.js';
import {RequestMessage} from "./request-message.js";
export type RequestOptions = {
bindings?: any;
language?: string;
accept?: string;
evaluationTimeout?: number;
batchSize?: number;
userAgent?: string;
materializeProperties?: string;
bulkResults?: boolean;
params?: Record<string, any>;
};
export type ClientOptions = ConnectionOptions & RequestOptions & { processor?: string };
/**
* A {@link Client} contains methods to send messages to a Gremlin Server.
*/
export default class Client {
private readonly _connection: Connection;
/**
* Creates a new instance of {@link Client}.
* @param {String} url The resource uri.
* @param {ClientOptions} [options] The connection options.
*/
constructor(
url: string,
private readonly options: ClientOptions = {},
) {
this._connection = new Connection(url, options);
}
/**
* Opens the underlying connection to the Gremlin Server, if it's not already opened.
* @returns {Promise}
*/
open(): Promise<void> {
return this._connection.open();
}
/**
* Returns true if the underlying connection is open
* @returns {Boolean}
*/
get isOpen(): boolean {
return this._connection.isOpen;
}
/**
* Send a request to the Gremlin Server and buffer the entire response.
* @param {string} message The script to send
* @param {Object|null} [bindings] The script bindings, if any.
* @param {RequestOptions} [requestOptions] Configuration specific to the current request.
* @returns {Promise<ResultSet>}
*/
submit(message: string, bindings: any | null, requestOptions?: RequestOptions): Promise<any> {
return this._connection.submit(this.#buildRequest(message, bindings, requestOptions));
}
/**
* Send a request to the Gremlin Server and stream results incrementally.
* Returns an AsyncGenerator that yields individual result items as they are
* deserialized from the response. For bulked responses, yields Traverser objects.
* @param {string} message The script to send
* @param {Object|null} [bindings] The script bindings, if any.
* @param {RequestOptions} [requestOptions] Configuration specific to the current request.
* @returns {AsyncGenerator<any>}
*/
async *stream(message: string, bindings: any | null, requestOptions?: RequestOptions): AsyncGenerator<any> {
return yield* this._connection.stream(this.#buildRequest(message, bindings, requestOptions));
}
#buildRequest(message: string, bindings: any | null, requestOptions?: RequestOptions): RequestMessage {
const requestBuilder = RequestMessage.build(message)
.addG(this.options.traversalSource || 'g');
if (requestOptions?.language) {
requestBuilder.addLanguage(requestOptions.language);
}
if (requestOptions?.bindings) {
if (typeof requestOptions.bindings === 'string') {
requestBuilder.addBindingsString(requestOptions.bindings);
} else {
requestBuilder.addBindings(requestOptions.bindings);
}
}
if (bindings) {
if (typeof bindings === 'string') {
requestBuilder.addBindingsString(bindings);
} else {
requestBuilder.addBindings(bindings);
}
}
if (requestOptions?.materializeProperties) {
requestBuilder.addMaterializeProperties(requestOptions.materializeProperties);
}
if (requestOptions?.evaluationTimeout) {
requestBuilder.addTimeoutMillis(requestOptions.evaluationTimeout);
}
if (requestOptions?.bulkResults) {
requestBuilder.addBulkResults(requestOptions.bulkResults);
}
return requestBuilder.create();
}
/**
* Closes the underlying connection
* @returns {Promise}
*/
close(): Promise<void> {
return this._connection.close();
}
/**
* Adds an event listener to the connection
* @param {String} event The event name that you want to listen to.
* @param {Function} handler The callback to be called when the event occurs.
*/
addListener(event: string, handler: (...args: any[]) => unknown) {
this._connection.on(event, handler);
}
/**
* Removes a previously added event listener to the connection
* @param {String} event The event name that you want to listen to.
* @param {Function} handler The event handler to be removed.
*/
removeListener(event: string, handler: (...args: any[]) => unknown) {
this._connection.removeListener(event, handler);
}
}