UNPKG

@connectv/core

Version:

agent-based reactive programming library for typescript/javascript

101 lines 3.24 kB
import { Subject, defer } from 'rxjs'; import { BasePin } from './base'; import { PinLockedError } from './errors/locked.error'; import { UnresolvedPinObservableError } from './errors/unresolved-observable.error'; /** * * Represents pins that you can connect other pins to. * */ export class Connectible extends BasePin { constructor() { super(); this._resolving = false; this._deference_connected = false; this._inbound = []; } /** * * @note it will throw an error if this pin is already locked. * You can read more about this [here](https://connective.dev/docs/pin#subscribing-and-binding). * */ connect(pin) { if (this.locked) throw new PinLockedError(); if (!this._inbound.includes(pin)) this._inbound.push(pin); return this; } /** * * @note Accessing this property locks the pin. * You can read more about this [here](https://connective.dev/docs/pin#subscribing-and-binding). * */ get observable() { if (this.shouldResolve(this._inbound, this._observable)) { if (this._resolving) { if (!this._deferred) { this._deferred = new Subject(); } return this._deferred; } else { this._resolving = true; this._observable = this.resolve(this._inbound); if (this._deferred) { let _pristine = this._observable; this._observable = defer(() => { if (!this._deference_connected) { this.track(_pristine.subscribe(this._deferred)); this._deference_connected = true; } return _pristine; }); } this._resolving = false; } } if (!this._observable) throw new UnresolvedPinObservableError(); return this._observable; } /** * * @note Calling `.clear()` will unlock the pin and disconnect it from * all the pins its connected to (removing their references). There is no guarantee * that the pin will be usable afterwards. * */ clear() { this._inbound.length = 0; this._observable = undefined; this._deference_connected = false; if (this._deferred) { this._deferred.complete(); this._deferred = undefined; } return super.clear(); } /** * * @returns `true` if the pin is locked, `false` if not. * You can read more about this [here](https://connective.dev/docs/pin#subscribing-and-binding). * */ get locked() { return this.isLocked(this._observable); } /** * * @returns `true` if any other pin is connected to this pin, `false` if not. * */ get connected() { return this.isConnected(); } /** * * Override this to determine the value of `.connected` through other means. * */ isConnected() { return this._inbound.length > 0; } } //# sourceMappingURL=connectible.js.map