hypercore-fetch 8.6.1 → 9.0.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/.github/workflows/test.yml +1 -1
- package/LICENSE +0 -0
- package/README.md +67 -116
- package/index.js +501 -663
- package/package.json +8 -16
- package/test.js +287 -182
- package/bin.js +0 -27
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -5,59 +5,51 @@ Implementation of Fetch that uses the Hyper SDK for loading p2p content
|
|
|
5
5
|
`npm install --save hypercore-fetch`
|
|
6
6
|
|
|
7
7
|
```javascript
|
|
8
|
-
|
|
8
|
+
import makeHyperFetch from 'hypercore-fetch'
|
|
9
|
+
import * as SDK from 'hyper-sdk'
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
// Create in-memory hyper-sdk instance
|
|
12
|
+
const sdk = await SDK.create({storage: false})
|
|
11
13
|
|
|
12
|
-
const
|
|
14
|
+
const fetch = await makeFetch({
|
|
15
|
+
sdk: true,
|
|
16
|
+
writable: true
|
|
17
|
+
})
|
|
13
18
|
|
|
14
|
-
const
|
|
19
|
+
const someURL = `hyper://TODO_REAL_URL_HERE_PLEASE`
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
```
|
|
21
|
+
const response = await fetch(someURL)
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
const data = await response.text()
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
npm i -g hypercore-fetch
|
|
23
|
-
|
|
24
|
-
hypercore-fetch hyper://somethingorother
|
|
25
|
-
|
|
26
|
-
# Or
|
|
27
|
-
|
|
28
|
-
npx hypercore-fetch hyper://somethingorother
|
|
25
|
+
console.log(data)
|
|
29
26
|
```
|
|
30
27
|
|
|
31
28
|
## API
|
|
32
29
|
|
|
33
|
-
### `
|
|
30
|
+
### `makeHyperFetch({sdk, writable=false, extensionMessages = writable, renderIndex}) => fetch()`
|
|
34
31
|
|
|
35
32
|
Creates a hypercore-fetch instance.
|
|
36
33
|
|
|
37
|
-
The `
|
|
38
|
-
|
|
39
|
-
You can pass in options for the [Dat SDK](https://github.com/datproject/sdk) to have it be auto-created,
|
|
40
|
-
or you can pass in both a function matching `const archive = Hyperdrive(key)` and a `const resolved = await resolveName(url)` function (where `resolved` is an instance of URL, uses hyper-dns by default).
|
|
41
|
-
|
|
42
|
-
Set `session` to your Electron session if you want to enable setting the `body` of fetch requests to Electron's [UploadData](https://www.electronjs.org/docs/api/structures/upload-data) API in their protocol handlers.
|
|
34
|
+
The `sdk` argument should be an instance of [hyper-sdk](https://github.com/RangerMauve/hyper-sdk).
|
|
43
35
|
|
|
44
|
-
|
|
36
|
+
The `writable` flag toggles whether the `PUT`/`POST`/`DELETE` methods are available.
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+
`extensionMessages` enables/disables Hypercore Extension Message support which is used for sending extra data to peers on top of hypercore replication streams.
|
|
47
39
|
|
|
48
|
-
|
|
40
|
+
`renderIndex` is an optional function to override the HTML index rendering functionality. By default it will make a simple page which renders links to files and folders within the directory.
|
|
41
|
+
This function takes the `url`, `files` array and `fetch` instance as arguments.
|
|
49
42
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Closes resources for the Dat SDK. This does nothing if you specified the Hyperdrive and `resolveName` options.
|
|
43
|
+
After you've created it, `fetch` will behave like it does in [browsers](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
|
|
53
44
|
|
|
54
45
|
### Common Headers
|
|
55
46
|
|
|
56
47
|
Each response will contain a header for the canonical URL represented as a `Link` header with `rel=canonical`.
|
|
57
48
|
|
|
58
|
-
|
|
49
|
+
There is also an `ETag` header which will be a JSON string containging the drive's current `version`, or the file's sequence number.
|
|
50
|
+
This will change only when the drive has gotten an update of some sort and is monotonically incrementing.
|
|
59
51
|
|
|
60
|
-
|
|
52
|
+
If the resource is a file, it may contain the `Last-Modified` header if the file has had a `metadata.mtime` flag set upon update.
|
|
61
53
|
|
|
62
54
|
### `fetch('hyper://NAME/example.txt', {method: 'GET'})`
|
|
63
55
|
|
|
@@ -66,15 +58,7 @@ This will attempt to load `example.txt` from the archive labeled by `NAME`.
|
|
|
66
58
|
It will also load `index.html` files automatically for a folder.
|
|
67
59
|
You can find the details about how resolution works in the [resolve-dat-path](https://github.com/RangerMauve/resolve-dat-path/blob/master/index.js#L3) module.
|
|
68
60
|
|
|
69
|
-
`NAME` can either be the
|
|
70
|
-
|
|
71
|
-
The response headers will contain `X-Blocks` for the number of blocks of data this file represents on disk, and `X-Blocks-Downloaded` which is the number of blocks from this file that have been downloaded locally.
|
|
72
|
-
|
|
73
|
-
### `fetch('hyper://NAME/.well-known/dat', {method: 'GET'})`
|
|
74
|
-
|
|
75
|
-
This is used by the dat-dns module for resoving dns domains to `dat://` URLs.
|
|
76
|
-
|
|
77
|
-
This will return some text which will have a `dat://` URL of your archive, followed by a newline and a TTL for the DNS record.
|
|
61
|
+
`NAME` can either be the 52 character [z32 encoded](https://github.com/mafintosh/z32) key for a Hyperdrive or Hypercore , or a domain to parse with the [DNSLink](https://www.dnslink.io/) standard.
|
|
78
62
|
|
|
79
63
|
### `fetch('hyper://NAME/example/', {method: 'GET'})`
|
|
80
64
|
|
|
@@ -85,6 +69,7 @@ By default it will return a JSON array of files and folders in that directory.
|
|
|
85
69
|
You can differentiate a folder from files by the fact that it ends with a `/`.
|
|
86
70
|
|
|
87
71
|
You can set the `Accept` header to `text/html` in order to have it return a basic HTML page with links to files and folders in that directory.
|
|
72
|
+
This can be overrided with the `renderIndex` option if you want custom index pages.
|
|
88
73
|
|
|
89
74
|
e.g.
|
|
90
75
|
|
|
@@ -94,112 +79,65 @@ e.g.
|
|
|
94
79
|
|
|
95
80
|
Files in the directory will be listed under their name, sub-directories will have a `/` appended to them.
|
|
96
81
|
|
|
97
|
-
`NAME` can either be the
|
|
82
|
+
`NAME` can either be the 52 character [z32 encoded](https://github.com/mafintosh/z32) key for a Hyperdrive or Hypercore , or a domain to parse with the [DNSLink](https://www.dnslink.io/) standard.
|
|
98
83
|
|
|
99
84
|
### `fetch('hyper://NAME/example/?noResolve', {method: 'GET'})`
|
|
100
85
|
|
|
101
86
|
Adding `?noResolve` to a URL will prevent resolving `index.html` files and will attempt to load the path as is.
|
|
102
87
|
This can be useful for list files in a directory that would normally render as a page.
|
|
103
88
|
|
|
104
|
-
`NAME` can either be the
|
|
89
|
+
`NAME` can either be the 52 character [z32 encoded](https://github.com/mafintosh/z32) key for a Hyperdrive or Hypercore , or a domain to parse with the [DNSLink](https://www.dnslink.io/) standard.
|
|
90
|
+
|
|
91
|
+
### `fetch('hyper://localhost/?key=NAME', {method: 'POST'})`
|
|
105
92
|
|
|
106
|
-
|
|
93
|
+
In order to create a writable Hyperdrive with its own URL, you must first generate a keypair for it.
|
|
107
94
|
|
|
108
|
-
|
|
95
|
+
`NAME` can be any alphanumeric string which can be used for key generation in [Corestore](https://github.com/holepunchto/corestore).
|
|
109
96
|
|
|
110
|
-
|
|
97
|
+
The response body will contain a `hyper://` URL with the new Hyperdrive.
|
|
111
98
|
|
|
112
|
-
|
|
113
|
-
The `data` for the event will contain the version at the time of the change.
|
|
99
|
+
You can then use this with `PUT`/`DELETE` requests.
|
|
114
100
|
|
|
115
|
-
|
|
101
|
+
Note that this is only available with the `writable: true` flag.
|
|
116
102
|
|
|
117
|
-
|
|
103
|
+
### `fetch('hyper://localhost/?key=NAME', {method: 'GET'})`
|
|
118
104
|
|
|
119
|
-
|
|
105
|
+
If you want to resolve the public key URL of a previously created Hyperdrive, you can do this with the `GET` method on the key creation URL.
|
|
120
106
|
|
|
121
|
-
|
|
107
|
+
`NAME` can be any alphanumeric string which can be used for key generation in [Corestore](https://github.com/holepunchto/corestore).
|
|
108
|
+
|
|
109
|
+
The response body will contain a `hyper://` URL with the new Hyperdrive.
|
|
110
|
+
|
|
111
|
+
You can then use this with `PUT`/`DELETE` requests.
|
|
112
|
+
|
|
113
|
+
Note that this is only available with the `writable: true` flag.
|
|
122
114
|
|
|
123
115
|
### `fetch('hyper://NAME/example.txt', {method: 'PUT', body: 'Hello World'})`
|
|
124
116
|
|
|
125
117
|
You can add files to archives using a `PUT` method along with a `body`.
|
|
126
118
|
|
|
127
|
-
The `body` can be
|
|
119
|
+
The `body` can be any of the options supported by the Fetch API such as a `String`, `Blob`, `FormData`, or `ReadableStream`.
|
|
128
120
|
|
|
129
|
-
`NAME` can either be the
|
|
121
|
+
`NAME` can either be the 52 character [z32 encoded](https://github.com/mafintosh/z32) key for a Hyperdrive or Hypercore , or a domain to parse with the [DNSLink](https://www.dnslink.io/) standard.
|
|
130
122
|
|
|
131
|
-
|
|
123
|
+
Note that this is only available with the `writable: true` flag.
|
|
132
124
|
|
|
133
125
|
### `fetch('hyper://NAME/folder/', {method: 'PUT', body: new FormData()})`
|
|
134
126
|
|
|
135
127
|
You can add multiple files to a folder using the `PUT` method with a [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) body.
|
|
136
128
|
|
|
137
|
-
You can [append](https://developer.mozilla.org/en-US/docs/Web/API/FormData) to a FormData with `formData.append(
|
|
129
|
+
You can [append](https://developer.mozilla.org/en-US/docs/Web/API/FormData) to a FormData with `formData.append('file', content, 'filename.txt')` where `fieldname` gets ignored (use something like `file`?) the `content` can either be a String, Blob, or some sort of stream.
|
|
138
130
|
The `filename` will be the filename within the directory that gets created.
|
|
139
131
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
### `fetch('hyper://NAME/example.txt', {method: 'DELETE'})`
|
|
143
|
-
|
|
144
|
-
You can delete a file in an archive by using the `DELETE` method.
|
|
145
|
-
|
|
146
|
-
You cannot delete directories if they are not empty.
|
|
147
|
-
|
|
148
|
-
`NAME` can either be the 64 character hex key for an archive, a domain to parse with [dat-dns](https://www.npmjs.com/package/dat-dns), or a name for an archive which allows you to write to it.
|
|
149
|
-
|
|
150
|
-
### `fetch('hyper://NAME/example.txt', {method: 'GET', headers: {'x-download': 'cache'}})`
|
|
151
|
-
|
|
152
|
-
You can download a file or an entire folder to the local cache using the `x-download` header set to `cache` in a `GET` request.
|
|
153
|
-
|
|
154
|
-
`NAME` can either be the 64 character hex key for an archive, a domain to parse with [dat-dns](https://www.npmjs.com/package/dat-dns), or a name for an archive which allows you to write to it.
|
|
155
|
-
|
|
156
|
-
You can use `/` for the path to download the entire contents
|
|
132
|
+
Note that you must use the name `file` for uploaded files.
|
|
157
133
|
|
|
158
|
-
|
|
134
|
+
`NAME` can either be the 52 character [z32 encoded](https://github.com/mafintosh/z32) key for a Hyperdrive or Hypercore , or a domain to parse with the [DNSLink](https://www.dnslink.io/) standard.
|
|
159
135
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
This is like the opposite of using `x-download` to download data.
|
|
163
|
-
|
|
164
|
-
This does not delete data, it only deletes the cached data from disk.
|
|
165
|
-
|
|
166
|
-
`NAME` can either be the 64 character hex key for an archive, a domain to parse with [dat-dns](https://www.npmjs.com/package/dat-dns), or a name for an archive which allows you to write to it.
|
|
167
|
-
|
|
168
|
-
You can use `/` for the path to clear all data for the archive.
|
|
169
|
-
|
|
170
|
-
### `fetch('hyper://NAME/$/tags/TAG_NAME', {method: 'PUT'})`
|
|
171
|
-
|
|
172
|
-
You can add a tag a version of the archive with a human readable name (like SPAGHETTI), in the example represented as `tagName` by doing a PUT into the special `/$/tags/` folder.
|
|
173
|
-
|
|
174
|
-
Afterwards you can load the archive at that given version with `hyper://NAME+TAG_NAME`.
|
|
175
|
-
|
|
176
|
-
E.g.
|
|
177
|
-
|
|
178
|
-
`PUT hyper://123kjh213kjh123/$/tags/v4.20`
|
|
179
|
-
`GET hyper://123kjh213kjh123+v4.20/example.txt`
|
|
180
|
-
|
|
181
|
-
### `fetch('hyper://NAME/$/tags/', {method: 'GET'})`
|
|
182
|
-
|
|
183
|
-
You can get a list of all tags by doing a `GET` on the `/$/tags/` folder.
|
|
184
|
-
|
|
185
|
-
The response will be a JSON object which maps tag names to archive versions.
|
|
186
|
-
|
|
187
|
-
Use `await response.json()` to get the data out.
|
|
188
|
-
|
|
189
|
-
e.g.
|
|
190
|
-
|
|
191
|
-
```json
|
|
192
|
-
{
|
|
193
|
-
"tagOne": 1,
|
|
194
|
-
"example": 100000
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### `fetch('hyper://NAME/$/tags/TAG_NAME', {method: 'DELETE'})`
|
|
136
|
+
### `fetch('hyper://NAME/example.txt', {method: 'DELETE'})`
|
|
199
137
|
|
|
200
|
-
You can delete a
|
|
138
|
+
You can delete a file or directory tree in a Hyperdrive by using the `DELETE` method.
|
|
201
139
|
|
|
202
|
-
|
|
140
|
+
`NAME` can either be the 52 character [z32 encoded](https://github.com/mafintosh/z32) key for a Hyperdrive or Hypercore , or a domain to parse with the [DNSLink](https://www.dnslink.io/) standard.
|
|
203
141
|
|
|
204
142
|
### `fetch('hyper://NAME/$/extensions/')`
|
|
205
143
|
|
|
@@ -207,33 +145,46 @@ You can list the current [hypercore extensions](https://github.com/hypercore-pro
|
|
|
207
145
|
|
|
208
146
|
This will give you a directory listing with the names of all the extensions.
|
|
209
147
|
|
|
148
|
+
Note that this requires the `extensionMessages: true` flag.
|
|
149
|
+
|
|
210
150
|
### `fetch('hyper://NAME/$/extensions/EXTENSION_NAME')`
|
|
211
151
|
|
|
212
152
|
You can list the peers that you are replication with which have registered this extension by doing a `GET` to the directory for the extension.
|
|
213
153
|
|
|
214
154
|
This is also how you can register an extension that hasn't been registered yet.
|
|
215
155
|
|
|
216
|
-
The list will be a JSON array with objects that contain the fields `remotePublicKey
|
|
156
|
+
The list will be a JSON array with objects that contain the fields `remotePublicKey` and `remoteHost`.
|
|
157
|
+
|
|
158
|
+
Note that this requires the `extensionMessages: true` flag.
|
|
217
159
|
|
|
218
160
|
### `fetch('hyper://NAME/$/extensions/', {headers: {'Accept': 'text/event-stream'}})`
|
|
219
161
|
|
|
220
162
|
Using the `text/event-stream` content type in the `Accept` header will get back an event stream with the extension events.
|
|
221
163
|
|
|
164
|
+
You can get the browser's [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) over hypercore-fetch by using the [@rangermauve/fetch-to-eventsource](https://github.com/RangerMauve/fetch-event-source) module.
|
|
165
|
+
|
|
222
166
|
The `event` will be the name of the extension you got the data for, the `id` (accessible by `e.lastEventId` in EventSource) will be set to the ID of the peer that sent it.
|
|
223
167
|
|
|
224
168
|
Only extension messages that have been queried before via a `GET` to the EXTENSION_NAME will be visible in this stream.
|
|
225
169
|
|
|
226
170
|
There are also two special events: `peer-open` which gets emitted whena new peer has connected, and `peer-remove` which gets emitted when an existing peer disconnects.
|
|
227
171
|
|
|
172
|
+
Note that this requires the `extensionMessages: true` flag.
|
|
173
|
+
|
|
228
174
|
### `fetch('hyper://NAME/$/extensions/EXTENSION_NAME', {method: 'POST', body: 'Example'})`
|
|
229
175
|
|
|
230
176
|
You can broadcast an extension message to all peers that are replicating that extension type with a `POST` to the extension's URL.
|
|
231
177
|
|
|
232
|
-
The `body` of the request will be used as the payload.
|
|
178
|
+
The `body` of the request will be used as the payload.
|
|
179
|
+
Please note that only utf8 encoded text is currently supported due to limitations of the event-stream encoding.
|
|
180
|
+
|
|
181
|
+
Note that this requires the `extensionMessages: true` flag.
|
|
233
182
|
|
|
234
183
|
### `fetch('hyper://NAME/$/extensions/EXTENSION_NAME/REMOTE_PUBLIC_KEY', {method: 'POST', body: 'Example'})`
|
|
235
184
|
|
|
236
185
|
You can send an extension message to a specific peer by doing a `POST` to the extension with their remote public key ID.
|
|
237
186
|
|
|
238
|
-
The `body` of the request will be used as the payload.
|
|
187
|
+
The `body` of the request will be used as the payload.
|
|
188
|
+
Please note that only utf8 encoded text is currently supported due to limitations of the event-stream encoding.
|
|
239
189
|
|
|
190
|
+
Note that this requires the `extensionMessages: true` flag.
|