Skip to content

Instantly share code, notes, and snippets.

@alshdavid
Last active February 5, 2022 11:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alshdavid/00168ec6e1366342aad48b2a599e8400 to your computer and use it in GitHub Desktop.
Save alshdavid/00168ec6e1366342aad48b2a599e8400 to your computer and use it in GitHub Desktop.
export type Callback<T extends Array<any> = [], U = void> = (...args: T) => U
export interface Subscriber<T> {
subscribe(
value: Callback<[T], any>,
error?: Callback<[unknown], any>,
complete?: Callback<[], any>
): Unsubscriber
}
export interface Unsubscriber {
unsubscribe(): void
}
export class Observable<T> implements Subscriber<T> {
private _setup: Callback<[
Callback<[T]>,
Callback<[any]>,
Callback
], void | Callback<[], any>>
constructor(
setup: Callback<[
Callback<[T]>,
Callback<[any]>,
Callback,
], void | Callback<[], any>>
) {
this._setup = setup;
}
subscribe(
valueCallback: Callback<[T]>,
errorCallback?: Callback<[unknown]>,
completeCallback?: Callback<[], any>,
): Unsubscriber {
let isActive: boolean = true;
const teardown = this._setup(
(value: T) => {
if (isActive) valueCallback(value)
},
(error: unknown) => {
if (!isActive) return;
if (errorCallback) errorCallback(error);
isActive = false;
},
() => {
if (!isActive) return;
if (typeof teardown === 'function') teardown();
if (completeCallback) completeCallback();
isActive = false;
}
)
if (!isActive && teardown) {
teardown()
}
return new Subscription(() => {
if (teardown) teardown()
isActive = false
})
}
}
export class Subscription implements Unsubscriber {
constructor(
public unsubscribe: () => void
) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment