braidfs 0.0.142 → 0.0.144
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/index.js +36 -111
- package/package.json +4 -3
package/index.js
CHANGED
|
@@ -379,7 +379,10 @@ async function scan_files() {
|
|
|
379
379
|
var timestamp = new Date().toLocaleTimeString(
|
|
380
380
|
'en-US', {minute: '2-digit', second: '2-digit', hour: '2-digit'}
|
|
381
381
|
)
|
|
382
|
-
|
|
382
|
+
var mem = process.memoryUsage()
|
|
383
|
+
var heapMB = (mem.heapUsed / 1024 / 1024).toFixed(1)
|
|
384
|
+
var rssMB = (mem.rss / 1024 / 1024).toFixed(1)
|
|
385
|
+
console.log(`scan files.. ${timestamp}. ${Date.now() - st}ms [${heapMB} MB heap, ${rssMB} MB RSS]`)
|
|
383
386
|
}
|
|
384
387
|
scan_files.running = false
|
|
385
388
|
|
|
@@ -1184,121 +1187,43 @@ function ReconnectRateLimiter(wait_time) {
|
|
|
1184
1187
|
return self
|
|
1185
1188
|
}
|
|
1186
1189
|
|
|
1190
|
+
// Undici-based fetch with HTTP/2 support for HTTPS,
|
|
1191
|
+
// falls back to built-in fetch for HTTP (faster, no Agent overhead)
|
|
1192
|
+
// Timeout defaults: connect.timeout=10s,
|
|
1193
|
+
// headersTimeout=5min, bodyTimeout=5min,
|
|
1194
|
+
// keepAliveTimeout=4s, keepAliveMaxTimeout=10min
|
|
1187
1195
|
async function fetch_http2(url, options = {}) {
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
var sessionInfo = fetch_http2.sessions.get(u.origin)
|
|
1198
|
-
if (!sessionInfo || sessionInfo.session.closed) {
|
|
1199
|
-
var session = require("http2").connect(u.origin, {
|
|
1200
|
-
rejectUnauthorized: options.rejectUnauthorized !== false,
|
|
1201
|
-
})
|
|
1202
|
-
sessionInfo = { session, pendingRejects: new Set() }
|
|
1203
|
-
|
|
1204
|
-
session.on("error", (e) => {
|
|
1205
|
-
for (var f of sessionInfo.pendingRejects) f(e)
|
|
1206
|
-
fetch_http2.sessions.delete(u.origin)
|
|
1207
|
-
})
|
|
1208
|
-
session.on("close", () => {
|
|
1209
|
-
var e = new Error('Session closed')
|
|
1210
|
-
for (var f of sessionInfo.pendingRejects) f(e)
|
|
1211
|
-
fetch_http2.sessions.delete(u.origin)
|
|
1212
|
-
})
|
|
1213
|
-
fetch_http2.sessions.set(u.origin, sessionInfo)
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
var session = sessionInfo.session
|
|
1217
|
-
|
|
1218
|
-
return await new Promise((resolve, reject) => {
|
|
1219
|
-
sessionInfo.pendingRejects.add(reject)
|
|
1220
|
-
|
|
1221
|
-
var responseTimeout = setTimeout(() => {
|
|
1222
|
-
stream.destroy(new Error('Response timeout'))
|
|
1223
|
-
}, options.responseTimeout || 10000)
|
|
1224
|
-
|
|
1225
|
-
var stream = session.request({
|
|
1226
|
-
":method": options.method || "GET",
|
|
1227
|
-
":path": u.pathname + u.search,
|
|
1228
|
-
":scheme": "https",
|
|
1229
|
-
":authority": u.host,
|
|
1230
|
-
...Object.fromEntries(options.headers || []),
|
|
1231
|
-
})
|
|
1232
|
-
|
|
1233
|
-
options.signal?.addEventListener("abort",
|
|
1234
|
-
() => stream.destroy(new Error("Request aborted")),
|
|
1235
|
-
{ once: true })
|
|
1236
|
-
|
|
1237
|
-
stream.on("response", headers => {
|
|
1238
|
-
clearTimeout(responseTimeout)
|
|
1239
|
-
sessionInfo.pendingRejects.delete(reject)
|
|
1240
|
-
var status = +headers[":status"]
|
|
1241
|
-
resolve({
|
|
1242
|
-
ok: status >= 200 && status < 300,
|
|
1243
|
-
status,
|
|
1244
|
-
statusText: "",
|
|
1245
|
-
headers: new Headers(Object.fromEntries(
|
|
1246
|
-
Object.entries(headers).filter(([k]) =>
|
|
1247
|
-
typeof k === "string" && !k.startsWith(":")))),
|
|
1248
|
-
body: new ReadableStream({
|
|
1249
|
-
start(ctrl) {
|
|
1250
|
-
stream.on("data", x => ctrl.enqueue(new Uint8Array(x)))
|
|
1251
|
-
stream.on("end", () => ctrl.close())
|
|
1252
|
-
stream.on("error", err => ctrl.error(err))
|
|
1253
|
-
},
|
|
1254
|
-
cancel() { stream.destroy() },
|
|
1255
|
-
}),
|
|
1256
|
-
bodyUsed: false,
|
|
1257
|
-
async _consumeBody() {
|
|
1258
|
-
this.bodyUsed = true
|
|
1259
|
-
var chunks = []
|
|
1260
|
-
var reader = this.body.getReader()
|
|
1261
|
-
|
|
1262
|
-
while (true) {
|
|
1263
|
-
var { done, value } = await reader.read()
|
|
1264
|
-
if (done) break
|
|
1265
|
-
chunks.push(value)
|
|
1266
|
-
}
|
|
1267
|
-
return Buffer.concat(chunks.map((c) => (Buffer.isBuffer(c) ? c : Buffer.from(c))))
|
|
1268
|
-
},
|
|
1269
|
-
async text() { return (await this._consumeBody()).toString() },
|
|
1270
|
-
async json() { return JSON.parse(await this.text()) },
|
|
1271
|
-
async arrayBuffer() {
|
|
1272
|
-
var b = await this._consumeBody()
|
|
1273
|
-
return b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength)
|
|
1274
|
-
},
|
|
1275
|
-
})
|
|
1276
|
-
})
|
|
1277
|
-
|
|
1278
|
-
stream.on("error", (err) => {
|
|
1279
|
-
clearTimeout(responseTimeout)
|
|
1280
|
-
sessionInfo.pendingRejects.delete(reject)
|
|
1281
|
-
reject(err)
|
|
1282
|
-
})
|
|
1283
|
-
|
|
1284
|
-
var body = options.body
|
|
1285
|
-
if (!body) return stream.end()
|
|
1286
|
-
|
|
1287
|
-
if (body instanceof Uint8Array || Buffer.isBuffer(body)) stream.end(body)
|
|
1288
|
-
else if (body instanceof Blob) body.arrayBuffer()
|
|
1289
|
-
.then((b) => stream.end(Buffer.from(b)))
|
|
1290
|
-
.catch(reject)
|
|
1291
|
-
else stream.end(typeof body === "string" ? body : JSON.stringify(body))
|
|
1196
|
+
// Use built-in fetch for HTTP (faster, no need for HTTP/2)
|
|
1197
|
+
if (new URL(url).protocol !== 'https:')
|
|
1198
|
+
return fetch(url, options)
|
|
1199
|
+
|
|
1200
|
+
if (!fetch_http2.undici) {
|
|
1201
|
+
fetch_http2.undici = require('undici')
|
|
1202
|
+
var makeAgent = (insecure) => new fetch_http2.undici.Agent({
|
|
1203
|
+
allowH2: true,
|
|
1204
|
+
connect: { rejectUnauthorized: !insecure },
|
|
1292
1205
|
})
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
// console.log("HTTP/2 failed, falling back to HTTP/1.1:", err.message)
|
|
1296
|
-
return fetch(url, options)
|
|
1297
|
-
}
|
|
1298
|
-
throw err
|
|
1206
|
+
fetch_http2.agent = makeAgent(false)
|
|
1207
|
+
fetch_http2.insecureAgent = makeAgent(true)
|
|
1299
1208
|
}
|
|
1209
|
+
|
|
1210
|
+
// Workaround: undici HTTP/2 can hang with empty body on some servers
|
|
1211
|
+
// See https://github.com/nodejs/undici/issues/2589
|
|
1212
|
+
var body = options.body
|
|
1213
|
+
if (body?.length === 0) body = undefined
|
|
1214
|
+
|
|
1215
|
+
return fetch_http2.undici.fetch(url, {
|
|
1216
|
+
method: options.method || 'GET',
|
|
1217
|
+
headers: options.headers,
|
|
1218
|
+
body,
|
|
1219
|
+
signal: options.signal,
|
|
1220
|
+
dispatcher: options.rejectUnauthorized === false
|
|
1221
|
+
? fetch_http2.insecureAgent
|
|
1222
|
+
: fetch_http2.agent,
|
|
1223
|
+
})
|
|
1300
1224
|
}
|
|
1301
1225
|
|
|
1226
|
+
|
|
1302
1227
|
////////////////////////////////
|
|
1303
1228
|
|
|
1304
1229
|
function normalize_url(url) {
|
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "braidfs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.144",
|
|
4
4
|
"description": "braid technology synchronizing files and webpages",
|
|
5
5
|
"author": "Braid Working Group",
|
|
6
6
|
"repository": "braid-org/braidfs",
|
|
7
7
|
"homepage": "https://braid.org",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"braid-http": "~1.3.86",
|
|
10
|
-
"braid-text": "~0.2.
|
|
10
|
+
"braid-text": "~0.2.105",
|
|
11
11
|
"braid-blob": "~0.0.49",
|
|
12
|
-
"chokidar": "^4.0.3"
|
|
12
|
+
"chokidar": "^4.0.3",
|
|
13
|
+
"undici": "^7.18.2"
|
|
13
14
|
},
|
|
14
15
|
"bin": {
|
|
15
16
|
"braidfs": "./index.sh"
|