diff --git a/api-documents/kit.md b/api-documents/kit.md index 0257338..f4e1e19 100644 --- a/api-documents/kit.md +++ b/api-documents/kit.md @@ -44,6 +44,7 @@ A toolkit for browser extension developing. | [DOMProxyEvents](./kit.domproxyevents.md) | Events on the DOMProxy object | | [DOMProxyOptions](./kit.domproxyoptions.md) | Options for DOMProxy | | [Serialization](./kit.serialization.md) | Define how to do serialization and deserialization of remote procedure call | +| [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md) | | | [TargetBoundEventRegistry](./kit.targetboundeventregistry.md) | | | [UnboundedRegistry](./kit.unboundedregistry.md) | | | [WatcherEvents](./kit.watcherevents.md) | | diff --git a/api-documents/kit.targetboundeventlisteneroptions.md b/api-documents/kit.targetboundeventlisteneroptions.md new file mode 100644 index 0000000..0323d7d --- /dev/null +++ b/api-documents/kit.targetboundeventlisteneroptions.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [@holoflows/kit](./kit.md) > [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md) + +## TargetBoundEventListenerOptions interface + +Signature: + +```typescript +export interface TargetBoundEventListenerOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [once?](./kit.targetboundeventlisteneroptions.once.md) | boolean | (Optional) Run the listener only once. | +| [signal?](./kit.targetboundeventlisteneroptions.signal.md) | AbortSignal | (Optional) Cancel the listener by AbortSignal | + diff --git a/api-documents/kit.targetboundeventlisteneroptions.once.md b/api-documents/kit.targetboundeventlisteneroptions.once.md new file mode 100644 index 0000000..5bcae86 --- /dev/null +++ b/api-documents/kit.targetboundeventlisteneroptions.once.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@holoflows/kit](./kit.md) > [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md) > [once](./kit.targetboundeventlisteneroptions.once.md) + +## TargetBoundEventListenerOptions.once property + +Run the listener only once. + +Signature: + +```typescript +once?: boolean; +``` diff --git a/api-documents/kit.targetboundeventlisteneroptions.signal.md b/api-documents/kit.targetboundeventlisteneroptions.signal.md new file mode 100644 index 0000000..1e6849d --- /dev/null +++ b/api-documents/kit.targetboundeventlisteneroptions.signal.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@holoflows/kit](./kit.md) > [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md) > [signal](./kit.targetboundeventlisteneroptions.signal.md) + +## TargetBoundEventListenerOptions.signal property + +Cancel the listener by AbortSignal + +Signature: + +```typescript +signal?: AbortSignal; +``` diff --git a/api-documents/kit.targetboundeventregistry.md b/api-documents/kit.targetboundeventregistry.md index 2ea5e0f..31a5002 100644 --- a/api-documents/kit.targetboundeventregistry.md +++ b/api-documents/kit.targetboundeventregistry.md @@ -15,7 +15,7 @@ export interface TargetBoundEventRegistry | Method | Description | | --- | --- | | [off(callback)](./kit.targetboundeventregistry.off.md) | | -| [on(callback)](./kit.targetboundeventregistry.on.md) | | +| [on(callback, options)](./kit.targetboundeventregistry.on.md) | | | [pause()](./kit.targetboundeventregistry.pause.md) | Pausing the dispatch of this event. Collect all new incoming events. | | [send(data)](./kit.targetboundeventregistry.send.md) | | diff --git a/api-documents/kit.targetboundeventregistry.on.md b/api-documents/kit.targetboundeventregistry.on.md index 7eb88fd..872df8d 100644 --- a/api-documents/kit.targetboundeventregistry.on.md +++ b/api-documents/kit.targetboundeventregistry.on.md @@ -7,7 +7,7 @@ Signature: ```typescript -on(callback: (data: T) => void): () => void; +on(callback: (data: T) => void, options?: TargetBoundEventListenerOptions): () => void; ``` ## Parameters @@ -15,6 +15,7 @@ on(callback: (data: T) => void): () => void; | Parameter | Type | Description | | --- | --- | --- | | callback | (data: T) => void | | +| options | [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md) | | Returns: diff --git a/doc/holoflows-kit.api.report.md b/doc/holoflows-kit.api.report.md index 1fc9d7a..f12e3df 100644 --- a/doc/holoflows-kit.api.report.md +++ b/doc/holoflows-kit.api.report.md @@ -4,6 +4,8 @@ ```ts +/// + import { Emitter } from '@servie/events'; import { EventListener as EventListener_2 } from '@servie/events'; @@ -108,7 +110,7 @@ export function getEnvironment(): Environment; export class IntervalWatcher extends Watcher { startWatch(interval: number): this; stopWatch(): void; - } +} // @public export function isEnvironment(env: Environment): boolean; @@ -160,7 +162,7 @@ export class LiveSelector { reverse(): LiveSelector; slice(start?: number, end?: number): LiveSelector; sort(compareFn?: (a: T, b: T) => number): LiveSelector; - } +} // @public (undocumented) export enum MessageTarget { @@ -186,7 +188,7 @@ export class MutationObserverWatcher; startWatch(options: MutationObserverInit): this; stopWatch(): void; - } +} // @public export function printEnvironment(e?: Environment): string; @@ -205,12 +207,18 @@ export type ShouldAcceptExternalConnectionResult = boolean | { acceptAs: Environment; }; +// @public (undocumented) +export interface TargetBoundEventListenerOptions { + once?: boolean; + signal?: AbortSignal; +} + // @public (undocumented) export interface TargetBoundEventRegistry { // (undocumented) off(callback: (data: T) => void): void; // (undocumented) - on(callback: (data: T) => void): () => void; + on(callback: (data: T) => void, options?: TargetBoundEventListenerOptions): () => void; pause(): (reducer?: (data: T[]) => T[]) => Promise; // (undocumented) send(data: T): void; @@ -247,7 +255,7 @@ export class ValueRef { removeListener(fn: (newVal: T, oldVal: T) => void): void; get value(): T; set value(newVal: T); - } +} // Warning: (ae-forgotten-export) The symbol "ResultOf" needs to be exported by the entry point index.d.ts // @@ -302,40 +310,40 @@ export abstract class Watcher { // @eventProperty (undocumented) onAdd: [ { - key: unknown; - value: T; - } + key: unknown; + value: T; + } ]; // @eventProperty (undocumented) onChange: [ { - oldKey: unknown; - newKey: unknown; - oldValue?: T; - newValue: T; - } + oldKey: unknown; + newKey: unknown; + oldValue?: T; + newValue: T; + } ]; // @eventProperty (undocumented) onIteration: [ { - new: Map; - removed: Map; - current: Map; - } + new: Map; + removed: Map; + current: Map; + } ]; // @eventProperty (undocumented) onRemove: [ { - key: unknown; - value: T; - } + key: unknown; + value: T; + } ]; } @@ -358,7 +366,7 @@ export class WebExtensionMessage { // (undocumented) logFormatter: (instance: this, key: string, data: unknown) => unknown[]; serialization: Serialization; - } +} // @public (undocumented) export interface WebExtensionMessageOptions { @@ -366,5 +374,4 @@ export interface WebExtensionMessageOptions { readonly externalExtensionID?: string; } - ``` diff --git a/src/Extension/MessageChannel.ts b/src/Extension/MessageChannel.ts index 66a4f9d..8090259 100644 --- a/src/Extension/MessageChannel.ts +++ b/src/Extension/MessageChannel.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/strict-boolean-expressions */ +/* eslint-disable no-bitwise */ import { Emitter } from '@servie/events' import { EventIterator } from 'event-iterator' import { Environment, getEnvironment, isEnvironment } from './Context' @@ -5,7 +7,7 @@ import { Environment, getEnvironment, isEnvironment } from './Context' /** * Define how to do serialization and deserialization of remote procedure call */ - export interface Serialization { +export interface Serialization { /** * Do serialization * @param from - original data @@ -27,9 +29,15 @@ export enum MessageTarget { /** Externals not included */ Broadcast = Environment.HasBrowserAPI, All = Broadcast | IncludeLocal, } +export interface TargetBoundEventListenerOptions { + /** Run the listener only once. */ + once?: boolean + /** Cancel the listener by AbortSignal */ + signal?: AbortSignal +} export interface TargetBoundEventRegistry { /** @returns A function to remove the listener */ - on(callback: (data: T) => void): () => void + on(callback: (data: T) => void, options?: TargetBoundEventListenerOptions): () => void off(callback: (data: T) => void): void send(data: T): void /** @@ -210,7 +218,7 @@ export class WebExtensionMessage { * * This API only works in the BackgroundPage. */ - public serialization: Serialization = { deserialization: x => x, serialization: x => x } + public serialization: Serialization = { deserialization: (x) => x, serialization: (x) => x } public logFormatter: (instance: this, key: string, data: unknown) => unknown[] = (instance, key, data) => { return [ `%cReceive%c %c${String(key)}`, @@ -285,9 +293,13 @@ function UnboundedRegistry( }) } let binder: TargetBoundEventRegistry - function on(cb: (data: T) => void) { + function on(cb: (data: T) => void, options?: TargetBoundEventListenerOptions) { eventListener.on(eventName, cb) - return () => eventListener.off(eventName, cb) + + const off = () => eventListener.off(eventName, cb) + if (options?.once) eventListener.on(eventName, off) + if (options?.signal) options.signal.addEventListener('abort', off) + return off } function off(cb: (data: T) => void) { eventListener.off(eventName, cb) @@ -386,7 +398,7 @@ function backgroundPortBoarding(port: browser.runtime.Port, sender: undefined | // Client will report it's environment flag on connection port.onMessage.addListener(function environmentListener(x) { const obj = backgroundOnlyLivingPorts.get(port)! - if (typeof obj.environment === "undefined") obj.environment = Number(x) + if (typeof obj.environment === 'undefined') obj.environment = Number(x) port.onMessage.removeListener(environmentListener) }) port.onMessage.addListener(backgroundPageMessageHandler.bind(port))