Skip to content

Commit e7b307a

Browse files
committed
Added write support for hypercore
1 parent de3e482 commit e7b307a

File tree

6 files changed

+87
-18
lines changed

6 files changed

+87
-18
lines changed

README.md

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ Download an installer from the [releases page](https://github.com/RangerMauve/ag
4747
- [x] `hyper://`
4848
- Able to read from archives
4949
- Able to resolve `dat-dns` domains
50+
- Able to write create and modify archives
5051
- [x] `dat://`
5152
- Able to read from archives
5253
- Able to resovle `dat-dns` domains
53-
- 😢 No `DatArchive` support.
54-
- A bunch of websites are probably broken.
54+
- No `DatArchive` support.
5555
- [ ] ipfs
5656
- Working on reading from URLs
5757

@@ -86,6 +86,53 @@ You can set these to whatever you want and it will override the defaults listed
8686

8787
Check out `app/actions.js` for a full list of action names since some of them don't have keyboard shortcuts by default.
8888

89+
## Fetch API for `hyper://`
90+
91+
### `fetch('hyper://NAME/example.txt', {method: 'GET'})`
92+
93+
This will attempt to load `example.txt` from the archive labeled by `NAME`.
94+
95+
It will also load `index.html` files automatically for a folder.
96+
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.
97+
98+
`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.
99+
100+
### `fetch('hyper://NAME/index.json', {method: 'GET'})`
101+
102+
The `index.json` file is special in that it will be modified to contain some extra parameters in the JSON content.
103+
104+
This extends from the [Index.json Manifest](https://docs.beakerbrowser.com/developers/index.json-manifest) spec in Beaker.
105+
106+
`url` will get set to the `hyper://` URL of the archive. This will resolve the `NAME` to always be the 64 character hex key.
107+
108+
### `fetch('hyper://NAME/example/', {method: 'GET'})`
109+
110+
When doing a `GET` on a directory, you will get a directory listing.
111+
112+
By default it will render out an HTML page with links to files within that directory.
113+
114+
You can set the `Accept` header to `application/json` in order to have it return a JSON array with file names.
115+
116+
`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.
117+
118+
### `fetch('hyper://NAME/example.txt', {method: 'PUT', body: 'Hello World'})`
119+
120+
You can add files to archives using a `PUT` method along with a `body`.
121+
122+
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).
123+
124+
`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.
125+
126+
Your `NAME` will likely be a `name` in most cases to ensure you have a writeable archive.
127+
128+
### `fetch('hyper://NAME/example.txt', {method: 'DELETE'})`
129+
130+
You can delete a file in an archive by using the `DELETE` method.
131+
132+
You cannot delete directories if they are not empty.
133+
134+
`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.
135+
89136
## Contributing
90137

91138
Feel free to open a Github issue if you wish to tackle one of the items on the roadmap, or message @RangerMauve directly on whatever platform you can find them on.

app/protocols/dat-protocol.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ module.exports = async function createHandler () {
1515
}
1616
const fetch = datFetch({
1717
Hyperdrive,
18-
resolveName
18+
resolveName,
19+
// Even though we could make it mutable, lets keep the legacy code immutable
20+
writable: false
1921
})
2022
return async function protocolHandler ({ url }, sendResponse) {
21-
// console.log('Loading', url)
2223
const response = await fetch(url)
2324

2425
const { status: statusCode, body: data, headers: responseHeaders } = response

app/protocols/hyper-protocol.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,19 @@ const SDK = require('dat-sdk')
33

44
module.exports = async function createHandler () {
55
const sdk = await SDK()
6-
const fetch = datFetch(sdk)
6+
const {Hyperdrive, resovleName} = sdk
7+
const fetch = datFetch({Hyperdrive, resovleName, writable: true})
8+
79
return async function protocolHandler (req, sendResponse) {
8-
const { url, headers: requestHeaders, method } = req
10+
const { url, headers: requestHeaders, method, uploadData } = req
911

1012
console.log(req)
1113

12-
const response = await fetch(url, { headers: requestHeaders, method })
14+
const body = uploadData ? (
15+
uploadData.length > 1 ? uploadData : uploadData[0]
16+
) : null
17+
18+
const response = await fetch(url, { headers: requestHeaders, method, body })
1319

1420
const { status: statusCode, body: data, headers: responseHeaders } = response
1521
const headers = {

app/ui/electron-browser-view.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ class BrowserViewElement extends HTMLElement {
168168
this.addEventListener('focus', () => {
169169
if (this.view) this.view.webContents.focus()
170170
})
171+
172+
window.addEventListener('beforeunload', () => {
173+
if(this.view) this.view.destroy()
174+
})
171175
}
172176

173177
connectedCallback () {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
},
9696
"dependencies": {
9797
"@geut/hyperdrive-promise": "^3.0.1",
98-
"dat-fetch": "^2.3.0",
98+
"dat-fetch": "^3.0.0",
9999
"dat-sdk": "^2.1.0",
100100
"dat-sdk-old": "^1.0.0",
101101
"electron-extensions": "^6.0.4",

yarn.lock

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,18 +2195,17 @@ dat-encoding@^5.0.1:
21952195
dependencies:
21962196
safe-buffer "^5.0.1"
21972197

2198-
dat-fetch@^2.3.0:
2199-
version "2.3.0"
2200-
resolved "https://registry.yarnpkg.com/dat-fetch/-/dat-fetch-2.3.0.tgz#49ba04e837cc16227b0f12de11ab0ea096a1060d"
2201-
integrity sha512-SKn2r6Jbg5fQ5E6Go70vrunvFV0yLBZro4pl/0/nKb8hF1fsI4NrICX2BW1Dsqnx3BAwNEf+tBUccmFbqVIVSQ==
2198+
dat-fetch@^3.0.0:
2199+
version "3.0.0"
2200+
resolved "https://registry.yarnpkg.com/dat-fetch/-/dat-fetch-3.0.0.tgz#ce257aaf60c0590bba36c084c83834f5fa1d65ec"
2201+
integrity sha512-qyT5B6YFAlN8LH7RH1Z/1nCdWgOLwwmUavo3GJp/9eYaJWcw3uexnpg13OflVkZkvnzkFek/NY0pPOe39aRGlA==
22022202
dependencies:
22032203
concat-stream "^2.0.0"
2204-
dat-node "^3.5.15"
2205-
dat-sdk "^2.0.0"
22062204
end-of-stream-promise "^1.0.0"
22072205
fetch-headers "^2.0.0"
2206+
fetch-request-body-to-stream "^1.0.0"
22082207
mime "^2.4.4"
2209-
node-fetch "^2.6.0"
2208+
pump-promise "^1.0.0"
22102209
range-parser "^1.2.1"
22112210
resolve-dat-path "^1.2.0"
22122211

@@ -2227,7 +2226,7 @@ dat-link-resolve@^2.3.0:
22272226
debug "^4.1.1"
22282227
simple-get "^3.0.3"
22292228

2230-
dat-node@^3.5.15, dat-node@^3.5.3:
2229+
dat-node@^3.5.3:
22312230
version "3.5.15"
22322231
resolved "https://registry.yarnpkg.com/dat-node/-/dat-node-3.5.15.tgz#8dd07ef353003ab1b2214487ffce486bd286cc0e"
22332232
integrity sha512-hL7JlZr17x25t+RHJN5saBEOn/fZFt6d8FyS2p+XxnVIQug9bGjnbAXdWbRVO9UJLfnZyKfB23wjvHND1015+g==
@@ -2280,7 +2279,7 @@ dat-sdk@^1.0.3:
22802279
universal-prompt "^1.0.0"
22812280
url-parse "^1.4.7"
22822281

2283-
dat-sdk@^2.0.0, dat-sdk@^2.1.0:
2282+
dat-sdk@^2.1.0:
22842283
version "2.1.0"
22852284
resolved "https://registry.yarnpkg.com/dat-sdk/-/dat-sdk-2.1.0.tgz#23af231f02b5f9d09f74d32977d14dec74326e2c"
22862285
integrity sha512-AZDKfCjSQu2Exb3J1P4MK2zg+zordeMbOmSCexKdMpKnOafin/nAbHoPQ/74JKi+PXKs4f66+mEmcoqAYla0sw==
@@ -3604,6 +3603,11 @@ fetch-headers@^2.0.0:
36043603
resolved "https://registry.yarnpkg.com/fetch-headers/-/fetch-headers-2.0.0.tgz#bab7531c39b3d72d21ac189f179756f08541cf55"
36053604
integrity sha1-urdTHDmz1y0hrBifF5dW8IVBz1U=
36063605

3606+
fetch-request-body-to-stream@^1.0.0:
3607+
version "1.0.0"
3608+
resolved "https://registry.yarnpkg.com/fetch-request-body-to-stream/-/fetch-request-body-to-stream-1.0.0.tgz#9c65db075d909c9dec20d6f2cc041d61a795896b"
3609+
integrity sha512-CuB3VWmpgb5nRS4K6OJ7ybQJBUM79G6Q6cm3kj+U/UvPV3Jxl6gupdpIF9r3YfLe05BEFKnT0MtOhjGYNTZ3Nw==
3610+
36073611
figures@^3.0.0:
36083612
version "3.2.0"
36093613
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
@@ -8386,7 +8390,14 @@ public-encrypt@^4.0.0:
83868390
randombytes "^2.0.1"
83878391
safe-buffer "^5.1.2"
83888392

8389-
pump@^1.0.2, pump@^1.0.3:
8393+
pump-promise@^1.0.0:
8394+
version "1.0.0"
8395+
resolved "https://registry.yarnpkg.com/pump-promise/-/pump-promise-1.0.0.tgz#1a10f3fcb9382fbdcddb21b3b52d5340a5f1f9f7"
8396+
integrity sha1-GhDz/Lk4L73N2yGztS1TQKXx+fc=
8397+
dependencies:
8398+
pump "^1.0.1"
8399+
8400+
pump@^1.0.1, pump@^1.0.2, pump@^1.0.3:
83908401
version "1.0.3"
83918402
resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954"
83928403
integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==

0 commit comments

Comments
 (0)