Skip to content

Commit

Permalink
feat: support once and signal in MessageChannel
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Works committed Sep 2, 2021
1 parent dfbe7fd commit 7c3d0d0
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 31 deletions.
1 change: 1 addition & 0 deletions api-documents/kit.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) | |
Expand Down
19 changes: 19 additions & 0 deletions api-documents/kit.targetboundeventlisteneroptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@holoflows/kit](./kit.md) &gt; [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md)

## TargetBoundEventListenerOptions interface

<b>Signature:</b>

```typescript
export interface TargetBoundEventListenerOptions
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [once?](./kit.targetboundeventlisteneroptions.once.md) | boolean | <i>(Optional)</i> Run the listener only once. |
| [signal?](./kit.targetboundeventlisteneroptions.signal.md) | AbortSignal | <i>(Optional)</i> Cancel the listener by AbortSignal |

13 changes: 13 additions & 0 deletions api-documents/kit.targetboundeventlisteneroptions.once.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@holoflows/kit](./kit.md) &gt; [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md) &gt; [once](./kit.targetboundeventlisteneroptions.once.md)

## TargetBoundEventListenerOptions.once property

Run the listener only once.

<b>Signature:</b>

```typescript
once?: boolean;
```
13 changes: 13 additions & 0 deletions api-documents/kit.targetboundeventlisteneroptions.signal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@holoflows/kit](./kit.md) &gt; [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md) &gt; [signal](./kit.targetboundeventlisteneroptions.signal.md)

## TargetBoundEventListenerOptions.signal property

Cancel the listener by AbortSignal

<b>Signature:</b>

```typescript
signal?: AbortSignal;
```
2 changes: 1 addition & 1 deletion api-documents/kit.targetboundeventregistry.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface TargetBoundEventRegistry<T>
| 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) | |

3 changes: 2 additions & 1 deletion api-documents/kit.targetboundeventregistry.on.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
<b>Signature:</b>

```typescript
on(callback: (data: T) => void): () => void;
on(callback: (data: T) => void, options?: TargetBoundEventListenerOptions): () => void;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| callback | (data: T) =&gt; void | |
| options | [TargetBoundEventListenerOptions](./kit.targetboundeventlisteneroptions.md) | |

<b>Returns:</b>

Expand Down
53 changes: 30 additions & 23 deletions doc/holoflows-kit.api.report.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
```ts

/// <reference types="global" />

import { Emitter } from '@servie/events';
import { EventListener as EventListener_2 } from '@servie/events';

Expand Down Expand Up @@ -108,7 +110,7 @@ export function getEnvironment(): Environment;
export class IntervalWatcher<T, Before extends Element = HTMLSpanElement, After extends Element = HTMLSpanElement, SingleMode extends boolean = false> extends Watcher<T, Before, After, SingleMode> {
startWatch(interval: number): this;
stopWatch(): void;
}
}

// @public
export function isEnvironment(env: Environment): boolean;
Expand Down Expand Up @@ -160,7 +162,7 @@ export class LiveSelector<T, SingleMode extends boolean = false> {
reverse(): LiveSelector<T, SingleMode>;
slice(start?: number, end?: number): LiveSelector<T, SingleMode>;
sort(compareFn?: (a: T, b: T) => number): LiveSelector<T, SingleMode>;
}
}

// @public (undocumented)
export enum MessageTarget {
Expand All @@ -186,7 +188,7 @@ export class MutationObserverWatcher<T, Before extends Element = HTMLSpanElement
protected liveSelector: LiveSelector<T, SingleMode>;
startWatch(options: MutationObserverInit): this;
stopWatch(): void;
}
}

// @public
export function printEnvironment(e?: Environment): string;
Expand All @@ -205,12 +207,18 @@ export type ShouldAcceptExternalConnectionResult = boolean | {
acceptAs: Environment;
};

// @public (undocumented)
export interface TargetBoundEventListenerOptions {
once?: boolean;
signal?: AbortSignal;
}

// @public (undocumented)
export interface TargetBoundEventRegistry<T> {
// (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<void>;
// (undocumented)
send(data: T): void;
Expand Down Expand Up @@ -247,7 +255,7 @@ export class ValueRef<T> {
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
//
Expand Down Expand Up @@ -302,40 +310,40 @@ export abstract class Watcher<T, Before extends Element, After extends Element,
ignored: boolean;
stack: string;
};
}
}

// @public (undocumented)
export interface WatcherEvents<T> {
// @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<unknown, T>;
removed: Map<unknown, T>;
current: Map<unknown, T>;
}
new: Map<unknown, T>;
removed: Map<unknown, T>;
current: Map<unknown, T>;
}
];
// @eventProperty (undocumented)
onRemove: [
{
key: unknown;
value: T;
}
key: unknown;
value: T;
}
];
}

Expand All @@ -358,13 +366,12 @@ export class WebExtensionMessage<Message> {
// (undocumented)
logFormatter: (instance: this, key: string, data: unknown) => unknown[];
serialization: Serialization;
}
}

// @public (undocumented)
export interface WebExtensionMessageOptions {
readonly domain?: string;
readonly externalExtensionID?: string;
}


```
24 changes: 18 additions & 6 deletions src/Extension/MessageChannel.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* 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'

/**
* Define how to do serialization and deserialization of remote procedure call
*/
export interface Serialization {
export interface Serialization {
/**
* Do serialization
* @param from - original data
Expand All @@ -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<T> {
/** @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
/**
Expand Down Expand Up @@ -210,7 +218,7 @@ export class WebExtensionMessage<Message> {
*
* 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)}`,
Expand Down Expand Up @@ -285,9 +293,13 @@ function UnboundedRegistry<T>(
})
}
let binder: TargetBoundEventRegistry<T>
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)
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 7c3d0d0

Please sign in to comment.