Table of Contents:
There are three core API's of hyper-dns, each optimized for a different usecases:
-
resolveProtocol(protocol, domain)
→ For a simple lookup of one particular protocolconst { resolveProtocol } = require('hyper-dns') const key = await resolveProtocol('dat', 'dat-ecosystem.org')
-
resolve(domain)
→ For finding out what protocols are supported by a given domainconst { resolve } = require('hyper-dns') const keys = await resolve('dat-ecosystem.org') // keys contains all supported protocols with null or the key value
-
resolveURL(url)
→ If you have a given url, locate the best matching decentralized keyconst { resolveURL } = require('hyper-dns') try { const url = resolveURL('dat-ecosystem.org/some/path?query') url.protocol // to contain the best matching protocol for the given domain url.hostname // to contain the key, if a decentralized key was found url.pathname // other url properties exist as well. } catch (error) { /* An error may be thrown if no protocol can be matched! */ }
const { resolveProtocol, resolve, resolveURL } = require('hyper-dns')
Returns either null
if no key could be found or a string
containing the key.
protocol
name of the protocol or a protocol implementationname
name to be looked upopts.dohLookups
(optional) array of https endpoints to look up DNS recordsopts.userAgent
(optional)string
ornull
of the user-agent to be used during https requestsopts.cache
(Cache, optional, default caching logic differs by runtime) Caching implementation to be used during execution, set tonull
orundefined
to prevent caching. (see Caching)opts.ignoreCache
(boolean, default=false
) Can be used to ignore the content of the cache. Note: this is different from settingopts.cache = null
in that a result will be written to cache even ifignoreCache
is true.opts.ignoreCachedMiss
(boolean, default=false
) Will retry to resolve the a name only if a miss was cached.opts.context
(optional) Context to be used for protocol execution. (see Architecture Guide)opts.ttl
(defaults to3600
= 1 hour) Defaultttl
in seconds to be used if protocol doesn't specify attl
opts.minTTL
(defaults to30
= 1/2 min) Minimumttl
in seconds that can be used for records, good to prevent rapid cache invalidationopts.maxTTL
(defaults to604800
= 1 week) Maximumttl
to store records for, good to indicator for stale requests.opts.corsWarning
handler with signature(name: string, url: string) => void
to be called if a http request has been noticed to have not any cors headers set, set tofalsish
to prevent any message.opts.localPort
(optional) port used when trying to lookupwell-known
entries on a local domain.opts.protocols
(optional) list of supported protocols, defaults to common list of supported protocols. (see Protocol Guide)
Note: resolveProtocol.DEFAULTS
contains the object with all defaults.
About the .corsWarning option: Some protocols support the lookup of https resources to identify a name. This is problematic when you try to run hyper-dns
in a browser if that domain didn't set the CORS header access-control-allow-origin = *
, as it will not notice why a request failed. In order for the users of hyper-dns
to quickly notice if that is the case, it will show a warning on the command line.
Returns an object with the resolveProtocol()
results for all given protocols, like:
{
dat: 'ae14a...fc651',
hyper: null,
cabal: '3bea1...8569a',
// The protocols are derived from the `opts.protocols` option
}
opts
The same options as forresolveProtocols()
apply.
Note: resolve.DEFAULTS
contains the object with all defaults.
opts
uses the same options asresolveProtocol
but adds:opts.protocolPreference
(optional: Array of names) order of protocols to look up with preferenceopts.fallbackProtocol
(default: https) protocol to be used if no other protocol can be found.
Note: resolveURL.DEFAULTS
contains the object with all defaults.
Returns a LightURL instance that contains all properties of the input url in a readable manner.
The resolveURL
API has two different modes that behave slightly different:
-
If you pass in a URL like
hyper://dat-ecosystem.org
with a full protocol specified, it will look up only thehyper
protocol and throw arequire('hyper-dns').RecordNotFoundError
if no record for that protocol could be found.try { const url = await resolveURL('hyper://dat-ecosystem.org') url.href === 'hyper://ae14a...fc651' // if a hyper record was found } catch (err) { err.code === 'ENOTFOUND' // if no HYPER record was found }
-
If you pass in a URL like
dat-ecosystem.org
it will try, with preference, all given protocols and use the first result as result. If non of the protocols could be found it will fall-back toopts.fallbackProtocol
.const url = await resolveURL('dat-ecosystem.org') url.href === 'hyper://ae14a...fc651' // if a hyper record was found url.href === 'https://dat-ecosystem.org' // if no record was found
resolveURL() will work for local domains if the protocol supports it! In this case it fill forward the port specified to as opts.localPort
if it hasn't been overwritten.
const { cache, createCacheSQLite, createCacheLRU } = require('hyper-dns')
All Cache
instances have to implement a common interface:
interface Cache {
get (
protocol: string,
name: string
): Promise<
undefined // If no cache entry was found
| {
key:
string
| null // Indicating a cache-miss! (Needs to be stored)
,
expires: number
}
>
set (
protocol: string,
name: string,
entry: { key: string | null, expires: number }
): Promise<void>
}
The result of get()
operations will be sanitizied.
The cache holds the instance for the default opts.cache
option to be used by resolveProtocol
, resolve
or resolveURL
.
In browsers this will default to a lru-cache
and in node to the sqlite-cache
.
This is the default cache when using
hyper-dns
in the browser.
opts.maxSize
(number, default=1000) Amount of entries to keep in the cache.
The LRU cache uses the quick-lru paging mechanism to keep entries in memory
This is only available in Node.js! With its default options, it is also the default cache of
resolve
operations in Node.js! Using this operation in the browser will cause an error!
opts.file
(string, default=see below) file path for the cacheopts.table
(string, default=names) database table to store cache entries inopts.maxSize
(number, default=1000) amount of domains to keep in memoryopts.autoClose
(number, default=5000) milliseconds of inactivity before the SQLite instance is closed. Set autoClose to 0 to keep the database open.opts.maxWalSize
(number, default=10485760) max size that triggers a wal_checkpoint operationopts.walCheckInterval
(number, default 5000) interval to check the wal size
The default file
for storing data is system specific and we use the env-paths library to figure out where it is stored.
envPaths('hyper-dns', { suffix: '' }).cache + '/cache.db'
↑ This is the pattern for the default path.
- It will start a sqlite instance on demand and will close it after the specified
.opts.autoClose
timeout. - It will keep once requested entries in a
lru
cache with the provided.maxSize
to reduceI/O
. - It uses the
journal_mode = WAL
which is done for better performance.
Note: This implementation uses the better-sqlite3 library.
const { protocols } = require('hyper-dns')
protocols.dat // certainly supported protocol
Object containing all default supported protocols. More about this in the Protocol Guide.
const { createResolveContext } = require('hyper-dns')
createResolveContext
can be used to create Context
implementations for the opts.context
option of resolve...()
operations. (more in the Protocol Guide)
The following options form resolveProtocol(opts) are used: ttl
, corsWarning
, userAgent
, dohLookups
, localPort
. More about these options in the resolveProtocol(opts)
documentation.
signal
(AbortSignal, optional) - an abort signal to be used to cancel all protocol requests.
Initially the URL implementation was supposed to be used. Sadly browsers and node.js are not 100% compatible and furthermore decentralized web protocols also have an additional "version" specifier.
This is why hyper-dns
provides a custom LightURL
, named to prevent confusion with the regular URL
.
const { LightURL } = require('hyper-dns')
const url = new LightURL('dat://dat-ecosystem.org/organization')
url.protocol == 'dat://'
url.hostname == 'dat-ecosystem.org'
url.pathname == '/organization'
url.href == 'dat://dat-ecosystem.org/organization'
url
(string) the url, or path segment to be used to create the stringbase
(string or LightURL instance, optional)
The biggest incompatibility to URL is that path names and query strings are not uri encoded but kept in their original form!
Important Note: Instances are frozen upon creation. This means you can't modify properties as you usually would with URL
instances to reduce complexity.
Another difference is the additional versionedHref
property which contains the parsed version as well!
const { LightURL, resolveURL } = require('hyper-dns')
const input = '../démonstration.html'
const base = await resolveURL('dat://dat-ecosystem.org+1234/base/index.html')
// Getting the relative path for a dat URL
const url = new LightURL(input, base)
// To stay compatible the .href doesn't contain a version
url.href === 'dat://dat-ecosystem.org/démonstration.html'
// But the new property versionedHref contains everything
url.versionedHref === 'dat://dat-ecosystem.org+1234/démonstration.html'