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.
File without changes
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
- const fetch = require('hypercore-fetch')()
8
+ import makeHyperFetch from 'hypercore-fetch'
9
+ import * as SDK from 'hyper-sdk'
9
10
 
10
- const someURL = `hyper://blog.mauve.moe`
11
+ // Create in-memory hyper-sdk instance
12
+ const sdk = await SDK.create({storage: false})
11
13
 
12
- const response = await fetch(`${someURL}/index.json`)
14
+ const fetch = await makeFetch({
15
+ sdk: true,
16
+ writable: true
17
+ })
13
18
 
14
- const json = await response.json()
19
+ const someURL = `hyper://TODO_REAL_URL_HERE_PLEASE`
15
20
 
16
- console.log(json)
17
- ```
21
+ const response = await fetch(someURL)
18
22
 
19
- You can also use the bundled CLI
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
- ### `makeFetch({Hyperdrive, resolveURL, base, session, writable}) => fetch()`
30
+ ### `makeHyperFetch({sdk, writable=false, extensionMessages = writable, renderIndex}) => fetch()`
34
31
 
35
32
  Creates a hypercore-fetch instance.
36
33
 
37
- The `base` parameter can be used to specify what the base URL is for relative paths like `fetch('./dat.json')`.
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
- If you don't want to allow write access to archives, pass in `writable: false`.
36
+ The `writable` flag toggles whether the `PUT`/`POST`/`DELETE` methods are available.
45
37
 
46
- Typically, you don't need to pass in any of these and they're there for more advanced users.
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
- After you've created it, `fetch` will be have like it does in [browsers](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
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
- ### `await fetch.close()`
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
- Each response will also contain the `Allow` header of all the methods currently allowed. If the archive is writable, this will contain `PUT`.
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
- There is also an `ETag` header which will be a JSON string containging the drive's current `version`. This will change only when the drive has gotten an update of some sort and is monotonically incrementing.
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 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.
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 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.
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 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.
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
- 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.
93
+ In order to create a writable Hyperdrive with its own URL, you must first generate a keypair for it.
107
94
 
108
- ### `fetch('hyper://NAME/', {headers: {'Accept': 'text/event-stream'}})`
95
+ `NAME` can be any alphanumeric string which can be used for key generation in [Corestore](https://github.com/holepunchto/corestore).
109
96
 
110
- Using the `text/event-stream` content type in the `Accept` header will get back an event stream full of `change` events for every time a file at that path changes.
97
+ The response body will contain a `hyper://` URL with the new Hyperdrive.
111
98
 
112
- This can be useful if you want to trigger a download every time a file changes.
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
- This stream of data can be used with the `EventSource` in browsers.
101
+ Note that this is only available with the `writable: true` flag.
116
102
 
117
- Currently there's no way to watch for changes to specific files, so that should be handled at the application level.
103
+ ### `fetch('hyper://localhost/?key=NAME', {method: 'GET'})`
118
104
 
119
- You can also watch for the `download` and `upload` events which will be emitted whenever you download or upload blocks from the hyperdrive.
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
- The `data` for the event will contain a JSON encoded object with the `index` of the block, and the `source` which is the public key of the hypercore (either the metadata of the hyperdrive, or the content feed).
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 either a `String`, an `ArrayBuffer`, a `Blob`, a WHATWG `ReadableStream`, a Node.js `Stream`, or electron's [UploadData](https://www.electronjs.org/docs/api/structures/upload-data) object (make sure to specify the `session` argument in the `makeFetch` function for electron support).
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 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.
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
- Your `NAME` will likely be a `name` in most cases to ensure you have a writeable archive.
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(fieldname, content, 'filename.txt')` where `fieldname` gets ignored (use something like `file`?) the `content` can either be a String, Blob, or some sort of stream.
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
- `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.
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
- ### `fetch('hyper://NAME/example.txt', {method: 'DELETE', headers: {'x-clear': 'cache'}})`
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
- You can clear the data stored in the local cache for a file or folder using the `x-clear` header set to `cache` in a `DELETE` request..
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 given tag with the `DELETE` method on a name within the special `$/tags/` folder.
138
+ You can delete a file or directory tree in a Hyperdrive by using the `DELETE` method.
201
139
 
202
- Specify the tag you want in the URL, and it'll be removed from the tags list.
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`, `remoteAddress`, `remoteType`, and `stats`
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. Please note that only utf8 encoded text is currently supported due to limitations of the event-stream encoding.
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. Please note that only utf8 encoded text is currently supported due to limitations of the event-stream encoding.
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.