Comparing version 0.0.20240113 to 0.0.20240630
import { Data, Interest, Nack, Name, NameMultiSet } from "@ndn/packet"; | ||
import { safeIter } from "@ndn/util"; | ||
import { pushable } from "it-pushable"; | ||
import { pushable, safeIter } from "@ndn/util"; | ||
import { filter, pipeline, tap } from "streaming-iterables"; | ||
@@ -36,3 +35,3 @@ import { TypedEventTarget } from "typescript-event-target"; | ||
running = true; | ||
txQueue = pushable({ objectMode: true }); | ||
txQueue = pushable(); | ||
constructor(fw, rxtx, attributes) { | ||
@@ -69,3 +68,3 @@ super(); | ||
} | ||
this.txQueue.end(new Error("close")); | ||
this.txQueue.fail(new Error("close")); | ||
this.dispatchTypedEvent("close", new Event("close")); | ||
@@ -72,0 +71,0 @@ this.fw.dispatchTypedEvent("facerm", new Forwarder.FaceEvent("facerm", this)); |
import { Data, Interest, Nack, Name, NameMultiSet } from "@ndn/packet"; | ||
import { safeIter } from "@ndn/util"; | ||
import { pushable } from "it-pushable"; | ||
import { pushable, safeIter } from "@ndn/util"; | ||
import { filter, pipeline, tap } from "streaming-iterables"; | ||
@@ -36,3 +35,3 @@ import { TypedEventTarget } from "typescript-event-target"; | ||
running = true; | ||
txQueue = pushable({ objectMode: true }); | ||
txQueue = pushable(); | ||
constructor(fw, rxtx, attributes) { | ||
@@ -69,3 +68,3 @@ super(); | ||
} | ||
this.txQueue.end(new Error("close")); | ||
this.txQueue.fail(new Error("close")); | ||
this.dispatchTypedEvent("close", new Event("close")); | ||
@@ -72,0 +71,0 @@ this.fw.dispatchTypedEvent("facerm", new Forwarder.FaceEvent("facerm", this)); |
@@ -13,3 +13,3 @@ import { type NameLike } from "@ndn/packet"; | ||
}; | ||
/** A socket or network interface associated with forwarding plane. */ | ||
/** A socket or network interface associated with logical forwarder. */ | ||
export interface FwFace extends TypedEventTarget<EventMap> { | ||
@@ -20,30 +20,71 @@ readonly fw: Forwarder; | ||
/** Shutdown the face. */ | ||
close(): void; | ||
toString(): string; | ||
close: () => void; | ||
toString: () => string; | ||
/** Determine if a route is present on the face. */ | ||
hasRoute(name: NameLike): boolean; | ||
/** Add a route toward the face. */ | ||
addRoute(name: NameLike, announcement?: FwFace.RouteAnnouncement): void; | ||
hasRoute: (name: NameLike) => boolean; | ||
/** | ||
* Add a route toward the face. | ||
* @param name - Route name. | ||
* @param announcement - Prefix announcement name or how to derive it from `name`. | ||
* | ||
* @remarks | ||
* When the logical forwarder receives an Interest matching `name`, it may forward the Interest | ||
* to this face. Unless `announcement` is set to `false`, this also invokes | ||
* {@link addAnnouncement} to readvertise the name prefix to remote forwarders. | ||
*/ | ||
addRoute: (name: NameLike, announcement?: FwFace.RouteAnnouncement) => void; | ||
/** Remove a route toward the face. */ | ||
removeRoute(name: NameLike, announcement?: FwFace.RouteAnnouncement): void; | ||
/** Add a prefix announcement associated with the face. */ | ||
addAnnouncement(name: NameLike): void; | ||
removeRoute: (name: NameLike, announcement?: FwFace.RouteAnnouncement) => void; | ||
/** | ||
* Add a prefix announcement associated with the face. | ||
* @param name - Prefix announcement name. | ||
* | ||
* @remarks | ||
* The announcement is passed to {@link ReadvertiseDestination}s (e.g. NFD prefix registration | ||
* client) on the logical forwarder, so that remote forwarders would send Interests matching | ||
* the prefix to the local logical forwarder. | ||
* | ||
* Multiple FwFaces could make the same announcement. When the last FwFace making an announcement | ||
* is closed, the announcement is withdrawn from {@link ReadvertiseDestination}s. | ||
* | ||
* This function has no effect if `FwFace.Attributes.advertiseFrom` is set to `false`. | ||
*/ | ||
addAnnouncement: (name: NameLike) => void; | ||
/** Remove a prefix announcement associated with the face. */ | ||
removeAnnouncement(name: NameLike): void; | ||
removeAnnouncement: (name: NameLike) => void; | ||
} | ||
export declare namespace FwFace { | ||
/** Attributes of a logical forwarder face. */ | ||
interface Attributes extends Record<string, unknown> { | ||
/** Short string to identify the face. */ | ||
describe?: string; | ||
/** Whether face is local. Default is false. */ | ||
/** | ||
* Whether face is local. | ||
* @defaultValue false | ||
*/ | ||
local?: boolean; | ||
/** Whether to readvertise registered routes. Default is true. */ | ||
/** | ||
* Whether to allow prefix announcements. | ||
* @defaultValue true | ||
* @remarks | ||
* If `false`, {@link FwFace.addAnnouncement} has no effect. | ||
*/ | ||
advertiseFrom?: boolean; | ||
/** | ||
* Whether routes registered on this face would cause FIB to stop matching onto shorter prefixes. | ||
* Default is true. | ||
* More explanation in @ndn/endpoint package ProducerOptions type. | ||
* @defaultValue true | ||
* @see {@link \@ndn/endpoint!ProducerOptions.routeCapture} | ||
*/ | ||
routeCapture?: boolean; | ||
[k: string]: unknown; | ||
} | ||
/** | ||
* Describe how to derive route announcement from name prefix in {@link FwFace.addRoute}. | ||
* | ||
* @remarks | ||
* - `false`: no announcement is made. | ||
* - `true`: same as route name. | ||
* - number: n-component prefix of route name. | ||
* - {@link Name} or string: specified name. | ||
*/ | ||
type RouteAnnouncement = boolean | number | NameLike; | ||
@@ -56,10 +97,15 @@ type RxTxEventMap = Pick<EventMap, "up" | "down">; | ||
} | ||
/** A logical face with separate RX and TX packet streams. */ | ||
interface RxTx extends RxTxBase { | ||
/** RX packet stream received by the logical forwarder. */ | ||
rx: AsyncIterable<FwPacket>; | ||
/** Function to accept TX packet stream sent by the logical forwarder. */ | ||
tx: (iterable: AsyncIterable<FwPacket>) => void; | ||
} | ||
/** A logical face with duplex RX and TX packet streams. */ | ||
interface RxTxDuplex extends RxTxBase { | ||
/** | ||
* The transform function takes an iterable of packets sent by the forwarder, | ||
* and returns an iterable of packets received by the forwarder. | ||
* Duplex RX and TX streams. | ||
* @param iterable - TX packet stream sent by the logical forwarder. | ||
* @returns RX packet stream received by the logical forwarder. | ||
*/ | ||
@@ -66,0 +112,0 @@ duplex: (iterable: AsyncIterable<FwPacket>) => AsyncIterable<FwPacket>; |
@@ -12,3 +12,3 @@ import { trackEventListener } from "@ndn/util"; | ||
}; | ||
/** Create a new forwarding plane. */ | ||
/** Create a new logical forwarder. */ | ||
function create(options) { | ||
@@ -19,11 +19,9 @@ return new ForwarderImpl({ ...Forwarder.DefaultOptions, ...options }); | ||
let defaultInstance; | ||
/** Access the default forwarding plane instance. */ | ||
/** Access the default logical forwarder instance. */ | ||
function getDefault() { | ||
if (!defaultInstance) { | ||
defaultInstance = Forwarder.create(); | ||
} | ||
defaultInstance ??= create(); | ||
return defaultInstance; | ||
} | ||
Forwarder.getDefault = getDefault; | ||
/** Replace the default forwarding plane instance. */ | ||
/** Replace the default logical forwarder instance. */ | ||
function replaceDefault(fw) { | ||
@@ -33,8 +31,5 @@ defaultInstance = fw; | ||
Forwarder.replaceDefault = replaceDefault; | ||
/** Delete default instance (mainly for unit testing). */ | ||
/** Close and delete the default logical forwarder instance (mainly for unit testing). */ | ||
function deleteDefault() { | ||
if (!defaultInstance) { | ||
return; | ||
} | ||
defaultInstance.close(); | ||
defaultInstance?.close(); | ||
defaultInstance = undefined; | ||
@@ -41,0 +36,0 @@ } |
@@ -12,3 +12,3 @@ import { trackEventListener } from "@ndn/util"; | ||
}; | ||
/** Create a new forwarding plane. */ | ||
/** Create a new logical forwarder. */ | ||
function create(options) { | ||
@@ -19,11 +19,9 @@ return new ForwarderImpl({ ...Forwarder.DefaultOptions, ...options }); | ||
let defaultInstance; | ||
/** Access the default forwarding plane instance. */ | ||
/** Access the default logical forwarder instance. */ | ||
function getDefault() { | ||
if (!defaultInstance) { | ||
defaultInstance = Forwarder.create(); | ||
} | ||
defaultInstance ??= create(); | ||
return defaultInstance; | ||
} | ||
Forwarder.getDefault = getDefault; | ||
/** Replace the default forwarding plane instance. */ | ||
/** Replace the default logical forwarder instance. */ | ||
function replaceDefault(fw) { | ||
@@ -33,8 +31,5 @@ defaultInstance = fw; | ||
Forwarder.replaceDefault = replaceDefault; | ||
/** Delete default instance (mainly for unit testing). */ | ||
/** Close and delete the default logical forwarder instance (mainly for unit testing). */ | ||
function deleteDefault() { | ||
if (!defaultInstance) { | ||
return; | ||
} | ||
defaultInstance.close(); | ||
defaultInstance?.close(); | ||
defaultInstance = undefined; | ||
@@ -41,0 +36,0 @@ } |
@@ -26,3 +26,3 @@ import type { Data, Interest, Nack, Name } from "@ndn/packet"; | ||
}; | ||
/** Forwarding plane. */ | ||
/** Logical forwarder. */ | ||
export interface Forwarder extends TypedEventTarget<EventMap> { | ||
@@ -33,4 +33,4 @@ /** Node names, used in forwarding hint processing. */ | ||
readonly faces: ReadonlySet<FwFace>; | ||
/** Add a logical face to the forwarding plane. */ | ||
addFace(face: FwFace.RxTx | FwFace.RxTxDuplex, attributes?: FwFace.Attributes): FwFace; | ||
/** Add a logical face to the logical forwarder. */ | ||
addFace: (face: FwFace.RxTx | FwFace.RxTxDuplex, attributes?: FwFace.Attributes) => FwFace; | ||
/** | ||
@@ -40,5 +40,6 @@ * Cancel timers and other I/O resources. | ||
*/ | ||
close(): void; | ||
close: () => void; | ||
} | ||
export declare namespace Forwarder { | ||
/** {@link Forwarder.create} options. */ | ||
interface Options { | ||
@@ -49,9 +50,9 @@ /** Whether to try matching Data without PIT token. */ | ||
const DefaultOptions: Required<Options>; | ||
/** Create a new forwarding plane. */ | ||
/** Create a new logical forwarder. */ | ||
function create(options?: Options): Forwarder; | ||
/** Access the default forwarding plane instance. */ | ||
/** Access the default logical forwarder instance. */ | ||
function getDefault(): Forwarder; | ||
/** Replace the default forwarding plane instance. */ | ||
/** Replace the default logical forwarder instance. */ | ||
function replaceDefault(fw?: Forwarder): void; | ||
/** Delete default instance (mainly for unit testing). */ | ||
/** Close and delete the default logical forwarder instance (mainly for unit testing). */ | ||
function deleteDefault(): void; | ||
@@ -58,0 +59,0 @@ /** Face event. */ |
@@ -1,5 +0,5 @@ | ||
export * from "./packet_browser.js"; | ||
export { FwPacket, CancelInterest, RejectInterest } from "./packet_browser.js"; | ||
export { Forwarder } from "./forwarder_browser.js"; | ||
export { ReadvertiseDestination } from "./readvertise_browser.js"; | ||
export { TapFace } from "./tap-face_browser.js"; | ||
export { Tracer as FwTracer } from "./tracer_browser.js"; | ||
export { FwTracer } from "./tracer_browser.js"; |
@@ -1,5 +0,5 @@ | ||
export * from "./packet_node.js"; | ||
export { FwPacket, CancelInterest, RejectInterest } from "./packet_node.js"; | ||
export { Forwarder } from "./forwarder_node.js"; | ||
export { ReadvertiseDestination } from "./readvertise_node.js"; | ||
export { TapFace } from "./tap-face_node.js"; | ||
export { Tracer as FwTracer } from "./tracer_node.js"; | ||
export { FwTracer } from "./tracer_node.js"; |
@@ -1,2 +0,2 @@ | ||
export * from "./packet.js"; | ||
export { FwPacket, CancelInterest, RejectInterest } from "./packet.js"; | ||
export type { FwFace } from "./face.js"; | ||
@@ -6,2 +6,2 @@ export { Forwarder } from "./forwarder.js"; | ||
export { TapFace } from "./tap-face.js"; | ||
export { Tracer as FwTracer } from "./tracer.js"; | ||
export { FwTracer } from "./tracer.js"; |
@@ -7,3 +7,3 @@ export var FwPacket; | ||
FwPacket.create = create; | ||
/** Whether this is a plain packet that can be sent on the wire. */ | ||
/** Determine whether this is a plain packet that can be sent on the wire. */ | ||
function isEncodable({ reject, cancel }) { | ||
@@ -10,0 +10,0 @@ return !reject && !cancel; |
@@ -7,3 +7,3 @@ export var FwPacket; | ||
FwPacket.create = create; | ||
/** Whether this is a plain packet that can be sent on the wire. */ | ||
/** Determine whether this is a plain packet that can be sent on the wire. */ | ||
function isEncodable({ reject, cancel }) { | ||
@@ -10,0 +10,0 @@ return !reject && !cancel; |
import type { Data, Interest, Nack } from "@ndn/packet"; | ||
type L3Pkt = Interest | Data | Nack; | ||
/** A logical packet in the forwarder. */ | ||
/** A logical packet in the logical forwarder. */ | ||
export interface FwPacket<T extends L3Pkt = L3Pkt> { | ||
@@ -13,3 +13,3 @@ l3: T; | ||
function create<T extends L3Pkt>(l3: T, token?: unknown, congestionMark?: number): FwPacket<T>; | ||
/** Whether this is a plain packet that can be sent on the wire. */ | ||
/** Determine whether this is a plain packet that can be sent on the wire. */ | ||
function isEncodable({ reject, cancel }: FwPacket): boolean; | ||
@@ -21,4 +21,4 @@ } | ||
l3: Interest; | ||
token?: unknown; | ||
constructor(reject: RejectInterest.Reason, l3: Interest, token?: unknown); | ||
token?: unknown | undefined; | ||
constructor(reject: RejectInterest.Reason, l3: Interest, token?: unknown | undefined); | ||
} | ||
@@ -31,6 +31,6 @@ export declare namespace RejectInterest { | ||
l3: Interest; | ||
token?: unknown; | ||
constructor(l3: Interest, token?: unknown); | ||
token?: unknown | undefined; | ||
constructor(l3: Interest, token?: unknown | undefined); | ||
readonly cancel = true; | ||
} | ||
export {}; |
@@ -143,3 +143,4 @@ import { __importDefault, __importStar } from "tslib"; | ||
* Satisfy pending Interests with incoming Data. | ||
* @returns true if Data satisfies any pending Interest; false if Data is unsolicited. | ||
* @returns `true` if Data satisfies one or more pending Interests; | ||
* `false` if Data is unsolicited. | ||
*/ | ||
@@ -146,0 +147,0 @@ async satisfy(face, { l3: data, token }) { |
@@ -143,3 +143,4 @@ import { __importDefault, __importStar } from "tslib"; | ||
* Satisfy pending Interests with incoming Data. | ||
* @returns true if Data satisfies any pending Interest; false if Data is unsolicited. | ||
* @returns `true` if Data satisfies one or more pending Interests; | ||
* `false` if Data is unsolicited. | ||
*/ | ||
@@ -146,0 +147,0 @@ async satisfy(face, { l3: data, token }) { |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
import { type Data, Interest } from "@ndn/packet"; | ||
@@ -67,3 +66,4 @@ import DefaultMap from "mnemonist/default-map.js"; | ||
* Satisfy pending Interests with incoming Data. | ||
* @returns true if Data satisfies any pending Interest; false if Data is unsolicited. | ||
* @returns `true` if Data satisfies one or more pending Interests; | ||
* `false` if Data is unsolicited. | ||
*/ | ||
@@ -70,0 +70,0 @@ satisfy(face: FaceImpl, { l3: data, token }: FwPacket<Data>): Promise<boolean>; |
import { __importDefault, __importStar } from "tslib"; | ||
import { NameMap, NameMultiMap } from "@ndn/packet"; | ||
import { pushable } from "it-pushable"; | ||
import { pushable } from "@ndn/util"; | ||
import _cjsDefaultImport0 from "retry"; const retry = __importDefault(_cjsDefaultImport0).default; | ||
@@ -9,2 +9,3 @@ import { Forwarder } from "./forwarder_browser.js"; | ||
* | ||
* @remarks | ||
* This class keeps track of what prefixes are announced by the owning forwarder. | ||
@@ -52,4 +53,5 @@ * It accepts announcements from faces attached to the forwarder, and then informs | ||
* | ||
* @remarks | ||
* Generally, a prefix advertised to a destination would cause Interests matching the prefix | ||
* to come to the forwarder, aka prefix registration. | ||
* to come to the local logical forwarder, aka prefix registration. | ||
*/ | ||
@@ -60,3 +62,3 @@ export class ReadvertiseDestination { | ||
table = new NameMap(); | ||
queue = pushable({ objectMode: true }); | ||
queue = pushable(); | ||
closed = false; | ||
@@ -83,2 +85,3 @@ constructor(retryOptions = { | ||
* | ||
* @remarks | ||
* Once detached, this instance is no longer usable. | ||
@@ -93,3 +96,3 @@ */ | ||
} | ||
this.queue.end(); | ||
this.queue.stop(); | ||
this.closed = true; | ||
@@ -96,0 +99,0 @@ } |
import { __importDefault, __importStar } from "tslib"; | ||
import { NameMap, NameMultiMap } from "@ndn/packet"; | ||
import { pushable } from "it-pushable"; | ||
import { pushable } from "@ndn/util"; | ||
import _cjsDefaultImport0 from "retry"; const retry = __importDefault(_cjsDefaultImport0).default; | ||
@@ -9,2 +9,3 @@ import { Forwarder } from "./forwarder_node.js"; | ||
* | ||
* @remarks | ||
* This class keeps track of what prefixes are announced by the owning forwarder. | ||
@@ -52,4 +53,5 @@ * It accepts announcements from faces attached to the forwarder, and then informs | ||
* | ||
* @remarks | ||
* Generally, a prefix advertised to a destination would cause Interests matching the prefix | ||
* to come to the forwarder, aka prefix registration. | ||
* to come to the local logical forwarder, aka prefix registration. | ||
*/ | ||
@@ -60,3 +62,3 @@ export class ReadvertiseDestination { | ||
table = new NameMap(); | ||
queue = pushable({ objectMode: true }); | ||
queue = pushable(); | ||
closed = false; | ||
@@ -83,2 +85,3 @@ constructor(retryOptions = { | ||
* | ||
* @remarks | ||
* Once detached, this instance is no longer usable. | ||
@@ -93,3 +96,3 @@ */ | ||
} | ||
this.queue.end(); | ||
this.queue.stop(); | ||
this.closed = true; | ||
@@ -96,0 +99,0 @@ } |
@@ -8,2 +8,3 @@ import { type Name, NameMap, NameMultiMap } from "@ndn/packet"; | ||
* | ||
* @remarks | ||
* This class keeps track of what prefixes are announced by the owning forwarder. | ||
@@ -29,4 +30,5 @@ * It accepts announcements from faces attached to the forwarder, and then informs | ||
* | ||
* @remarks | ||
* Generally, a prefix advertised to a destination would cause Interests matching the prefix | ||
* to come to the forwarder, aka prefix registration. | ||
* to come to the local logical forwarder, aka prefix registration. | ||
*/ | ||
@@ -37,3 +39,3 @@ export declare abstract class ReadvertiseDestination<State extends {} = {}> { | ||
protected readonly table: NameMap<ReadvertiseDestination.Record<State>>; | ||
protected readonly queue: import("it-pushable").Pushable<Name, void, unknown>; | ||
protected readonly queue: import("@ndn/util").Pushable<Name>; | ||
protected closed: boolean; | ||
@@ -46,2 +48,3 @@ constructor(retryOptions?: ReadvertiseDestination.RetryOptions); | ||
* | ||
* @remarks | ||
* Once detached, this instance is no longer usable. | ||
@@ -48,0 +51,0 @@ */ |
import { __importDefault, __importStar } from "tslib"; | ||
import { assert, MultiMap } from "@ndn/util"; | ||
import { pushable } from "it-pushable"; | ||
import { assert, MultiMap, pushable } from "@ndn/util"; | ||
import _cjsDefaultImport0 from "mnemonist/default-weak-map.js"; const DefaultWeakMap = __importDefault(_cjsDefaultImport0).default; | ||
@@ -8,6 +7,2 @@ import { Forwarder } from "./forwarder_browser.js"; | ||
fw; | ||
static instances = new DefaultWeakMap((fw) => new TapRxController(fw)); | ||
static lookup(fw) { | ||
return TapRxController.instances.get(fw); | ||
} | ||
taps = new MultiMap(); | ||
@@ -20,3 +15,3 @@ constructor(fw) { | ||
add(src, dst) { | ||
assert.equal(src.fw, this.fw); | ||
assert(src.fw === this.fw); | ||
this.taps.add(src, dst); | ||
@@ -31,3 +26,3 @@ } | ||
for (const { rx } of dst) { | ||
rx.end(); | ||
rx.stop(); | ||
} | ||
@@ -40,3 +35,3 @@ this.detachIfIdle(); | ||
this.fw.removeEventListener("facerm", this.facerm); | ||
TapRxController.instances.delete(this.fw); | ||
ctrls.delete(this.fw); | ||
} | ||
@@ -51,5 +46,7 @@ } | ||
} | ||
const ctrls = new DefaultWeakMap((fw) => new TapRxController(fw)); | ||
/** | ||
* Create a secondary face by tapping on a primary face. | ||
* | ||
* @remarks | ||
* TapFace is useful for sending in-band management commands to a specific neighbor, after being | ||
@@ -62,16 +59,16 @@ * added to a temporary secondary Forwarder. The TapFace shares the same transport as the primary | ||
face; | ||
constructor(face) { | ||
this.face = face; | ||
this.ctrl = ctrls.get(face.fw); | ||
this.ctrl.add(this.face, this); | ||
} | ||
get attributes() { | ||
return { | ||
...this.face.attributes, | ||
describe: `tap(${this.face})`, | ||
...this.face.attributes, | ||
}; | ||
} | ||
rx = pushable({ objectMode: true }); | ||
ctrl; | ||
constructor(face) { | ||
this.face = face; | ||
this.ctrl = TapRxController.lookup(face.fw); | ||
this.ctrl.add(this.face, this); | ||
} | ||
tx = async (iterable) => { | ||
rx = pushable(); | ||
async tx(iterable) { | ||
for await (const pkt of iterable) { | ||
@@ -81,6 +78,10 @@ this.face.send(pkt); | ||
this.ctrl.remove(this.face, this); | ||
}; | ||
} | ||
} | ||
(function (TapFace) { | ||
/** Create a new Forwarder and add a TapFace. */ | ||
/** | ||
* Create a new {@link Forwarder} and add a {@link TapFace}. | ||
* @param face - FwFace on the existing forwarder. | ||
* @returns FwFace on a new forwarder. The forwarder may be retrieved in `.fw` property. | ||
*/ | ||
function create(face) { | ||
@@ -87,0 +88,0 @@ const fw = Forwarder.create(); |
import { __importDefault, __importStar } from "tslib"; | ||
import { assert, MultiMap } from "@ndn/util"; | ||
import { pushable } from "it-pushable"; | ||
import { assert, MultiMap, pushable } from "@ndn/util"; | ||
import _cjsDefaultImport0 from "mnemonist/default-weak-map.js"; const DefaultWeakMap = __importDefault(_cjsDefaultImport0).default; | ||
@@ -8,6 +7,2 @@ import { Forwarder } from "./forwarder_node.js"; | ||
fw; | ||
static instances = new DefaultWeakMap((fw) => new TapRxController(fw)); | ||
static lookup(fw) { | ||
return TapRxController.instances.get(fw); | ||
} | ||
taps = new MultiMap(); | ||
@@ -20,3 +15,3 @@ constructor(fw) { | ||
add(src, dst) { | ||
assert.equal(src.fw, this.fw); | ||
assert(src.fw === this.fw); | ||
this.taps.add(src, dst); | ||
@@ -31,3 +26,3 @@ } | ||
for (const { rx } of dst) { | ||
rx.end(); | ||
rx.stop(); | ||
} | ||
@@ -40,3 +35,3 @@ this.detachIfIdle(); | ||
this.fw.removeEventListener("facerm", this.facerm); | ||
TapRxController.instances.delete(this.fw); | ||
ctrls.delete(this.fw); | ||
} | ||
@@ -51,5 +46,7 @@ } | ||
} | ||
const ctrls = new DefaultWeakMap((fw) => new TapRxController(fw)); | ||
/** | ||
* Create a secondary face by tapping on a primary face. | ||
* | ||
* @remarks | ||
* TapFace is useful for sending in-band management commands to a specific neighbor, after being | ||
@@ -62,16 +59,16 @@ * added to a temporary secondary Forwarder. The TapFace shares the same transport as the primary | ||
face; | ||
constructor(face) { | ||
this.face = face; | ||
this.ctrl = ctrls.get(face.fw); | ||
this.ctrl.add(this.face, this); | ||
} | ||
get attributes() { | ||
return { | ||
...this.face.attributes, | ||
describe: `tap(${this.face})`, | ||
...this.face.attributes, | ||
}; | ||
} | ||
rx = pushable({ objectMode: true }); | ||
ctrl; | ||
constructor(face) { | ||
this.face = face; | ||
this.ctrl = TapRxController.lookup(face.fw); | ||
this.ctrl.add(this.face, this); | ||
} | ||
tx = async (iterable) => { | ||
rx = pushable(); | ||
async tx(iterable) { | ||
for await (const pkt of iterable) { | ||
@@ -81,6 +78,10 @@ this.face.send(pkt); | ||
this.ctrl.remove(this.face, this); | ||
}; | ||
} | ||
} | ||
(function (TapFace) { | ||
/** Create a new Forwarder and add a TapFace. */ | ||
/** | ||
* Create a new {@link Forwarder} and add a {@link TapFace}. | ||
* @param face - FwFace on the existing forwarder. | ||
* @returns FwFace on a new forwarder. The forwarder may be retrieved in `.fw` property. | ||
*/ | ||
function create(face) { | ||
@@ -87,0 +88,0 @@ const fw = Forwarder.create(); |
@@ -6,2 +6,3 @@ import type { FwFace } from "./face.js"; | ||
* | ||
* @remarks | ||
* TapFace is useful for sending in-band management commands to a specific neighbor, after being | ||
@@ -14,16 +15,20 @@ * added to a temporary secondary Forwarder. The TapFace shares the same transport as the primary | ||
readonly face: FwFace; | ||
constructor(face: FwFace); | ||
get attributes(): { | ||
describe: string; | ||
local?: boolean | undefined; | ||
advertiseFrom?: boolean | undefined; | ||
routeCapture?: boolean | undefined; | ||
local?: boolean; | ||
advertiseFrom?: boolean; | ||
routeCapture?: boolean; | ||
}; | ||
readonly rx: import("it-pushable").Pushable<FwPacket<import("@ndn/packet").Interest | import("@ndn/packet").Data | import("@ndn/packet").Nack>, void, unknown>; | ||
private readonly ctrl; | ||
constructor(face: FwFace); | ||
tx: (iterable: AsyncIterable<FwPacket>) => Promise<void>; | ||
readonly rx: import("@ndn/util").Pushable<FwPacket<import("@ndn/packet").Interest | import("@ndn/packet").Data | import("@ndn/packet").Nack>>; | ||
tx(iterable: AsyncIterable<FwPacket>): Promise<void>; | ||
} | ||
export declare namespace TapFace { | ||
/** Create a new Forwarder and add a TapFace. */ | ||
/** | ||
* Create a new {@link Forwarder} and add a {@link TapFace}. | ||
* @param face - FwFace on the existing forwarder. | ||
* @returns FwFace on a new forwarder. The forwarder may be retrieved in `.fw` property. | ||
*/ | ||
function create(face: FwFace): FwFace; | ||
} |
import { Data, Interest, Nack } from "@ndn/packet"; | ||
import { console } from "@ndn/util"; | ||
import { Forwarder } from "./forwarder_browser.js"; | ||
/** Print trace logs from Forwarder events. */ | ||
export class Tracer { | ||
/** Print trace logs from {@link Forwarder} events. */ | ||
export class FwTracer { | ||
static enable(opts = {}) { | ||
return new Tracer(opts); | ||
return new FwTracer(opts); | ||
} | ||
@@ -9,0 +9,0 @@ output; |
import { Data, Interest, Nack } from "@ndn/packet"; | ||
import { console } from "@ndn/util"; | ||
import { Forwarder } from "./forwarder_node.js"; | ||
/** Print trace logs from Forwarder events. */ | ||
export class Tracer { | ||
/** Print trace logs from {@link Forwarder} events. */ | ||
export class FwTracer { | ||
static enable(opts = {}) { | ||
return new Tracer(opts); | ||
return new FwTracer(opts); | ||
} | ||
@@ -9,0 +9,0 @@ output; |
import { Forwarder } from "./forwarder.js"; | ||
/** Print trace logs from Forwarder events. */ | ||
export declare class Tracer { | ||
static enable(opts?: Tracer.Options): Tracer; | ||
/** Print trace logs from {@link Forwarder} events. */ | ||
export declare class FwTracer { | ||
static enable(opts?: FwTracer.Options): FwTracer; | ||
private readonly output; | ||
private readonly fw; | ||
constructor({ output, fw, face, prefix, ann, pkt, }: Tracer.Options); | ||
private constructor(); | ||
disable(): void; | ||
private faceadd; | ||
private facerm; | ||
private prefixadd; | ||
private prefixrm; | ||
private annadd; | ||
private annrm; | ||
private pktrx; | ||
private pkttx; | ||
private readonly faceadd; | ||
private readonly facerm; | ||
private readonly prefixadd; | ||
private readonly prefixrm; | ||
private readonly annadd; | ||
private readonly annrm; | ||
private readonly pktrx; | ||
private readonly pkttx; | ||
private pkt; | ||
} | ||
export declare namespace Tracer { | ||
export declare namespace FwTracer { | ||
interface Output { | ||
log(str: string): void; | ||
log: (str: string) => void; | ||
} | ||
@@ -26,3 +26,3 @@ interface Options { | ||
* Where to write log entries. | ||
* Default is stderr in Node and developer console in browser. | ||
* @defaultValue `console` | ||
*/ | ||
@@ -32,3 +32,3 @@ output?: Output; | ||
* Logical Forwarder instance. | ||
* @default Forwarder.getDefault() | ||
* @defaultValue `Forwarder.getDefault()` | ||
*/ | ||
@@ -38,3 +38,3 @@ fw?: Forwarder; | ||
* Whether to log face creations and deletions. | ||
* @default true | ||
* @defaultValue true | ||
*/ | ||
@@ -44,3 +44,3 @@ face?: boolean; | ||
* Whether to log prefix registrations. | ||
* @default true | ||
* @defaultValue true | ||
*/ | ||
@@ -50,3 +50,3 @@ prefix?: boolean; | ||
* Whether to log prefix announcements. | ||
* @default true | ||
* @defaultValue true | ||
*/ | ||
@@ -56,3 +56,3 @@ ann?: boolean; | ||
* Whether to log packets. | ||
* @default true | ||
* @defaultValue true | ||
*/ | ||
@@ -59,0 +59,0 @@ pkt?: boolean; |
{ | ||
"name": "@ndn/fw", | ||
"version": "0.0.20240113", | ||
"description": "NDNts: Forwarding Plane", | ||
"version": "0.0.20240630", | ||
"description": "NDNts: Logical Forwarder", | ||
"keywords": [ | ||
@@ -22,17 +22,16 @@ "NDN", | ||
"url": "https://github.com/yoursunny/NDNts.git", | ||
"directory": "packages/fw" | ||
"directory": "pkg/fw" | ||
}, | ||
"dependencies": { | ||
"@ndn/packet": "0.0.20240113", | ||
"@ndn/util": "0.0.20240113", | ||
"@ndn/packet": "0.0.20240630", | ||
"@ndn/util": "0.0.20240630", | ||
"@types/retry": "^0.12.5", | ||
"hirestime": "^7.0.3", | ||
"it-pushable": "^3.2.3", | ||
"mnemonist": "^0.39.7", | ||
"hirestime": "^7.0.4", | ||
"mnemonist": "^0.39.8", | ||
"retry": "^0.13.1", | ||
"streaming-iterables": "^8.0.1", | ||
"tslib": "^2.6.2", | ||
"typescript-event-target": "^1.1.0" | ||
"tslib": "^2.6.3", | ||
"typescript-event-target": "^1.1.1" | ||
}, | ||
"types": "lib/mod.d.ts" | ||
} |
@@ -5,10 +5,10 @@ # @ndn/fw | ||
This package implements the forwarding plane, the central piece of NDN stack. | ||
It exports a **Forwarder** type that represents the forwarding plane, and a **FwFace** type that represents a *face* attached to the forwarding plane. | ||
This package implements the logical forwarder, the central piece of NDN stack. | ||
It exports a **Forwarder** type that represents the logical forwarder, and a **FwFace** type that represents a *face* attached to the logical forwarder. | ||
## Concepts | ||
You may be wondering: why there's a forwarding plane in my application? | ||
You may be wondering: why there's a forwarder in my application? | ||
The main purpose is to demultiplex incoming packets. | ||
Suppose 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. | ||
Suppose a producer application can serve multiple kinds of data, the logical forwarder 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. | ||
@@ -18,3 +18,3 @@ This leads to our definition of the *face*: **a face is a duplex stream of packets**. | ||
It could also be a part of application logic, as implemented in `@ndn/endpoint` package. | ||
Creating 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. | ||
Creating a `FwFace` for application logic is a cheap operation: 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. | ||
@@ -24,3 +24,3 @@ A *packet* transmitted or received on an `FwFace` is typically an Interest or a Data. | ||
You can also send a `CancelInterest` command to cancel a pending Interest, and receive a `RejectInterest` notice when the Interest is canceled or has expired. | ||
Obviously, 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. | ||
Obviously, these tokens and commands are not encodable, so they are only available for communication between application logic and the logical forwarder, but cannot appear beyond the NDNts application. | ||
@@ -27,0 +27,0 @@ ## Forwarding Behavior |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
83616
9
2302
+ Added@ndn/packet@0.0.20240630(transitive)
+ Added@ndn/tlv@0.0.20240630(transitive)
+ Added@ndn/util@0.0.20240630(transitive)
+ Added@shigen/polyfill-symbol-dispose@1.0.1(transitive)
+ Addedevent-iterator@2.0.0(transitive)
+ Addedtiny-invariant@1.3.3(transitive)
+ Addedwait-your-turn@1.0.1(transitive)
- Removedit-pushable@^3.2.3
- Removed@ndn/packet@0.0.20240113(transitive)
- Removed@ndn/tlv@0.0.20240113(transitive)
- Removed@ndn/util@0.0.20240113(transitive)
- Removed@types/minimalistic-assert@1.0.3(transitive)
- Removedit-pushable@3.2.3(transitive)
- Removedminimalistic-assert@1.0.1(transitive)
- Removedp-defer@4.0.1(transitive)
Updated@ndn/packet@0.0.20240630
Updated@ndn/util@0.0.20240630
Updatedhirestime@^7.0.4
Updatedmnemonist@^0.39.8
Updatedtslib@^2.6.3