UNPKG

nats

Version:

Node.js client for NATS, a lightweight, high-performance cloud native messaging system

283 lines 11.5 kB
"use strict"; /* * Copyright 2021-2022 The NATS Authors * Licensed 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. */ 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StoredMsgImpl = exports.StreamAPIImpl = exports.convertStreamSourceDomain = void 0; const types_1 = require("./types"); const jsbaseclient_api_1 = require("./jsbaseclient_api"); const jslister_1 = require("./jslister"); const jsutil_1 = require("./jsutil"); const headers_1 = require("./headers"); const kv_1 = require("./kv"); const objectstore_1 = require("./objectstore"); function convertStreamSourceDomain(s) { if (s === undefined) { return undefined; } const { domain } = s; if (domain === undefined) { return s; } const copy = Object.assign({}, s); delete copy.domain; if (domain === "") { return copy; } if (copy.external) { throw new Error("domain and external are both set"); } copy.external = { api: `$JS.${domain}.API` }; return copy; } exports.convertStreamSourceDomain = convertStreamSourceDomain; class StreamAPIImpl extends jsbaseclient_api_1.BaseApiClient { constructor(nc, opts) { super(nc, opts); } add(cfg = {}) { var _a; return __awaiter(this, void 0, void 0, function* () { (0, jsutil_1.validateStreamName)(cfg.name); cfg.mirror = convertStreamSourceDomain(cfg.mirror); //@ts-ignore: the sources are either set or not - so no item should be undefined in the list cfg.sources = (_a = cfg.sources) === null || _a === void 0 ? void 0 : _a.map(convertStreamSourceDomain); const r = yield this._request(`${this.prefix}.STREAM.CREATE.${cfg.name}`, cfg); const si = r; this._fixInfo(si); return si; }); } delete(stream) { return __awaiter(this, void 0, void 0, function* () { (0, jsutil_1.validateStreamName)(stream); const r = yield this._request(`${this.prefix}.STREAM.DELETE.${stream}`); const cr = r; return cr.success; }); } update(name, cfg = {}) { var _a; return __awaiter(this, void 0, void 0, function* () { if (typeof name === "object") { const sc = name; name = sc.name; cfg = sc; console.trace(`\u001B[33m >> streams.update(config: StreamConfig) api changed to streams.update(name: string, config: StreamUpdateConfig) - this shim will be removed - update your code. \u001B[0m`); } (0, jsutil_1.validateStreamName)(name); const old = yield this.info(name); const update = Object.assign(old.config, cfg); update.mirror = convertStreamSourceDomain(update.mirror); //@ts-ignore: the sources are either set or not - so no item should be undefined in the list update.sources = (_a = update.sources) === null || _a === void 0 ? void 0 : _a.map(convertStreamSourceDomain); const r = yield this._request(`${this.prefix}.STREAM.UPDATE.${name}`, update); const si = r; this._fixInfo(si); return si; }); } info(name, data) { return __awaiter(this, void 0, void 0, function* () { (0, jsutil_1.validateStreamName)(name); const subj = `${this.prefix}.STREAM.INFO.${name}`; const r = yield this._request(subj, data); let si = r; let { total, limit } = si; // check how many subjects we got in the first request let have = si.state.subjects ? Object.getOwnPropertyNames(si.state.subjects).length : 1; // if the response is paged, we have a large list of subjects // handle the paging and return a StreamInfo with all of it if (total && total > have) { const infos = [si]; const paged = data || {}; let i = 0; // total could change, so it is possible to have collected // more that the total while (total > have) { i++; paged.offset = limit * i; const r = yield this._request(subj, paged); // update it in case it changed total = r.total; infos.push(r); const count = Object.getOwnPropertyNames(r.state.subjects).length; have += count; // if request returns less than limit it is done if (count < limit) { // done break; } } // collect all the subjects let subjects = {}; for (let i = 0; i < infos.length; i++) { si = infos[i]; if (si.state.subjects) { subjects = Object.assign(subjects, si.state.subjects); } } // don't give the impression we paged si.offset = 0; si.total = 0; si.limit = 0; si.state.subjects = subjects; } this._fixInfo(si); return si; }); } list(subject = "") { const payload = (subject === null || subject === void 0 ? void 0 : subject.length) ? { subject } : {}; const listerFilter = (v) => { const slr = v; slr.streams.forEach((si) => { this._fixInfo(si); }); return slr.streams; }; const subj = `${this.prefix}.STREAM.LIST`; return new jslister_1.ListerImpl(subj, listerFilter, this, payload); } // FIXME: init of sealed, deny_delete, deny_purge shouldn't be necessary // https://github.com/nats-io/nats-server/issues/2633 _fixInfo(si) { si.config.sealed = si.config.sealed || false; si.config.deny_delete = si.config.deny_delete || false; si.config.deny_purge = si.config.deny_purge || false; si.config.allow_rollup_hdrs = si.config.allow_rollup_hdrs || false; } purge(name, opts) { return __awaiter(this, void 0, void 0, function* () { if (opts) { const { keep, seq } = opts; if (typeof keep === "number" && typeof seq === "number") { throw new Error("can specify one of keep or seq"); } } (0, jsutil_1.validateStreamName)(name); const v = yield this._request(`${this.prefix}.STREAM.PURGE.${name}`, opts); return v; }); } deleteMessage(stream, seq, erase = true) { return __awaiter(this, void 0, void 0, function* () { (0, jsutil_1.validateStreamName)(stream); const dr = { seq }; if (!erase) { dr.no_erase = true; } const r = yield this._request(`${this.prefix}.STREAM.MSG.DELETE.${stream}`, dr); const cr = r; return cr.success; }); } getMessage(stream, query) { return __awaiter(this, void 0, void 0, function* () { (0, jsutil_1.validateStreamName)(stream); const r = yield this._request(`${this.prefix}.STREAM.MSG.GET.${stream}`, query); const sm = r; return new StoredMsgImpl(sm); }); } find(subject) { return this.findStream(subject); } listKvs() { const filter = (v) => { var _a, _b; const slr = v; const kvStreams = slr.streams.filter((v) => { return v.config.name.startsWith(kv_1.kvPrefix); }); kvStreams.forEach((si) => { this._fixInfo(si); }); let cluster = ""; if (kvStreams.length) { cluster = (_b = (_a = this.nc.info) === null || _a === void 0 ? void 0 : _a.cluster) !== null && _b !== void 0 ? _b : ""; } const status = kvStreams.map((si) => { return new kv_1.KvStatusImpl(si, cluster); }); return status; }; const subj = `${this.prefix}.STREAM.LIST`; return new jslister_1.ListerImpl(subj, filter, this); } listObjectStores() { const filter = (v) => { const slr = v; const objStreams = slr.streams.filter((v) => { return v.config.name.startsWith(objectstore_1.osPrefix); }); objStreams.forEach((si) => { this._fixInfo(si); }); const status = objStreams.map((si) => { return new objectstore_1.ObjectStoreStatusImpl(si); }); return status; }; const subj = `${this.prefix}.STREAM.LIST`; return new jslister_1.ListerImpl(subj, filter, this); } names(subject = "") { const payload = (subject === null || subject === void 0 ? void 0 : subject.length) ? { subject } : {}; const listerFilter = (v) => { const slr = v; return slr.streams; }; const subj = `${this.prefix}.STREAM.NAMES`; return new jslister_1.ListerImpl(subj, listerFilter, this, payload); } } exports.StreamAPIImpl = StreamAPIImpl; class StoredMsgImpl { constructor(smr) { this.subject = smr.message.subject; this.seq = smr.message.seq; this.time = new Date(Date.parse(smr.message.time)); this.data = smr.message.data ? this._parse(smr.message.data) : types_1.Empty; if (smr.message.hdrs) { const hd = this._parse(smr.message.hdrs); this.header = headers_1.MsgHdrsImpl.decode(hd); } else { this.header = (0, headers_1.headers)(); } } _parse(s) { const bs = atob(s); const len = bs.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = bs.charCodeAt(i); } return bytes; } } exports.StoredMsgImpl = StoredMsgImpl; //# sourceMappingURL=jsmstream_api.js.map