@nxtedition/lib 19.1.0 → 19.1.1
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/couch.js +175 -92
- package/package.json +7 -7
package/couch.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
|
+
import stream from 'node:stream'
|
|
2
3
|
import querystring from 'node:querystring'
|
|
3
4
|
import createError from 'http-errors'
|
|
4
5
|
import { makeWeakCache } from './weakCache.js'
|
|
@@ -8,7 +9,6 @@ import urljoin from 'url-join'
|
|
|
8
9
|
import undici from 'undici'
|
|
9
10
|
import { AbortError } from './errors.js'
|
|
10
11
|
import split2 from 'split2'
|
|
11
|
-
import stream from 'node:stream'
|
|
12
12
|
|
|
13
13
|
// https://github.com/fastify/fastify/blob/main/lib/reqIdGenFactory.js
|
|
14
14
|
// 2,147,483,647 (2^31 − 1) stands for max SMI value (an internal optimization of V8).
|
|
@@ -886,26 +886,21 @@ function _normalizeAllDocsOptions({
|
|
|
886
886
|
}
|
|
887
887
|
}
|
|
888
888
|
|
|
889
|
-
class Handler {
|
|
890
|
-
#
|
|
891
|
-
#
|
|
892
|
-
#decoder = new TextDecoder()
|
|
893
|
-
#resolve
|
|
894
|
-
#reject
|
|
895
|
-
#resume
|
|
896
|
-
#abort
|
|
889
|
+
class Handler extends undici.DecoratorHandler {
|
|
890
|
+
#str
|
|
891
|
+
#decoder
|
|
897
892
|
#onAbort
|
|
898
893
|
#signal
|
|
899
|
-
#next
|
|
900
894
|
#statusCode
|
|
901
895
|
#statusText
|
|
902
896
|
#opts
|
|
897
|
+
#handler
|
|
898
|
+
|
|
899
|
+
constructor({ opts, signal, handler }) {
|
|
900
|
+
super(handler)
|
|
903
901
|
|
|
904
|
-
|
|
905
|
-
this.#next = next
|
|
902
|
+
this.#handler = handler
|
|
906
903
|
this.#opts = opts
|
|
907
|
-
this.#resolve = resolve
|
|
908
|
-
this.#reject = reject
|
|
909
904
|
this.#signal = signal
|
|
910
905
|
}
|
|
911
906
|
|
|
@@ -913,101 +908,64 @@ class Handler {
|
|
|
913
908
|
if (this.#signal?.aborted) {
|
|
914
909
|
abort(this.#signal.reason)
|
|
915
910
|
} else {
|
|
916
|
-
this.#abort = abort
|
|
917
911
|
if (this.#signal) {
|
|
918
912
|
this.#onAbort = () => abort(this.#signal.reason)
|
|
919
913
|
this.#signal.addEventListener('abort', this.#onAbort)
|
|
920
914
|
}
|
|
915
|
+
|
|
916
|
+
this.#str = ''
|
|
917
|
+
this.#decoder = null
|
|
918
|
+
this.#handler.onConnect?.(abort)
|
|
921
919
|
}
|
|
922
920
|
}
|
|
923
921
|
|
|
924
922
|
onHeaders(statusCode, rawHeaders, resume, statusText) {
|
|
925
923
|
this.#statusCode = statusCode
|
|
926
924
|
this.#statusText = statusText
|
|
927
|
-
this.#resume = resume
|
|
928
925
|
|
|
929
926
|
if (this.#statusCode >= 200 && this.#statusCode < 300) {
|
|
930
|
-
this.#
|
|
927
|
+
this.#handler.onHeaders?.(statusCode, rawHeaders, resume, statusText)
|
|
928
|
+
} else {
|
|
929
|
+
this.#decoder = new TextDecoder()
|
|
931
930
|
}
|
|
932
931
|
}
|
|
933
932
|
|
|
934
933
|
onData(data) {
|
|
935
|
-
if (
|
|
934
|
+
if (this.#decoder) {
|
|
936
935
|
this.#str += this.#decoder.decode(data, { stream: true })
|
|
937
936
|
} else {
|
|
938
|
-
|
|
939
|
-
lines[0] = this.#str + lines[0]
|
|
940
|
-
this.#str = lines.pop() ?? ''
|
|
941
|
-
|
|
942
|
-
const rows = []
|
|
943
|
-
for (const line of lines) {
|
|
944
|
-
if (this.#state === 0) {
|
|
945
|
-
if (line.endsWith('[')) {
|
|
946
|
-
this.#state = 1
|
|
947
|
-
} else {
|
|
948
|
-
throw new Error('unexpected data')
|
|
949
|
-
}
|
|
950
|
-
} else if (this.#state === 1) {
|
|
951
|
-
if (line.startsWith(']')) {
|
|
952
|
-
this.#state = 2
|
|
953
|
-
} else {
|
|
954
|
-
rows.push(JSON.parse(line.slice(0, line.lastIndexOf('}') + 1)))
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
if (rows.length === 0) {
|
|
960
|
-
return true
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
const thenable = this.#next(rows)
|
|
964
|
-
|
|
965
|
-
if (!thenable) {
|
|
966
|
-
return true
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
thenable.then(this.#resume, this.#abort)
|
|
970
|
-
|
|
971
|
-
return false
|
|
937
|
+
return this.#handler?.onData(data)
|
|
972
938
|
}
|
|
973
939
|
}
|
|
974
940
|
|
|
975
|
-
onComplete() {
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
try {
|
|
988
|
-
body = JSON.parse(this.#str)
|
|
989
|
-
reason = body.reason
|
|
990
|
-
error = body.error
|
|
991
|
-
} catch {
|
|
992
|
-
// Do nothing...
|
|
993
|
-
}
|
|
941
|
+
onComplete(trailers) {
|
|
942
|
+
if (this.#decoder) {
|
|
943
|
+
let body
|
|
944
|
+
let reason
|
|
945
|
+
let error
|
|
946
|
+
try {
|
|
947
|
+
body = JSON.parse(this.#str)
|
|
948
|
+
reason = body.reason
|
|
949
|
+
error = body.error
|
|
950
|
+
} catch {
|
|
951
|
+
// Do nothing...
|
|
952
|
+
}
|
|
994
953
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
},
|
|
954
|
+
this.onFinally(
|
|
955
|
+
Object.assign(new Error(this.#statusText ?? reason), {
|
|
956
|
+
reason,
|
|
957
|
+
error,
|
|
958
|
+
data: {
|
|
959
|
+
req: this.#opts,
|
|
960
|
+
res: {
|
|
961
|
+
body,
|
|
962
|
+
statusCode: this.#statusCode,
|
|
1005
963
|
},
|
|
1006
|
-
}
|
|
1007
|
-
)
|
|
1008
|
-
|
|
964
|
+
},
|
|
965
|
+
}),
|
|
966
|
+
)
|
|
1009
967
|
} else {
|
|
1010
|
-
this.onFinally(null)
|
|
968
|
+
this.onFinally(null, trailers)
|
|
1011
969
|
}
|
|
1012
970
|
}
|
|
1013
971
|
|
|
@@ -1021,14 +979,127 @@ class Handler {
|
|
|
1021
979
|
}
|
|
1022
980
|
|
|
1023
981
|
if (err) {
|
|
1024
|
-
this.#
|
|
982
|
+
this.#handler.onError?.(err)
|
|
983
|
+
} else {
|
|
984
|
+
this.#handler.onComplete?.(val)
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
class StreamOutput extends stream.Readable {
|
|
990
|
+
#str
|
|
991
|
+
#resume
|
|
992
|
+
#abort
|
|
993
|
+
#state
|
|
994
|
+
#decoder
|
|
995
|
+
#didPush = false
|
|
996
|
+
|
|
997
|
+
constructor({ highWaterMark }) {
|
|
998
|
+
super({ objectMode: true, highWaterMark })
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
_read() {
|
|
1002
|
+
this.#resume?.()
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
_destroy(err, callback) {
|
|
1006
|
+
this.#abort?.(err)
|
|
1007
|
+
callback(err)
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
onConnect(abort) {
|
|
1011
|
+
if (this.destroyed) {
|
|
1012
|
+
abort(this.errored)
|
|
1013
|
+
} else if (!this.#didPush) {
|
|
1014
|
+
this.#state = 0
|
|
1015
|
+
this.#str = ''
|
|
1016
|
+
this.#abort = abort
|
|
1017
|
+
this.#decoder = new TextDecoder()
|
|
1025
1018
|
} else {
|
|
1026
|
-
|
|
1019
|
+
throw new Error('unusable')
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
onHeaders(statusCode, rawHeaders, resume, statusText) {
|
|
1024
|
+
if (statusCode >= 300 || statusCode < 200) {
|
|
1025
|
+
throw new Error('invalid status code: ' + statusCode)
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
this.#resume = resume
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
onData(data) {
|
|
1032
|
+
const lines = this.#decoder.decode(data, { stream: true }).split(/\r?\n+/)
|
|
1033
|
+
lines[0] = this.#str + lines[0]
|
|
1034
|
+
this.#str = lines.pop() ?? ''
|
|
1035
|
+
|
|
1036
|
+
for (const line of lines) {
|
|
1037
|
+
if (this.#state === 0) {
|
|
1038
|
+
if (line.endsWith('[')) {
|
|
1039
|
+
this.#state = 1
|
|
1040
|
+
} else {
|
|
1041
|
+
throw new Error('unexpected data')
|
|
1042
|
+
}
|
|
1043
|
+
} else if (this.#state === 1) {
|
|
1044
|
+
if (line.startsWith(']')) {
|
|
1045
|
+
this.#state = 2
|
|
1046
|
+
} else {
|
|
1047
|
+
this.push(JSON.parse(line.slice(0, line.lastIndexOf('}') + 1)))
|
|
1048
|
+
this.#didPush = true
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1027
1051
|
}
|
|
1052
|
+
|
|
1053
|
+
return this.readableLength < this.readableHighWaterMark
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
onComplete() {
|
|
1057
|
+
assert(this.#state === 2)
|
|
1058
|
+
this.push(null)
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
onError(err) {
|
|
1062
|
+
this.destroy(err)
|
|
1028
1063
|
}
|
|
1029
1064
|
}
|
|
1030
1065
|
|
|
1031
|
-
|
|
1066
|
+
class PromiseOutput {
|
|
1067
|
+
#resolve
|
|
1068
|
+
#reject
|
|
1069
|
+
#str
|
|
1070
|
+
#decoder
|
|
1071
|
+
|
|
1072
|
+
constructor({ resolve, reject }) {
|
|
1073
|
+
this.#resolve = resolve
|
|
1074
|
+
this.#reject = reject
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
onConnect() {
|
|
1078
|
+
this.#decoder = new TextDecoder()
|
|
1079
|
+
this.#str = ''
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
onHeaders(statusCode, rawHeaders, resume, statusText) {
|
|
1083
|
+
if (statusCode >= 300 || statusCode < 200) {
|
|
1084
|
+
throw new Error('invalid status code: ' + statusCode)
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
onData(data) {
|
|
1089
|
+
this.#str += this.#decoder.decode(data, { stream: true })
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
onComplete() {
|
|
1093
|
+
this.#str += this.#decoder.decode(undefined, { stream: false })
|
|
1094
|
+
this.#resolve(JSON.parse(this.#str))
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
onError(err) {
|
|
1098
|
+
this.#reject(err)
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
export function request(
|
|
1032
1103
|
url,
|
|
1033
1104
|
{
|
|
1034
1105
|
body,
|
|
@@ -1037,8 +1108,8 @@ export async function request(
|
|
|
1037
1108
|
headers,
|
|
1038
1109
|
dispatcher = undici.getGlobalDispatcher(),
|
|
1039
1110
|
signal,
|
|
1111
|
+
stream,
|
|
1040
1112
|
},
|
|
1041
|
-
next,
|
|
1042
1113
|
) {
|
|
1043
1114
|
url = new URL(url)
|
|
1044
1115
|
if (url.search) {
|
|
@@ -1055,7 +1126,19 @@ export async function request(
|
|
|
1055
1126
|
},
|
|
1056
1127
|
body: body != null && typeof body === 'object' ? JSON.stringify(body) : body,
|
|
1057
1128
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1129
|
+
|
|
1130
|
+
dispatcher = dispatcher.compose(
|
|
1131
|
+
(dispatch) => (opts, handler) => dispatch(opts, new Handler({ opts, signal, handler })),
|
|
1132
|
+
)
|
|
1133
|
+
|
|
1134
|
+
if (stream) {
|
|
1135
|
+
const handler = new StreamOutput({ highWaterMark: stream.highWaterMark ?? 128 })
|
|
1136
|
+
dispatcher.dispatch(opts, handler)
|
|
1137
|
+
return handler
|
|
1138
|
+
} else {
|
|
1139
|
+
return new Promise((resolve, reject) => {
|
|
1140
|
+
const handler = new PromiseOutput({ resolve, reject })
|
|
1141
|
+
dispatcher.dispatch(opts, handler)
|
|
1142
|
+
})
|
|
1143
|
+
}
|
|
1061
1144
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/lib",
|
|
3
|
-
"version": "19.1.
|
|
3
|
+
"version": "19.1.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Robert Nagy <robert.nagy@boffins.se>",
|
|
6
6
|
"type": "module",
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
"/__tests__"
|
|
76
76
|
],
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@aws-sdk/client-s3": "^3.
|
|
78
|
+
"@aws-sdk/client-s3": "^3.554.0",
|
|
79
79
|
"@elastic/elasticsearch": "^8.13.1",
|
|
80
|
-
"@elastic/transport": "^8.5.
|
|
81
|
-
"@nxtedition/nxt-undici": "^2.0.
|
|
80
|
+
"@elastic/transport": "^8.5.1",
|
|
81
|
+
"@nxtedition/nxt-undici": "^2.0.46",
|
|
82
82
|
"date-fns": "^3.6.0",
|
|
83
83
|
"fast-querystring": "^1.1.1",
|
|
84
84
|
"hasha": "^6.0.0",
|
|
@@ -94,13 +94,13 @@
|
|
|
94
94
|
"p-queue": "^8.0.1",
|
|
95
95
|
"pino": "^8.20.0",
|
|
96
96
|
"pino-std-serializers": "^6.2.2",
|
|
97
|
-
"qs": "^6.12.
|
|
97
|
+
"qs": "^6.12.1",
|
|
98
98
|
"request-target": "^1.0.2",
|
|
99
99
|
"smpte-timecode": "^1.3.5",
|
|
100
100
|
"split-string": "^6.0.0",
|
|
101
101
|
"split2": "^4.2.0",
|
|
102
102
|
"toobusy-js": "^0.5.1",
|
|
103
|
-
"undici": "^6.
|
|
103
|
+
"undici": "^6.13.0",
|
|
104
104
|
"url-join": "^5.0.0"
|
|
105
105
|
},
|
|
106
106
|
"devDependencies": {
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
"eslint-config-prettier": "^9.1.0",
|
|
112
112
|
"eslint-config-standard": "^17.0.0",
|
|
113
113
|
"eslint-plugin-import": "^2.29.1",
|
|
114
|
-
"eslint-plugin-n": "^17.1
|
|
114
|
+
"eslint-plugin-n": "^17.2.1",
|
|
115
115
|
"eslint-plugin-node": "^11.1.0",
|
|
116
116
|
"eslint-plugin-promise": "^6.0.0",
|
|
117
117
|
"husky": "^9.0.11",
|