The v1 API
The v1 API
Section titled “The v1 API”The mport 1.x API (published as the unscoped mport, last version 1.0.0), kept with
the same signatures as a thin layer over the router.
mport()
Section titled “mport()”mport<T>(input: string | { name, version?, path? }, importOptions?: ImportCallOptions): Promise<T>The default export: MPort() with the default origins. Resolves to the module.
MPort() and MPortURL()
Section titled “MPort() and MPortURL()”MPort(options?: { cdns?, useCache?, cacheKey? }): (input, importOptions?) => Promise<module>MPort(...origins: string[]): (input, importOptions?) => Promise<module>MPortURL(options?): (input, importOptions?) => Promise<[module, url, info]>MPortURL(...origins: string[]): (input, importOptions?) => Promise<[module, url, info]>| Option | Type | Default | Meaning |
|---|---|---|---|
cdns |
Array<string | { path, versionMarker?, defaultVersion? }> |
DEFAULT_ORIGINS |
origins to race; strings are { path }; an empty array means the default |
useCache |
"localhost" |
none | remember each winning URL in localStorage and reuse it |
cacheKey |
string |
"mport-cache" |
the localStorage key (one JSON object of input → URL) |
Passing only strings (MPort("a.cdn/", "b.cdn/")) is the same as { cdns: [...] }.
importOptions is passed to import(url, importOptions) (the Firefox entry ignores it).
Input: "name@version/path" or { name, version, path }. With no version, v1 uses
latest (it does not resolve ranges; the CDN does). Scoped names work.
With a path, each call builds a router over the origins,
race(...origins.map(origin)) with probe: "import", resolveVersions: false and a
circuit breaker that never opens, and resolves: every origin’s URL is imported at once and
the first import to succeed wins. info is that Resolution without module
(url, provider (the origin path), version, trace, …). If every import fails it
rejects with a RoutingError.
Without a path, it races <origin>/<name>@<version>/package.json from every origin
(JSON import in the standard entry, fetch in the Firefox entry), takes the first that
loads, picks its entry with entryOf() (so exports → module → main,
preferring ESM), and imports that one URL from the same origin. info is
{ url, name, version, packageJson, entry, cached: false } with no trace. If no
package.json loads it rejects with AggregateError("mport: could not load <name>");
if the entry import fails, that error is the rejection (there is no failover for the
entry).
useCache: "localhost": before racing, a stored URL for the same input is used if it
starts with https:// plus one of the current origins’ paths. Then the call imports it
directly and info is { url, cached: true, trace: [] }; if that import fails, the call
rejects rather than racing again. Storage errors are ignored.
The Firefox entry point
Section titled “The Firefox entry point”@johnhenry/mport/firefox exports the same names. Its importer is the one-argument
import(url) (so importOptions is ignored), it reads package.json with fetch
(rejecting with mport: <url> responded <status> on a non-OK response), and no module it
loads contains a two-argument import(), which older SpiderMonkey rejects at parse time.
test/v1.test.mjs walks its import graph to keep it that way.
Differences from 1.x
Section titled “Differences from 1.x”Nothing that 1.x exported has been removed. Behaviour changes, all bug fixes, plus one addition:
| 1.x | Now |
|---|---|
Promise.race: one CDN that failed quickly rejected the whole import |
the first success wins |
"@scope/[email protected]/x.js" split on the first @ |
scoped names parse |
MPort("a.cdn/", "b.cdn/") ignored its arguments |
the origins are used |
useCache: "localhost" compared a URL host with an origin path and never matched |
it stores and reuses the winner |
mport/firefox referenced undefined variables |
it works |
path-less imports used main |
exports → module → main, preferring ESM; this can change which file loads for packages whose main is CommonJS |
MPortURL resolved to [module, url] |
[module, url, info]; two-element destructuring is unaffected |
the 1.0.0 tarball lacked config.mjs and race-which.mjs |
the package ships all of src/ |
the package was mport |
it is @johnhenry/mport, restarting at 0.0.0; the router API (createRouter and everything above) is new |
The default race still mixes builds (raw jsDelivr/unpkg files against jspm’s transformed
output), because that is what 1.x did. For consistent builds use a router, e.g.
createRouter({ "*": race(jsDelivr(), unpkg()) }).
Constants
Section titled “Constants”| Export | Value |
|---|---|
DEFAULT_ORIGINS |
["cdn.jsdelivr.net/npm/", "ga.jspm.io/npm:", "unpkg.com/"], the v1 race |
DEFAULT_CACHE_KEY |
"mport-cache", the v1 localStorage key |