Files

557 lines
115 KiB
HTML

<!DOCTYPE html><html class="default" lang="en" data-base="./"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>@nats-io/nats-core</title><meta name="description" content="Documentation for @nats-io/nats-core"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script><script async src="assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="index.html" class="title">@nats-io/nats-core</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h1>@nats-io/nats-core</h1></div><div class="tsd-panel tsd-typography"><p><a href="./LICENSE"><img src="https://img.shields.io/badge/Licence-Apache%202.0-blue.svg" alt="License"></a>
<img src="https://github.com/nats-io/nats.js/actions/workflows/test.yml/badge.svg" alt="nats-core">
<a href="https://nats-io.github.io/nats.js/core/index.html"><img src="https://img.shields.io/badge/JSDoc-reference-blue" alt="JSDoc"></a></p>
<p><a href="https://jsr.io/@nats-io/nats-core"><img src="https://jsr.io/badges/@nats-io/nats-core" alt="JSR"></a>
<a href="https://jsr.io/@nats-io/nats-core"><img src="https://jsr.io/badges/@nats-io/nats-core/score" alt="JSR"></a></p>
<p><a href="https://www.npmjs.com/package/@nats-io/nats-core"><img src="https://img.shields.io/npm/v/%40nats-io%2Fnats-core" alt="NPM Version"></a>
<img src="https://img.shields.io/npm/dt/%40nats-io%2Fnats-core" alt="NPM Downloads">
<img src="https://img.shields.io/npm/dm/%40nats-io%2Fnats-core" alt="NPM Downloads"></p>
<h1 id="core" class="tsd-anchor-link">Core<a href="#core" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>The <em>core</em> module implements the <em>core</em> functionality for JavaScript clients:</p>
<ul>
<li>Connection, authentication, connection lifecycle</li>
<li>NATS protocol handling - messaging functionality (publish, subscribe and
request reply)</li>
</ul>
<p>A native transports (node, deno) modules are a peer module that export a
<code>connect</code> function which returns a concrete instance of a <code>NatsConnection</code>. The
transport library re-exports all the functionality in this module, to make it
the entry point into the NATS JavaScript ecosystem.</p>
<p>You can use this module as a runtime agnostic dependency and implement
functionality that uses a NATS client connection without binding your code to a
particular runtime. For example, the @nats-io/jetstream library depends on
@nats-io/nats-core to implement all of its JetStream protocol.</p>
<h2 id="websocket-support" class="tsd-anchor-link">WebSocket Support<a href="#websocket-support" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The <em>core</em> module also offers a for W3C Websocket transport (aka browser, Deno,
and Node v22) via the exported <code>wsconnect</code> function. This function is
semantically equivalent to the traditional <code>connect</code>, but returns a
<code>NatsConnection</code> that is backed by a W3C WebSocket.</p>
<p>Note that wsconnect assumes <code>wss://</code> connections. If you provide a port, it
likewise resolve to <code>wss://localhost:443</code>. If you specify a <code>ws://</code> URL, the
client assumes port 80, which is likely not the port. Check your server
configuration as the port for WebSocket protocol is NOT 4222.</p>
<h1 id="installation" class="tsd-anchor-link">Installation<a href="#installation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>For a quick overview of the libraries and how to install them, see
<a href="media/runtimes.md">runtimes.md</a>.</p>
<p>If you are not implementing a NATS client compatible module, you can use this
repository to view the documentation of the NATS core functionality. Your NATS
client instance already uses and re-exports the module implemented here, so
there's no need for you to directly depend on this library.</p>
<p>Note that this module is distributed in two different registries:</p>
<ul>
<li>npm a node-specific library supporting CJS (<code>require</code>) and ESM (<code>import</code>) for
node specific projects</li>
<li>jsr a node and other ESM (<code>import</code>) compatible runtimes (deno, browser, node)</li>
</ul>
<p>If your application doesn't use <code>require</code>, you can simply depend on the JSR
version.</p>
<h2 id="npm" class="tsd-anchor-link">NPM<a href="#npm" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The NPM registry hosts a node-only compatible version of the library
<a href="https://www.npmjs.com/package/@nats-io/nats-core">@nats-io/nats-core</a>
supporting both CJS and ESM:</p>
<pre><code class="bash"><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-2">install</span><span class="hl-1"> </span><span class="hl-2">@nats-io/nats-core</span>
</code><button type="button">Copy</button></pre>
<h2 id="jsr" class="tsd-anchor-link">JSR<a href="#jsr" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The JSR registry hosts the ESM-only
<a href="https://jsr.io/@nats-io/nats-core">@nats-io/nats-core</a> version of the library.</p>
<pre><code class="bash"><span class="hl-0">deno</span><span class="hl-1"> </span><span class="hl-2">add</span><span class="hl-1"> </span><span class="hl-2">jsr:@nats-io/nats-core</span>
</code><button type="button">Copy</button></pre>
<pre><code class="bash"><span class="hl-0">npx</span><span class="hl-1"> </span><span class="hl-2">jsr</span><span class="hl-1"> </span><span class="hl-2">add</span><span class="hl-1"> </span><span class="hl-2">@nats-io/nats-core</span>
</code><button type="button">Copy</button></pre>
<pre><code class="bash"><span class="hl-0">yarn</span><span class="hl-1"> </span><span class="hl-2">dlx</span><span class="hl-1"> </span><span class="hl-2">jsr</span><span class="hl-1"> </span><span class="hl-2">add</span><span class="hl-1"> </span><span class="hl-2">@nats-io/nats-core</span>
</code><button type="button">Copy</button></pre>
<pre><code class="bash"><span class="hl-0">bunx</span><span class="hl-1"> </span><span class="hl-2">jsr</span><span class="hl-1"> </span><span class="hl-2">add</span><span class="hl-1"> </span><span class="hl-2">@nats-io/nats-core</span>
</code><button type="button">Copy</button></pre>
<h2 id="referencing-the-library" class="tsd-anchor-link">Referencing the library<a href="#referencing-the-library" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Once you import the library, you can reference in your code as:</p>
<pre><code class="javascript"><span class="hl-3">import</span><span class="hl-1"> </span><span class="hl-4">*</span><span class="hl-1"> </span><span class="hl-3">as</span><span class="hl-1"> </span><span class="hl-5">nats_core</span><span class="hl-1"> </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/nats-core&quot;</span><span class="hl-1">;</span><br/><span class="hl-6">// or in node (only when using CJS)</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nats_core</span><span class="hl-1"> = </span><span class="hl-0">require</span><span class="hl-1">(</span><span class="hl-2">&quot;@nats-io/nats-core&quot;</span><span class="hl-1">);</span>
</code><button type="button">Copy</button></pre>
<p>The main entry point for this library is the <code>NatsConnection</code>.</p>
<h2 id="basics" class="tsd-anchor-link">Basics<a href="#basics" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><h3 id="connecting-to-a-nats-server" class="tsd-anchor-link">Connecting to a nats-server<a href="#connecting-to-a-nats-server" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To connect to a server you use the <code>connect()</code> exposed by your selected
transport. The connect function returns a connection which implements the
<code>NatsConnection</code> that you can use to interact with the server.</p>
<p>The <code>connect()</code> function will accept a <code>ConnectOptions</code> which customizes some of
the client behaviors. In general all options apply to all transports where
possible. Options that are non-sensical on a particular runtime will be
documented by your transport module.</p>
<p>By default, <code>connect()</code> will attempt a connection on <code>127.0.0.1:4222</code>. If the
connection is dropped, the client will attempt to reconnect. You can customize
the server you want to connect to by specifying <code>port</code> (for local connections),
or full hostport on the <code>servers</code> option. Note that the <code>servers</code> option can be
a single hostport (a string) or an array of hostports.</p>
<p>The example below will attempt to connect to different servers by specifying
different <code>ConnectionOptions</code>. At least two of them should work if your internet
is working.</p>
<pre><code class="typescript"><span class="hl-6">// import the connect function from a transport</span><br/><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">servers</span><span class="hl-1"> = [</span><br/><span class="hl-1"> {},</span><br/><span class="hl-1"> { </span><span class="hl-5">servers:</span><span class="hl-1"> [</span><span class="hl-2">&quot;demo.nats.io:4442&quot;</span><span class="hl-1">, </span><span class="hl-2">&quot;demo.nats.io:4222&quot;</span><span class="hl-1">] },</span><br/><span class="hl-1"> { </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">&quot;demo.nats.io:4443&quot;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-5">port:</span><span class="hl-1"> </span><span class="hl-8">4222</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">&quot;localhost&quot;</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span><br/><span class="hl-5">servers</span><span class="hl-1">.</span><span class="hl-0">forEach</span><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> (</span><span class="hl-5">v</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">(</span><span class="hl-5">v</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`connected to </span><span class="hl-4">${</span><span class="hl-5">nc</span><span class="hl-9">.</span><span class="hl-0">getServer</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">// this promise indicates the client closed</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">done</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">closed</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-6">// do something with the connection</span><br/><br/><span class="hl-1"> </span><span class="hl-6">// close the connection</span><br/><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">close</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-6">// check if the close was OK</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">err</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">done</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">err</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`error closing:`</span><span class="hl-1">, </span><span class="hl-5">err</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> } </span><span class="hl-3">catch</span><span class="hl-1"> (</span><span class="hl-5">_err</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`error connecting to </span><span class="hl-4">${</span><span class="hl-7">JSON</span><span class="hl-9">.</span><span class="hl-0">stringify</span><span class="hl-9">(</span><span class="hl-5">v</span><span class="hl-9">)</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">});</span>
</code><button type="button">Copy</button></pre>
<p>To disconnect from the nats-server, call <code>close()</code> on the connection. A
connection can also be terminated when an unexpected error happens. For example,
the server returns a run-time error. In those cases, the client will re-initiate
a connection, it the connection options allow it.</p>
<p>By default, the client will always attempt to reconnect if the connection is
disrupted for a reason other than calling <code>close()</code>. To get notified when the
connection is closed, await the resolution of the Promise returned by
<code>closed()</code>. If closed resolves to a value, the value is a <code>NatsError</code> indicating
why the connection closed.</p>
<h3 id="publish-and-subscribe" class="tsd-anchor-link">Publish and Subscribe<a href="#publish-and-subscribe" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>The basic NATS client operations are <code>publish</code> to send messages and <code>subscribe</code>
to receive messages.</p>
<p>Messages are published to a <em>subject</em>. A <em>subject</em> is like a URL with the
exception that it doesn't specify an actual endpoint. Subjects can be any
string, but until you learn more about NATS stick to the simple rule that
subjects that are just simple ASCII printable letters and number characters. All
recipients that have expressed interest in a subject will receive messages
addressed to that subject (provided they have access and permissions to get it).
To express interest in a subject, you create a <code>subscription</code>.</p>
<p>In JavaScript clients subscriptions work as an async iterator - clients simply
loop to process messages as they happen.</p>
<p>NATS messages are payload agnostic. Payloads are <code>Uint8Arrays</code> or <code>string</code>.
Messages also provide a <code>string()</code> and <code>json()</code> that allows you to convert the
underlying <code>Uint8Array</code> into a string or parse by using <code>JSON.parse()</code> (which
can fail to parse if the payload is not the expected format).</p>
<p>To cancel a subscription and terminate your interest, you call <code>unsubscribe()</code>
or <code>drain()</code> on a subscription. Unsubscribe will typically terminate regardless
of whether there are messages in flight for the client. Drain ensures that all
messages that are inflight are processed before canceling the subscription.
Connections can also be drained as well. Draining a connection closes it, after
all subscriptions have been drained and all outbound messages have been sent to
the server.</p>
<pre><code class="typescript"><span class="hl-6">// import the connect function from a transport</span><br/><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-6">// to create a connection to a nats-server:</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">({ </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">&quot;demo.nats.io:4222&quot;</span><span class="hl-1"> });</span><br/><br/><span class="hl-6">// create a simple subscriber and iterate over messages</span><br/><span class="hl-6">// matching the subscription</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">sub</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;hello&quot;</span><span class="hl-1">);</span><br/><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">sub</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`[</span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2">]: </span><span class="hl-4">${</span><span class="hl-5">m</span><span class="hl-9">.</span><span class="hl-0">string</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">&quot;subscription closed&quot;</span><span class="hl-1">);</span><br/><span class="hl-1">})();</span><br/><br/><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">publish</span><span class="hl-1">(</span><span class="hl-2">&quot;hello&quot;</span><span class="hl-1">, </span><span class="hl-2">&quot;world&quot;</span><span class="hl-1">);</span><br/><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">publish</span><span class="hl-1">(</span><span class="hl-2">&quot;hello&quot;</span><span class="hl-1">, </span><span class="hl-2">&quot;again&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-6">// we want to ensure that messages that are in flight</span><br/><span class="hl-6">// get processed, so we are going to drain the</span><br/><span class="hl-6">// connection. Drain is the same as close, but makes</span><br/><span class="hl-6">// sure that all messages in flight get seen</span><br/><span class="hl-6">// by the iterator. After calling drain,</span><br/><span class="hl-6">// the connection closes.</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">drain</span><span class="hl-1">();</span>
</code><button type="button">Copy</button></pre>
<pre><code class="typescript"><span class="hl-4">interface</span><span class="hl-1"> </span><span class="hl-10">Person</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">name</span><span class="hl-1">: </span><span class="hl-10">string</span><span class="hl-1">;</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-6">// create a simple subscriber and iterate over messages</span><br/><span class="hl-6">// matching the subscription</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">sub</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;people&quot;</span><span class="hl-1">);</span><br/><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">sub</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-6">// typescript will see this as a Person</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">p</span><span class="hl-1"> = </span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-0">json</span><span class="hl-1">&lt;</span><span class="hl-10">Person</span><span class="hl-1">&gt;();</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`[</span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2">]: </span><span class="hl-4">${</span><span class="hl-5">p</span><span class="hl-9">.</span><span class="hl-5">name</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})();</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">p</span><span class="hl-1"> = { </span><span class="hl-5">name:</span><span class="hl-1"> </span><span class="hl-2">&quot;Memo&quot;</span><span class="hl-1"> } </span><span class="hl-3">as</span><span class="hl-1"> </span><span class="hl-10">Person</span><span class="hl-1">;</span><br/><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">publish</span><span class="hl-1">(</span><span class="hl-2">&quot;people&quot;</span><span class="hl-1">, </span><span class="hl-7">JSON</span><span class="hl-1">.</span><span class="hl-0">stringify</span><span class="hl-1">(</span><span class="hl-5">p</span><span class="hl-1">));</span>
</code><button type="button">Copy</button></pre>
<h3 id="wildcard-subscriptions" class="tsd-anchor-link">Wildcard Subscriptions<a href="#wildcard-subscriptions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Subjects can be used to organize messages into hierarchies. For example, a
subject may contain additional information that can be useful in providing a
context to the message, such as the ID of the client that sent the message, or
the region where a message originated.</p>
<p>Instead of subscribing to each specific subject, you can create subscriptions
that have subjects with wildcards. Wildcards match one or more tokens in a
subject. A token is a string following a period (<code>.</code>).</p>
<p>All subscriptions are independent. If two different subscriptions match a
subject, both will get to process the message:</p>
<pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><span class="hl-3">import</span><span class="hl-1"> </span><span class="hl-3">type</span><span class="hl-1"> { </span><span class="hl-5">Subscription</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">({ </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">&quot;demo.nats.io:4222&quot;</span><span class="hl-1"> });</span><br/><br/><span class="hl-6">// subscriptions can have wildcard subjects</span><br/><span class="hl-6">// the &#39;*&#39; matches any string in the specified token position</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">s1</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;help.*.system&quot;</span><span class="hl-1">);</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">s2</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;help.me.*&quot;</span><span class="hl-1">);</span><br/><span class="hl-6">// the &#39;&gt;&#39; matches any tokens in that position or following</span><br/><span class="hl-6">// &#39;&gt;&#39; can only be specified at the end</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">s3</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;help.&gt;&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-0">printMsgs</span><span class="hl-1">(</span><span class="hl-5">s</span><span class="hl-1">: </span><span class="hl-10">Subscription</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">subj</span><span class="hl-1"> = </span><span class="hl-5">s</span><span class="hl-1">.</span><span class="hl-0">getSubject</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`listening for </span><span class="hl-4">${</span><span class="hl-5">subj</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">c</span><span class="hl-1"> = </span><span class="hl-8">13</span><span class="hl-1"> - </span><span class="hl-5">subj</span><span class="hl-1">.</span><span class="hl-5">length</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">pad</span><span class="hl-1"> = </span><span class="hl-2">&quot;&quot;</span><span class="hl-1">.</span><span class="hl-0">padEnd</span><span class="hl-1">(</span><span class="hl-5">c</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">s</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">`[</span><span class="hl-4">${</span><span class="hl-5">subj</span><span class="hl-4">}</span><span class="hl-2">]</span><span class="hl-4">${</span><span class="hl-5">pad</span><span class="hl-4">}</span><span class="hl-2"> #</span><span class="hl-4">${</span><span class="hl-5">s</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> - </span><span class="hl-4">${</span><span class="hl-5">m</span><span class="hl-9">.</span><span class="hl-5">subject</span><span class="hl-4">}</span><span class="hl-2"> </span><span class="hl-4">${</span><br/><span class="hl-9"> </span><span class="hl-5">m</span><span class="hl-9">.</span><span class="hl-5">data</span><span class="hl-9"> </span><span class="hl-1">?</span><span class="hl-9"> </span><span class="hl-2">&quot; &quot;</span><span class="hl-9"> </span><span class="hl-1">+</span><span class="hl-9"> </span><span class="hl-5">m</span><span class="hl-9">.</span><span class="hl-0">string</span><span class="hl-9">() </span><span class="hl-1">:</span><span class="hl-9"> </span><span class="hl-2">&quot;&quot;</span><br/><span class="hl-9"> </span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">,</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-0">printMsgs</span><span class="hl-1">(</span><span class="hl-5">s1</span><span class="hl-1">);</span><br/><span class="hl-0">printMsgs</span><span class="hl-1">(</span><span class="hl-5">s2</span><span class="hl-1">);</span><br/><span class="hl-0">printMsgs</span><span class="hl-1">(</span><span class="hl-5">s3</span><span class="hl-1">);</span><br/><br/><span class="hl-6">// don&#39;t exit until the client closes</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">closed</span><span class="hl-1">();</span>
</code><button type="button">Copy</button></pre>
<h3 id="services-requestreply" class="tsd-anchor-link">Services: Request/Reply<a href="#services-requestreply" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Request/Reply is NATS equivalent to an HTTP request. To make requests you
publish messages as you did before, but also specify a <code>reply</code> subject. The
<code>reply</code> subject is where a service will publish (send) your response.</p>
<p>NATS provides syntactic sugar, for publishing requests. The <code>request()</code> API will
generate a reply subject and manage the creation of a subscription under the
covers to receive the reply. It will also start a timer to ensure that if a
response is not received within your specified time, the request fails. The
example also illustrates a graceful shutdown.</p>
<h4 id="services" class="tsd-anchor-link">Services<a href="#services" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Here's an example of a service. It is a bit more complicated than expected
simply to illustrate not only how to create responses, but how the subject
itself is used to dispatch different behaviors.</p>
<pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1">, </span><span class="hl-5">Subscription</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/nats-deno&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-6">// create a connection</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">({ </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">&quot;demo.nats.io&quot;</span><span class="hl-1"> });</span><br/><br/><span class="hl-6">// this subscription listens for `time` requests and returns the current time</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">sub</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;time&quot;</span><span class="hl-1">);</span><br/><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> (</span><span class="hl-5">sub</span><span class="hl-1">: </span><span class="hl-10">Subscription</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`listening for </span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getSubject</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> requests...`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">sub</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-0">respond</span><span class="hl-1">(</span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-0">Date</span><span class="hl-1">().</span><span class="hl-0">toISOString</span><span class="hl-1">())) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">`[time] handled #</span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-3">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`[time] #</span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> ignored - no reply subject`</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`subscription </span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getSubject</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> drained.`</span><span class="hl-1">);</span><br/><span class="hl-1">})(</span><span class="hl-5">sub</span><span class="hl-1">);</span><br/><br/><span class="hl-6">// this subscription listens for admin.uptime and admin.stop</span><br/><span class="hl-6">// requests to admin.uptime returns how long the service has been running</span><br/><span class="hl-6">// requests to admin.stop gracefully stop the client by draining</span><br/><span class="hl-6">// the connection</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">started</span><span class="hl-1"> = </span><span class="hl-5">Date</span><span class="hl-1">.</span><span class="hl-0">now</span><span class="hl-1">();</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">msub</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;admin.*&quot;</span><span class="hl-1">);</span><br/><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> (</span><span class="hl-5">sub</span><span class="hl-1">: </span><span class="hl-10">Subscription</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`listening for </span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getSubject</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> requests [uptime | stop]`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">// it would be very good to verify the origin of the request</span><br/><span class="hl-1"> </span><span class="hl-6">// before implementing something that allows your service to be managed.</span><br/><span class="hl-1"> </span><span class="hl-6">// NATS can limit which client can send or receive on what subjects.</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">sub</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">chunks</span><span class="hl-1"> = </span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-5">subject</span><span class="hl-1">.</span><span class="hl-0">split</span><span class="hl-1">(</span><span class="hl-2">&quot;.&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">`[admin] #</span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> handling </span><span class="hl-4">${</span><span class="hl-5">chunks</span><span class="hl-9">[</span><span class="hl-8">1</span><span class="hl-9">]</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">switch</span><span class="hl-1"> (</span><span class="hl-5">chunks</span><span class="hl-1">[</span><span class="hl-8">1</span><span class="hl-1">]) {</span><br/><span class="hl-1"> </span><span class="hl-3">case</span><span class="hl-1"> </span><span class="hl-2">&quot;uptime&quot;</span><span class="hl-1">:</span><br/><span class="hl-1"> </span><span class="hl-6">// send the number of millis since up</span><br/><span class="hl-1"> </span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-0">respond</span><span class="hl-1">(</span><span class="hl-2">`</span><span class="hl-4">${</span><span class="hl-5">Date</span><span class="hl-9">.</span><span class="hl-0">now</span><span class="hl-9">() </span><span class="hl-1">-</span><span class="hl-9"> </span><span class="hl-5">started</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">break</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">case</span><span class="hl-1"> </span><span class="hl-2">&quot;stop&quot;</span><span class="hl-1">: {</span><br/><span class="hl-1"> </span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-0">respond</span><span class="hl-1">(</span><span class="hl-2">`[admin] #</span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> stopping....`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">// gracefully shutdown</span><br/><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">drain</span><span class="hl-1">()</span><br/><span class="hl-1"> .</span><span class="hl-0">catch</span><span class="hl-1">((</span><span class="hl-5">err</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">&quot;error draining&quot;</span><span class="hl-1">, </span><span class="hl-5">err</span><span class="hl-1">);</span><br/><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-3">break</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-3">default</span><span class="hl-1">:</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">`[admin] #</span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> ignoring request for </span><span class="hl-4">${</span><span class="hl-5">m</span><span class="hl-9">.</span><span class="hl-5">subject</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">,</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`subscription </span><span class="hl-4">${</span><span class="hl-5">sub</span><span class="hl-9">.</span><span class="hl-0">getSubject</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> drained.`</span><span class="hl-1">);</span><br/><span class="hl-1">})(</span><span class="hl-5">msub</span><span class="hl-1">);</span><br/><br/><span class="hl-6">// wait for the client to close here.</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">closed</span><span class="hl-1">().</span><span class="hl-0">then</span><span class="hl-1">((</span><span class="hl-5">err</span><span class="hl-1">?: </span><span class="hl-10">void</span><span class="hl-1"> | </span><span class="hl-10">Error</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">let</span><span class="hl-1"> </span><span class="hl-5">m</span><span class="hl-1"> = </span><span class="hl-2">`connection to </span><span class="hl-4">${</span><span class="hl-5">nc</span><span class="hl-9">.</span><span class="hl-0">getServer</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> closed`</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">err</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">m</span><span class="hl-1"> = </span><span class="hl-2">`</span><span class="hl-4">${</span><span class="hl-5">m</span><span class="hl-4">}</span><span class="hl-2"> with an error: </span><span class="hl-4">${</span><span class="hl-5">err</span><span class="hl-9">.</span><span class="hl-5">message</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-5">m</span><span class="hl-1">);</span><br/><span class="hl-1">});</span>
</code><button type="button">Copy</button></pre>
<h4 id="making-requests" class="tsd-anchor-link">Making Requests<a href="#making-requests" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Here's a simple example of a client making a simple request from the service
above:</p>
<pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1">, </span><span class="hl-5">Empty</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;../../src/types.ts&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-6">// create a connection</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">({ </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">&quot;demo.nats.io:4222&quot;</span><span class="hl-1"> });</span><br/><br/><span class="hl-6">// the client makes a request and receives a promise for a message</span><br/><span class="hl-6">// by default the request times out after 1s (1000 millis) and has</span><br/><span class="hl-6">// no payload.</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">request</span><span class="hl-1">(</span><span class="hl-2">&quot;time&quot;</span><span class="hl-1">, </span><span class="hl-5">Empty</span><span class="hl-1">, { </span><span class="hl-5">timeout:</span><span class="hl-1"> </span><span class="hl-8">1000</span><span class="hl-1"> })</span><br/><span class="hl-1"> .</span><span class="hl-0">then</span><span class="hl-1">((</span><span class="hl-5">m</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`got response: </span><span class="hl-4">${</span><span class="hl-5">m</span><span class="hl-9">.</span><span class="hl-0">string</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> })</span><br/><span class="hl-1"> .</span><span class="hl-0">catch</span><span class="hl-1">((</span><span class="hl-5">err</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`problem with request: </span><span class="hl-4">${</span><span class="hl-5">err</span><span class="hl-9">.</span><span class="hl-5">message</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">close</span><span class="hl-1">();</span>
</code><button type="button">Copy</button></pre>
<p>Of course you can also use a tool like the nats cli:</p>
<pre><code class="bash"><span class="hl-1">&gt; nats -s demo.nats.io req </span><span class="hl-4">time</span><span class="hl-1"> </span><span class="hl-2">&quot;&quot;</span><br/><span class="hl-0">11:39:59</span><span class="hl-1"> </span><span class="hl-2">Sending</span><span class="hl-1"> </span><span class="hl-2">request</span><span class="hl-1"> </span><span class="hl-2">on</span><span class="hl-1"> </span><span class="hl-2">&quot;time&quot;</span><br/><span class="hl-0">11:39:59</span><span class="hl-1"> </span><span class="hl-2">Received</span><span class="hl-1"> </span><span class="hl-2">with</span><span class="hl-1"> </span><span class="hl-2">rtt</span><span class="hl-1"> </span><span class="hl-2">97.814458ms</span><br/><span class="hl-0">2024-06-26T16:39:59.710Z</span><br/><br/><span class="hl-1">&gt; nats -s demo.nats.io req admin.uptime </span><span class="hl-2">&quot;&quot;</span><br/><span class="hl-0">11:38:41</span><span class="hl-1"> </span><span class="hl-2">Sending</span><span class="hl-1"> </span><span class="hl-2">request</span><span class="hl-1"> </span><span class="hl-2">on</span><span class="hl-1"> </span><span class="hl-2">&quot;admin.uptime&quot;</span><br/><span class="hl-0">11:38:41</span><span class="hl-1"> </span><span class="hl-2">Received</span><span class="hl-1"> </span><span class="hl-2">with</span><span class="hl-1"> </span><span class="hl-2">rtt</span><span class="hl-1"> </span><span class="hl-2">99.065458ms</span><br/><span class="hl-0">61688</span><br/><br/><span class="hl-1">&gt;nats -s demo.nats.io req admin.stop </span><span class="hl-2">&quot;&quot;</span><br/><span class="hl-0">11:39:08</span><span class="hl-1"> </span><span class="hl-2">Sending</span><span class="hl-1"> </span><span class="hl-2">request</span><span class="hl-1"> </span><span class="hl-2">on</span><span class="hl-1"> </span><span class="hl-2">&quot;admin.stop&quot;</span><br/><span class="hl-0">11:39:08</span><span class="hl-1"> </span><span class="hl-2">Received</span><span class="hl-1"> </span><span class="hl-2">with</span><span class="hl-1"> </span><span class="hl-2">rtt</span><span class="hl-1"> </span><span class="hl-2">100.004959ms</span><br/><span class="hl-1">[admin] </span><span class="hl-6">#5 stopping....</span>
</code><button type="button">Copy</button></pre>
<h3 id="queue-groups" class="tsd-anchor-link">Queue Groups<a href="#queue-groups" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Queue groups allow scaling of services horizontally. Subscriptions for members
of a queue group are treated as a single service. When you send a message to a
queue group subscription, only a single client in a queue group will receive it.</p>
<p>There can be any number of queue groups. Each group is treated as its own
independent unit. Note that non-queue subscriptions are also independent of
subscriptions in a queue group.</p>
<pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><span class="hl-3">import</span><span class="hl-1"> </span><span class="hl-3">type</span><span class="hl-1"> { </span><span class="hl-5">NatsConnection</span><span class="hl-1">, </span><span class="hl-5">Subscription</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-0">createService</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-5">name</span><span class="hl-1">: </span><span class="hl-10">string</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">count</span><span class="hl-1"> = </span><span class="hl-8">1</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">queue</span><span class="hl-1"> = </span><span class="hl-2">&quot;&quot;</span><span class="hl-1">,</span><br/><span class="hl-1">): </span><span class="hl-10">Promise</span><span class="hl-1">&lt;</span><span class="hl-10">NatsConnection</span><span class="hl-1">[]&gt; {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">conns</span><span class="hl-1">: </span><span class="hl-10">NatsConnection</span><span class="hl-1">[] = [];</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> (</span><span class="hl-4">let</span><span class="hl-1"> </span><span class="hl-5">i</span><span class="hl-1"> = </span><span class="hl-8">1</span><span class="hl-1">; </span><span class="hl-5">i</span><span class="hl-1"> &lt;= </span><span class="hl-5">count</span><span class="hl-1">; </span><span class="hl-5">i</span><span class="hl-1">++) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">n</span><span class="hl-1"> = </span><span class="hl-5">queue</span><span class="hl-1"> ? </span><span class="hl-2">`</span><span class="hl-4">${</span><span class="hl-5">name</span><span class="hl-4">}</span><span class="hl-2">-</span><span class="hl-4">${</span><span class="hl-5">i</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1"> : </span><span class="hl-5">name</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">(</span><br/><span class="hl-1"> { </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">&quot;demo.nats.io:4222&quot;</span><span class="hl-1">, </span><span class="hl-5">name:</span><span class="hl-1"> </span><span class="hl-2">`</span><span class="hl-4">${</span><span class="hl-5">n</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1"> },</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">closed</span><span class="hl-1">()</span><br/><span class="hl-1"> .</span><span class="hl-0">then</span><span class="hl-1">((</span><span class="hl-5">err</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">err</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">error</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">`service </span><span class="hl-4">${</span><span class="hl-5">n</span><span class="hl-4">}</span><span class="hl-2"> exited because of error: </span><span class="hl-4">${</span><span class="hl-5">err</span><span class="hl-9">.</span><span class="hl-5">message</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">,</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-6">// create a subscription - note the option for a queue, if set</span><br/><span class="hl-1"> </span><span class="hl-6">// any client with the same queue will be the queue group.</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">sub</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;echo&quot;</span><span class="hl-1">, { </span><span class="hl-5">queue:</span><span class="hl-1"> </span><span class="hl-5">queue</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">_</span><span class="hl-1"> = </span><span class="hl-0">handleRequest</span><span class="hl-1">(</span><span class="hl-5">n</span><span class="hl-1">, </span><span class="hl-5">sub</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`</span><span class="hl-4">${</span><span class="hl-5">n</span><span class="hl-4">}</span><span class="hl-2"> is listening for &#39;echo&#39; requests...`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-5">conns</span><span class="hl-1">.</span><span class="hl-0">push</span><span class="hl-1">(</span><span class="hl-5">nc</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-3">return</span><span class="hl-1"> </span><span class="hl-5">conns</span><span class="hl-1">;</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-6">// simple handler for service requests</span><br/><span class="hl-4">async</span><span class="hl-1"> </span><span class="hl-4">function</span><span class="hl-1"> </span><span class="hl-0">handleRequest</span><span class="hl-1">(</span><span class="hl-5">name</span><span class="hl-1">: </span><span class="hl-10">string</span><span class="hl-1">, </span><span class="hl-5">s</span><span class="hl-1">: </span><span class="hl-10">Subscription</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">p</span><span class="hl-1"> = </span><span class="hl-8">12</span><span class="hl-1"> - </span><span class="hl-5">name</span><span class="hl-1">.</span><span class="hl-5">length</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">pad</span><span class="hl-1"> = </span><span class="hl-2">&quot;&quot;</span><span class="hl-1">.</span><span class="hl-0">padEnd</span><span class="hl-1">(</span><span class="hl-5">p</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">s</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-6">// respond returns true if the message had a reply subject, thus it could respond</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-0">respond</span><span class="hl-1">(</span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-5">data</span><span class="hl-1">)) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">`[</span><span class="hl-4">${</span><span class="hl-5">name</span><span class="hl-4">}</span><span class="hl-2">]:</span><span class="hl-4">${</span><span class="hl-5">pad</span><span class="hl-4">}</span><span class="hl-2"> #</span><span class="hl-4">${</span><span class="hl-5">s</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> echoed </span><span class="hl-4">${</span><span class="hl-5">m</span><span class="hl-9">.</span><span class="hl-0">string</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">,</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> } </span><span class="hl-3">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">`[</span><span class="hl-4">${</span><span class="hl-5">name</span><span class="hl-4">}</span><span class="hl-2">]:</span><span class="hl-4">${</span><span class="hl-5">pad</span><span class="hl-4">}</span><span class="hl-2"> #</span><span class="hl-4">${</span><span class="hl-5">s</span><span class="hl-9">.</span><span class="hl-0">getProcessed</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2"> ignoring request - no reply subject`</span><span class="hl-1">,</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-6">// let&#39;s create two queue groups and a standalone subscriber</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">conns</span><span class="hl-1">: </span><span class="hl-10">NatsConnection</span><span class="hl-1">[] = [];</span><br/><span class="hl-5">conns</span><span class="hl-1">.</span><span class="hl-0">push</span><span class="hl-1">(...</span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">createService</span><span class="hl-1">(</span><span class="hl-2">&quot;echo&quot;</span><span class="hl-1">, </span><span class="hl-8">3</span><span class="hl-1">, </span><span class="hl-2">&quot;echo&quot;</span><span class="hl-1">));</span><br/><span class="hl-5">conns</span><span class="hl-1">.</span><span class="hl-0">push</span><span class="hl-1">(...</span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">createService</span><span class="hl-1">(</span><span class="hl-2">&quot;other-echo&quot;</span><span class="hl-1">, </span><span class="hl-8">2</span><span class="hl-1">, </span><span class="hl-2">&quot;other-echo&quot;</span><span class="hl-1">));</span><br/><span class="hl-5">conns</span><span class="hl-1">.</span><span class="hl-0">push</span><span class="hl-1">(...</span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">createService</span><span class="hl-1">(</span><span class="hl-2">&quot;standalone&quot;</span><span class="hl-1">));</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">a</span><span class="hl-1">: </span><span class="hl-10">Promise</span><span class="hl-1">&lt;</span><span class="hl-10">void</span><span class="hl-1"> | </span><span class="hl-10">Error</span><span class="hl-1">&gt;[] = [];</span><br/><span class="hl-5">conns</span><span class="hl-1">.</span><span class="hl-0">forEach</span><span class="hl-1">((</span><span class="hl-5">c</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">a</span><span class="hl-1">.</span><span class="hl-0">push</span><span class="hl-1">(</span><span class="hl-5">c</span><span class="hl-1">.</span><span class="hl-0">closed</span><span class="hl-1">());</span><br/><span class="hl-1">});</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-10">Promise</span><span class="hl-1">.</span><span class="hl-0">all</span><span class="hl-1">(</span><span class="hl-5">a</span><span class="hl-1">);</span>
</code><button type="button">Copy</button></pre>
<p>Run it and publish a request to the subject <code>echo</code> to see what happens.</p>
<h2 id="advanced-usage" class="tsd-anchor-link">Advanced Usage<a href="#advanced-usage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><h3 id="headers" class="tsd-anchor-link">Headers<a href="#headers" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>NATS headers are similar to HTTP headers. Headers are enabled automatically if
the server supports them. Note that if you publish a message using headers but
the server doesn't support them, an Error is thrown. Also note that even if you
are publishing a message with a header, it is possible for the recipient to not
support them.</p>
<pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1">, </span><span class="hl-5">createInbox</span><span class="hl-1">, </span><span class="hl-5">Empty</span><span class="hl-1">, </span><span class="hl-5">headers</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;../../src/types.ts&quot;</span><span class="hl-1">;</span><br/><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">nuid</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;../../nats-base-client/nuid.ts&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">(</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">`demo.nats.io`</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">);</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">subj</span><span class="hl-1"> = </span><span class="hl-0">createInbox</span><span class="hl-1">();</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">sub</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-5">subj</span><span class="hl-1">);</span><br/><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">sub</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-5">headers</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> [</span><span class="hl-7">key</span><span class="hl-1">, </span><span class="hl-7">value</span><span class="hl-1">] </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-5">headers</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`</span><span class="hl-4">${</span><span class="hl-5">key</span><span class="hl-4">}</span><span class="hl-2">=</span><span class="hl-4">${</span><span class="hl-5">value</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-6">// reading a header is not case sensitive</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">&quot;id&quot;</span><span class="hl-1">, </span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-5">headers</span><span class="hl-1">.</span><span class="hl-0">get</span><span class="hl-1">(</span><span class="hl-2">&quot;id&quot;</span><span class="hl-1">));</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})().</span><span class="hl-0">then</span><span class="hl-1">();</span><br/><br/><span class="hl-6">// header names can be any printable ASCII character with the exception of `:`.</span><br/><span class="hl-6">// header values can be any ASCII character except `\r` or `\n`.</span><br/><span class="hl-6">// see https://www.ietf.org/rfc/rfc822.txt</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">h</span><span class="hl-1"> = </span><span class="hl-0">headers</span><span class="hl-1">();</span><br/><span class="hl-5">h</span><span class="hl-1">.</span><span class="hl-0">append</span><span class="hl-1">(</span><span class="hl-2">&quot;id&quot;</span><span class="hl-1">, </span><span class="hl-5">nuid</span><span class="hl-1">.</span><span class="hl-0">next</span><span class="hl-1">());</span><br/><span class="hl-5">h</span><span class="hl-1">.</span><span class="hl-0">append</span><span class="hl-1">(</span><span class="hl-2">&quot;unix_time&quot;</span><span class="hl-1">, </span><span class="hl-5">Date</span><span class="hl-1">.</span><span class="hl-0">now</span><span class="hl-1">().</span><span class="hl-0">toString</span><span class="hl-1">());</span><br/><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">publish</span><span class="hl-1">(</span><span class="hl-5">subj</span><span class="hl-1">, </span><span class="hl-5">Empty</span><span class="hl-1">, { </span><span class="hl-5">headers:</span><span class="hl-1"> </span><span class="hl-5">h</span><span class="hl-1"> });</span><br/><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">flush</span><span class="hl-1">();</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">close</span><span class="hl-1">();</span>
</code><button type="button">Copy</button></pre>
<h3 id="no-responders" class="tsd-anchor-link">No Responders<a href="#no-responders" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Requests can fail for many reasons. A common reason for a failure is the lack of
interest in the subject. Typically these surface as a timeout error. If the
server is enabled to use headers, it will also enable a <code>no responders</code> feature.
If you send a request for which there's no interest, the request will be
immediately rejected:</p>
<pre><code class="typescript"><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><span class="hl-3">import</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">NoRespondersError</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">RequestError</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">TimeoutError</span><span class="hl-1">,</span><br/><span class="hl-1">} </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">`demo.nats.io`</span><span class="hl-1">,</span><br/><span class="hl-1">});</span><br/><br/><span class="hl-3">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">request</span><span class="hl-1">(</span><span class="hl-2">&quot;hello.world&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-5">m</span><span class="hl-1">.</span><span class="hl-5">data</span><span class="hl-1">);</span><br/><span class="hl-1">} </span><span class="hl-3">catch</span><span class="hl-1"> (</span><span class="hl-5">err</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">err</span><span class="hl-1"> </span><span class="hl-4">instanceof</span><span class="hl-1"> </span><span class="hl-10">RequestError</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">err</span><span class="hl-1">.</span><span class="hl-5">cause</span><span class="hl-1"> </span><span class="hl-4">instanceof</span><span class="hl-1"> </span><span class="hl-10">TimeoutError</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">&quot;someone is listening but didn&#39;t respond&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-3">else</span><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">err</span><span class="hl-1">.</span><span class="hl-5">cause</span><span class="hl-1"> </span><span class="hl-4">instanceof</span><span class="hl-1"> </span><span class="hl-10">NoRespondersError</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">&quot;no one is listening to &#39;hello.world&#39;&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-3">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">`failed due to unknown error: </span><span class="hl-4">${</span><span class="hl-9">(</span><span class="hl-5">err</span><span class="hl-9">.</span><span class="hl-5">cause</span><span class="hl-9"> </span><span class="hl-3">as</span><span class="hl-9"> </span><span class="hl-10">Error</span><span class="hl-9">)?.</span><span class="hl-5">message</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">,</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> } </span><span class="hl-3">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`request failed: </span><span class="hl-4">${</span><span class="hl-9">(</span><span class="hl-5">err</span><span class="hl-9"> </span><span class="hl-3">as</span><span class="hl-9"> </span><span class="hl-10">Error</span><span class="hl-9">).</span><span class="hl-5">message</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">close</span><span class="hl-1">();</span>
</code><button type="button">Copy</button></pre>
<h3 id="authentication" class="tsd-anchor-link">Authentication<a href="#authentication" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>NATS supports many different forms of credentials:</p>
<ul>
<li>username/password</li>
<li>token</li>
<li>NKEYS</li>
<li>client certificates</li>
<li>JWTs</li>
</ul>
<p>For user/password and token authentication, you can simply provide them as
<code>ConnectionOptions</code> - see <code>user</code>, <code>pass</code>, <code>token</code>. Internally these mechanisms
are implemented as an <code>Authenticator</code>. An <code>Authenticator</code> is simply a function
that handles the type of authentication specified.</p>
<p>Setting the <code>user</code>/<code>pass</code> or <code>token</code> options, simply initializes an
<code>Authenticator</code> and sets the username/password.</p>
<pre><code class="typescript"><span class="hl-6">// if the connection requires authentication, provide `user` and `pass` or</span><br/><span class="hl-6">// `token` options in the NatsConnectionOptions</span><br/><span class="hl-3">import</span><span class="hl-1"> { </span><span class="hl-5">connect</span><span class="hl-1"> } </span><span class="hl-3">from</span><span class="hl-1"> </span><span class="hl-2">&quot;@nats-io/transport-deno&quot;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc1</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-5">servers:</span><span class="hl-1"> </span><span class="hl-2">&quot;127.0.0.1:4222&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">user:</span><span class="hl-1"> </span><span class="hl-2">&quot;jenny&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">pass:</span><span class="hl-1"> </span><span class="hl-2">&quot;867-5309&quot;</span><span class="hl-1">,</span><br/><span class="hl-1">});</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc2</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">({ </span><span class="hl-5">port:</span><span class="hl-1"> </span><span class="hl-8">4222</span><span class="hl-1">, </span><span class="hl-5">token:</span><span class="hl-1"> </span><span class="hl-2">&quot;t0pS3cret!&quot;</span><span class="hl-1"> });</span>
</code><button type="button">Copy</button></pre>
<h4 id="authenticators" class="tsd-anchor-link">Authenticators<a href="#authenticators" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>NKEYs and JWT authentication are more complex, as they cryptographically respond
to a server challenge.</p>
<p>Because NKEY and JWT authentication may require reading data from a file or an
HTTP cookie, these forms of authentication will require a bit more from the
developer to activate them. The work is related to accessing these resources
varies depending on the platform.</p>
<p>After the credential artifacts are read, you can use one of these functions to
create the authenticator. You then simply assign it to the <code>authenticator</code>
property of the <code>ConnectionOptions</code>:</p>
<ul>
<li><code>nkeyAuthenticator(seed?: Uint8Array | (() =&gt; Uint8Array)): Authenticator</code></li>
<li><code>jwtAuthenticator(jwt: string | (() =&gt; string), seed?: Uint8Array | (()=&gt; Uint8Array)): Authenticator</code></li>
<li><code>credsAuthenticator(creds: Uint8Array | (() =&gt; Uint8Array)): Authenticator</code></li>
</ul>
<p>Note that the authenticators provide the ability to specify functions that
return the desired value. This enables dynamic environments such as a browser
where values accessed by fetching a value from a cookie.</p>
<p>Here's an example:</p>
<pre><code class="javascript"><span class="hl-6">// read the creds file as necessary, in the case it</span><br/><span class="hl-6">// is part of the code for illustration purposes (this a partial creds)</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">creds</span><span class="hl-1"> = </span><span class="hl-2">`-----BEGIN NATS USER JWT-----</span><br/><span class="hl-2"> eyJ0eXAiOiJqdSDJB....</span><br/><span class="hl-2"> ------END NATS USER JWT------</span><br/><br/><span class="hl-2">************************* IMPORTANT *************************</span><br/><span class="hl-2"> NKEY Seed printed below can be used sign and prove identity.</span><br/><span class="hl-2"> NKEYs are sensitive and should be treated as secrets.</span><br/><br/><span class="hl-2"> -----BEGIN USER NKEY SEED-----</span><br/><span class="hl-2"> SUAIBDPBAUTW....</span><br/><span class="hl-2"> ------END USER NKEY SEED------</span><br/><span class="hl-2">`</span><span class="hl-1">;</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">(</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">port:</span><span class="hl-1"> </span><span class="hl-8">4222</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">authenticator:</span><span class="hl-1"> </span><span class="hl-0">credsAuthenticator</span><span class="hl-1">(</span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-0">TextEncoder</span><span class="hl-1">().</span><span class="hl-0">encode</span><span class="hl-1">(</span><span class="hl-5">creds</span><span class="hl-1">)),</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">);</span>
</code><button type="button">Copy</button></pre>
<h3 id="flush" class="tsd-anchor-link">Flush<a href="#flush" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Flush sends a <code>PING</code> protocol message to the server. When the server responds
with <code>PONG</code> you are guaranteed that all pending data was sent and received by
the server. Note <code>ping()</code> effectively adds a server round-trip. All NATS clients
handle their buffering optimally, so <code>ping(): Promise&lt;void&gt;</code> shouldn't be used
except in cases where you are writing some sort of test, as you may be degrading
the performance of the client.</p>
<pre><code class="javascript"><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">publish</span><span class="hl-1">(</span><span class="hl-2">&quot;foo&quot;</span><span class="hl-1">);</span><br/><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">publish</span><span class="hl-1">(</span><span class="hl-2">&quot;bar&quot;</span><span class="hl-1">);</span><br/><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">flush</span><span class="hl-1">();</span>
</code><button type="button">Copy</button></pre>
<h3 id="publishoptions" class="tsd-anchor-link"><code>PublishOptions</code><a href="#publishoptions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>When you publish a message you can specify some options:</p>
<ul>
<li><code>reply</code> - this is a subject to receive a reply (you must set up a subscription
on the reply subject) before you publish.</li>
<li><code>headers</code> - a set of headers to decorate the message.</li>
</ul>
<h3 id="subscriptionoptions" class="tsd-anchor-link"><code>SubscriptionOptions</code><a href="#subscriptionoptions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>You can specify several options when creating a subscription:</p>
<ul>
<li><code>max</code>: maximum number of messages to receive - auto unsubscribe</li>
<li><code>timeout</code>: how long to wait for the first message</li>
<li><code>queue</code>: the <a href="#queue-groups">queue group</a> name the subscriber belongs to</li>
<li><code>callback</code>: a function with the signature
<code>(err: Error|null, msg: Msg) =&gt; void;</code> that should be used for handling the
message. Subscriptions with callbacks are NOT iterators.</li>
</ul>
<h4 id="auto-unsubscribe" class="tsd-anchor-link">Auto Unsubscribe<a href="#auto-unsubscribe" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="javascript"><span class="hl-6">// subscriptions can auto unsubscribe after a certain number of messages</span><br/><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;foo&quot;</span><span class="hl-1">, { </span><span class="hl-5">max:</span><span class="hl-1"> </span><span class="hl-8">10</span><span class="hl-1"> });</span>
</code><button type="button">Copy</button></pre>
<h4 id="timeout-subscriptions" class="tsd-anchor-link">Timeout Subscriptions<a href="#timeout-subscriptions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="javascript"><span class="hl-6">// create subscription with a timeout, if no message arrives</span><br/><span class="hl-6">// within the timeout, the subscription throws a timeout error</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">sub</span><span class="hl-1"> = </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">subscribe</span><span class="hl-1">(</span><span class="hl-2">&quot;hello&quot;</span><span class="hl-1">, { </span><span class="hl-5">timeout:</span><span class="hl-1"> </span><span class="hl-8">1000</span><span class="hl-1"> });</span><br/><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">_m</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">sub</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-6">// handle the messages</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})().</span><span class="hl-0">catch</span><span class="hl-1">((</span><span class="hl-5">err</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">if</span><span class="hl-1"> (</span><span class="hl-5">err</span><span class="hl-1"> </span><span class="hl-4">instanceof</span><span class="hl-1"> </span><span class="hl-10">TimeoutError</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`sub timed out!`</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-3">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-2">`sub iterator got an error!`</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">close</span><span class="hl-1">();</span><br/><span class="hl-1">});</span>
</code><button type="button">Copy</button></pre>
<h3 id="requestoptions" class="tsd-anchor-link"><code>RequestOptions</code><a href="#requestoptions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>When making a request, there are several options you can pass:</p>
<ul>
<li><code>timeout</code>: how long to wait for the response</li>
<li><code>headers</code>: optional headers to include with the message</li>
<li><code>noMux</code>: create a new subscription to handle the request. Normally a shared
subscription is used to receive response messages.</li>
<li><code>reply</code>: optional subject where the reply should be sent.</li>
</ul>
<h4 id="nomux-and-reply" class="tsd-anchor-link"><code>noMux</code> and <code>reply</code><a href="#nomux-and-reply" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Under the hood, the request API simply uses a wildcard subscription to handle
all requests you send.</p>
<p>In some cases, the default subscription strategy doesn't work correctly. For
example, a client may be constrained by the subjects where it can receive
replies.</p>
<p>When <code>noMux</code> is set to <code>true</code>, the client will create a normal subscription for
receiving the response to a generated inbox subject before the request is
published. The <code>reply</code> option can be used to override the generated inbox
subject with an application provided one. Note that setting <code>reply</code> requires
<code>noMux</code> to be <code>true</code>:</p>
<pre><code class="typescript"><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">m</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">request</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">&quot;q&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">Empty</span><span class="hl-1">,</span><br/><span class="hl-1"> { </span><span class="hl-5">reply:</span><span class="hl-1"> </span><span class="hl-2">&quot;bar&quot;</span><span class="hl-1">, </span><span class="hl-5">noMux:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">, </span><span class="hl-5">timeout:</span><span class="hl-1"> </span><span class="hl-8">1000</span><span class="hl-1"> },</span><br/><span class="hl-1">);</span>
</code><button type="button">Copy</button></pre>
<h3 id="draining-connections-and-subscriptions" class="tsd-anchor-link">Draining Connections and Subscriptions<a href="#draining-connections-and-subscriptions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Draining provides for a graceful way to unsubscribe or close a connection
without losing messages that have already been dispatched to the client.</p>
<p>You can drain a subscription or all subscriptions in a connection.</p>
<p>When you drain a subscription, the client sends an <code>unsubscribe</code> protocol
message to the server followed by a <code>flush</code>. The subscription handler is only
removed after the server responds. Thus all pending messages for the
subscription have been processed.</p>
<p>Draining a connection, drains all subscriptions. However when you drain the
connection it becomes impossible to make new subscriptions or send new requests.
After the last subscription is drained it also becomes impossible to publish a
message. These restrictions do not exist when just draining a subscription.</p>
<h3 id="lifecycle-and-informational-events" class="tsd-anchor-link">Lifecycle and Informational Events<a href="#lifecycle-and-informational-events" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Clients can get notification on various event types by calling
<code>status(): AsyncIterable&lt;Status&gt;</code> on the connection, the currently included
status <code>type</code>s include:</p>
<ul>
<li><code>disconnect</code> - the client disconnected from the specified <code>server</code></li>
<li><code>reconnect</code> - the client reconnected to the specified <code>server</code></li>
<li><code>reconnecting</code> - the client is in its reconnect loop</li>
<li><code>update</code> - the cluster configuration has been updated, if servers were added
the <code>added</code> list will specify them, if servers were deleted servers the
<code>deleted</code> list will specify them.</li>
<li><code>ldm</code> - the server has started its lame duck mode and will evict clients</li>
<li><code>error</code> - an async error (such as a permission violation) was received, the
error is specified in the <code>error</code> property. Note that permission errors for
subscriptions are also notified to the subscription.</li>
<li><code>ping</code> - the server has not received a response for client pings, the number
of outstanding pings are notified in the <code>pendingPings</code> property. Note that
this should onlyl be <code>1</code> under normal operations.</li>
<li><code>staleConnection</code> - the connection is stale (client will reconnect)</li>
<li><code>forceReconnect</code> - the client has been instructed to reconnect because of
user-code (<code>reconnect()</code>)</li>
<li><code>close</code> - the client has closed, no further reconnects will be attempted.</li>
</ul>
<pre><code class="javascript"><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">nc</span><span class="hl-1"> = </span><span class="hl-3">await</span><span class="hl-1"> </span><span class="hl-0">connect</span><span class="hl-1">(</span><span class="hl-5">opts</span><span class="hl-1">);</span><br/><span class="hl-1">(</span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">info</span><span class="hl-1">(</span><span class="hl-2">`connected </span><span class="hl-4">${</span><span class="hl-5">nc</span><span class="hl-9">.</span><span class="hl-0">getServer</span><span class="hl-9">()</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">for</span><span class="hl-1"> </span><span class="hl-3">await</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-7">s</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">status</span><span class="hl-1">()) {</span><br/><span class="hl-1"> </span><span class="hl-3">switch</span><span class="hl-1"> (</span><span class="hl-5">s</span><span class="hl-1">.</span><span class="hl-5">type</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-3">case</span><span class="hl-1"> </span><span class="hl-2">&quot;disconnect&quot;</span><span class="hl-1">:</span><br/><span class="hl-1"> </span><span class="hl-3">case</span><span class="hl-1"> </span><span class="hl-2">&quot;reconnect&quot;</span><span class="hl-1">:</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><span class="hl-5">s</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-3">break</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-3">default</span><span class="hl-1">:</span><br/><span class="hl-1"> </span><span class="hl-6">// ignored</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">})().</span><span class="hl-0">then</span><span class="hl-1">();</span><br/><br/><span class="hl-5">nc</span><span class="hl-1">.</span><span class="hl-0">closed</span><span class="hl-1">()</span><br/><span class="hl-1"> .</span><span class="hl-0">then</span><span class="hl-1">((</span><span class="hl-5">err</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-5">console</span><span class="hl-1">.</span><span class="hl-0">log</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">`connection closed </span><span class="hl-4">${</span><span class="hl-5">err</span><span class="hl-9"> </span><span class="hl-1">?</span><span class="hl-9"> </span><span class="hl-2">&quot; with error: &quot;</span><span class="hl-9"> </span><span class="hl-1">+</span><span class="hl-9"> </span><span class="hl-5">err</span><span class="hl-9">.</span><span class="hl-5">message</span><span class="hl-9"> </span><span class="hl-1">:</span><span class="hl-9"> </span><span class="hl-2">&quot;&quot;</span><span class="hl-4">}</span><span class="hl-2">`</span><span class="hl-1">,</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> });</span>
</code><button type="button">Copy</button></pre>
<p>Be aware that when a client closes, you will need to wait for the <code>closed()</code>
promise to resolve. When it resolves, the client is done and will not reconnect.</p>
<h3 id="async-vs-callbacks" class="tsd-anchor-link">Async vs. Callbacks<a href="#async-vs-callbacks" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Previous versions of the JavaScript NATS clients specified callbacks for message
processing. This required complex handling logic when a service required
coordination of operations. Callbacks are an inversion of control anti-pattern.</p>
<p>The async APIs trivialize complex coordination and makes your code easier to
maintain. With that said, there are some implications:</p>
<ul>
<li>Async subscriptions buffer inbound messages.</li>
<li>Subscription processing delays until the runtime executes the promise related
microtasks at the end of an event loop.</li>
</ul>
<p>In a traditional callback-based library, I/O happens after all data yielded by a
read in the current event loop completes processing. This means that callbacks
are invoked as part of processing. With async, the processing is queued in a
microtask queue. At the end of the event loop, the runtime processes the
microtasks, which in turn resumes your functions. As expected, this increases
latency, but also provides additional liveliness.</p>
<p>To reduce async latency, the NATS client allows processing a subscription in the
same event loop that dispatched the message. Simply specify a <code>callback</code> in the
subscription options. The signature for a callback is
<code>(err: (NatsError|null), msg: Msg) =&gt; void</code>. When specified, the subscription
iterator will never yield a message, as the callback will intercept all
messages.</p>
<p>Note that <code>callback</code> likely shouldn't even be documented, as likely it is a
workaround to an underlying application problem where you should be considering
a different strategy to horizontally scale your application, or reduce pressure
on the clients, such as using queue workers, or more explicitly targeting
messages. With that said, there are many situations where using callbacks can be
more performant or appropriate.</p>
<h2 id="connection-options" class="tsd-anchor-link">Connection Options<a href="#connection-options" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>The following is the list of connection options and default values.</p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>authenticator</code></td>
<td>none</td>
<td>Specifies the authenticator function that sets the client credentials.</td>
</tr>
<tr>
<td><code>debug</code></td>
<td><code>false</code></td>
<td>If <code>true</code>, the client prints protocol interactions to the console. Useful for debugging.</td>
</tr>
<tr>
<td><code>ignoreClusterUpdates</code></td>
<td><code>false</code></td>
<td>If <code>true</code> the client will ignore any cluster updates provided by the server.</td>
</tr>
<tr>
<td><code>ignoreAuthErrorAbort</code></td>
<td><code>false</code></td>
<td>Prevents client connection aborts if the client fails more than twice in a row with an authentication error</td>
</tr>
<tr>
<td><code>inboxPrefix</code></td>
<td><code>&quot;_INBOX&quot;</code></td>
<td>Sets de prefix for automatically created inboxes - <code>createInbox(prefix)</code></td>
</tr>
<tr>
<td><code>maxPingOut</code></td>
<td><code>2</code></td>
<td>Max number of pings the client will allow unanswered before raising a stale connection error.</td>
</tr>
<tr>
<td><code>maxReconnectAttempts</code></td>
<td><code>10</code></td>
<td>Sets the maximum number of reconnect attempts. The value of <code>-1</code> specifies no limit.</td>
</tr>
<tr>
<td><code>name</code></td>
<td></td>
<td>Optional client name - recommended to be set to a unique client name.</td>
</tr>
<tr>
<td><code>noAsyncTraces</code></td>
<td><code>false</code></td>
<td>When <code>true</code> the client will not add additional context to errors associated with request operations. Setting this option to <code>true</code> will greatly improve performance of request/reply and JetStream publishers.</td>
</tr>
<tr>
<td><code>noEcho</code></td>
<td><code>false</code></td>
<td>Subscriptions receive messages published by the client. Requires server support (1.2.0). If set to true, and the server does not support the feature, an error with code <code>NO_ECHO_NOT_SUPPORTED</code> is emitted, and the connection is aborted. Note that it is possible for this error to be emitted on reconnect when the server reconnects to a server that does not support the feature.</td>
</tr>
<tr>
<td><code>noRandomize</code></td>
<td><code>false</code></td>
<td>If set, the order of user-specified servers is randomized.</td>
</tr>
<tr>
<td><code>noResolve</code></td>
<td>none</td>
<td>If true, client will not resolve host names.</td>
</tr>
<tr>
<td><code>pass</code></td>
<td></td>
<td>Sets the password for a connection.</td>
</tr>
<tr>
<td><code>pedantic</code></td>
<td><code>false</code></td>
<td>Turns on strict subject format checks.</td>
</tr>
<tr>
<td><code>pingInterval</code></td>
<td><code>120000</code></td>
<td>Number of milliseconds between client-sent pings.</td>
</tr>
<tr>
<td><code>port</code></td>
<td><code>4222</code></td>
<td>Port to connect to (only used if <code>servers</code> is not specified).</td>
</tr>
<tr>
<td><code>reconnect</code></td>
<td><code>true</code></td>
<td>If false, client will not attempt reconnecting.</td>
</tr>
<tr>
<td><code>reconnectDelayHandler</code></td>
<td>Generated function</td>
<td>A function that returns the number of millis to wait before the next connection to a server it connected to <code>()=&gt;number</code>.</td>
</tr>
<tr>
<td><code>reconnectJitter</code></td>
<td><code>100</code></td>
<td>Number of millis to randomize after <code>reconnectTimeWait</code>.</td>
</tr>
<tr>
<td><code>reconnectJitterTLS</code></td>
<td><code>1000</code></td>
<td>Number of millis to randomize after <code>reconnectTimeWait</code> when TLS options are specified.</td>
</tr>
<tr>
<td><code>reconnectTimeWait</code></td>
<td><code>2000</code></td>
<td>If disconnected, the client will wait the specified number of milliseconds between reconnect attempts.</td>
</tr>
<tr>
<td><code>servers</code></td>
<td><code>&quot;localhost:4222&quot;</code></td>
<td>String or Array of hostport for servers.</td>
</tr>
<tr>
<td><code>timeout</code></td>
<td>20000</td>
<td>Number of milliseconds the client will wait for a connection to be established. If it fails it will emit a <code>connection_timeout</code> event with a NatsError that provides the hostport of the server where the connection was attempted.</td>
</tr>
<tr>
<td><code>tls</code></td>
<td>TlsOptions</td>
<td>A configuration object for requiring a TLS connection (not applicable to <a href="http://nats.ws">nats.ws</a>).</td>
</tr>
<tr>
<td><code>token</code></td>
<td></td>
<td>Sets a authorization token for a connection.</td>
</tr>
<tr>
<td><code>user</code></td>
<td></td>
<td>Sets the username for a connection.</td>
</tr>
<tr>
<td><code>verbose</code></td>
<td><code>false</code></td>
<td>Turns on <code>+OK</code> protocol acknowledgements.</td>
</tr>
<tr>
<td><code>waitOnFirstConnect</code></td>
<td><code>false</code></td>
<td>If <code>true</code> the client will fall back to a reconnect mode if it fails its first connection attempt.</td>
</tr>
</tbody>
</table>
<h3 id="tlsoptions" class="tsd-anchor-link">TlsOptions<a href="#tlsoptions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><table>
<thead>
<tr>
<th>Option</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ca</code></td>
<td>N/A</td>
<td>CA certificate</td>
</tr>
<tr>
<td><code>caFile</code></td>
<td></td>
<td>CA certificate filepath</td>
</tr>
<tr>
<td><code>cert</code></td>
<td>N/A</td>
<td>Client certificate</td>
</tr>
<tr>
<td><code>certFile</code></td>
<td>N/A</td>
<td>Client certificate file path</td>
</tr>
<tr>
<td><code>key</code></td>
<td>N/A</td>
<td>Client key</td>
</tr>
<tr>
<td><code>keyFile</code></td>
<td>N/A</td>
<td>Client key file path</td>
</tr>
<tr>
<td><code>handshakeFirst</code></td>
<td>false</td>
<td>Connects to the server directly as TLS rather than upgrade the connection. Note that the server must be configured accordingly.</td>
</tr>
</tbody>
</table>
<p>In some Node and Deno clients, having the option set to an empty option,
requires the client have a secured connection.</p>
<h3 id="jitter" class="tsd-anchor-link">Jitter<a href="#jitter" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>The settings <code>reconnectTimeWait</code>, <code>reconnectJitter</code>, <code>reconnectJitterTLS</code>,
<code>reconnectDelayHandler</code> are all related. They control how long before the NATS
client attempts to reconnect to a server it has previously connected.</p>
<p>The intention of the settings is to spread out the number of clients attempting
to reconnect to a server over a period of time, and thus preventing a
<a href="https://docs.nats.io/developing-with-nats/reconnect/random">&quot;Thundering Herd&quot;</a>.</p>
<p>The relationship between these is:</p>
<ul>
<li>If <code>reconnectDelayHandler</code> is specified, the client will wait the value
returned by this function. No other value will be taken into account.</li>
<li>If the client specified TLS options, the client will generate a number between
0 and <code>reconnectJitterTLS</code> and add it to <code>reconnectTimeWait</code>.</li>
<li>If the client didn't specify TLS options, the client will generate a number
between 0 and <code>reconnectJitter</code> and add it to <code>reconnectTimeWait</code>.</li>
</ul>
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#core"><span>Core</span></a><ul><li><a href="#websocket-support"><span>Web<wbr/>Socket <wbr/>Support</span></a></li></ul><a href="#installation"><span>Installation</span></a><ul><li><a href="#npm"><span>NPM</span></a></li><li><a href="#jsr"><span>JSR</span></a></li><li><a href="#referencing-the-library"><span>Referencing the library</span></a></li><li><a href="#basics"><span>Basics</span></a></li><li><ul><li><a href="#connecting-to-a-nats-server"><span>Connecting to a nats-<wbr/>server</span></a></li><li><a href="#publish-and-subscribe"><span>Publish and <wbr/>Subscribe</span></a></li><li><a href="#wildcard-subscriptions"><span>Wildcard <wbr/>Subscriptions</span></a></li><li><a href="#services-requestreply"><span>Services: <wbr/>Request/<wbr/>Reply</span></a></li><li><ul><li><a href="#services"><span>Services</span></a></li><li><a href="#making-requests"><span>Making <wbr/>Requests</span></a></li></ul></li><li><a href="#queue-groups"><span>Queue <wbr/>Groups</span></a></li></ul></li><li><a href="#advanced-usage"><span>Advanced <wbr/>Usage</span></a></li><li><ul><li><a href="#headers"><span>Headers</span></a></li><li><a href="#no-responders"><span>No <wbr/>Responders</span></a></li><li><a href="#authentication"><span>Authentication</span></a></li><li><ul><li><a href="#authenticators"><span>Authenticators</span></a></li></ul></li><li><a href="#flush"><span>Flush</span></a></li><li><a href="#publishoptions"><span>Publish<wbr/>Options</span></a></li><li><a href="#subscriptionoptions"><span>Subscription<wbr/>Options</span></a></li><li><ul><li><a href="#auto-unsubscribe"><span>Auto <wbr/>Unsubscribe</span></a></li><li><a href="#timeout-subscriptions"><span>Timeout <wbr/>Subscriptions</span></a></li></ul></li><li><a href="#requestoptions"><span>Request<wbr/>Options</span></a></li><li><ul><li><a href="#nomux-and-reply"><span>no<wbr/>Mux and reply</span></a></li></ul></li><li><a href="#draining-connections-and-subscriptions"><span>Draining <wbr/>Connections and <wbr/>Subscriptions</span></a></li><li><a href="#lifecycle-and-informational-events"><span>Lifecycle and <wbr/>Informational <wbr/>Events</span></a></li><li><a href="#async-vs-callbacks"><span>Async vs. <wbr/>Callbacks</span></a></li></ul></li><li><a href="#connection-options"><span>Connection <wbr/>Options</span></a></li><li><ul><li><a href="#tlsoptions"><span>Tls<wbr/>Options</span></a></li><li><a href="#jitter"><span>Jitter</span></a></li></ul></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">@nats-io/nats-core</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>