If you find any discrepancies please add an issue here.
##General API notes and conventions
We use a naming convention that anything starting “p_” returns a promise so you know to "await" it if you want a result.
Ideally functions should take a String, Buffer or where applicable Object as parameters with automatic conversion.
And anything that takes a URL should take either a string or parsed URL object.
The verbose parameter is a boolean that is an indicator of a need to output to the console. Normally it will be passed down to called functions and default to false.
Note that example_block.html collects this from the URL and passes it to the library,
which is intended to be a good way to see what is happening.
Note: I am gradually (March2018) changing the API to take an opts {} dict which includes verbose as one field. This process is incomplete, but I’m happy to see it accelerated if there is any code built on this, just let mitra@archive.org know.
##Overview
The Transport layer provides a layer that is intended to be independent of the underlying storage/transport mechanism.
Documents are retrieved by a list of URLs, where in each URL, the left side helps identify the transport, and the right side can be the internal format of the underlying transport BUT must be identifiable e.g. ipfs:/ipfs/12345abc or https://gateway.dweb.me/content/contenthash/Qm..., this format will evolve if a standard URL for the decentralized space is defined.
The actual urls used might change as the Decentralized Web universe reaches consensus (for example dweb:/ipfs/Q123 is an alternative seen in some places)
This spec will in the future probably add a variation that sends events as the block is retrieved to allow for streaming.
##Transport Class
Fields|
:---|---
options | Holds options passed to constructor
name|Short name of transport e.g. “HTTP”, “IPFS”
supportURLs|Array of url prefixes supported e.g. [‘ipfs’,’http’]
supportFunctions|Array of functions supported on those urls, current (April 2018) full list would be: `['fetch', 'store', 'add', 'list', 'reverse', 'newlisturls', "get", "set", "keys", "getall", "delete", "newtable", "newdatabase", "listmonitor"]`
status|Numeric indication of transport status: Started(0); Failed(1); Starting(2); Loaded(3)
###Setup of a transport
Transport setup is split into 3 parts, this allows the Transports class to do the first phase on all the transports synchronously,
then asynchronously (or at a later point) try and connect to all of them in parallel.
#####static setup0 (options, verbose)
First part of setup, create obj, add to Transports but dont attempt to connect, typically called instead of p_setup if want to parallelize connections. In almost all cases this will call the constructor of the subclass
Should be synchronous and leave `status=STATUS_LOADED`
```
options Object fields including those needed by transport layer
verbose boolean - true for debugging output
Resolves to Instance of subclass of Transport
```
Default options should be set in each transport, but can be overwritten,
for example to overwrite the options for HTTP call it with
Setup a callback called whenever an item is added to a list, typically it would be called immediately after a p_rawlist to get any more items not returned by p_rawlist.
```
url Identifier of list (as used by p_rawlist and "signedby" parameter of p_rawadd
cb(obj) function(obj) Callback for each new item added to the list
Obtain a pair of URLs for a new list. The transport can use information in the cl to generate this or create something random (the former is encouraged since it means repeat tests might not generate new lists). Possession of the publicurl should be sufficient to read the list, the privateurl should be required to read (for some transports they will be identical, and higher layers should check for example that a signature is signed.
```
cl CommonList instance that can be used as a seed for the URL
verbose boolean - True for debugging output
Returns [privateurl, publicurl]
```
###Transport: Support for KeyValueTable
#####async p_newdatabase(pubkey, {verbose}) {
Create a new database based on some existing object
```
pubkey: Something that is, or has a pubkey, by default support Dweb.PublicPrivate, KeyPair
or an array of strings as in the output of keypair.publicexport()
returns: {publicurl, privateurl} which may be the same if there is no write authentication
```
#####async p_newtable(pubkey, table, {verbose}) {
Create a new table,
```
pubkey: Is or has a pubkey (see p_newdatabase)
table: String representing the table - unique to the database
returns: {privateurl, publicurl} which may be the same if there is no write authentication
`fetch.range` i.e. it will fetch a range of bytes if specified in {start, end} to p_rawfetch()
###Other useful functions
The HTTP Transport can be used for utility functions as well as via the Transports interface.
e.g. Transports.http().p_httpfetch("http://foo.com/bar", {method: 'GET'} )
#####p_httpfetch(url, init, verbose)
Fetch a url.
If the result
url: HTTP or HTTPS url
init: Init parameter to fetch (see for docs)
verbose: boolean for debugging
returns: Depends on mime type;
If application/json returns a Object,
If text/* returns text
Oherwise Buffer
#####p_GET(url, {start, end, verbose})
Shortcut to do a HTTP/POST get, sets `mode: cors, redirect: follow, keepalive: true, cache: default`
start: First byte to retrieve
end: Last byte to retrieve (undefined means end of file)
Note that it passes start and end as the Range header, most servers support it,
but it does not (yet) explicitly check the result.
#####p_POST(url, type, data, verbose)
Shortcut to do a HTTP/HTTPS POST. sets same options as p_GET
data: Data to send to fetch, typically the body,
type: Currently not passed as header{Content-type} because fetch appears to ignore it.
##TransportIPFS
A subclass of Transport for handling IPFS connections
The code works, however there are a number of key IPFS issues <TODOdocumenthere> that mean that not
every IPFS `CID` will be resolvable, since:
* IPFS javascript doesnt yet support CIDv1 so can't recognize the CIDs starting with "z"
* WSS only can find blocks known about by peers connected to the same star.
* urlstore on the archive.org gateway is not advertising the files in a way that WSS finds them.
* Protocol Labs (IPFS)) have been unable to get WSS to connect to our gateway machine
Other parts of this code work but just note that usage should be aware that problems may be to do
with your specific configuration and use cases.
It looks at `options { ipfs }` for its options.
Option|Default|Meaning
------|-------|-------
repo|/tmp/dweb_ipfsv2700|Local file system (only relevant if running under Node)
config Addresses |Swarm: ['/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star']}|Connects currently (April 2018) to ipfs.io, this may change.
EXPERIMENTAL pubsub|true|Requires pubsub for list monitoring etc
supportURLS = `ipfs:*` (TODO: may in the future support `dweb:/ipfs/*`)
SupportFunctions (note YJS uses IPFS and supports some other functions):
`fetch, store`
SupportFeatures:
fetch.range Not supported (currently April 2018))
Currently there is code for p_f_createReadStream. It works but because of some other IPFS issues is disabled.
##TransportYJS
A subclass of Transport for handling YJS connections.
Uses IPFS as its transport (other transports are possible with YJS and may be worth experimenting with)
supportURLS = `yjs:*` (TODO: may in the future support `dweb:/yjs/*`)
supportFunctions (note YJS uses IPFS and supports some other functions):