Security News
ESLint is Now Language-Agnostic: Linting JSON, Markdown, and Beyond
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
@dldc/pubsub
Advanced tools
A simple pub/sub written in Typescript
import { Suub } from 'suub';
const mySub = Suub.createSubscription<number>();
const unsub = mySub.subscribe((num) => {
console.log('num: ' + num);
});
mySub.emit(45); // num: 45
unsub();
To create a Subscription
you need to import the Suub.createSubscription
function and call it.
import { Suub } from 'suub';
const subscription = Suub.createSubscription();
If you use TypeScript, you need to pass a type parameter to the Suub.createSubscription
function to define the type of the value associated with the subscription.
import { Suub } from 'suub';
const numSubscription = Suub.createSubscription<number>();
If you don't want your subscription not to emit any value, you can use the Suub.createVoidSubscription
function.
import { Suub } from 'suub';
const voidSubscription = Suub.createVoidSubscription();
You have two ways to subscribe
/ unsubscribe
.
const callback = () => {
/*...*/
};
subscription.subscribe(callback);
// later
subscription.unsubscribe(callback);
subscription.subscribeById('mySubId', () => {
/*...*/
});
// later
subscription.unsubscribeById('mySubId');
In both case the subscribe[ById]
return a function that will unsubscribe:
const unsub = subscription.subscribe(/*...*/);
// later
unsub();
To emit a value and trigger all subscribed callback
you need to call the emit
method.
subscription.emit(42);
// for void subscription you don't need to pass any value
subscription.emit();
The subscribe[ById]
methods accept a optional function after the callback, this function will be called when this callback you are subscribing is unsubscribed.
subscription.subscribe(
() => {
/* ... */
},
() => {
console.log('Unsubscribed !');
}
);
// or with a subId
subscription.subscribeById(
'mySub',
() => {
/* ... */
},
() => {
console.log('Unsubscribed !');
}
);
You can call unsubscribeAll
method on a subscription to remove all callback. This will also trigger the onUnsubscribe
if any.
subscription.unsubscribeAll();
Subscription
optionsThe Subscription.create
(or Subscription.createVoid
) functions accept an option object as parameter (all properties are optional):
const sub = Subscription.create({
onFirstSubscription: () => {},
onLastUnsubscribe: () => {},
onDestroy: () => {},
maxSubscriptionCount: 10000,
maxRecursiveEmit: 1000,
maxUnsubscribeAllLoop: 1000,
});
onFirstSubscription
A function called when the number of subscribers goes from
0
to1
onLastUnsubscribe
A function called when the number of subscribers goes from
1
to0
onDestroy
A function called when the
destroy
method is called. Note that during this call theSubscription
is already destroyed and you can't callemit
orsubscribe
anymore.
maxSubscriptionCount
A number to limit the maximum number of simultaneous subscriptions (default is
10000
). This limit exist to detect infinit subscription loop.
maxRecursiveEmit
A number to limit the maximum recursive call of
emit
(default is1000
). This limit exist to detect infinite loop where youemit
in acallback
.
maxUnsubscribeAllLoop
A number to limit the maximum recursive call of
subscribe
inside aonUnsubscribe
callback (default is1000
).
The isSubscribed[ById]
methods let you test whether or not a callback / subId is currently subscribed
subscription.isSubscribed(myCallback); // <- boolean
subscription.isSubscribedById('my-sub-id'); // <- boolean
You can call the size
method to get the number of subscriptions.
subscription.size();
You can call the destroy
method to destroy a subscription. This will unsubscribe all callback and call the onDestroy
option if any.
subscription.destroy();
Once destroyed, calling emit
or subscribe[ById]
will throw an error. You can still call the other methods but they will have no effect.
You can check if a subscription is destroyed by calling the isDestroyed
method.
subscription.isDestroyed(); // <- boolean
// TODO
In other words, calling subscribe
on an already subscribed callback or subId will not make the callback called twice. But it will move the callback at the end of the subscription list.
In the case of a subId, the callback will be replaced by the new one.
unsubscribe
in a callback it will have effect immediatly.If the callback you unsubscribe is supposed to run after the current callback, it will not be called.
subscribe
in a callback it will not be called immediatly.But it will be in the next emit
.
emit()
in a callback it will defer the call to after the current emit is done.subscribe
/ unsubscribe
/ emit
in an onUnsubscribed
it will behave the same as if it was in the callback itselfdestroy
will unsubscribe all callback and call the onUnsubscribe
if anyIn these onUnsubscribe
callback the subscription is considered destroyed so you can't call emit
or subscribe
anymore.
destroy
on a destroyed subscription will have no effectThis is a no-op, it will not call onDestroy
again.
onDestroy
is calledThis means that you can't call emit
or subscribe
in the onDestroy
callback and that isDestroyed
will return true
in the onDestroy
callback.
Take a look at the Examples folder.
export type Unsubscribe = () => void;
export type OnUnsubscribed = () => void;
export type SubscriptionCallback<T> = (value: T) => void;
export type VoidSubscriptionCallback = () => void;
export type UnsubscribeAllMethod = () => void;
export interface SubscribeMethod<T> {
(callback: SubscriptionCallback<T>, onUnsubscribe?: OnUnsubscribed): Unsubscribe;
(subId: string, callback: SubscriptionCallback<T>, onUnsubscribe?: OnUnsubscribed): Unsubscribe;
}
export interface VoidSubscribeMethod {
(callback: VoidSubscriptionCallback, onUnsubscribe?: OnUnsubscribed): Unsubscribe;
(subId: string, callback: VoidSubscriptionCallback, onUnsubscribe?: OnUnsubscribed): Unsubscribe;
}
export interface IsSubscribedMethod<T> {
(subId: string): boolean;
(callback: SubscriptionCallback<T>): boolean;
}
export interface UnsubscribeMethod<T> {
(subId: string): void;
(callback: SubscriptionCallback<T>): void;
}
export interface VoidIsSubscribedMethod {
(subId: string): boolean;
(callback: VoidSubscriptionCallback): boolean;
}
export interface VoidUnsubscribeMethod {
(subId: string): void;
(callback: VoidSubscriptionCallback): void;
}
export interface ISubscription<T> {
subscribe: SubscribeMethod<T>;
unsubscribe: UnsubscribeMethod<T>;
unsubscribeAll: UnsubscribeAllMethod;
isSubscribed: IsSubscribedMethod<T>;
size: () => number;
emit: (newValue: T) => void;
destroy: () => void;
isDestroyed: () => boolean;
}
export interface IVoidSubscription {
subscribe: VoidSubscribeMethod;
unsubscribe: VoidUnsubscribeMethod;
unsubscribeAll: UnsubscribeAllMethod;
isSubscribed: VoidIsSubscribedMethod;
size: () => number;
emit: () => void;
destroy: () => void;
isDestroyed: () => boolean;
}
export interface ISubscriptionOptions {
onFirstSubscription?: () => void;
onLastUnsubscribe?: () => void;
onDestroy?: () => void;
maxSubscriptionCount?: number;
maxRecursiveEmit?: number;
}
FAQs
A simple pub/sub written in Typescript
The npm package @dldc/pubsub receives a total of 1 weekly downloads. As such, @dldc/pubsub popularity was classified as not popular.
We found that @dldc/pubsub demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
Security News
Members Hub is conducting large-scale campaigns to artificially boost Discord server metrics, undermining community trust and platform integrity.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.