UNPKG

aws-crt

Version:

NodeJS/browser bindings to the aws-c-* libraries

298 lines 13.1 kB
"use strict"; /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RequestResponseClient = exports.StreamingOperationBase = void 0; /** * * @packageDocumentation * @module mqtt_request_response * @mergeTarget * */ const error_1 = require("./error"); const mqtt_request_response_internal = __importStar(require("../common/mqtt_request_response_internal")); const native_resource_1 = require("./native_resource"); const event_1 = require("../common/event"); const binding_1 = __importDefault(require("./binding")); const io_1 = require("./io"); __exportStar(require("../common/mqtt_request_response"), exports); /** * An AWS MQTT service streaming operation. A streaming operation listens to messages on * a particular topic, deserializes them using a service model, and emits the modeled data as Javascript events. */ class StreamingOperationBase extends (0, native_resource_1.NativeResourceMixin)(event_1.BufferedEventEmitter) { static new(options, client) { if (!options) { throw new error_1.CrtError("invalid configuration for streaming operation"); } let operation = new StreamingOperationBase(client); operation._super(binding_1.default.mqtt_streaming_operation_new(operation, client.native_handle(), options, (streamingOperation, type, error_code) => { StreamingOperationBase._s_on_subscription_status_update(operation, type, error_code); }, (streamingOperation, publishEvent) => { StreamingOperationBase._s_on_incoming_publish(operation, publishEvent); })); client.registerUnclosedStreamingOperation(operation); return operation; } constructor(client) { super(); this.state = mqtt_request_response_internal.StreamingOperationState.None; this.client = client; } /** * Triggers the streaming operation to start listening to the configured stream of events. Has no effect on an * already-open operation. It is an error to attempt to re-open a closed streaming operation. */ open() { if (this.state == mqtt_request_response_internal.StreamingOperationState.None) { this.state = mqtt_request_response_internal.StreamingOperationState.Open; binding_1.default.mqtt_streaming_operation_open(this.native_handle()); } else if (this.state == mqtt_request_response_internal.StreamingOperationState.Closed) { throw new error_1.CrtError("MQTT streaming operation already closed"); } } /** * Stops a streaming operation from listening to the configured stream of events and releases all native * resources associated with the stream. */ close() { if (this.state != mqtt_request_response_internal.StreamingOperationState.Closed) { this.client.unregisterUnclosedStreamingOperation(this); this.state = mqtt_request_response_internal.StreamingOperationState.Closed; binding_1.default.mqtt_streaming_operation_close(this.native_handle()); } } on(event, listener) { super.on(event, listener); return this; } static _s_on_subscription_status_update(streamingOperation, type, error_code) { let statusEvent = { type: type }; if (error_code != 0) { statusEvent.error = new error_1.CrtError(error_code); } process.nextTick(() => { streamingOperation.emit(StreamingOperationBase.SUBSCRIPTION_STATUS, statusEvent); }); } static _s_on_incoming_publish(streamingOperation, publishEvent) { process.nextTick(() => { streamingOperation.emit(StreamingOperationBase.INCOMING_PUBLISH, publishEvent); }); } } exports.StreamingOperationBase = StreamingOperationBase; /** * Event emitted when the stream's subscription status changes. * * Listener type: {@link SubscriptionStatusListener} * * @event */ StreamingOperationBase.SUBSCRIPTION_STATUS = 'subscriptionStatus'; /** * Event emitted when a stream message is received * * Listener type: {@link IncomingPublishListener} * * @event */ StreamingOperationBase.INCOMING_PUBLISH = 'incomingPublish'; /** * Native implementation of an MQTT-based request-response client tuned for AWS MQTT services. * * Supports streaming operations (listen to a stream of modeled events from an MQTT topic) and request-response * operations (performs the subscribes, publish, and incoming publish correlation and error checking needed to * perform simple request-response operations over MQTT). */ class RequestResponseClient extends (0, native_resource_1.NativeResourceMixin)(event_1.BufferedEventEmitter) { constructor() { super(); this.state = mqtt_request_response_internal.RequestResponseClientState.Ready; this.unclosedOperations = new Set(); } /** * Creates a new MQTT service request-response client that uses an MQTT5 client as the protocol implementation. * * @param protocolClient protocol client to use for all operations * @param options configuration options for the desired request-response client */ static newFromMqtt5(protocolClient, options) { if (!protocolClient) { throw new error_1.CrtError("protocol client is null"); } let client = new RequestResponseClient(); client._super(binding_1.default.mqtt_request_response_client_new_from_5(client, protocolClient.native_handle(), options)); return client; } /** * Creates a new MQTT service request-response client that uses an MQTT311 client as the protocol implementation. * * @param protocolClient protocol client to use for all operations * @param options configuration options for the desired request-response client */ static newFromMqtt311(protocolClient, options) { if (!protocolClient) { throw new error_1.CrtError("protocol client is null"); } let client = new RequestResponseClient(); client._super(binding_1.default.mqtt_request_response_client_new_from_311(client, protocolClient.native_handle(), options)); return client; } /** * Triggers cleanup of native resources associated with the request-response client. Closing a client will fail * all incomplete requests and close all outstanding streaming operations. * * This must be called when finished with a client; otherwise, native resources will leak. */ close() { if (this.state != mqtt_request_response_internal.RequestResponseClientState.Closed) { this.state = mqtt_request_response_internal.RequestResponseClientState.Closed; this.closeStreamingOperations(); binding_1.default.mqtt_request_response_client_close(this.native_handle()); } } /** * Creates a new streaming operation from a set of configuration options. A streaming operation provides a * mechanism for listening to a specific event stream from an AWS MQTT-based service. * * @param streamOptions configuration options for the streaming operation */ createStream(streamOptions) { if (this.state == mqtt_request_response_internal.RequestResponseClientState.Closed) { throw new error_1.CrtError("MQTT request-response client has already been closed"); } return StreamingOperationBase.new(streamOptions, this); } /** * Submits a request to the request-response client. * * @param requestOptions description of the request to perform * * Returns a promise that resolves to a response to the request or an error describing how the request attempt * failed. * * A "successful" request-response execution flow is defined as "the service sent a response payload that * correlates with the request payload." Upon deserialization (which is the responsibility of the service model * client, one layer up), such a payload may actually indicate a failure. */ submitRequest(requestOptions) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { if (this.state == mqtt_request_response_internal.RequestResponseClientState.Closed) { reject(new error_1.CrtError("MQTT request-response client has already been closed")); return; } if (!requestOptions) { reject(new error_1.CrtError("null request options")); return; } function curriedPromiseCallback(errorCode, topic, response) { return RequestResponseClient._s_on_request_completion(resolve, reject, errorCode, topic, response); } try { binding_1.default.mqtt_request_response_client_submit_request(this.native_handle(), requestOptions, curriedPromiseCallback); } catch (e) { reject(e); } }); }); } /** * * Adds a streaming operation to the set of operations that will be closed automatically when the * client is closed. * * @internal * * @param operation streaming operation to add */ registerUnclosedStreamingOperation(operation) { if (this.unclosedOperations) { this.unclosedOperations.add(operation); } } /** * * Removes a streaming operation from the set of operations that will be closed automatically when the * client is closed. * * @internal * * @param operation streaming operation to remove */ unregisterUnclosedStreamingOperation(operation) { if (this.unclosedOperations) { this.unclosedOperations.delete(operation); } } closeStreamingOperations() { if (this.unclosedOperations) { // swap out the set so that calls to unregisterUnclosedStreamingOperation do not mess with things mid-iteration let unclosedOperations = this.unclosedOperations; this.unclosedOperations = undefined; for (const operation of unclosedOperations) { operation.close(); } } } static _s_on_request_completion(resolve, reject, errorCode, topic, payload) { if (errorCode == 0 && topic !== undefined && payload !== undefined) { let response = { payload: payload, topic: topic, }; resolve(response); } else { reject(new error_1.CrtError((0, io_1.error_code_to_string)(errorCode))); } } } exports.RequestResponseClient = RequestResponseClient; //# sourceMappingURL=mqtt_request_response.js.map