Comparing version 0.0.20210930 to 0.0.20220501
@@ -1,8 +0,6 @@ | ||
import { __importDefault, __importStar } from "tslib"; | ||
import { Data, Interest, Nack } from "@ndn/packet"; | ||
import { toHex } from "@ndn/tlv"; | ||
import _cjsDefaultImport0 from "mnemonist/multi-set.js"; const MultiSet = __importDefault(_cjsDefaultImport0).default; | ||
import { Data, Interest, Nack, Name, NameMultiSet } from "@ndn/packet"; | ||
import { safeIter } from "@ndn/util"; | ||
import { pushable } from "it-pushable"; | ||
import { EventEmitter } from "events"; | ||
import _cjsDefaultImport1 from "p-fifo"; const Fifo = __importDefault(_cjsDefaultImport1).default; | ||
import { buffer, filter, pipeline, tap } from "streaming-iterables"; | ||
import { filter, pipeline, tap } from "streaming-iterables"; | ||
function duplexFromRxTx(rxtx) { | ||
@@ -26,3 +24,3 @@ return (iterable) => { | ||
} | ||
return announcement; | ||
return Name.from(announcement); | ||
} | ||
@@ -34,7 +32,6 @@ export class FaceImpl extends EventEmitter { | ||
this.rxtx = rxtx; | ||
this.routes = new MultiSet(); | ||
this.announcements = new MultiSet(); | ||
this.routes = new NameMultiSet(); | ||
this.announcements = new NameMultiSet(); | ||
this.running = true; | ||
this.txQueue = new Fifo(); | ||
this.txQueueLength = 0; | ||
this.txQueue = pushable(); | ||
this.handleLowerUp = () => { | ||
@@ -74,3 +71,3 @@ this.emit("up"); | ||
fw.faces.add(this); | ||
void pipeline(() => this.txLoop(), buffer(this.fw.options.faceTxBuffer), tap((pkt) => fw.emit("pkttx", this, pkt)), duplexFromRxTx(rxtx), tap((pkt) => fw.emit("pktrx", this, pkt)), buffer(this.fw.options.faceRxBuffer), this.rxLoop); | ||
void pipeline(() => this.txLoop(), tap((pkt) => fw.emit("pkttx", this, pkt)), duplexFromRxTx(rxtx), tap((pkt) => fw.emit("pktrx", this, pkt)), this.rxLoop); | ||
rxtx.on?.("up", this.handleLowerUp); | ||
@@ -87,9 +84,9 @@ rxtx.on?.("down", this.handleLowerDown); | ||
this.fw.faces.delete(this); | ||
for (const nameHex of this.routes.keys()) { | ||
this.fw.fib.delete(this, nameHex); | ||
for (const [name] of this.routes.multiplicities()) { | ||
this.fw.fib.delete(this, name.valueHex); | ||
} | ||
for (const nameHex of this.announcements.keys()) { | ||
this.fw.readvertise.removeAnnouncement(this, undefined, nameHex); | ||
for (const [name] of this.announcements.multiplicities()) { | ||
this.fw.readvertise.removeAnnouncement(this, name); | ||
} | ||
void this.txQueue.push(false); | ||
this.txQueue.end(new Error("close")); | ||
this.emit("close"); | ||
@@ -101,11 +98,11 @@ this.fw.emit("facerm", this); | ||
} | ||
hasRoute(name) { | ||
return this.routes.has(toHex(name.value)); | ||
hasRoute(nameInput) { | ||
const name = Name.from(nameInput); | ||
return this.routes.count(name) > 0; | ||
} | ||
addRoute(name, announcement = true) { | ||
addRoute(nameInput, announcement = true) { | ||
const name = Name.from(nameInput); | ||
this.fw.emit("prefixadd", this, name); | ||
const nameHex = toHex(name.value); | ||
this.routes.add(nameHex); | ||
if (this.routes.count(nameHex) === 1) { | ||
this.fw.fib.insert(this, nameHex, this.attributes.routeCapture); | ||
if (this.routes.add(name) === 1) { | ||
this.fw.fib.insert(this, name.valueHex, this.attributes.routeCapture); | ||
} | ||
@@ -117,3 +114,4 @@ const ann = computeAnnouncement(name, announcement); | ||
} | ||
removeRoute(name, announcement = true) { | ||
removeRoute(nameInput, announcement = true) { | ||
const name = Name.from(nameInput); | ||
const ann = computeAnnouncement(name, announcement); | ||
@@ -123,27 +121,23 @@ if (ann) { | ||
} | ||
const nameHex = toHex(name.value); | ||
this.routes.remove(nameHex); | ||
if (this.routes.count(nameHex) === 0) { | ||
this.fw.fib.delete(this, nameHex); | ||
if (this.routes.remove(name) === 0) { | ||
this.fw.fib.delete(this, name.valueHex); | ||
} | ||
this.fw.emit("prefixrm", this, name); | ||
} | ||
addAnnouncement(name) { | ||
addAnnouncement(nameInput) { | ||
if (!this.attributes.advertiseFrom) { | ||
return; | ||
} | ||
const nameHex = toHex(name.value); | ||
this.announcements.add(nameHex); | ||
if (this.announcements.count(nameHex) === 1) { | ||
this.fw.readvertise.addAnnouncement(this, name, nameHex); | ||
const name = Name.from(nameInput); | ||
if (this.announcements.add(name) === 1) { | ||
this.fw.readvertise.addAnnouncement(this, name); | ||
} | ||
} | ||
removeAnnouncement(name) { | ||
removeAnnouncement(nameInput) { | ||
if (!this.attributes.advertiseFrom) { | ||
return; | ||
} | ||
const nameHex = toHex(name.value); | ||
this.announcements.remove(nameHex); | ||
if (this.announcements.count(nameHex) === 0) { | ||
this.fw.readvertise.removeAnnouncement(this, name, nameHex); | ||
const name = Name.from(nameInput); | ||
if (this.announcements.remove(name) === 0) { | ||
this.fw.readvertise.removeAnnouncement(this, name); | ||
} | ||
@@ -156,21 +150,7 @@ } | ||
} | ||
void (async () => { | ||
++this.txQueueLength; | ||
await this.txQueue.push(pkt); | ||
--this.txQueueLength; | ||
})(); | ||
this.txQueue.push(pkt); | ||
} | ||
async *txLoop() { | ||
while (true) { | ||
const pkt = await this.txQueue.shift(); | ||
if (!this.running || pkt === false) { | ||
break; | ||
} | ||
yield pkt; | ||
} | ||
while (!this.txQueue.isEmpty()) { | ||
void this.txQueue.shift(); | ||
} | ||
this.close(); | ||
txLoop() { | ||
return safeIter(this.txQueue); | ||
} | ||
} |
@@ -1,8 +0,6 @@ | ||
import { __importDefault, __importStar } from "tslib"; | ||
import { Data, Interest, Nack } from "@ndn/packet"; | ||
import { toHex } from "@ndn/tlv"; | ||
import _cjsDefaultImport0 from "mnemonist/multi-set.js"; const MultiSet = __importDefault(_cjsDefaultImport0).default; | ||
import { Data, Interest, Nack, Name, NameMultiSet } from "@ndn/packet"; | ||
import { safeIter } from "@ndn/util"; | ||
import { pushable } from "it-pushable"; | ||
import { EventEmitter } from "node:events"; | ||
import _cjsDefaultImport1 from "p-fifo"; const Fifo = __importDefault(_cjsDefaultImport1).default; | ||
import { buffer, filter, pipeline, tap } from "streaming-iterables"; | ||
import { filter, pipeline, tap } from "streaming-iterables"; | ||
function duplexFromRxTx(rxtx) { | ||
@@ -26,3 +24,3 @@ return (iterable) => { | ||
} | ||
return announcement; | ||
return Name.from(announcement); | ||
} | ||
@@ -34,7 +32,6 @@ export class FaceImpl extends EventEmitter { | ||
this.rxtx = rxtx; | ||
this.routes = new MultiSet(); | ||
this.announcements = new MultiSet(); | ||
this.routes = new NameMultiSet(); | ||
this.announcements = new NameMultiSet(); | ||
this.running = true; | ||
this.txQueue = new Fifo(); | ||
this.txQueueLength = 0; | ||
this.txQueue = pushable(); | ||
this.handleLowerUp = () => { | ||
@@ -74,3 +71,3 @@ this.emit("up"); | ||
fw.faces.add(this); | ||
void pipeline(() => this.txLoop(), buffer(this.fw.options.faceTxBuffer), tap((pkt) => fw.emit("pkttx", this, pkt)), duplexFromRxTx(rxtx), tap((pkt) => fw.emit("pktrx", this, pkt)), buffer(this.fw.options.faceRxBuffer), this.rxLoop); | ||
void pipeline(() => this.txLoop(), tap((pkt) => fw.emit("pkttx", this, pkt)), duplexFromRxTx(rxtx), tap((pkt) => fw.emit("pktrx", this, pkt)), this.rxLoop); | ||
rxtx.on?.("up", this.handleLowerUp); | ||
@@ -87,9 +84,9 @@ rxtx.on?.("down", this.handleLowerDown); | ||
this.fw.faces.delete(this); | ||
for (const nameHex of this.routes.keys()) { | ||
this.fw.fib.delete(this, nameHex); | ||
for (const [name] of this.routes.multiplicities()) { | ||
this.fw.fib.delete(this, name.valueHex); | ||
} | ||
for (const nameHex of this.announcements.keys()) { | ||
this.fw.readvertise.removeAnnouncement(this, undefined, nameHex); | ||
for (const [name] of this.announcements.multiplicities()) { | ||
this.fw.readvertise.removeAnnouncement(this, name); | ||
} | ||
void this.txQueue.push(false); | ||
this.txQueue.end(new Error("close")); | ||
this.emit("close"); | ||
@@ -101,11 +98,11 @@ this.fw.emit("facerm", this); | ||
} | ||
hasRoute(name) { | ||
return this.routes.has(toHex(name.value)); | ||
hasRoute(nameInput) { | ||
const name = Name.from(nameInput); | ||
return this.routes.count(name) > 0; | ||
} | ||
addRoute(name, announcement = true) { | ||
addRoute(nameInput, announcement = true) { | ||
const name = Name.from(nameInput); | ||
this.fw.emit("prefixadd", this, name); | ||
const nameHex = toHex(name.value); | ||
this.routes.add(nameHex); | ||
if (this.routes.count(nameHex) === 1) { | ||
this.fw.fib.insert(this, nameHex, this.attributes.routeCapture); | ||
if (this.routes.add(name) === 1) { | ||
this.fw.fib.insert(this, name.valueHex, this.attributes.routeCapture); | ||
} | ||
@@ -117,3 +114,4 @@ const ann = computeAnnouncement(name, announcement); | ||
} | ||
removeRoute(name, announcement = true) { | ||
removeRoute(nameInput, announcement = true) { | ||
const name = Name.from(nameInput); | ||
const ann = computeAnnouncement(name, announcement); | ||
@@ -123,27 +121,23 @@ if (ann) { | ||
} | ||
const nameHex = toHex(name.value); | ||
this.routes.remove(nameHex); | ||
if (this.routes.count(nameHex) === 0) { | ||
this.fw.fib.delete(this, nameHex); | ||
if (this.routes.remove(name) === 0) { | ||
this.fw.fib.delete(this, name.valueHex); | ||
} | ||
this.fw.emit("prefixrm", this, name); | ||
} | ||
addAnnouncement(name) { | ||
addAnnouncement(nameInput) { | ||
if (!this.attributes.advertiseFrom) { | ||
return; | ||
} | ||
const nameHex = toHex(name.value); | ||
this.announcements.add(nameHex); | ||
if (this.announcements.count(nameHex) === 1) { | ||
this.fw.readvertise.addAnnouncement(this, name, nameHex); | ||
const name = Name.from(nameInput); | ||
if (this.announcements.add(name) === 1) { | ||
this.fw.readvertise.addAnnouncement(this, name); | ||
} | ||
} | ||
removeAnnouncement(name) { | ||
removeAnnouncement(nameInput) { | ||
if (!this.attributes.advertiseFrom) { | ||
return; | ||
} | ||
const nameHex = toHex(name.value); | ||
this.announcements.remove(nameHex); | ||
if (this.announcements.count(nameHex) === 0) { | ||
this.fw.readvertise.removeAnnouncement(this, name, nameHex); | ||
const name = Name.from(nameInput); | ||
if (this.announcements.remove(name) === 0) { | ||
this.fw.readvertise.removeAnnouncement(this, name); | ||
} | ||
@@ -156,21 +150,7 @@ } | ||
} | ||
void (async () => { | ||
++this.txQueueLength; | ||
await this.txQueue.push(pkt); | ||
--this.txQueueLength; | ||
})(); | ||
this.txQueue.push(pkt); | ||
} | ||
async *txLoop() { | ||
while (true) { | ||
const pkt = await this.txQueue.shift(); | ||
if (!this.running || pkt === false) { | ||
break; | ||
} | ||
yield pkt; | ||
} | ||
while (!this.txQueue.isEmpty()) { | ||
void this.txQueue.shift(); | ||
} | ||
this.close(); | ||
txLoop() { | ||
return safeIter(this.txQueue); | ||
} | ||
} |
@@ -1,6 +0,6 @@ | ||
import { Name } from "@ndn/packet"; | ||
import { type NameLike } from "@ndn/packet"; | ||
import type TypedEmitter from "typed-emitter"; | ||
import type { Forwarder, ForwarderImpl } from "./forwarder"; | ||
import type { FwPacket } from "./packet"; | ||
interface Events { | ||
declare type Events = { | ||
/** Emitted upon face is up as reported by lower layer. */ | ||
@@ -12,3 +12,3 @@ up: () => void; | ||
close: () => void; | ||
} | ||
}; | ||
/** A socket or network interface associated with forwarding plane. */ | ||
@@ -19,3 +19,2 @@ export interface FwFace extends TypedEmitter<Events> { | ||
readonly running: boolean; | ||
readonly txQueueLength: number; | ||
/** Shutdown the face. */ | ||
@@ -25,11 +24,11 @@ close(): void; | ||
/** Determine if a route is present on the face. */ | ||
hasRoute(name: Name): boolean; | ||
hasRoute(name: NameLike): boolean; | ||
/** Add a route toward the face. */ | ||
addRoute(name: Name, announcement?: FwFace.RouteAnnouncement): void; | ||
addRoute(name: NameLike, announcement?: FwFace.RouteAnnouncement): void; | ||
/** Remove a route toward the face. */ | ||
removeRoute(name: Name, announcement?: FwFace.RouteAnnouncement): void; | ||
removeRoute(name: NameLike, announcement?: FwFace.RouteAnnouncement): void; | ||
/** Add a prefix announcement associated with the face. */ | ||
addAnnouncement(name: Name): void; | ||
addAnnouncement(name: NameLike): void; | ||
/** Remove a prefix announcement associated with the face. */ | ||
removeAnnouncement(name: Name): void; | ||
removeAnnouncement(name: NameLike): void; | ||
} | ||
@@ -51,9 +50,11 @@ export declare namespace FwFace { | ||
} | ||
type RouteAnnouncement = boolean | number | Name; | ||
interface RxTxEvents { | ||
type RouteAnnouncement = boolean | number | NameLike; | ||
type RxTxEvents = { | ||
up: () => void; | ||
down: () => void; | ||
} | ||
interface RxTxBase extends Partial<TypedEmitter<RxTxEvents>> { | ||
}; | ||
interface RxTxBase { | ||
readonly attributes?: Attributes; | ||
on?: (...args: Parameters<TypedEmitter<RxTxEvents>["on"]>) => void; | ||
off?: (...args: Parameters<TypedEmitter<RxTxEvents>["off"]>) => void; | ||
} | ||
@@ -81,11 +82,10 @@ interface RxTx extends RxTxBase { | ||
private readonly txQueue; | ||
txQueueLength: number; | ||
constructor(fw: ForwarderImpl, rxtx: FwFace.RxTx | FwFace.RxTxDuplex, attributes: FwFace.Attributes); | ||
close(): void; | ||
toString(): string; | ||
hasRoute(name: Name): boolean; | ||
addRoute(name: Name, announcement?: FwFace.RouteAnnouncement): void; | ||
removeRoute(name: Name, announcement?: FwFace.RouteAnnouncement): void; | ||
addAnnouncement(name: Name): void; | ||
removeAnnouncement(name: Name): void; | ||
hasRoute(nameInput: NameLike): boolean; | ||
addRoute(nameInput: NameLike, announcement?: FwFace.RouteAnnouncement): void; | ||
removeRoute(nameInput: NameLike, announcement?: FwFace.RouteAnnouncement): void; | ||
addAnnouncement(nameInput: NameLike): void; | ||
removeAnnouncement(nameInput: NameLike): void; | ||
/** Transmit a packet on the face. */ | ||
@@ -92,0 +92,0 @@ send(pkt: FwPacket): void; |
import { __importDefault, __importStar } from "tslib"; | ||
import { lpm } from "@ndn/packet"; | ||
import _cjsDefaultImport0 from "minimalistic-assert"; const assert = __importDefault(_cjsDefaultImport0).default; | ||
import _cjsDefaultImport1 from "mnemonist/default-map.js"; const DefaultMap = __importDefault(_cjsDefaultImport1).default; | ||
import { assert } from "@ndn/util"; | ||
import _cjsDefaultImport0 from "mnemonist/default-map.js"; const DefaultMap = __importDefault(_cjsDefaultImport0).default; | ||
class FibEntry { | ||
@@ -33,3 +33,3 @@ constructor() { | ||
result.add(nh); | ||
capture || (capture = c); | ||
capture ||= c; | ||
} | ||
@@ -36,0 +36,0 @@ if (capture) { |
import { __importDefault, __importStar } from "tslib"; | ||
import { lpm } from "@ndn/packet"; | ||
import _cjsDefaultImport0 from "minimalistic-assert"; const assert = __importDefault(_cjsDefaultImport0).default; | ||
import _cjsDefaultImport1 from "mnemonist/default-map.js"; const DefaultMap = __importDefault(_cjsDefaultImport1).default; | ||
import { assert } from "@ndn/util"; | ||
import _cjsDefaultImport0 from "mnemonist/default-map.js"; const DefaultMap = __importDefault(_cjsDefaultImport0).default; | ||
class FibEntry { | ||
@@ -33,3 +33,3 @@ constructor() { | ||
result.add(nh); | ||
capture || (capture = c); | ||
capture ||= c; | ||
} | ||
@@ -36,0 +36,0 @@ if (capture) { |
@@ -1,2 +0,2 @@ | ||
import { Name } from "@ndn/packet"; | ||
import { type Name } from "@ndn/packet"; | ||
import type { FaceImpl } from "./face"; | ||
@@ -7,3 +7,3 @@ export declare class Fib { | ||
delete(face: FaceImpl, nameHex: string): void; | ||
lookup(name: Name): Set<FaceImpl>; | ||
lookup(name: Name): ReadonlySet<FaceImpl>; | ||
} |
@@ -9,4 +9,2 @@ import { EventEmitter } from "events"; | ||
Forwarder.DefaultOptions = { | ||
faceRxBuffer: 16, | ||
faceTxBuffer: 16, | ||
dataNoTokenMatch: true, | ||
@@ -44,5 +42,5 @@ }; | ||
export class ForwarderImpl extends EventEmitter { | ||
constructor(options) { | ||
constructor(opts) { | ||
super(); | ||
this.options = options; | ||
this.opts = opts; | ||
this.nodeNames = []; | ||
@@ -52,3 +50,3 @@ this.faces = new Set(); | ||
this.readvertise = new Readvertise(this); | ||
this.pit = new Pit(options.dataNoTokenMatch); | ||
this.pit = new Pit(opts.dataNoTokenMatch); | ||
} | ||
@@ -59,3 +57,3 @@ addFace(face, attributes = {}) { | ||
pickInterestForwardingName(interest) { | ||
const fhName = interest.fwHint?.delegations[0]?.name; | ||
const fhName = interest.fwHint?.delegations[0]; | ||
if (fhName && this.nodeNames.every((nodeName) => !fhName.isPrefixOf(nodeName))) { | ||
@@ -95,3 +93,6 @@ return fhName; | ||
this.readvertise.close(); | ||
for (const face of this.faces) { | ||
face.close(); | ||
} | ||
} | ||
} |
@@ -9,4 +9,2 @@ import { EventEmitter } from "node:events"; | ||
Forwarder.DefaultOptions = { | ||
faceRxBuffer: 16, | ||
faceTxBuffer: 16, | ||
dataNoTokenMatch: true, | ||
@@ -44,5 +42,5 @@ }; | ||
export class ForwarderImpl extends EventEmitter { | ||
constructor(options) { | ||
constructor(opts) { | ||
super(); | ||
this.options = options; | ||
this.opts = opts; | ||
this.nodeNames = []; | ||
@@ -52,3 +50,3 @@ this.faces = new Set(); | ||
this.readvertise = new Readvertise(this); | ||
this.pit = new Pit(options.dataNoTokenMatch); | ||
this.pit = new Pit(opts.dataNoTokenMatch); | ||
} | ||
@@ -59,3 +57,3 @@ addFace(face, attributes = {}) { | ||
pickInterestForwardingName(interest) { | ||
const fhName = interest.fwHint?.delegations[0]?.name; | ||
const fhName = interest.fwHint?.delegations[0]; | ||
if (fhName && this.nodeNames.every((nodeName) => !fhName.isPrefixOf(nodeName))) { | ||
@@ -95,3 +93,6 @@ return fhName; | ||
this.readvertise.close(); | ||
for (const face of this.faces) { | ||
face.close(); | ||
} | ||
} | ||
} |
@@ -1,4 +0,4 @@ | ||
import { Data, Interest, Nack, Name } from "@ndn/packet"; | ||
import type { Data, Interest, Nack, Name } from "@ndn/packet"; | ||
import type TypedEmitter from "typed-emitter"; | ||
import { FaceImpl, FwFace } from "./face"; | ||
import { type FwFace, FaceImpl } from "./face"; | ||
import { Fib } from "./fib"; | ||
@@ -8,3 +8,3 @@ import type { FwPacket } from "./packet"; | ||
import { Readvertise } from "./readvertise"; | ||
interface Events { | ||
declare type Events = { | ||
/** Emitted before adding face. */ | ||
@@ -26,3 +26,3 @@ faceadd: (face: FwFace) => void; | ||
pkttx: (face: FwFace, pkt: FwPacket) => void; | ||
} | ||
}; | ||
/** Forwarding plane. */ | ||
@@ -33,3 +33,3 @@ export interface Forwarder extends TypedEmitter<Events> { | ||
/** Logical faces. */ | ||
readonly faces: Set<FwFace>; | ||
readonly faces: ReadonlySet<FwFace>; | ||
/** Add a logical face to the forwarding plane. */ | ||
@@ -45,6 +45,2 @@ addFace(face: FwFace.RxTx | FwFace.RxTxDuplex, attributes?: FwFace.Attributes): FwFace; | ||
interface Options { | ||
/** Per-face RX buffer length. */ | ||
faceRxBuffer?: number; | ||
/** Per-face TX buffer length. */ | ||
faceTxBuffer?: number; | ||
/** Whether to try matching Data without PIT token. */ | ||
@@ -65,3 +61,3 @@ dataNoTokenMatch?: boolean; | ||
export declare class ForwarderImpl extends ForwarderImpl_base implements Forwarder { | ||
readonly options: Required<Forwarder.Options>; | ||
readonly opts: Required<Forwarder.Options>; | ||
readonly nodeNames: Name[]; | ||
@@ -72,3 +68,3 @@ readonly faces: Set<FaceImpl>; | ||
readonly readvertise: Readvertise; | ||
constructor(options: Required<Forwarder.Options>); | ||
constructor(opts: Required<Forwarder.Options>); | ||
addFace(face: FwFace.RxTx | FwFace.RxTxDuplex, attributes?: FwFace.Attributes): FwFace; | ||
@@ -75,0 +71,0 @@ private pickInterestForwardingName; |
import { __importDefault, __importStar } from "tslib"; | ||
import { Interest } from "@ndn/packet"; | ||
import { toHex } from "@ndn/tlv"; | ||
import _cjsDefaultImport0 from "hirestime"; const hirestime = __importDefault(_cjsDefaultImport0).default; | ||
@@ -109,3 +108,3 @@ import _cjsDefaultImport1 from "mnemonist/default-map.js"; const DefaultMap = __importDefault(_cjsDefaultImport1).default; | ||
this.byName.set(entry.key, entry); | ||
entry.token ?? (entry.token = this.generateToken()); | ||
entry.token ??= this.generateToken(); | ||
this.byToken.set(entry.token, entry); | ||
@@ -127,3 +126,3 @@ } | ||
lookup({ l3: interest }, canInsert = true) { | ||
const key = `${toHex(interest.name.value)} ${interest.canBePrefix ? "+" : "-"}${interest.mustBeFresh ? "+" : "-"}`; | ||
const key = `${interest.name.valueHex} ${interest.canBePrefix ? "+" : "-"}${interest.mustBeFresh ? "+" : "-"}`; | ||
let entry = this.byName.get(key); | ||
@@ -156,3 +155,3 @@ if (!entry && canInsert) { | ||
for (let prefix = data.name; prefix.length > 0; prefix = prefix.getPrefix(-1)) { | ||
const prefixHex = toHex(prefix.value); | ||
const prefixHex = prefix.valueHex; | ||
for (const keySuffix of keySuffixes) { | ||
@@ -159,0 +158,0 @@ const entry = this.byName.get(prefixHex + keySuffix); |
import { __importDefault, __importStar } from "tslib"; | ||
import { Interest } from "@ndn/packet"; | ||
import { toHex } from "@ndn/tlv"; | ||
import _cjsDefaultImport0 from "hirestime"; const hirestime = __importDefault(_cjsDefaultImport0).default; | ||
@@ -109,3 +108,3 @@ import _cjsDefaultImport1 from "mnemonist/default-map.js"; const DefaultMap = __importDefault(_cjsDefaultImport1).default; | ||
this.byName.set(entry.key, entry); | ||
entry.token ?? (entry.token = this.generateToken()); | ||
entry.token ??= this.generateToken(); | ||
this.byToken.set(entry.token, entry); | ||
@@ -127,3 +126,3 @@ } | ||
lookup({ l3: interest }, canInsert = true) { | ||
const key = `${toHex(interest.name.value)} ${interest.canBePrefix ? "+" : "-"}${interest.mustBeFresh ? "+" : "-"}`; | ||
const key = `${interest.name.valueHex} ${interest.canBePrefix ? "+" : "-"}${interest.mustBeFresh ? "+" : "-"}`; | ||
let entry = this.byName.get(key); | ||
@@ -156,3 +155,3 @@ if (!entry && canInsert) { | ||
for (let prefix = data.name; prefix.length > 0; prefix = prefix.getPrefix(-1)) { | ||
const prefixHex = toHex(prefix.value); | ||
const prefixHex = prefix.valueHex; | ||
for (const keySuffix of keySuffixes) { | ||
@@ -159,0 +158,0 @@ const entry = this.byName.get(prefixHex + keySuffix); |
import { __importDefault, __importStar } from "tslib"; | ||
import { Name } from "@ndn/packet"; | ||
import { fromHex } from "@ndn/tlv"; | ||
import _cjsDefaultImport0 from "it-pushable"; const pushable = __importDefault(_cjsDefaultImport0).default; | ||
import _cjsDefaultImport1 from "mnemonist/multi-map.js"; const MultiMap = __importDefault(_cjsDefaultImport1).default; | ||
import _cjsDefaultImport2 from "retry"; const retry = __importDefault(_cjsDefaultImport2).default; | ||
import { NameMap, NameMultiMap } from "@ndn/packet"; | ||
import { pushable } from "it-pushable"; | ||
import _cjsDefaultImport0 from "retry"; const retry = __importDefault(_cjsDefaultImport0).default; | ||
/** | ||
@@ -17,8 +15,7 @@ * Manage advertised prefix of the forwarder. | ||
this.fw = fw; | ||
this.announcements = new MultiMap(Set); | ||
this.announcements = new NameMultiMap(); | ||
this.destinations = new Set(); | ||
} | ||
addAnnouncement(face, name, nameHex) { | ||
this.announcements.set(nameHex, face); | ||
if (this.announcements.multiplicity(nameHex) > 1) { | ||
addAnnouncement(face, name) { | ||
if (this.announcements.add(name, face) > 1) { | ||
return; | ||
@@ -28,14 +25,12 @@ } | ||
for (const dest of this.destinations) { | ||
dest.advertise(name, nameHex); | ||
dest.advertise(name); | ||
} | ||
} | ||
removeAnnouncement(face, name, nameHex) { | ||
this.announcements.remove(nameHex, face); | ||
if (this.announcements.multiplicity(nameHex) > 0) { | ||
removeAnnouncement(face, name) { | ||
if (this.announcements.remove(name, face) > 0) { | ||
return; | ||
} | ||
name ?? (name = new Name(fromHex(nameHex))); | ||
this.fw.emit("annrm", name); | ||
for (const dest of this.destinations) { | ||
dest.withdraw(name, nameHex); | ||
dest.withdraw(name); | ||
} | ||
@@ -67,3 +62,3 @@ } | ||
this.retryOptions = retryOptions; | ||
this.table = new Map(); | ||
this.table = new NameMap(); | ||
this.queue = pushable(); | ||
@@ -76,4 +71,4 @@ this.closed = false; | ||
this.readvertise.destinations.add(this); | ||
for (const nameHex of this.readvertise.announcements.keys()) { | ||
this.queue.push(nameHex); | ||
for (const [name] of this.readvertise.announcements.associations()) { | ||
this.queue.push(name); | ||
} | ||
@@ -90,4 +85,4 @@ void this.process(); | ||
this.readvertise = undefined; | ||
for (const [nameHex, record] of this.table) { | ||
this.queue.push(nameHex); | ||
for (const [name, record] of this.table) { | ||
this.queue.push(name); | ||
record.status = ReadvertiseDestination.Status.WITHDRAWING; | ||
@@ -99,19 +94,17 @@ } | ||
/** Set a prefix to be advertised. */ | ||
advertise(name, nameHex) { | ||
let record = this.table.get(nameHex); | ||
advertise(name) { | ||
let record = this.table.get(name); | ||
if (!record) { | ||
record = { | ||
name, | ||
status: ReadvertiseDestination.Status.ADVERTISING, | ||
state: this.makeState(name, nameHex), | ||
state: this.makeState(name), | ||
}; | ||
this.table.set(nameHex, record); | ||
this.table.set(name, record); | ||
} | ||
record.status = ReadvertiseDestination.Status.ADVERTISING; | ||
this.restart(nameHex, record); | ||
this.restart(name, record); | ||
} | ||
/** Set a prefix to be withdrawn. */ | ||
withdraw(name, nameHex) { | ||
void name; | ||
const record = this.table.get(nameHex); | ||
withdraw(name) { | ||
const record = this.table.get(name); | ||
if (!record) { | ||
@@ -121,5 +114,5 @@ return; | ||
record.status = ReadvertiseDestination.Status.WITHDRAWING; | ||
this.restart(nameHex, record); | ||
this.restart(name, record); | ||
} | ||
restart(nameHex, record) { | ||
restart(name, record) { | ||
record.retry?.stop(); | ||
@@ -132,3 +125,3 @@ record.retry = retry.operation(this.retryOptions); | ||
else { | ||
this.queue.push(nameHex); | ||
this.queue.push(name); | ||
} | ||
@@ -138,12 +131,12 @@ }); | ||
async process() { | ||
for await (const nameHex of this.queue) { | ||
const record = this.table.get(nameHex); | ||
for await (const name of this.queue) { | ||
const record = this.table.get(name); | ||
if (!record) { | ||
continue; | ||
} | ||
const { name, status, retry, state } = record; | ||
const { status, retry, state } = record; | ||
switch (status) { | ||
case ReadvertiseDestination.Status.ADVERTISING: | ||
try { | ||
await this.doAdvertise(name, state, nameHex); | ||
await this.doAdvertise(name, state); | ||
if (record.status === ReadvertiseDestination.Status.ADVERTISING) { | ||
@@ -160,7 +153,7 @@ record.status = ReadvertiseDestination.Status.ADVERTISED; | ||
try { | ||
await this.doWithdraw(record.name, state, nameHex); | ||
await this.doWithdraw(name, state); | ||
if (record.status === ReadvertiseDestination.Status.WITHDRAWING) { | ||
record.status = ReadvertiseDestination.Status.WITHDRAWN; | ||
retry.stop(); | ||
this.table.delete(nameHex); | ||
this.table.delete(name); | ||
} | ||
@@ -176,5 +169,4 @@ } | ||
/** Create per-prefix state. */ | ||
makeState(name, nameHex) { | ||
makeState(name) { | ||
void name; | ||
void nameHex; | ||
return {}; | ||
@@ -181,0 +173,0 @@ } |
import { __importDefault, __importStar } from "tslib"; | ||
import { Name } from "@ndn/packet"; | ||
import { fromHex } from "@ndn/tlv"; | ||
import _cjsDefaultImport0 from "it-pushable"; const pushable = __importDefault(_cjsDefaultImport0).default; | ||
import _cjsDefaultImport1 from "mnemonist/multi-map.js"; const MultiMap = __importDefault(_cjsDefaultImport1).default; | ||
import _cjsDefaultImport2 from "retry"; const retry = __importDefault(_cjsDefaultImport2).default; | ||
import { NameMap, NameMultiMap } from "@ndn/packet"; | ||
import { pushable } from "it-pushable"; | ||
import _cjsDefaultImport0 from "retry"; const retry = __importDefault(_cjsDefaultImport0).default; | ||
/** | ||
@@ -17,8 +15,7 @@ * Manage advertised prefix of the forwarder. | ||
this.fw = fw; | ||
this.announcements = new MultiMap(Set); | ||
this.announcements = new NameMultiMap(); | ||
this.destinations = new Set(); | ||
} | ||
addAnnouncement(face, name, nameHex) { | ||
this.announcements.set(nameHex, face); | ||
if (this.announcements.multiplicity(nameHex) > 1) { | ||
addAnnouncement(face, name) { | ||
if (this.announcements.add(name, face) > 1) { | ||
return; | ||
@@ -28,14 +25,12 @@ } | ||
for (const dest of this.destinations) { | ||
dest.advertise(name, nameHex); | ||
dest.advertise(name); | ||
} | ||
} | ||
removeAnnouncement(face, name, nameHex) { | ||
this.announcements.remove(nameHex, face); | ||
if (this.announcements.multiplicity(nameHex) > 0) { | ||
removeAnnouncement(face, name) { | ||
if (this.announcements.remove(name, face) > 0) { | ||
return; | ||
} | ||
name ?? (name = new Name(fromHex(nameHex))); | ||
this.fw.emit("annrm", name); | ||
for (const dest of this.destinations) { | ||
dest.withdraw(name, nameHex); | ||
dest.withdraw(name); | ||
} | ||
@@ -67,3 +62,3 @@ } | ||
this.retryOptions = retryOptions; | ||
this.table = new Map(); | ||
this.table = new NameMap(); | ||
this.queue = pushable(); | ||
@@ -76,4 +71,4 @@ this.closed = false; | ||
this.readvertise.destinations.add(this); | ||
for (const nameHex of this.readvertise.announcements.keys()) { | ||
this.queue.push(nameHex); | ||
for (const [name] of this.readvertise.announcements.associations()) { | ||
this.queue.push(name); | ||
} | ||
@@ -90,4 +85,4 @@ void this.process(); | ||
this.readvertise = undefined; | ||
for (const [nameHex, record] of this.table) { | ||
this.queue.push(nameHex); | ||
for (const [name, record] of this.table) { | ||
this.queue.push(name); | ||
record.status = ReadvertiseDestination.Status.WITHDRAWING; | ||
@@ -99,19 +94,17 @@ } | ||
/** Set a prefix to be advertised. */ | ||
advertise(name, nameHex) { | ||
let record = this.table.get(nameHex); | ||
advertise(name) { | ||
let record = this.table.get(name); | ||
if (!record) { | ||
record = { | ||
name, | ||
status: ReadvertiseDestination.Status.ADVERTISING, | ||
state: this.makeState(name, nameHex), | ||
state: this.makeState(name), | ||
}; | ||
this.table.set(nameHex, record); | ||
this.table.set(name, record); | ||
} | ||
record.status = ReadvertiseDestination.Status.ADVERTISING; | ||
this.restart(nameHex, record); | ||
this.restart(name, record); | ||
} | ||
/** Set a prefix to be withdrawn. */ | ||
withdraw(name, nameHex) { | ||
void name; | ||
const record = this.table.get(nameHex); | ||
withdraw(name) { | ||
const record = this.table.get(name); | ||
if (!record) { | ||
@@ -121,5 +114,5 @@ return; | ||
record.status = ReadvertiseDestination.Status.WITHDRAWING; | ||
this.restart(nameHex, record); | ||
this.restart(name, record); | ||
} | ||
restart(nameHex, record) { | ||
restart(name, record) { | ||
record.retry?.stop(); | ||
@@ -132,3 +125,3 @@ record.retry = retry.operation(this.retryOptions); | ||
else { | ||
this.queue.push(nameHex); | ||
this.queue.push(name); | ||
} | ||
@@ -138,12 +131,12 @@ }); | ||
async process() { | ||
for await (const nameHex of this.queue) { | ||
const record = this.table.get(nameHex); | ||
for await (const name of this.queue) { | ||
const record = this.table.get(name); | ||
if (!record) { | ||
continue; | ||
} | ||
const { name, status, retry, state } = record; | ||
const { status, retry, state } = record; | ||
switch (status) { | ||
case ReadvertiseDestination.Status.ADVERTISING: | ||
try { | ||
await this.doAdvertise(name, state, nameHex); | ||
await this.doAdvertise(name, state); | ||
if (record.status === ReadvertiseDestination.Status.ADVERTISING) { | ||
@@ -160,7 +153,7 @@ record.status = ReadvertiseDestination.Status.ADVERTISED; | ||
try { | ||
await this.doWithdraw(record.name, state, nameHex); | ||
await this.doWithdraw(name, state); | ||
if (record.status === ReadvertiseDestination.Status.WITHDRAWING) { | ||
record.status = ReadvertiseDestination.Status.WITHDRAWN; | ||
retry.stop(); | ||
this.table.delete(nameHex); | ||
this.table.delete(name); | ||
} | ||
@@ -176,5 +169,4 @@ } | ||
/** Create per-prefix state. */ | ||
makeState(name, nameHex) { | ||
makeState(name) { | ||
void name; | ||
void nameHex; | ||
return {}; | ||
@@ -181,0 +173,0 @@ } |
@@ -1,4 +0,2 @@ | ||
import { Name } from "@ndn/packet"; | ||
import pushable from "it-pushable"; | ||
import MultiMap from "mnemonist/multi-map.js"; | ||
import { Name, NameMap, NameMultiMap } from "@ndn/packet"; | ||
import * as retry from "retry"; | ||
@@ -17,6 +15,6 @@ import type { FaceImpl } from "./face"; | ||
constructor(fw: ForwarderImpl); | ||
readonly announcements: MultiMap<string, FaceImpl, Set<FaceImpl>>; | ||
readonly announcements: NameMultiMap<FaceImpl>; | ||
readonly destinations: Set<ReadvertiseDestination<{}>>; | ||
addAnnouncement(face: FaceImpl, name: Name, nameHex: string): void; | ||
removeAnnouncement(face: FaceImpl, name: Name | undefined, nameHex: string): void; | ||
addAnnouncement(face: FaceImpl, name: Name): void; | ||
removeAnnouncement(face: FaceImpl, name: Name): void; | ||
/** | ||
@@ -37,4 +35,4 @@ * Cancel timers and other I/O resources. | ||
private readvertise?; | ||
protected readonly table: Map<string, ReadvertiseDestination.Record<State>>; | ||
protected readonly queue: pushable.Pushable<string>; | ||
protected readonly table: NameMap<ReadvertiseDestination.Record<State>>; | ||
protected readonly queue: import("it-pushable").Pushable<Name>; | ||
protected closed: boolean; | ||
@@ -51,13 +49,13 @@ constructor(retryOptions?: ReadvertiseDestination.RetryOptions); | ||
/** Set a prefix to be advertised. */ | ||
advertise(name: Name, nameHex: string): void; | ||
advertise(name: Name): void; | ||
/** Set a prefix to be withdrawn. */ | ||
withdraw(name: Name, nameHex: string): void; | ||
protected restart(nameHex: string, record: ReadvertiseDestination.Record<State>): void; | ||
withdraw(name: Name): void; | ||
protected restart(name: Name, record: ReadvertiseDestination.Record<State>): void; | ||
private process; | ||
/** Create per-prefix state. */ | ||
protected makeState(name: Name, nameHex: string): State; | ||
protected makeState(name: Name): State; | ||
/** Advertise a prefix once. */ | ||
protected abstract doAdvertise(name: Name, state: State, nameHex: string): Promise<void>; | ||
protected abstract doAdvertise(name: Name, state: State): Promise<void>; | ||
/** Withdraw a prefix once. */ | ||
protected abstract doWithdraw(name: Name, state: State, nameHex: string): Promise<void>; | ||
protected abstract doWithdraw(name: Name, state: State): Promise<void>; | ||
} | ||
@@ -73,3 +71,2 @@ export declare namespace ReadvertiseDestination { | ||
interface Record<State> { | ||
name: Name; | ||
status: Status; | ||
@@ -76,0 +73,0 @@ retry?: retry.RetryOperation; |
import { __importDefault, __importStar } from "tslib"; | ||
import _cjsDefaultImport0 from "it-pushable"; const pushable = __importDefault(_cjsDefaultImport0).default; | ||
import _cjsDefaultImport1 from "minimalistic-assert"; const assert = __importDefault(_cjsDefaultImport1).default; | ||
import _cjsDefaultImport2 from "mnemonist/default-weak-map.js"; const DefaultWeakMap = __importDefault(_cjsDefaultImport2).default; | ||
import _cjsDefaultImport3 from "mnemonist/multi-map.js"; const MultiMap = __importDefault(_cjsDefaultImport3).default; | ||
import { assert } from "@ndn/util"; | ||
import { pushable } from "it-pushable"; | ||
import _cjsDefaultImport0 from "mnemonist/default-weak-map.js"; const DefaultWeakMap = __importDefault(_cjsDefaultImport0).default; | ||
import _cjsDefaultImport1 from "mnemonist/multi-map.js"; const MultiMap = __importDefault(_cjsDefaultImport1).default; | ||
import { Forwarder } from "./forwarder_browser.js"; | ||
@@ -7,0 +7,0 @@ class TapRxController { |
import { __importDefault, __importStar } from "tslib"; | ||
import _cjsDefaultImport0 from "it-pushable"; const pushable = __importDefault(_cjsDefaultImport0).default; | ||
import _cjsDefaultImport1 from "minimalistic-assert"; const assert = __importDefault(_cjsDefaultImport1).default; | ||
import _cjsDefaultImport2 from "mnemonist/default-weak-map.js"; const DefaultWeakMap = __importDefault(_cjsDefaultImport2).default; | ||
import _cjsDefaultImport3 from "mnemonist/multi-map.js"; const MultiMap = __importDefault(_cjsDefaultImport3).default; | ||
import { assert } from "@ndn/util"; | ||
import { pushable } from "it-pushable"; | ||
import _cjsDefaultImport0 from "mnemonist/default-weak-map.js"; const DefaultWeakMap = __importDefault(_cjsDefaultImport0).default; | ||
import _cjsDefaultImport1 from "mnemonist/multi-map.js"; const MultiMap = __importDefault(_cjsDefaultImport1).default; | ||
import { Forwarder } from "./forwarder_node.js"; | ||
@@ -7,0 +7,0 @@ class TapRxController { |
@@ -1,3 +0,2 @@ | ||
import pushable from "it-pushable"; | ||
import { FwFace } from "./face"; | ||
import { type FwFace } from "./face"; | ||
import type { FwPacket } from "./packet"; | ||
@@ -20,3 +19,3 @@ /** | ||
}; | ||
readonly rx: pushable.Pushable<FwPacket<import("@ndn/packet").Interest | import("@ndn/packet").Data | import("@ndn/packet").Nack>>; | ||
readonly rx: import("it-pushable").Pushable<FwPacket<import("@ndn/packet").Interest | import("@ndn/packet").Data | import("@ndn/packet").Nack>>; | ||
private readonly ctrl; | ||
@@ -23,0 +22,0 @@ constructor(face: FwFace); |
import { Data, Interest, Nack } from "@ndn/packet"; | ||
import { console } from "@ndn/util"; | ||
import { Forwarder } from "./forwarder_browser.js"; | ||
import { makeTracerOutput } from "./tracer-output_browser.js"; | ||
/** Print trace logs from Forwarder events. */ | ||
export class Tracer { | ||
constructor({ output = makeTracerOutput(), fw = Forwarder.getDefault(), face = true, prefix = true, ann = true, pkt = true, }) { | ||
constructor({ output = console, fw = Forwarder.getDefault(), face = true, prefix = true, ann = true, pkt = true, }) { | ||
this.faceadd = (face) => { | ||
@@ -8,0 +8,0 @@ this.output.log(`+Face ${face}`); |
import { Data, Interest, Nack } from "@ndn/packet"; | ||
import { console } from "@ndn/util"; | ||
import { Forwarder } from "./forwarder_node.js"; | ||
import { makeTracerOutput } from "./tracer-output_node.js"; | ||
/** Print trace logs from Forwarder events. */ | ||
export class Tracer { | ||
constructor({ output = makeTracerOutput(), fw = Forwarder.getDefault(), face = true, prefix = true, ann = true, pkt = true, }) { | ||
constructor({ output = console, fw = Forwarder.getDefault(), face = true, prefix = true, ann = true, pkt = true, }) { | ||
this.faceadd = (face) => { | ||
@@ -8,0 +8,0 @@ this.output.log(`+Face ${face}`); |
{ | ||
"name": "@ndn/fw", | ||
"version": "0.0.20210930", | ||
"version": "0.0.20220501", | ||
"description": "NDNts: Forwarding Plane", | ||
@@ -25,16 +25,15 @@ "keywords": [ | ||
"dependencies": { | ||
"@types/retry": "^0.12.1", | ||
"@ndn/packet": "0.0.20210930", | ||
"@ndn/tlv": "0.0.20210930", | ||
"@ndn/packet": "0.0.20220501", | ||
"@ndn/util": "0.0.20220501", | ||
"@types/retry": "^0.12.2", | ||
"hirestime": "^6.1.0", | ||
"it-pushable": "^1.4.2", | ||
"minimalistic-assert": "^1.0.1", | ||
"mnemonist": "^0.38.4", | ||
"p-fifo": "^1.0.0", | ||
"it-pushable": "^2.0.1", | ||
"mnemonist": "^0.39.1", | ||
"retry": "^0.13.1", | ||
"streaming-iterables": "^6.0.0", | ||
"tslib": "^2.3.1", | ||
"typed-emitter": "^1.3.1" | ||
"streaming-iterables": "^7.0.2", | ||
"tslib": "^2.4.0", | ||
"typed-emitter": "^2.1.0" | ||
}, | ||
"types": "lib/mod.d.ts" | ||
"types": "lib/mod.d.ts", | ||
"readme": "# @ndn/fw\n\nThis package is part of [NDNts](https://yoursunny.com/p/NDNts/), Named Data Networking libraries for the modern web.\n\nThis package implements the forwarding plane, the central piece of NDN stack.\nIt exports a **Forwarder** type that represents the forwarding plane, and a **FwFace** type that represents a *face* attached to the forwarding plane.\n\n## Concepts\n\nYou may be wondering: why there's a forwarding plane in my application?\nThe main purpose is to demultiplex incoming packets.\nSuppose a producer application can serve multiple kinds of data, the forwarding plane can dispatch incoming Interests of each kind of data to the correct Interest handler function in the application, so that the application does not perform this dispatching itself.\n\nThis leads to our definition of the *face*: **a face is a duplex stream of packets**.\nIt could be a connection to another network node or standalone forwarder, as implemented in `@ndn/l3face` package.\nIt could also be a part of application logic, as implemented in `@ndn/endpoint` package.\nCreating a `FwFace` for application logic is relatively cheap: if you need to receive different kinds of packets in separate callback functions, you should create one face per callback function, instead of sharing the same face and attempting to dispatch packets yourself.\n\nA *packet* transmitted or received on an `FwFace` is typically an Interest or a Data.\nFrom application logic, it is possible to associate arbitrary metadata, called a *token*, on an outgoing Interest, and receive them back on the corresponding Data.\nYou can also send a `CancelInterest` command to cancel a pending Interest, and receive a `RejectInterest` notice when the Interest is canceled or has expired.\nObviously, these tokens and commands are not encodable, so they are only available for communication between application logic and the forwarding plane, but cannot appear beyond the NDNts application.\n\n## Forwarding Behavior\n\nIt's sad but NDN does not have a formal forwarding behavior specification.\nThis package implements a simplified version of NDN forwarding behavior specified in [NDN-LAN dissertation](https://hdl.handle.net/10150/625652) chapter 3.\nThe main differences from a full forwarder include:\n\n* Forwarding strategy is dumb.\n* No Interest aggregation.\n* No Content Store (CS).\n * If your application needs data packet caching, use `@ndn/repo` package.\n* No Nack generation or processing.\n* Limited forwarding hint processing:\n * Only the first delegation name is considered. Others are ignored.\n * If the first delegation name is a prefix of one of the configured node names, FIB lookup uses the Interest name; otherwise, FIB lookup uses the first delegation name.\n * Forwarding hint is not stripped even if it matches a configured node name.\n\nThese are subject to change.\n" | ||
} |
10
79544
30
2095
+ Added@ndn/util@0.0.20220501
+ Added@ndn/packet@0.0.20220501(transitive)
+ Added@ndn/tlv@0.0.20220501(transitive)
+ Added@ndn/util@0.0.20220501(transitive)
+ Added@types/minimalistic-assert@1.0.3(transitive)
+ Addedit-pushable@2.0.2(transitive)
+ Addedmnemonist@0.39.8(transitive)
+ Addedrxjs@7.8.2(transitive)
+ Addedstreaming-iterables@7.1.0(transitive)
+ Addedtyped-emitter@2.1.0(transitive)
- Removed@ndn/tlv@0.0.20210930
- Removedminimalistic-assert@^1.0.1
- Removedp-fifo@^1.0.0
- Removed@ndn/packet@0.0.20210930(transitive)
- Removed@ndn/tlv@0.0.20210930(transitive)
- Removedfast-fifo@1.3.2(transitive)
- Removedit-pushable@1.4.2(transitive)
- Removedmnemonist@0.38.5(transitive)
- Removedp-defer@3.0.0(transitive)
- Removedp-fifo@1.0.0(transitive)
- Removedstreaming-iterables@6.2.0(transitive)
- Removedtyped-emitter@1.4.0(transitive)
Updated@ndn/packet@0.0.20220501
Updated@types/retry@^0.12.2
Updatedit-pushable@^2.0.1
Updatedmnemonist@^0.39.1
Updatedstreaming-iterables@^7.0.2
Updatedtslib@^2.4.0
Updatedtyped-emitter@^2.1.0