@sera4/essentia 1.1.65 → 1.1.66

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.
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@sera4/essentia",
3
- "version": "1.1.65",
3
+ "version": "1.1.66",
4
4
  "description": "A library of utilities for Teleporte Web Services",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "scripts": {
8
- "test": "NODE_ENV=test ./node_modules/.bin/mocha --forbid-only --reporter mocha-junit-reporter --reporter-options mochaFile=./test-results/result.xml --exit",
9
- "test:dev": "NODE_ENV=test ./node_modules/.bin/mocha --forbid-only",
10
- "test:only": "NODE_ENV=test ./node_modules/.bin/mocha --watch",
11
- "test:pretty": "NODE_ENV=test ./node_modules/.bin/mocha --reporter mocha-simple-html-reporter --reporter-options output=./test-results/result.html --exit",
12
- "last-commit": "node last-commit.js"
8
+ "test": "NODE_ENV=test NODE_OPTIONS='--no-experimental-require-module' ./node_modules/.bin/mocha --forbid-only --reporter mocha-junit-reporter --reporter-options mochaFile=./test-results/result.xml --exit",
9
+ "test:dev": "NODE_ENV=test NODE_OPTIONS='--no-experimental-require-module' ./node_modules/.bin/mocha --forbid-only",
10
+ "test:only": "NODE_ENV=test NODE_OPTIONS='--no-experimental-require-module' ./node_modules/.bin/mocha --watch",
11
+ "test:pretty": "NODE_ENV=test NODE_OPTIONS='--no-experimental-require-module' ./node_modules/.bin/mocha --reporter mocha-simple-html-reporter --reporter-options output=./test-results/result.html --exit",
12
+ "build": "echo 'no build step'",
13
+ "last-commit": "node last-commit.js",
14
+ "publish:package": "scripts/publish.sh"
13
15
  },
14
16
  "author": "Dev DM <dev@sera4.com>",
15
17
  "repository": {
@@ -18,7 +20,7 @@
18
20
  },
19
21
  "license": "UNLICENSED",
20
22
  "devDependencies": {
21
- "chai": "^4.3.4",
23
+ "chai": "^5.0.0",
22
24
  "express": "^4.17.1",
23
25
  "mocha": "^11.1.0",
24
26
  "mocha-junit-reporter": "^2.2.1",
@@ -27,7 +29,7 @@
27
29
  "sinon": "^5.1.1"
28
30
  },
