@nxtedition/lib 19.6.2 → 19.7.0

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/app.js CHANGED
@@ -1,3 +1,4 @@
1
+ import * as inspector from 'node:inspector'
1
2
  import os from 'node:os'
2
3
  import net from 'node:net'
3
4
  import assert from 'node:assert'
@@ -21,6 +22,7 @@ import hashString from './hash.js'
21
22
  import { makeTrace } from './trace.js'
22
23
  import compose from 'koa-compose'
23
24
  import { createServer } from './http.js'
25
+ import { json } from 'node:stream/consumers'
24
26
 
25
27
  export function makeApp(appConfig, onTerminate) {
26
28
  let ds
@@ -678,6 +680,40 @@ export function makeApp(appConfig, onTerminate) {
678
680
  }
679
681
  }
680
682
 
683
+ const inspectBC = new BroadcastChannel('nxt:inspect')
684
+ const inspectSet = new Set()
685
+
686
+ if (serviceWorkerId) {
687
+ inspectBC.onmessage = ({ data }) => {
688
+ const { type } = data
689
+
690
+ if (type === 'inspect:open') {
691
+ // TODO (fix): What happens if you call inspect:open multiple times?
692
+ inspector.open(data.port, data.hostname)
693
+ } else if (type === 'inspect:close') {
694
+ inspector.close()
695
+ }
696
+ }
697
+
698
+ inspectBC.postMessage({ type: 'inspect:register', id: serviceWorkerId })
699
+ destroyers.push(() => {
700
+ inspector.close()
701
+ inspectBC.postMessage({ type: 'inspect:unregister', id: serviceWorkerId })
702
+ })
703
+ } else {
704
+ inspectBC.onmessage = ({ data }) => {
705
+ const { type } = data
706
+
707
+ if (type === 'inspect:register') {
708
+ inspectSet.add(data.id)
709
+ } else if (type === 'inspect:unregister') {
710
+ inspectSet.delete(data.id)
711
+ }
712
+ }
713
+ }
714
+
715
+ destroyers.push(() => inspectBC.close())
716
+
681
717
  if (appConfig.http) {
682
718
  const httpConfig = { ...appConfig.http, ...config.http }
683
719
 
@@ -700,6 +736,36 @@ export function makeApp(appConfig, onTerminate) {
700
736
  return next()
701
737
  }
702
738
  },
739
+ async ({ req, res }, next) => {
740
+ if (req.url.startsWith('/inspect')) {
741
+ if (req.method === 'GET') {
742
+ res.end(JSON.stringify({ workers: Array.from(inspectSet).map((id) => ({ id })) }))
743
+ } else if (req.method === 'POST') {
744
+ const m = req.url.match(/^\/inspect\/([^/]+)/)
745
+ if (!m) {
746
+ res.statusCode = 404
747
+ res.end()
748
+ } else {
749
+ const { port, hostname } = await json(req)
750
+
751
+ // TODO (fix): What about return value & errors?
752
+ inspectBC.postMessage({
753
+ type: port || hostname ? 'inspect:open' : 'inspect:close',
754
+ id: m[1],
755
+ port,
756
+ hostname,
757
+ })
758
+
759
+ res.end()
760
+ }
761
+ } else {
762
+ res.statusCode = 405
763
+ res.end()
764
+ }
765
+ } else {
766
+ return next()
767
+ }
768
+ },
703
769
  appConfig.http.request
704
770
  ? appConfig.http.request
705
771
  : typeof appConfig.http === 'function'
package/couch.js CHANGED
@@ -1151,6 +1151,8 @@ export function request(
1151
1151
  stream,
1152
1152
  },
1153
1153
  ) {
1154
+ signal?.throwIfAborted()
1155
+
1154
1156
  url = new URL(url)
1155
1157
  if (url.search) {
1156
1158
  throw new Error('invalid url: ' + url.href)
package/http.js CHANGED
@@ -80,6 +80,7 @@ export async function request(ctx, next) {
80
80
  // TODO (fix): Use 'end' once we can trust that
81
81
  // 'end' or 'error' will always be emitted.
82
82
  .on('close', function () {
83
+ this.log.debug('request closed')
83
84
  resolve(null)
84
85
  ac.abort()
85
86
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "19.6.2",
3
+ "version": "19.7.0",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",
package/sequence.js CHANGED
@@ -101,6 +101,22 @@ export class Sequence {
101
101
  }
102
102
  }
103
103
 
104
+ compare(other) {
105
+ assert(other instanceof Sequence)
106
+
107
+ if (this.#parts.length !== other.#parts.length) {
108
+ return this.#parts.length - other.#parts.length
109
+ }
110
+
111
+ for (let n = 0; n < this.#parts.length; n++) {
112
+ if (this.#parts[n] !== other.#parts[n]) {
113
+ return this.#parts[n] < other.#parts[n] ? -1 : 1
114
+ }
115
+ }
116
+
117
+ return 0
118
+ }
119
+
104
120
  toString() {
105
121
  if (!this.#value) {
106
122
  let count = 0
package/trace.js CHANGED
@@ -68,14 +68,18 @@ export function makeTrace({
68
68
  const prefix = `{ "create": { "_index": "trace-${index}" } }\n{ "serviceName": "${serviceName}", "op": "`
69
69
 
70
70
  function trace(obj, op) {
71
- if (obj.serviceName) {
72
- throw new Error('invalid property `serviceName`')
73
- }
74
- if (obj.op) {
75
- throw new Error('invalid property `op`')
76
- }
77
- if (obj['@timestamp']) {
78
- throw new Error('invalid property `@timestamp`')
71
+ if (typeof obj === 'string') {
72
+ // Do nothing...
73
+ } else {
74
+ if (obj.serviceName) {
75
+ throw new Error('invalid property `serviceName`')
76
+ }
77
+ if (obj.op) {
78
+ throw new Error('invalid property `op`')
79
+ }
80
+ if (obj['@timestamp']) {
81
+ throw new Error('invalid property `@timestamp`')
82
+ }
79
83
  }
80
84
 
81
85
  if (pending > limit) {