hypercore-fetch 8.6.1 → 8.6.2-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/package.json CHANGED
@@ -1,11 +1,8 @@
1
1
  {
2
2
  "name": "hypercore-fetch",
3
- "version": "8.6.1",
3
+ "version": "8.6.2-0",
4
4
  "description": "Implementation of Fetch that uses the Dat SDK for loading p2p content",
5
- "bin": {
6
- "hypercore-fetch": "bin.js"
7
- },
8
- "main": "index.js",
5
+ "type": "module",
9
6
  "scripts": {
10
7
  "test": "node test",
11
8
  "lint": "standard --fix"
@@ -25,22 +22,16 @@
25
22
  },
26
23
  "homepage": "https://github.com/RangerMauve/hypercore-fetch#readme",
27
24
  "dependencies": {
28
- "busboy": "^0.3.1",
29
25
  "event-iterator": "^2.0.0",
30
- "fetch-headers": "^2.0.0",
31
- "hyper-dns": "^0.12.0",
32
- "hyper-sdk": "^3.0.9",
33
- "make-dir": "^3.1.0",
34
- "make-fetch": "^2.3.3",
35
- "mime": "^2.4.4",
26
+ "hyperdrive": "^11.0.0-alpha.10",
27
+ "make-fetch": "^3.1.0",
28
+ "mime": "^3.0.0",
36
29
  "range-parser": "^1.2.1",
37
- "resolve-dat-path": "^2.0.0",
38
- "sodium-universal": "^3.0.2",
39
- "streamx": "^2.10.0"
30
+ "streamx": "^2.13.0"
40
31
  },
41
32
  "devDependencies": {
42
- "form-data": "^4.0.0",
43
- "random-access-memory": "^3.1.1",
33
+ "@rangermauve/fetch-event-source": "^1.0.3",
34
+ "hyper-sdk": "^4.1.0",
44
35
  "standard": "^17.0.0",
45
36
  "tape": "^5.2.2"
46
37
  }
package/test.js CHANGED
@@ -1,282 +1,341 @@
1
- const SDK = require('hyper-sdk')
2
- const test = require('tape')
3
- const FormData = require('form-data')
1
+ /* global FormData, Blob */
2
+ import * as SDK from 'hyper-sdk'
3
+ import test from 'tape'
4
+ import createEventSource from '@rangermauve/fetch-event-source'
5
+ import { once } from 'events'
4
6
 
5
- runTests()
7
+ import makeHyperFetch from './index.js'
6
8
 
7
9
  const SAMPLE_CONTENT = 'Hello World'
10
+ let count = 0
11
+ function next () {
12
+ return count++
13
+ }
8
14
 
9
- async function runTests () {
10
- const { Hyperdrive, close } = await SDK({
11
- persist: false
12
- })
13
-
14
- const { Hyperdrive: Hyperdrive2, close: close2 } = await SDK({
15
- persist: false
15
+ async function nextURL (t) {
16
+ const createResponse = await fetch(`hyper://localhost/?key=example${next()}`, {
17
+ method: 'post'
16
18
  })
19
+ await checkResponse(createResponse, t, 'Created new drive')
17
20
 
18
- const fetch = require('./')({
19
- Hyperdrive,
20
- writable: true
21
- })
21
+ const created = await createResponse.text()
22
+ return created
23
+ }
22
24
 
23
- const fetch2 = require('./')({
24
- Hyperdrive: Hyperdrive2,
25
- writable: true
26
- })
25
+ const sdk1 = await SDK.create({ storage: false })
26
+ const sdk2 = await SDK.create({ storage: false })
27
27
 
28
- test.onFinish(() => {
29
- close()
30
- close2()
31
- })
28
+ const fetch = await makeHyperFetch({
29
+ sdk: sdk1,
30
+ writable: true
31
+ })
32
32
 
33
- test('Read index.html', async (t) => {
34
- const archive = Hyperdrive('example1')
33
+ const fetch2 = await makeHyperFetch({
34
+ sdk: sdk2,
35
+ writable: true
36
+ })
35
37
 
36
- const FILE_LOCATION = '/index.html'
37
- const FILE_DATA = '<h1>Hello World!</h1>'
38
+ test.onFinish(() => {
39
+ sdk1.close()
40
+ sdk2.close()
41
+ })
38
42
 
39
- await archive.writeFile(FILE_LOCATION, FILE_DATA)
43
+ test('Quick check', async (t) => {
44
+ const createResponse = await fetch(`hyper://localhost/?key=example${next()}`, {
45
+ method: 'post'
46
+ })
40
47
 
41
- const url = `hyper://${archive.key.toString('hex')}${FILE_LOCATION}`
48
+ await checkResponse(createResponse, t, 'Created new drive')
42
49
 
43
- t.pass('Prepped archive ' + url)
50
+ const created = await createResponse.text()
44
51
 
45
- const response = await fetch(url)
52
+ t.ok(created.startsWith('hyper://'), 'Created drive has hyper URL')
46
53
 
47
- t.pass('got response')
54
+ const existsResponse = await fetch(created)
48
55
 
49
- const text = await response.text()
56
+ await checkResponse(existsResponse, t)
50
57
 
51
- t.pass('got response text')
58
+ t.deepEqual(await existsResponse.json(), [], 'Empty dir on create')
52
59
 
53
- const contentType = response.headers.get('content-type')
60
+ const uploadLocation = new URL('./example.txt', created)
54
61
 
55
- t.equal(contentType, 'text/html; charset=utf-8')
56
- t.equal(text, FILE_DATA)
57
- t.pass('Headers ' + [...response.headers.entries()])
62
+ const uploadResponse = await fetch(uploadLocation, {
63
+ method: 'put',
64
+ body: SAMPLE_CONTENT
58
65
  })
59
66
 
60
- test('GET .well-known/dat', async (t) => {
61
- const response = await fetch('hyper://example/.well-known/dat')
62
- t.ok(response, 'Got response')
63
- t.equal(response.status, 200, 'Got OK response code')
64
- const text = await response.text()
65
- t.ok(text.startsWith('dat://'), 'Returned dat URL')
66
- })
67
+ await checkResponse(uploadResponse, t)
67
68
 
68
- test('GET .well-known/hyper', async (t) => {
69
- const response = await fetch('hyper://example/.well-known/hyper')
70
- t.ok(response, 'Got response')
71
- t.equal(response.status, 200, 'Got OK response code')
72
- const text = await response.text()
73
- t.ok(text.startsWith('hyper://'), 'Returned dat URL')
74
- })
69
+ const uploadedContentResponse = await fetch(uploadLocation)
75
70
 
76
- test('PUT file', async (t) => {
77
- const response1 = await fetch('hyper://example/checkthis.txt', { method: 'PUT', body: SAMPLE_CONTENT })
71
+ await checkResponse(uploadedContentResponse, t)
78
72
 
79
- t.equal(response1.status, 200, 'Got OK response on write')
73
+ const content = await uploadedContentResponse.text()
74
+ const contentType = uploadedContentResponse.headers.get('Content-Type')
80
75
 
81
- const response2 = await fetch('hyper://example/checkthis.txt')
76
+ t.equal(contentType, 'text/plain; charset=utf-8', 'Content got expected mime type')
77
+ t.equal(content, SAMPLE_CONTENT, 'Got uploaded content back out')
82
78
 
83
- t.equal(response2.status, 200, 'Got OK response on read')
79
+ const dirResponse = await fetch2(created)
84
80
 
85
- t.equal(await response2.text(), SAMPLE_CONTENT, 'Read back written data')
86
- })
81
+ await checkResponse(dirResponse, t)
87
82
 
88
- test('PUT FormData to directory', async (t) => {
89
- const form = new FormData()
83
+ t.deepEqual(await dirResponse.json(), ['example.txt'], 'File got added')
84
+ })
90
85
 
91
- form.append('file', SAMPLE_CONTENT, {
92
- filename: 'example.txt'
93
- })
94
- const body = form.getBuffer()
95
- const headers = form.getHeaders()
86
+ test('PUT file', async (t) => {
87
+ const created = await nextURL(t)
96
88
 
97
- const response1 = await fetch('hyper://example/foo/bar/', {
98
- method: 'PUT',
99
- headers,
100
- body
101
- })
89
+ const uploadLocation = new URL('./example.txt', created)
102
90
 
103
- t.equal(response1.status, 200, 'Got OK response on directory upload')
91
+ const uploadResponse = await fetch(uploadLocation, {
92
+ method: 'put',
93
+ body: SAMPLE_CONTENT
94
+ })
104
95
 
105
- console.log(await response1.text())
96
+ await checkResponse(uploadResponse, t)
106
97
 
107
- const response2 = await fetch('hyper://example/foo/bar/example.txt')
98
+ const uploadedContentResponse = await fetch(uploadLocation)
108
99
 
109
- t.equal(response2.status, 200, 'Got OK response on read')
100
+ await checkResponse(uploadedContentResponse, t)
110
101
 
111
- t.equal(await response2.text(), SAMPLE_CONTENT, 'Read back written data')
112
- })
102
+ const content = await uploadedContentResponse.text()
103
+ const contentType = uploadedContentResponse.headers.get('Content-Type')
104
+
105
+ t.equal(contentType, 'text/plain; charset=utf-8', 'Content got expected mime type')
106
+ t.equal(content, SAMPLE_CONTENT, 'Got uploaded content back out')
107
+ })
108
+ test('PUT FormData', async (t) => {
109
+ const created = await nextURL(t)
113
110
 
114
- test('PUT file in new directory', async (t) => {
115
- const response1 = await fetch('hyper://example/fizz/buzz/example.txt', { method: 'PUT', body: SAMPLE_CONTENT })
111
+ const formData = new FormData()
112
+ formData.append('file', new Blob([SAMPLE_CONTENT]), 'example.txt')
113
+ formData.append('file', new Blob([SAMPLE_CONTENT]), 'example2.txt')
116
114
 
117
- t.equal(response1.status, 200, 'Got OK response on directory/file creation')
115
+ const uploadedResponse = await fetch(created, {
116
+ method: 'put',
117
+ body: formData
118
118
  })
119
119
 
120
- test('PUT to overwrite a file', async (t) => {
121
- const response1 = await fetch('hyper://example/baz/index.html', { method: 'PUT', body: SAMPLE_CONTENT })
122
- t.ok(response1.ok)
123
- const response2 = await fetch('hyper://example/baz/index.html', { method: 'PUT', body: SAMPLE_CONTENT })
120
+ await checkResponse(uploadedResponse, t)
124
121
 
125
- t.equal(response2.status, 200, 'Got OK response on file overwrite')
126
- })
122
+ const file2URL = new URL('/example2.txt', created)
123
+ const file2Response = await fetch(file2URL)
127
124
 
128
- test('DELETE file', async (t) => {
129
- const response1 = await fetch('hyper://example/test.txt', { method: 'PUT', body: SAMPLE_CONTENT })
130
- t.ok(response1.ok)
125
+ await checkResponse(file2Response, t)
126
+ const file2Content = await file2Response.text()
131
127
 
132
- const response2 = await fetch('hyper://example/test.txt', { method: 'DELETE' })
128
+ t.equal(file2Content, SAMPLE_CONTENT, 'file contents got uploaded')
133
129
 
134
- t.equal(response2.status, 200, 'Got OK response on file delete')
130
+ const listDirRequest = await fetch(created)
131
+ await checkResponse(listDirRequest, t)
132
+ const entries = await listDirRequest.json()
133
+ t.deepEqual(entries, ['example.txt', 'example2.txt'], 'new files are listed')
134
+ })
135
+ test('PUT into new directory', async (t) => {
136
+ const created = await nextURL(t)
135
137
 
136
- const response3 = await fetch('hyper://example/test.txt', { method: 'GET' })
138
+ const uploadLocation = new URL('./subfolder/example.txt', created)
137
139
 
138
- t.equal(response3.status, 404, 'Got not found on deleted file')
140
+ const uploadResponse = await fetch(uploadLocation, {
141
+ method: 'put',
142
+ body: SAMPLE_CONTENT
139
143
  })
140
144
 
141
- test('GET index.html', async (t) => {
142
- const response1 = await fetch('hyper://example/baz')
145
+ await checkResponse(uploadResponse, t)
143
146
 
144
- t.equal(await response1.text(), SAMPLE_CONTENT, 'Got index.html content')
147
+ const uploadedContentResponse = await fetch(uploadLocation)
145
148
 
146
- const response2 = await fetch('hyper://example/baz?noResolve')
149
+ await checkResponse(uploadedContentResponse, t)
147
150
 
148
- t.equal(response2.headers.get('content-type'), 'application/json; charset=utf-8', 'noResolve flag yields JSON by default')
149
- t.deepEqual(await response2.json(), ['index.html'], 'Listed directory')
151
+ const content = await uploadedContentResponse.text()
152
+ const contentType = uploadedContentResponse.headers.get('Content-Type')
150
153
 
151
- const response3 = await fetch('hyper://example/baz?noResolve')
152
- t.equal(response3.headers.get('content-type'), 'application/json; charset=utf-8', 'noResolve flag yields JSON by default')
153
- t.deepEqual(await response3.json(), ['index.html'], 'Listed directory')
154
- })
154
+ t.equal(contentType, 'text/plain; charset=utf-8', 'Content got expected mime type')
155
+ t.equal(content, SAMPLE_CONTENT, 'Got uploaded content back out')
155
156
 
156
- test('Create and read tags', async (t) => {
157
- await fetch('hyper://example/test.txt', { method: 'PUT', body: SAMPLE_CONTENT })
157
+ const listDirRequest = await fetch(created)
158
+ await checkResponse(listDirRequest, t)
159
+ const entries = await listDirRequest.json()
160
+ t.deepEqual(entries, ['subfolder/'], 'new files are listed')
161
+ })
162
+ test('PUT to overwrite a file', async (t) => {
163
+ const created = await nextURL(t)
158
164
 
159
- const response2 = await fetch('hyper://example/$/tags/tag1', { method: 'PUT' })
160
- t.ok(response2.ok, 'Able to create tag')
165
+ const uploadLocation = new URL('./example.txt', created)
161
166
 
162
- const version = await response2.json()
167
+ const uploadResponse = await fetch(uploadLocation, {
168
+ method: 'put',
169
+ body: SAMPLE_CONTENT
170
+ })
171
+ await checkResponse(uploadResponse, t)
163
172
 
164
- const response3 = await fetch('hyper://example/$/tags/')
173
+ const SHORTER_CONTENT = 'Hello'
165
174
 
166
- t.ok(response3.ok, 'Able to ask for tags')
167
- t.deepEqual(await response3.json(), { tag1: version }, 'Tag got created')
175
+ const overWriteResponse = await fetch(uploadLocation, {
176
+ method: 'put',
177
+ body: SHORTER_CONTENT
178
+ })
179
+ await checkResponse(overWriteResponse, t)
168
180
 
169
- // Insert a file which won't be available with the old tag
170
- await fetch('hyper://example/notaccessible.txt', { method: 'PUT', body: 'test' })
181
+ const uploadedContentResponse = await fetch(uploadLocation)
171
182
 
172
- const response4 = await fetch('hyper://example+tag1/notaccessible.txt')
183
+ await checkResponse(uploadedContentResponse, t)
173
184
 
174
- t.equal(response4.status, 404, 'Newer file not found in older tag')
185
+ const content = await uploadedContentResponse.text()
186
+ const contentType = uploadedContentResponse.headers.get('Content-Type')
175
187
 
176
- const response5 = await fetch('hyper://example/$/tags/tag1', { method: 'DELETE' })
188
+ t.equal(contentType, 'text/plain; charset=utf-8', 'Content got expected mime type')
189
+ t.equal(content, SHORTER_CONTENT, 'Got uploaded content back out')
190
+ })
191
+ test('DELETE a file', async (t) => {
192
+ const created = await nextURL(t)
177
193
 
178
- t.ok(response5.ok, 'Able to delete tag')
194
+ const formData = new FormData()
195
+ formData.append('file', new Blob([SAMPLE_CONTENT]), 'example.txt')
196
+ formData.append('file', new Blob([SAMPLE_CONTENT]), 'example2.txt')
179
197
 
180
- const response6 = await fetch('hyper://example/$/tags/')
198
+ const uploadedResponse = await fetch(created, {
199
+ method: 'put',
200
+ body: formData
201
+ })
202
+ await checkResponse(uploadedResponse, t)
181
203
 
182
- t.deepEqual(await response6.json(), {}, 'No tags left after delete')
204
+ const file2URL = new URL('/example2.txt', created)
205
+ const deleteResponse = await fetch(file2URL, {
206
+ method: 'delete'
183
207
  })
184
208
 
185
- test('Load Mauve\'s blog', async (t) => {
186
- const response = await fetch('hyper://blog.mauve.moe/')
209
+ await checkResponse(deleteResponse, t, 'Able to DELETE')
210
+
211
+ const dirResponse = await fetch(created)
212
+
213
+ await checkResponse(dirResponse, t)
187
214
 
188
- t.ok(response.ok, 'Succesfully loaded homepage')
215
+ t.deepEqual(await dirResponse.json(), ['example.txt'], 'Only one file remains')
216
+ })
217
+ test('DELETE a directory', async (t) => {
218
+ const created = await nextURL(t)
219
+
220
+ const uploadLocation = new URL('./subfolder/example.txt', created)
221
+
222
+ const uploadResponse = await fetch(uploadLocation, {
223
+ method: 'put',
224
+ body: SAMPLE_CONTENT
189
225
  })
226
+ await checkResponse(uploadResponse, t)
190
227
 
191
- test('Watch for changes', async (t) => {
192
- const response = await fetch('hyper://example/', {
193
- headers: {
194
- Accept: 'text/event-stream'
195
- }
196
- })
228
+ const deleteResponse = await fetch(created, {
229
+ method: 'delete'
230
+ })
231
+ await checkResponse(deleteResponse, t, 'Able to DELETE')
232
+
233
+ const listDirRequest = await fetch(created)
234
+ await checkResponse(listDirRequest, t)
235
+ const entries = await listDirRequest.json()
236
+ t.deepEqual(entries, [], 'subfolder got deleted')
237
+ })
238
+ test('Read index.html', async (t) => {
239
+ const created = await nextURL(t)
240
+ const uploadLocation = new URL('./index.html', created)
241
+
242
+ const uploadResponse = await fetch(uploadLocation, {
243
+ method: 'put',
244
+ body: SAMPLE_CONTENT
245
+ })
246
+ await checkResponse(uploadResponse, t)
197
247
 
198
- t.ok(response.ok, 'Able to open request')
199
- t.equal(response.headers.get('Content-Type'), 'text/event-stream', 'Response is event stream')
248
+ const uploadedContentResponse = await fetch(uploadLocation)
200
249
 
201
- const reader = await response.body.getReader()
250
+ await checkResponse(uploadedContentResponse, t)
202
251
 
203
- const [data] = await Promise.all([
204
- reader.read(),
205
- fetch('hyper://example/example4.txt', { method: 'PUT', body: 'Hello World' })
206
- ])
252
+ const content = await uploadedContentResponse.text()
253
+ const contentType = uploadedContentResponse.headers.get('Content-Type')
207
254
 
208
- t.ok(data.value, 'Got eventsource data after writing')
209
- t.ok(data.value.includes('event:change'), 'Eventsource data represents a change event')
210
- t.ok(data.value.endsWith('\n\n'), 'Ends with two newlines')
255
+ t.equal(contentType, 'text/html; charset=utf-8', 'got HTML mime type')
256
+ t.equal(content, SAMPLE_CONTENT, 'loaded index.html content')
257
+ })
258
+ test('Ignore index.html with noResolve', async (t) => {
259
+ const created = await nextURL(t)
260
+ const uploadLocation = new URL('./index.html', created)
211
261
 
212
- await reader.cancel()
262
+ const uploadResponse = await fetch(uploadLocation, {
263
+ method: 'put',
264
+ body: SAMPLE_CONTENT
213
265
  })
266
+ await checkResponse(uploadResponse, t)
214
267
 
215
- test('Send extension from one peer to another', async (t) => {
216
- const domainResponse = await fetch('hyper://example/.well-known/hyper')
217
- const domain = (await domainResponse.text()).split('\n')[0]
268
+ const noResolve = created + '?noResolve'
218
269
 
219
- const extensionURL = `${domain}/$/extensions/example`
220
- const extensionListURL = `${domain}/$/extensions/`
270
+ const listDirRequest = await fetch(noResolve)
271
+ await checkResponse(listDirRequest, t)
272
+ const entries = await listDirRequest.json()
273
+ t.deepEqual(entries, ['index.html'], 'able to list index.html')
274
+ })
275
+ test.skip('Read directory as HTML', async (t) => {
221
276
 
222
- // Load up extension message on peer 1
223
- await fetch(extensionURL)
224
- // Load up extension message on peer 2
225
- await fetch2(extensionURL)
277
+ })
226
278
 
227
- t.pass('Able to initialize extensions')
279
+ test('EventSource extension messages', async (t) => {
280
+ const domain = await nextURL(t)
228
281
 
229
- const extensionListRequest = await fetch(extensionListURL)
230
- const extensionList = await extensionListRequest.json()
282
+ const extensionURL = `${domain}$/extensions/example`
283
+ const extensionListURL = `${domain}$/extensions/`
231
284
 
232
- // Extension list will always be alphabetically sorted
233
- t.deepEqual(extensionList, ['example', 'hypertrie'], 'Got expected list of extensions')
285
+ // Load up extension message on peer 1
286
+ const extensionLoadResponse1 = await fetch(extensionURL)
287
+ await checkResponse(extensionLoadResponse1, t)
288
+ // Load up extension message on peer 2
289
+ const extensionLoadResponse2 = await fetch2(extensionURL)
290
+ await checkResponse(extensionLoadResponse2, t)
234
291
 
235
- // Wait a bit for them to connect
236
- // TODO: Peers API
237
- await delay(2000)
292
+ const extensionListRequest = await fetch(extensionListURL)
293
+ const extensionList = await extensionListRequest.json()
238
294
 
239
- const peerResponse1 = await fetch(extensionURL)
240
- const peerList1 = await peerResponse1.json()
295
+ // Extension list will always be alphabetically sorted
296
+ t.deepEqual(extensionList, ['example'], 'Got expected list of extensions')
241
297
 
242
- t.equal(peerList1.length, 1, 'Got one peer for extension message on peer1')
298
+ const peerResponse1 = await fetch(extensionURL)
299
+ const peerList1 = await peerResponse1.json()
243
300
 
244
- const peerResponse2 = await fetch2(extensionURL)
245
- const peerList2 = await peerResponse2.json()
301
+ t.equal(peerList1.length, 1, 'Got one peer for extension message on peer1')
246
302
 
247
- t.equal(peerList2.length, 1, 'Got one peer for extension message on peer2')
303
+ const peerResponse2 = await fetch2(extensionURL)
304
+ const peerList2 = await peerResponse2.json()
248
305
 
249
- const eventRequest = await fetch(extensionListURL, {
250
- headers: {
251
- Accept: 'text/event-stream'
252
- }
253
- })
306
+ t.equal(peerList2.length, 1, 'Got one peer for extension message on peer2')
254
307
 
255
- t.ok(eventRequest.ok, 'Able to open request')
256
- t.equal(eventRequest.headers.get('Content-Type'), 'text/event-stream', 'Response is event stream')
308
+ const { EventSource } = createEventSource(fetch)
309
+ const source = new EventSource(extensionListURL)
257
310
 
258
- const reader = await eventRequest.body.getReader()
311
+ await Promise.race([
312
+ once(source, 'open'),
313
+ once(source, 'error').then(([e]) => { throw e })
314
+ ])
259
315
 
260
- const toRead = reader.read()
316
+ const toRead = Promise.race([
317
+ once(source, 'example'),
318
+ once(source, 'error').then(([e]) => { throw e })
319
+ ])
261
320
 
262
- await delay(500)
321
+ const broadcastRequest = await fetch2(extensionURL, { method: 'POST', body: SAMPLE_CONTENT })
263
322
 
264
- const broadcastRequest = await fetch2(extensionURL, { method: 'POST', body: 'Hello World' })
323
+ t.ok(broadcastRequest.ok, 'Able to broadcast to peers')
265
324
 
266
- t.ok(broadcastRequest.ok, 'Able to broadcast to peers')
325
+ const [event] = await toRead
267
326
 
268
- const data = await toRead
327
+ const { type, data, lastEventId } = event
269
328
 
270
- t.ok(data.value, 'Got eventsource data after writing')
271
- t.ok(data.value.includes('event:example\n'), 'EventSource data represents an example event')
272
- t.ok(data.value.includes('data:Hello World\n'), 'EventSource data contains expected body')
273
- t.ok(data.value.includes('id:'), 'EventSource data contains an ID')
274
- t.ok(data.value.endsWith('\n\n'), 'Ends with two newlines')
275
-
276
- await reader.cancel()
277
- })
278
- }
329
+ t.equal(data, SAMPLE_CONTENT, 'Got data from event')
330
+ t.equal(type, 'example', 'Event got set to extension message name')
331
+ t.ok(lastEventId, 'Event contained peer ID')
332
+ })
279
333
 
280
- function delay (time) {
281
- return new Promise((resolve) => setTimeout(resolve, time))
334
+ async function checkResponse (response, t, successMessage = 'Response OK') {
335
+ if (!response.ok) {
336
+ const message = await response.text()
337
+ t.fail(new Error(`HTTP Error ${response.status}:\n${message}`))
338
+ } else {
339
+ t.pass(successMessage)
340
+ }
282
341
  }
package/bin.js DELETED
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const eosp = require('end-of-stream-promise')
4
- const { Readable } = require('streamx')
5
-
6
- run()
7
- .catch((e) => process.nextTick(() => {
8
- throw e
9
- }))
10
-
11
- async function run () {
12
- const fetch = require('./')()
13
-
14
- try {
15
- const url = process.argv[2]
16
-
17
- const response = await fetch(url)
18
-
19
- const stream = Readable.from(response.body)
20
-
21
- stream.pipe(process.stdout)
22
-
23
- await eosp(stream)
24
- } finally {
25
- fetch.close()
26
- }
27
- }