bare-addon-resolve
Low-level addon resolution algorithm for Bare
v1.11.0bare-addon-resolve — Low-level addon resolution algorithm for Bare.
npm i bare-addon-resolveUsage
For synchronous resolution:
const resolve = require('bare-addon-resolve')
function readPackage(url) {
// Read and parse `url` if it exists, otherwise `null`
}
for (const resolution of resolve('./addon', new URL('file:///directory/'), readPackage)) {
console.log(resolution)
}For asynchronous resolution:
const resolve = require('bare-addon-resolve')
async function readPackage(url) {
// Read and parse `url` if it exists, otherwise `null`
}
for await (const resolution of resolve('./addon', new URL('file:///directory/'), readPackage)) {
console.log(resolution)
}API
Functions
resolve
resolve(specifier: string, parentURL: URL, readPackage?: (url: URL) => JSON | null): Iterable<URL>Resolve specifier relative to parentURL, which must be a WHATWG URL instance. readPackage is called with a URL instance for every package manifest to be read and must either return the parsed JSON package manifest, if it exists, or null. If readPackage returns a promise, synchronous iteration is not supported. To set options, pass a ResolveOptions object between parentURL and readPackage: resolve(specifier, parentURL, opts, readPackage).
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
specifier | string | — | The module specifier to resolve. |
parentURL | URL | — | The URL to resolve specifier relative to. |
readPackage? | (url: URL) => JSON | null | — | Called with the URL of each package manifest encountered; must return the parsed manifest or null. Returning a promise disables synchronous iteration. |
Returns Iterable<URL> — Yields candidate resolution URLs for the caller to test, in the order the algorithm tries them.
Throws
INVALID_ADDON_SPECIFIER— the specifier is empty, is a scoped name without a/, or has a package name that starts with.or contains\or%. It is also thrown whenparentURLis afile:URL and a relative or absolute specifier contains a percent-encoded/or\(%2for%5c, in either case).INVALID_PACKAGE_NAME— a package manifest'snamefield contains__.
resolve.addon(specifier: string, parentURL: URL, opts?: ResolveOptions): Resolver
One step of the resolution algorithm, exposed for fine-grained use: resolve specifier as an addon — a relative or absolute specifier resolves via resolve.file/resolve.directory, otherwise via resolve.package.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
specifier | string | — | The addon specifier to resolve. |
parentURL | URL | — | The URL to resolve specifier relative to. |
opts? | ResolveOptions | — | Options; see ResolveOptions. If opts.resolutions is set, it is checked first and a matching entry short-circuits the rest of the algorithm, unless the entry is a deferred: URL. A deferred: entry is ignored and resolution continues as if there were no entry. Changed in v1.11.0: a deferred: entry was resolved with the module algorithm, so deferred:. yielded a JavaScript file such as the package's index.js instead of an addon. |
Returns Resolver — A Resolver yielding the candidate resolutions.
resolve.directory
resolve.directory(dirname: string, version: string, parentURL: URL, opts?: ResolveOptions): ResolverResolve the addon of the package in the directory dirname, relative to parentURL. It reads the package.json in that directory and resolves nothing when there is none, when its name is missing or empty, or when version is set and the manifest has a different version. The addon name is the manifest name with a leading @ removed and every / replaced by __.
It yields candidates in the order of these steps. A builtin match in step 1 ends the resolution. After that, it stops after the first step in which the caller reported a candidate as existing. A step goes through every host before it stops, so several hosts can each resolve to their own prebuild:
- A builtin, when the name matches an entry of
opts.builtins:builtin:<name>@<version>, orbuiltin:<name>when neither the package nor the entry has a version. An entry with a version matches only a package with that version, or a package with none.opts.builtinProtocolsets the protocol. - Native prebuilds:
prebuilds/<host>/<name>@<version>.<ext>when the package has a version, andprebuilds/<host>/<name>.<ext>when the specifier named none, for each host that does not start withwasi-and each ofopts.extensions. Fordarwin-arm64,darwin-x64,ios-arm64-simulator, andios-x64-simulator, the same names are also tried withuniversalin place of the architecture, such asdarwin-universal. Theprebuildsdirectory is looked up indirnameand then in each parent directory. - A linked addon, as
resolve.linkedyields them, unlessopts.linkedisfalse. - WebAssembly prebuilds: the same file names as step 2, for each host that starts with
wasi-, such aswasi-wasm32. They always use the.wasmextension, whateveropts.extensionsis.
Added in v1.11.0: step 4. Before, a wasi- host was looked up like a native one, with opts.extensions, in the same pass as the native hosts and before any linked addon.
const resolve = require('bare-addon-resolve')
function readPackage(url) {
if (url.href === 'file:///a/package.json') return { name: 'e', version: '1.2.3' }
return null
}
const options = { hosts: ['linux-x64', 'wasi-wasm32'], extensions: ['.bare'] }
for (const resolution of resolve('.', new URL('file:///a/index.js'), options, readPackage)) {
console.log(resolution.href)
}file:///a/prebuilds/linux-x64/e@1.2.3.bare
file:///a/prebuilds/linux-x64/e.bare
file:///prebuilds/linux-x64/e@1.2.3.bare
file:///prebuilds/linux-x64/e.bare
linked:libe.1.2.3.so
linked:libe.so
file:///a/prebuilds/wasi-wasm32/e@1.2.3.wasm
file:///a/prebuilds/wasi-wasm32/e.wasm
file:///prebuilds/wasi-wasm32/e@1.2.3.wasm
file:///prebuilds/wasi-wasm32/e.wasmA for...of loop reports no candidate as existing, so it lists them all. A caller that drives the generator and passes true back for a candidate that exists stops at the step that resolved, so the WebAssembly candidates are only reached when no native prebuild and no linked addon exists. See the Algorithm section of the README for the full lookup.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
dirname | string | — | The directory of the package, relative to parentURL. It must hold a package.json. |
version | string | — | The package version, if the specifier carried one, else null. |
parentURL | URL | — | The URL to resolve dirname relative to. |
opts? | ResolveOptions | — | Options; see ResolveOptions. |
Returns Resolver — A Resolver yielding the candidate resolutions.
resolve.file(filename: string, parentURL: URL, opts?: ResolveOptions): Resolver
Resolve filename as a file addon candidate relative to parentURL, trying each of opts.extensions in turn.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
filename | string | — | The file addon candidate, without an extension. |
parentURL | URL | — | The URL to resolve filename relative to. |
opts? | ResolveOptions | — | Options; extensions lists the candidate extensions to try, in order. |
Returns Resolver — A Resolver yielding the candidate resolutions.
resolve.linked(name: string, version?: string, opts?: ResolveOptions): Resolver
Resolve name to a linked: specifier, for runtimes that link addons ahead of time by platform (for example iOS or Android) rather than resolving a prebuild at runtime.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
name | string | — | The addon name to resolve to a linked: specifier. |
version? | string | — | The addon version, if any. |
opts? | ResolveOptions | — | Options; linked must not be false and hosts (or host) must be set, or resolution is skipped. linkedProtocol overrides the 'linked:' prefix. |
Returns Resolver — A Resolver yielding the candidate linked: resolutions.
resolve.package
resolve.package(packageSpecifier: string, packageVersion: string, parentURL: URL, opts?: ResolveOptions): ResolverResolve packageSpecifier (optionally @packageVersion) as a package name, locating the addon within it.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
packageSpecifier | string | — | The package name to resolve the addon within. |
packageVersion | string | — | The package version, if the specifier carried one, else null. |
parentURL | URL | — | The URL to resolve the package from. |
opts? | ResolveOptions | — | Options; see ResolveOptions. |
Returns Resolver — A Resolver yielding the candidate resolutions.
resolve.packageSelf
resolve.packageSelf(packageName: string, packageSubpath: string, packageVersion: string, parentURL: URL, opts?: ResolveOptions): ResolverResolve packageSubpath against the package named packageName, for when parentURL lies within that package's own scope — a package requiring its own addon by name.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
packageName | string | — | The package's own name, matched against each candidate scope's manifest. |
packageSubpath | string | — | The addon subpath to resolve within the matching package. |
packageVersion | string | — | The package version, if the specifier carried one, else null. |
parentURL | URL | — | A URL within the package's own scope to search upward from. |
opts? | ResolveOptions | — | Options; see ResolveOptions. |
Returns Resolver — A Resolver yielding the candidate resolutions.
resolve.url(specifier: string, parentURL: URL, opts?: ResolveOptions): Resolver
Resolve specifier as an absolute URL, yielding it as a single candidate.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
specifier | string | — | An absolute URL specifier. |
parentURL | URL | — | Unused; accepted for a consistent step-function signature. |
opts? | ResolveOptions | — | Options; see ResolveOptions. |
Returns Resolver — A Resolver yielding the candidate resolution.
Constants and variables
resolve.constants
resolve.constants: {
UNRESOLVED: number
YIELDED: number
RESOLVED: number
}The generator status codes yielded by each resolution step: UNRESOLVED, YIELDED, and RESOLVED.
Types
resolve.Resolver
type Resolver = Generator<
{ resolution: URL } | { package: URL },
number,
void | boolean | JSON | null
>The shared generator type every resolve.* step function returns.
ResolveOptions
interface ResolveOptions {
builtinProtocol?: string
builtins?: Builtins
conditions?: Conditions
extensions?: string[]
host?: string
hosts?: string[]
linked?: boolean
linkedProtocol?: string
matchedConditions?: string[]
resolutions?: ResolutionsMap
}hosts lists the <platform>-<arch>[-<environment>] combinations to look for prebuilds under, such as Bare.Addon.host in Bare. host is shorthand for a list of one. Added in v1.11.0: a host that starts with wasi- is a WebAssembly host. It is looked up after the native hosts and linked addons, as .wasm files whatever extensions is. See resolve.directory.
bare-addon-resolve/errors
AddonResolveError
AddonResolveError.INVALID_ADDON_SPECIFIER(msg: string): AddonResolveError
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
msg | string | — | The error message. |
Returns AddonResolveError — A new AddonResolveError with code INVALID_ADDON_SPECIFIER.
AddonResolveError.INVALID_PACKAGE_NAME(msg: string): AddonResolveError
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
msg | string | — | The error message. |
Returns AddonResolveError — A new AddonResolveError with code INVALID_PACKAGE_NAME.
code: string
See also
- Builds on
bare-module-resolveandbare-semver. - The resolved addon is the first candidate
resolveyields that exists as a file on the file system. Native prebuilds come first, then linked addons, then WebAssembly prebuilds. - The
resolve.*step functions are subject to change between minor releases; if using them directly, specify a tilde range (for example~1.11.0) when declaring the module dependency. The README lists the steps of each one. - Addons normally resolve through the runtime or are bundled by
bare-pack; reach for this module directly only when building tooling on the resolution algorithm itself, such asbare-module-traverse, which uses it to pick a package's WebAssembly build. - Bare modules — the full
bare-*catalog. - Bare runtime API — the runtime these modules extend.
Last updated on