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.
protocolname of the protocol or a protocol implementationnamename to be looked upopts.dohLookups(optional) array of https endpoints to look up DNS recordsopts.userAgent(optional)stringornullof 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 tonullorundefinedto 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 = nullin that a result will be written to cache even ifignoreCacheis 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) Defaultttlin seconds to be used if protocol doesn't specify attlopts.minTTL(defaults to30= 1/2 min) Minimumttlin seconds that can be used for records, good to prevent rapid cache invalidationopts.maxTTL(defaults to604800= 1 week) Maximumttlto store records for, good to indicator for stale requests.opts.corsWarninghandler with signature(name: string, url: string) => voidto be called if a http request has been noticed to have not any cors headers set, set tofalsishto prevent any message.opts.localPort(optional) port used when trying to lookupwell-knownentries 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
}optsThe same options as forresolveProtocols()apply.
Note: resolve.DEFAULTS contains the object with all defaults.
optsuses the same options asresolveProtocolbut 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.orgwith a full protocol specified, it will look up only thehyperprotocol and throw arequire('hyper-dns').RecordNotFoundErrorif 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.orgit 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-dnsin 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
resolveoperations 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.autoClosetimeout. - It will keep once requested entries in a
lrucache with the provided.maxSizeto reduceI/O. - It uses the
journal_mode = WALwhich is done for better performance.
Note: This implementation uses the better-sqlite3 library.
const { protocols } = require('hyper-dns')
protocols.dat // certainly supported protocolObject 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'