async-lube 2.0.0 → 2.1.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/CHANGELOG.md +34 -0
- package/README.md +1 -1
- package/docs/http.md +1 -1
- package/docs/reference.md +4 -2
- package/docs/tasks.md +19 -2
- package/package.json +4 -5
- package/public.d.ts +112 -0
- package/src/attempt.js +17 -7
- package/src/durable/context.js +107 -64
- package/src/durable/error.js +39 -15
- package/src/durable/index.js +18 -10
- package/src/durable/journal.js +29 -14
- package/src/durable/json.js +26 -9
- package/src/durable/lease.js +15 -5
- package/src/durable/persist.js +60 -22
- package/src/durable/run.js +103 -41
- package/src/durable/send.js +30 -13
- package/src/durable/serve.js +30 -24
- package/src/durable/state.js +28 -13
- package/src/durable/store.js +19 -10
- package/src/durable/watch.js +31 -11
- package/src/errors.js +9 -3
- package/src/flow/attempts.js +49 -29
- package/src/flow/builder.js +260 -161
- package/src/flow/compile.js +86 -66
- package/src/flow/graph.js +108 -42
- package/src/flow/index.js +13 -7
- package/src/flow/items.js +79 -46
- package/src/flow/nodes.js +267 -117
- package/src/flow/refs.js +27 -13
- package/src/flow/resources.js +9 -3
- package/src/flow/run.js +287 -114
- package/src/flow/streams.js +44 -19
- package/src/flow/subflows.js +93 -53
- package/src/http/config.js +11 -5
- package/src/http/index.js +25 -14
- package/src/http/refresh.js +29 -12
- package/src/http/request.js +246 -151
- package/src/http/response.js +105 -50
- package/src/http/retry.js +52 -27
- package/src/http/socket.js +220 -172
- package/src/http/sse.js +113 -74
- package/src/http/throttle.js +9 -4
- package/src/http/url.js +58 -35
- package/src/http/xhr.js +29 -24
- package/src/index.js +1 -0
- package/src/key.js +3 -5
- package/src/limiter.js +146 -65
- package/src/offload.js +116 -85
- package/src/offload_module.js +594 -0
- package/src/options.js +8 -4
- package/src/redial.js +129 -0
- package/src/signal.js +14 -4
- package/src/stream.js +353 -198
- package/types/attempt.d.ts.map +1 -1
- package/types/durable/index.d.ts.map +1 -1
- package/types/durable/state.d.ts.map +1 -1
- package/types/durable/store.d.ts.map +1 -1
- package/types/errors.d.ts.map +1 -1
- package/types/http/index.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/limiter.d.ts +5 -1
- package/types/limiter.d.ts.map +1 -1
- package/types/offload.d.ts +2 -16
- package/types/offload.d.ts.map +1 -1
- package/types/redial.d.ts +28 -0
- package/types/redial.d.ts.map +1 -0
- package/types/stream.d.ts +2 -0
- package/types/stream.d.ts.map +1 -1
package/src/flow/streams.js
CHANGED
|
@@ -29,13 +29,16 @@ function end_source(c, record, failure) {
|
|
|
29
29
|
record.source_error = failure
|
|
30
30
|
if (record.status == "waiting" && c.run_status == "running") {
|
|
31
31
|
clearTimeout(record.timer)
|
|
32
|
-
if (failure)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
if (failure) {
|
|
33
|
+
fail_input(c, record, failure.error)
|
|
34
|
+
} else {
|
|
35
|
+
settle(
|
|
36
|
+
c,
|
|
37
|
+
record.node.name,
|
|
38
|
+
"skipped",
|
|
39
|
+
void 0
|
|
40
|
+
)
|
|
41
|
+
}
|
|
39
42
|
} else if (failure && settled_statuses.has(record.status)) {
|
|
40
43
|
c.streaming = true
|
|
41
44
|
try {
|
|
@@ -43,12 +46,18 @@ function end_source(c, record, failure) {
|
|
|
43
46
|
} finally {
|
|
44
47
|
c.streaming = false
|
|
45
48
|
}
|
|
46
|
-
if (c.run_status != "running")
|
|
49
|
+
if (c.run_status != "running") {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
47
52
|
enter(c, [ record.node.name ], "*")
|
|
48
|
-
for (const name of c.records.keys())
|
|
53
|
+
for (const name of c.records.keys()) {
|
|
54
|
+
try_start(c, name)
|
|
55
|
+
}
|
|
49
56
|
drain(c)
|
|
50
57
|
schedule(c)
|
|
51
|
-
} else
|
|
58
|
+
} else {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
52
61
|
report(c)
|
|
53
62
|
publish(c)
|
|
54
63
|
}
|
|
@@ -61,11 +70,13 @@ function end_source(c, record, failure) {
|
|
|
61
70
|
function is_full(c, source, dependents) {
|
|
62
71
|
for (const dependent of dependents) {
|
|
63
72
|
const target = get_record(c, dependent)
|
|
64
|
-
const limit = target.node.options.limit
|
|
73
|
+
const limit = /** @type {number} */(target.node.options.limit)/**/
|
|
65
74
|
const waiting = target.node.arrive?.[source] == "queue"
|
|
66
75
|
? (target.queued?.get(source)?.length ?? 0) - (active_statuses.has(target.status) ? 1 : 0)
|
|
67
76
|
: target.backlog.length - target.backlog_head
|
|
68
|
-
if (waiting >= limit)
|
|
77
|
+
if (waiting >= limit) {
|
|
78
|
+
return true
|
|
79
|
+
}
|
|
69
80
|
}
|
|
70
81
|
return false
|
|
71
82
|
}
|
|
@@ -74,11 +85,15 @@ function is_full(c, source, dependents) {
|
|
|
74
85
|
* @returns {void}
|
|
75
86
|
*/
|
|
76
87
|
export function start_pumps(c) {
|
|
77
|
-
if (c.pumping || c.run_status != "running")
|
|
88
|
+
if (c.pumping || c.run_status != "running") {
|
|
89
|
+
return
|
|
90
|
+
}
|
|
78
91
|
c.pumping = true
|
|
79
92
|
for (const record of c.records.values()) {
|
|
80
93
|
const { dependents, name, source } = record.node
|
|
81
|
-
if (!source)
|
|
94
|
+
if (!source) {
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
82
97
|
const pressed = dependents.filter(
|
|
83
98
|
dependent => get_record(c, dependent).node.options.overflow == "wait"
|
|
84
99
|
)
|
|
@@ -105,7 +120,9 @@ export function start_pumps(c) {
|
|
|
105
120
|
try {
|
|
106
121
|
for (;;) {
|
|
107
122
|
const step = await reader.next()
|
|
108
|
-
if (stopped)
|
|
123
|
+
if (stopped) {
|
|
124
|
+
return
|
|
125
|
+
}
|
|
109
126
|
if (step.done) {
|
|
110
127
|
end_source(c, record, void 0)
|
|
111
128
|
return
|
|
@@ -121,10 +138,14 @@ export function start_pumps(c) {
|
|
|
121
138
|
resolve => c.room_waiters.push(resolve)
|
|
122
139
|
)
|
|
123
140
|
}
|
|
124
|
-
if (stopped)
|
|
141
|
+
if (stopped) {
|
|
142
|
+
return
|
|
143
|
+
}
|
|
125
144
|
}
|
|
126
145
|
} catch (error) {
|
|
127
|
-
if (!stopped)
|
|
146
|
+
if (!stopped) {
|
|
147
|
+
end_source(c, record, { error })
|
|
148
|
+
}
|
|
128
149
|
}
|
|
129
150
|
})()
|
|
130
151
|
}
|
|
@@ -135,7 +156,9 @@ export function start_pumps(c) {
|
|
|
135
156
|
*/
|
|
136
157
|
export function stop_pumps(c) {
|
|
137
158
|
c.pumping = false
|
|
138
|
-
for (const stop of c.pumps.splice(0))
|
|
159
|
+
for (const stop of c.pumps.splice(0)) {
|
|
160
|
+
stop()
|
|
161
|
+
}
|
|
139
162
|
wake_room(c)
|
|
140
163
|
}
|
|
141
164
|
/**
|
|
@@ -143,5 +166,7 @@ export function stop_pumps(c) {
|
|
|
143
166
|
* @returns {void}
|
|
144
167
|
*/
|
|
145
168
|
export function wake_room(c) {
|
|
146
|
-
for (const resolve of c.room_waiters.splice(0))
|
|
169
|
+
for (const resolve of c.room_waiters.splice(0)) {
|
|
170
|
+
resolve(void 0)
|
|
171
|
+
}
|
|
147
172
|
}
|
package/src/flow/subflows.js
CHANGED
|
@@ -22,29 +22,39 @@ function check_path(program, path, full, need) {
|
|
|
22
22
|
const head = dot < 0 ? path : path.slice(0, dot)
|
|
23
23
|
const name = program.name_of(head)
|
|
24
24
|
const node = name == null ? void 0 : program.node_of(name)
|
|
25
|
-
if (!node)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (dot < 0) {
|
|
29
|
-
if (need == "input" && node.kind != "input") throw Error(
|
|
30
|
-
`Flow node "${node.name}" is not an input`
|
|
25
|
+
if (!node) {
|
|
26
|
+
throw Error(
|
|
27
|
+
`"${head}" is not added to the flow`
|
|
31
28
|
)
|
|
29
|
+
}
|
|
30
|
+
if (dot < 0) {
|
|
31
|
+
if (need == "input" && node.kind != "input") {
|
|
32
|
+
throw Error(
|
|
33
|
+
`Flow node "${node.name}" is not an input`
|
|
34
|
+
)
|
|
35
|
+
}
|
|
32
36
|
return
|
|
33
37
|
}
|
|
34
|
-
if (node.kind != "flow")
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
if (node.kind != "flow") {
|
|
39
|
+
throw Error(
|
|
40
|
+
`Flow node "${node.name}" is not a flow, so "${full}" names nothing`
|
|
41
|
+
)
|
|
42
|
+
}
|
|
37
43
|
let rest = path.slice(dot + 1)
|
|
38
44
|
if (node.each) {
|
|
39
45
|
const next = rest.indexOf(".")
|
|
40
46
|
const key = next < 0 ? rest : rest.slice(0, next)
|
|
41
|
-
if (!is_index(key))
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
if (!is_index(key)) {
|
|
48
|
+
throw Error(
|
|
49
|
+
`Flow node "${node.name}" has no item ${key}`
|
|
50
|
+
)
|
|
51
|
+
}
|
|
44
52
|
rest = next < 0 ? "" : rest.slice(next + 1)
|
|
45
53
|
}
|
|
46
54
|
if (!rest) {
|
|
47
|
-
if (need == "any")
|
|
55
|
+
if (need == "any") {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
48
58
|
throw Error(
|
|
49
59
|
`The path "${full}" does not name ${need == "input" ? "an input" : "a node"}`
|
|
50
60
|
)
|
|
@@ -69,14 +79,18 @@ export function check_snapshot_names(program, path, problems) {
|
|
|
69
79
|
const name = path + node.name
|
|
70
80
|
if (!node.named) {
|
|
71
81
|
const message = `Flow node "${name}" has no name of its own, so a snapshot cannot find it after the code changes: add it with a name option`
|
|
72
|
-
if (!problems)
|
|
82
|
+
if (!problems) {
|
|
83
|
+
throw Error(message)
|
|
84
|
+
}
|
|
73
85
|
problems.push(message)
|
|
74
86
|
}
|
|
75
|
-
if (node.sub)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
if (node.sub) {
|
|
88
|
+
check_snapshot_names(
|
|
89
|
+
compile(node.sub),
|
|
90
|
+
name + ".",
|
|
91
|
+
problems
|
|
92
|
+
)
|
|
93
|
+
}
|
|
80
94
|
}
|
|
81
95
|
}
|
|
82
96
|
/**
|
|
@@ -86,17 +100,22 @@ export function check_snapshot_names(program, path, problems) {
|
|
|
86
100
|
* @returns {void}
|
|
87
101
|
*/
|
|
88
102
|
function count_sub(record, status, change) {
|
|
89
|
-
if (status == "running")
|
|
90
|
-
|
|
103
|
+
if (status == "running") {
|
|
104
|
+
record.sub_running += change
|
|
105
|
+
} else if (status == "waiting") {
|
|
106
|
+
record.sub_waiting += change
|
|
107
|
+
}
|
|
91
108
|
}
|
|
92
109
|
/**
|
|
93
110
|
* @param {NodeRecord} record
|
|
94
111
|
* @returns {string[]}
|
|
95
112
|
*/
|
|
96
113
|
export function failed_sub_keys(record) {
|
|
97
|
-
if (record.sub_runs.size)
|
|
98
|
-
|
|
99
|
-
|
|
114
|
+
if (record.sub_runs.size) {
|
|
115
|
+
return [ ...record.sub_runs ].filter(
|
|
116
|
+
([ , sub_run ]) => sub_run[FAILURES]()
|
|
117
|
+
).map(([ key ]) => key)
|
|
118
|
+
}
|
|
100
119
|
return Object.entries(record.resume_subs ?? {}).filter(
|
|
101
120
|
([ , sub ]) => has_snapshot_failures(sub)
|
|
102
121
|
)
|
|
@@ -114,9 +133,11 @@ export function find_sub_run(c, path, need) {
|
|
|
114
133
|
c,
|
|
115
134
|
name_or_throw(c, path.slice(0, dot))
|
|
116
135
|
)
|
|
117
|
-
if (record.node.kind != "flow")
|
|
118
|
-
|
|
119
|
-
|
|
136
|
+
if (record.node.kind != "flow") {
|
|
137
|
+
throw Error(
|
|
138
|
+
`Flow node "${record.node.name}" is not a flow, so "${path}" names nothing`
|
|
139
|
+
)
|
|
140
|
+
}
|
|
120
141
|
let rest = path.slice(dot + 1)
|
|
121
142
|
let key = ""
|
|
122
143
|
if (record.node.each) {
|
|
@@ -125,12 +146,16 @@ export function find_sub_run(c, path, need) {
|
|
|
125
146
|
rest = next < 0 ? "" : rest.slice(next + 1)
|
|
126
147
|
}
|
|
127
148
|
const sub_run = record.status == "running" ? record.sub_runs.get(key) : void 0
|
|
128
|
-
if (sub_run && active_statuses.has(sub_run.status))
|
|
149
|
+
if (sub_run && active_statuses.has(sub_run.status)) {
|
|
150
|
+
return [ sub_run, rest ]
|
|
151
|
+
}
|
|
129
152
|
check_path(c.program, path, path, need)
|
|
130
153
|
const count = record.status == "running" ? record.items?.length : void 0
|
|
131
|
-
if (count != null && Number(key) >= count)
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
if (count != null && Number(key) >= count) {
|
|
155
|
+
throw Error(
|
|
156
|
+
`Flow node "${record.node.name}" has no item ${key}`
|
|
157
|
+
)
|
|
158
|
+
}
|
|
134
159
|
return [ void 0, rest ]
|
|
135
160
|
}
|
|
136
161
|
/**
|
|
@@ -142,7 +167,9 @@ export function flatten_snapshot_errors(snapshot) {
|
|
|
142
167
|
const all = { ...snapshot.errors }
|
|
143
168
|
for (const [ name, data ] of Object.entries(snapshot.nodes)) {
|
|
144
169
|
for (const [ key, sub ] of Object.entries(data.subs ?? {})) {
|
|
145
|
-
for (const [ sub_key, error ] of Object.entries(flatten_snapshot_errors(sub)))
|
|
170
|
+
for (const [ sub_key, error ] of Object.entries(flatten_snapshot_errors(sub))) {
|
|
171
|
+
all[(key ? name + "." + key : name) + "." + sub_key] = error
|
|
172
|
+
}
|
|
146
173
|
}
|
|
147
174
|
}
|
|
148
175
|
return all
|
|
@@ -185,18 +212,6 @@ export async function run_sub(
|
|
|
185
212
|
const index = key ? Number(key) : c.item_index
|
|
186
213
|
/** @type {FlowStatus} */
|
|
187
214
|
let reported = "running"
|
|
188
|
-
/**
|
|
189
|
-
* @param {FlowStatus} status
|
|
190
|
-
* @returns {void}
|
|
191
|
-
*/
|
|
192
|
-
function on_change(status) {
|
|
193
|
-
count_sub(record, reported, -1)
|
|
194
|
-
count_sub(record, status, 1)
|
|
195
|
-
reported = status
|
|
196
|
-
c.version++
|
|
197
|
-
report(c)
|
|
198
|
-
schedule(c)
|
|
199
|
-
}
|
|
200
215
|
count_sub(record, reported, 1)
|
|
201
216
|
const sub_run = start_run(
|
|
202
217
|
compile(
|
|
@@ -220,7 +235,9 @@ export async function run_sub(
|
|
|
220
235
|
},
|
|
221
236
|
(c.trace_path ? c.trace_path + "." : "") + record.node.name + (key ? "." + key : "")
|
|
222
237
|
)
|
|
223
|
-
if (record.retrying && sub_snapshot)
|
|
238
|
+
if (record.retrying && sub_snapshot) {
|
|
239
|
+
sub_run.retry()
|
|
240
|
+
}
|
|
224
241
|
record.sub_runs.set(key, sub_run)
|
|
225
242
|
const sends = record.sends?.get(key)
|
|
226
243
|
if (sends) {
|
|
@@ -233,11 +250,25 @@ export async function run_sub(
|
|
|
233
250
|
}
|
|
234
251
|
try {
|
|
235
252
|
const value = await sub_run
|
|
236
|
-
if (record.sub_runs.get(key) == sub_run && !sub_run[FAILURES]())
|
|
253
|
+
if (record.sub_runs.get(key) == sub_run && !sub_run[FAILURES]()) {
|
|
254
|
+
record.sub_runs.delete(key)
|
|
255
|
+
}
|
|
237
256
|
return value
|
|
238
257
|
} finally {
|
|
239
258
|
sub_run[STOP]()
|
|
240
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* @param {FlowStatus} status
|
|
262
|
+
* @returns {void}
|
|
263
|
+
*/
|
|
264
|
+
function on_change(status) {
|
|
265
|
+
count_sub(record, reported, -1)
|
|
266
|
+
count_sub(record, status, 1)
|
|
267
|
+
reported = status
|
|
268
|
+
c.version++
|
|
269
|
+
report(c)
|
|
270
|
+
schedule(c)
|
|
271
|
+
}
|
|
241
272
|
}
|
|
242
273
|
/**
|
|
243
274
|
* @param {RunContext} c
|
|
@@ -267,18 +298,27 @@ export function send_path(c, path, value) {
|
|
|
267
298
|
return
|
|
268
299
|
}
|
|
269
300
|
check_path(c.program, path, path, "input")
|
|
270
|
-
if (record.abandoned && !active_statuses.has(record.status))
|
|
301
|
+
if (record.abandoned && !active_statuses.has(record.status)) {
|
|
302
|
+
return
|
|
303
|
+
}
|
|
271
304
|
const count = record.status == "running" ? record.items?.length : void 0
|
|
272
|
-
if (count != null && Number(key) >= count)
|
|
273
|
-
|
|
274
|
-
|
|
305
|
+
if (count != null && Number(key) >= count) {
|
|
306
|
+
throw Error(
|
|
307
|
+
`Flow node "${name}" has no item ${key}`
|
|
308
|
+
)
|
|
309
|
+
}
|
|
275
310
|
const item = record.items?.[Number(key)]
|
|
276
311
|
const is_kept = record.sub_runs.has(key) || !!record.resume_subs?.[key] || !!item?.failed
|
|
277
|
-
if (!is_kept && (record.status == "done" || record.status == "skipped" || item))
|
|
312
|
+
if (!is_kept && (record.status == "done" || record.status == "skipped" || item)) {
|
|
313
|
+
return
|
|
314
|
+
}
|
|
278
315
|
record.sends ??= new Map()
|
|
279
316
|
const sends = record.sends.get(key)
|
|
280
|
-
if (sends)
|
|
281
|
-
|
|
317
|
+
if (sends) {
|
|
318
|
+
sends.push([ rest, value ])
|
|
319
|
+
} else {
|
|
320
|
+
record.sends.set(key, [ [ rest, value ] ])
|
|
321
|
+
}
|
|
282
322
|
}
|
|
283
323
|
/**
|
|
284
324
|
* @param {NodeRecord} record
|
package/src/http/config.js
CHANGED
|
@@ -13,7 +13,9 @@ export const hook_names = /** @type {const} */([
|
|
|
13
13
|
* @returns {void}
|
|
14
14
|
*/
|
|
15
15
|
export function call_hook(hook, ...args) {
|
|
16
|
-
if (!hook)
|
|
16
|
+
if (!hook) {
|
|
17
|
+
return
|
|
18
|
+
}
|
|
17
19
|
try {
|
|
18
20
|
Promise.resolve(hook(...args))
|
|
19
21
|
.catch(noop)
|
|
@@ -26,9 +28,11 @@ export function call_hook(hook, ...args) {
|
|
|
26
28
|
*/
|
|
27
29
|
export async function merge_headers(source, target) {
|
|
28
30
|
const init = typeof source == "function" ? await source() : source
|
|
29
|
-
if (init)
|
|
30
|
-
(
|
|
31
|
-
|
|
31
|
+
if (init) {
|
|
32
|
+
new Headers(init).forEach(
|
|
33
|
+
(value, key) => target.set(key, value)
|
|
34
|
+
)
|
|
35
|
+
}
|
|
32
36
|
}
|
|
33
37
|
/**
|
|
34
38
|
* @param {import("../../public.js").Hooks} parent
|
|
@@ -65,7 +69,9 @@ export function omit_keys(source, keys) {
|
|
|
65
69
|
/** @type {Record<string, unknown>} */
|
|
66
70
|
const init = {}
|
|
67
71
|
for (const key of Object.keys(source)) {
|
|
68
|
-
if (!keys.has(key))
|
|
72
|
+
if (!keys.has(key)) {
|
|
73
|
+
init[key] = source[key]
|
|
74
|
+
}
|
|
69
75
|
}
|
|
70
76
|
return init
|
|
71
77
|
}
|
package/src/http/index.js
CHANGED
|
@@ -28,10 +28,14 @@ let client_count = 0
|
|
|
28
28
|
* @returns {string}
|
|
29
29
|
*/
|
|
30
30
|
function to_socket_url(url) {
|
|
31
|
-
if (scheme_regex.test(url))
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
31
|
+
if (scheme_regex.test(url)) {
|
|
32
|
+
return url.replace(/^http(s?):/i, "ws$1:")
|
|
33
|
+
}
|
|
34
|
+
if (typeof location == "undefined") {
|
|
35
|
+
throw TypeError(
|
|
36
|
+
`The URL "${url}" is relative: set base, or use an absolute URL`
|
|
37
|
+
)
|
|
38
|
+
}
|
|
35
39
|
return new URL(url, location.href).href.replace(/^http(s?):/i, "ws$1:")
|
|
36
40
|
}
|
|
37
41
|
/**
|
|
@@ -70,15 +74,16 @@ function http(
|
|
|
70
74
|
options,
|
|
71
75
|
false
|
|
72
76
|
),
|
|
73
|
-
/**
|
|
74
|
-
* @param {import("../../public.js").ExtendConfig} next
|
|
75
|
-
*/
|
|
77
|
+
/** @param {import("../../public.js").ExtendConfig} next */
|
|
76
78
|
extend: next => {
|
|
77
79
|
/** @type {Record<string, unknown>} */
|
|
78
80
|
const merged = { ...config }
|
|
79
81
|
for (const [ key, value ] of Object.entries(next)) {
|
|
80
|
-
if (value === null)
|
|
81
|
-
|
|
82
|
+
if (value === null) {
|
|
83
|
+
delete merged[key]
|
|
84
|
+
} else if (value !== void 0) {
|
|
85
|
+
merged[key] = value
|
|
86
|
+
}
|
|
82
87
|
}
|
|
83
88
|
if (config.headers && next.headers) {
|
|
84
89
|
merged["headers"] = async () => {
|
|
@@ -91,7 +96,9 @@ function http(
|
|
|
91
96
|
return headers
|
|
92
97
|
}
|
|
93
98
|
}
|
|
94
|
-
if (config.on && next.on)
|
|
99
|
+
if (config.on && next.on) {
|
|
100
|
+
merged["on"] = merge_hooks(config.on, next.on)
|
|
101
|
+
}
|
|
95
102
|
return http(merged, shared)
|
|
96
103
|
},
|
|
97
104
|
/**
|
|
@@ -207,9 +214,11 @@ function http(
|
|
|
207
214
|
{
|
|
208
215
|
create: (url, protocols) => {
|
|
209
216
|
const Socket = config.WebSocket ?? globalThis.WebSocket
|
|
210
|
-
if (!Socket)
|
|
211
|
-
|
|
212
|
-
|
|
217
|
+
if (!Socket) {
|
|
218
|
+
throw TypeError(
|
|
219
|
+
"WebSocket is not available: pass WebSocket in the config"
|
|
220
|
+
)
|
|
221
|
+
}
|
|
213
222
|
return protocols == null ? new Socket(url) : new Socket(url, protocols)
|
|
214
223
|
},
|
|
215
224
|
options,
|
|
@@ -221,7 +230,9 @@ function http(
|
|
|
221
230
|
/** @type {Record<string, string>} */
|
|
222
231
|
const hidden = {}
|
|
223
232
|
if (typeof options.params == "function") {
|
|
224
|
-
for (const key of Object.keys(extra ?? {}))
|
|
233
|
+
for (const key of Object.keys(extra ?? {})) {
|
|
234
|
+
hidden[key] = "***"
|
|
235
|
+
}
|
|
225
236
|
}
|
|
226
237
|
return {
|
|
227
238
|
redacted: to_socket_url(
|
package/src/http/refresh.js
CHANGED
|
@@ -60,7 +60,9 @@ export function get_refresh_state(refresher) {
|
|
|
60
60
|
*/
|
|
61
61
|
async function refresh(c, state, generation, error) {
|
|
62
62
|
if (generation != state.generation) {
|
|
63
|
-
if (generation == state.failed_generation)
|
|
63
|
+
if (generation == state.failed_generation) {
|
|
64
|
+
throw error
|
|
65
|
+
}
|
|
64
66
|
return
|
|
65
67
|
}
|
|
66
68
|
if (!state.refreshing) {
|
|
@@ -79,13 +81,17 @@ async function refresh(c, state, generation, error) {
|
|
|
79
81
|
.then(c.config.refresh)
|
|
80
82
|
.then(
|
|
81
83
|
() => {
|
|
82
|
-
if (state.generation != generation)
|
|
84
|
+
if (state.generation != generation) {
|
|
85
|
+
return
|
|
86
|
+
}
|
|
83
87
|
clearTimeout(state.timer)
|
|
84
88
|
state.generation++
|
|
85
89
|
state.refreshing = void 0
|
|
86
90
|
},
|
|
87
91
|
(/** @type {unknown} */ reason) => {
|
|
88
|
-
if (state.generation == generation)
|
|
92
|
+
if (state.generation == generation) {
|
|
93
|
+
fail_refresh(c, state, error, reason)
|
|
94
|
+
}
|
|
89
95
|
throw reason
|
|
90
96
|
}
|
|
91
97
|
)
|
|
@@ -116,7 +122,9 @@ async function refresh(c, state, generation, error) {
|
|
|
116
122
|
* @returns {void}
|
|
117
123
|
*/
|
|
118
124
|
export function reject_refreshed(c, state, generation, error) {
|
|
119
|
-
if (state.unauthorized_generation == generation)
|
|
125
|
+
if (state.unauthorized_generation == generation) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
120
128
|
state.unauthorized_generation = generation
|
|
121
129
|
call_hook(
|
|
122
130
|
c.config.on?.unauthorized,
|
|
@@ -132,7 +140,6 @@ export function reject_refreshed(c, state, generation, error) {
|
|
|
132
140
|
* @returns {void}
|
|
133
141
|
*/
|
|
134
142
|
function time_out_refresh(c, state, error, timeout_error) {
|
|
135
|
-
if (!state.refreshing) return
|
|
136
143
|
const controller = state.controller
|
|
137
144
|
state.time_out?.(timeout_error)
|
|
138
145
|
fail_refresh(c, state, error, timeout_error)
|
|
@@ -171,7 +178,9 @@ export async function wait_refresh(
|
|
|
171
178
|
: void 0
|
|
172
179
|
const waiting = refresh(c, state, generation, error)
|
|
173
180
|
const joined = state.generation == generation && state.refreshing != null
|
|
174
|
-
if (joined)
|
|
181
|
+
if (joined) {
|
|
182
|
+
state.waiters++
|
|
183
|
+
}
|
|
175
184
|
try {
|
|
176
185
|
await race_signal(waiting, controller.signal)
|
|
177
186
|
} catch (reason) {
|
|
@@ -182,13 +191,21 @@ export async function wait_refresh(
|
|
|
182
191
|
)
|
|
183
192
|
: void 0
|
|
184
193
|
if (joined && state.generation == generation && state.refreshing) {
|
|
185
|
-
if (timeout_error)
|
|
186
|
-
|
|
194
|
+
if (timeout_error) {
|
|
195
|
+
state.timed_out = timeout_error
|
|
196
|
+
}
|
|
197
|
+
if (--state.waiters == 0 && state.timed_out) {
|
|
198
|
+
time_out_refresh(c, state, error, state.timed_out)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (signal.aborted) {
|
|
202
|
+
throw signal.reason instanceof CancelError
|
|
203
|
+
? signal.reason
|
|
204
|
+
: new CancelError(signal.reason, summary)
|
|
205
|
+
}
|
|
206
|
+
if (timeout_error) {
|
|
207
|
+
throw timeout_error
|
|
187
208
|
}
|
|
188
|
-
if (signal.aborted) throw signal.reason instanceof CancelError
|
|
189
|
-
? signal.reason
|
|
190
|
-
: new CancelError(signal.reason, summary)
|
|
191
|
-
if (timeout_error) throw timeout_error
|
|
192
209
|
throw reason instanceof TimeoutError
|
|
193
210
|
? new TimeoutError(reason.timeout, summary)
|
|
194
211
|
: reason
|