29
31
  "dependencies": {
30
- "amqplib": "^0.8.0",
32
+ "amqplib": "^0.10.9",
31
33
  "argparse": "^2.0.1",
32
34
  "async": "^3.2.2",
33
35
  "axios": "^1.7.7",
package/package.tar.gz CHANGED
Binary file
@@ -1,4 +1,5 @@
1
- import * as jsdiff from 'diff';
1
+ import { createRequire } from 'module';
2
+ const jsdiff = createRequire(import.meta.url)('diff');
2
3
  import _ from 'lodash';
3
4
  import helpers from './helpers.js';
4
5
  import paginator from "../paginator/sql-pagination.js";
package/queue/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- import amqp from "amqplib/callback_api.js";
2
+ import amqp from "amqplib";
3
3
  import logger from "./queue-logger.js";
4
4
  import urlParse from "url-parse";
5
5
  import { Publisher } from "./publisher.js";
@@ -11,6 +11,7 @@ import { Subscriber } from "./subscriber.js";
11
11
  class S4Queue {
12
12
  constructor() {
13
13
  this.connection = null;
14
+ this.connectionTestChannel = null;
14
15
  this.retry = 10;
15
16
  this.pubs = {};
16
17
  this.subs = {};
@@ -30,15 +31,20 @@ class S4Queue {
30
31
  async testConnection() {
31
32
  if (!this.isConnected()) {
32
33
  this.connectionTestChannel = null;
33
- throw("queue service not connected")
34
+ throw new Error("queue service not connected");
34
35
  }
35
36
 
36
- this.connectionTestChannel = this.connectionTestChannel || await this.connection.createChannel();
37
37
  if (!this.connectionTestChannel) {
38
- throw("queue service failed to obtain a channel")
38
+ const ch = await this.connection.createChannel();
39
+ if (!ch) {
40
+ throw new Error("queue service failed to obtain a channel");
41
+ }
42
+ ch.on("error", () => { this.connectionTestChannel = null; });
43
+ ch.on("close", () => { this.connectionTestChannel = null; });
44
+ this.connectionTestChannel = ch;
39
45
  }
40
46
 
41
- await this.connectionTestChannel.assertExchange("--health-check--", "topic", {durable: false});
47
+ await this.connectionTestChannel.assertExchange("--health-check--", "topic", { durable: false });
42
48
  }
43
49
 
44
50
  /**
@@ -56,60 +62,51 @@ class S4Queue {
56
62
  const retry = parseInt(options.retryInterval);
57
63
  this.retry = retry || 10;
58
64
 
59
- logger.debug("Attempting connection...");
65
+ // We may run into issues with SNI TLS if
66
+ // we host with 3rd parties using our own certs.
67
+ // To avoid any issues, let's parse the url
68
+ // and provide the server name in the socket options
69
+ const urlParts = urlParse(options.connectionUrl);
70
+ const socketOptions = { servername: urlParts.hostname };
60
71
 
61
- // The docs say there is amqp.connect returning
62
- // a promise, but this version doesn't seem to like
63
- // when a callback isn't provided, therefore run
64
- // in a new Promise
65
- return new Promise((resolve, reject) => {
66
- // We may run into issues with SNI TLS if
67
- // we host with 3rd parties using our own certs.
68
- // To avoid any issues, let's parse the url
69
- // and provide the server name in the socket options
70
- const urlParts = urlParse(options.connectionUrl);
71
- const socketOptions = {servername: urlParts.hostname};
72
+ return new Promise((resolve) => {
73
+ const attempt = async () => {
74
+ logger.debug("Attempting connection...");
75
+ try {
76
+ const conn = await amqp.connect(options.connectionUrl, socketOptions);
72
77
 
73
- amqp.connect(options.connectionUrl, socketOptions, (err, conn) => {
78
+ this.connection = conn;
79
+ this.updatePubsAndSubsConnectionRef(conn);
74
80
 
75
- if (err) {
76
- logger.error("Error while connecting", err)
81
+ this.connection.on("error", (err) => {
82
+ logger.error("connection error", err);
83
+ // Do not attempt to reconnect as the
84
+ // 'close' event will also be emitted
85
+ // if this error closes the connection
86
+ });
87
+
88
+ this.connection.on("close", (err) => {
89
+ logger.error("connection closed");
90
+ this.connection = null;
91
+ this.connectionTestChannel = null;
92
+ if (err) {
93
+ logger.error("connection closed due to error:", err);
94
+ logger.error("Reconnecting in", this.retry, "seconds");
95
+ setTimeout(attempt, this.retry * 1000);
96
+ } else {
97
+ logger.debug("Will not re-attempt");
98
+ }
99
+ });
100
+
101
+ logger.debug("Connected");
102
+ resolve();
103
+ } catch (err) {
104
+ logger.error("Error while connecting", err);
77
105
  logger.error("Attempting again in", this.retry, "seconds");
78
- return setTimeout(() => this.openConnection(options), this.retry * 1000);
106
+ setTimeout(attempt, this.retry * 1000);
79
107
  }
80
-
81
- this.connection = conn;
82
- if (!this.connection) {
83
- return reject(new Error("Failed to obtain connection"));
84
- } else {
85
- this.updatePubsAndSubsConnectionRef(conn);
86
- }
87
-
88
- this.connection.on("error", (err) => {
89
- logger.error("connection error", err);
90
- // Do not attempt to reconnect as the
91
- // 'close' event will also be emitted
92
- // if this error closes the connection
93
- });
94
-
95
- this.connection.on("close", (err) => {
96
- logger.error("connection closed");
97
- this.connection = null;
98
- if (err) {
99
- logger.error("connection closed due to error:", err);
100
- logger.error("Reconnecting in", this.retry, "seconds");
101
- setTimeout(() => this.openConnection(options), this.retry * 1000);
102
- } else {
103
- // If there was no error, it is us who closed
104
- // this connection, thus a reconnection will not
105
- // be attempted.
106
- logger.debug("Will not re-attempt");
107
- }
108
- });
109
-
110
- logger.debug("Connected");
111
- resolve();
112
- });
108
+ };
109
+ attempt();
113
110
  });
114
111
  }
115
112
 
@@ -119,21 +116,12 @@ class S4Queue {
119
116
  * and subscribers
120
117
  */
121
118
  async closeConnection() {
122
- return new Promise((resolve, reject) => {
123
- if (!this.connection) {
124
- return resolve();
125
- }
126
- this.connection.close((err) => {
127
- if (err) {
128
- reject(err);
129
- } else {
130
- this.subs = {};
131
- this.pubs = {};
132
- this.connection = null;
133
- resolve();
134
- }
135
- });
136
- });
119
+ if (!this.connection) return;
120
+ await this.connection.close();
121
+ this.subs = {};
122
+ this.pubs = {};
123
+ this.connectionTestChannel = null;
124
+ this.connection = null;
137
125
  }
138
126
 
139
127
  /**
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
5
+ cd "$ROOT"
6
+
7
+ # ── Version resolution ────────────────────────────────────────────────────────
8
+ VERSION="${BUILD_VERSION:-}"
9
+
10
+ if [ -z "$VERSION" ]; then
11
+ VERSION=$(node -p "require('./package.json').version")
12
+ fi
13
+
14
+ if [ -z "$VERSION" ] || [ "$VERSION" = "0.0.0" ]; then
15
+ echo "error: no version specified — set BUILD_VERSION or package.json version" >&2
16
+ exit 1
17
+ fi
18
+
19
+ PACKAGE=$(node -p "require('./package.json').name")
20
+ echo "publishing $PACKAGE@$VERSION"
21
+
22
+ # ── Stamp version, restore on exit ───────────────────────────────────────────
23
+ ORIGINAL_VERSION=$(node -p "require('./package.json').version")
24
+ restore_version() {
25
+ npm pkg set version="$ORIGINAL_VERSION" --silent
26
+ }
27
+ trap restore_version EXIT
28
+
29
+ npm pkg set version="$VERSION" --silent
30
+
31
+ # ── Build ─────────────────────────────────────────────────────────────────────
32
+ echo "building..."
33
+ npm run build
34
+
35
+ # ── Dist-tag: prerelease versions get 'next', stable versions get 'latest' ───
36
+ if [[ "$VERSION" =~ -[a-zA-Z] ]]; then
37
+ DIST_TAG="next"
38
+ else
39
+ DIST_TAG="latest"
40
+ fi
41
+
42
+ # ── Publish ───────────────────────────────────────────────────────────────────
43
+ echo "publishing with tag: $DIST_TAG"
44
+ npm publish --access public --tag "$DIST_TAG"
45
+
46
+ echo "done: $PACKAGE@$VERSION"