@connectv/core
Version:
agent-based reactive programming library for typescript/javascript
206 lines • 7.41 kB
JavaScript
import { Subscription } from 'rxjs';
import { isBindable } from '../shared/bindable';
import { GroupObservableError } from './errors/group-subscription';
import { PartialFlow } from './partial-flow';
/**
*
* Represents [groups of pins](https://connective.dev/docs/group).
*
*/
export class Group {
constructor(pins) {
this.pins = pins;
}
/**
*
* @warning accessing this will result in an error since groups do not have
* underlying observables of their own.
*
*/
get observable() {
throw new GroupObservableError();
}
/**
*
* Connects all given pins to all pins in this group, so
* `group(c, d).from(a, b)` means both `a` and `b` will be connected
* to both `c` and `d`.
*
* If any `PartialFlow` is among given pins, all of the exit pins of the partial flow will be
* connected to all of the pins of this group
* (read more about partial flows [here](https://connective.dev/docs/agent#implicit-connection)).
*
* @param pins pins to be connected to pins of this group
* @returns a [group](https://connective.dev/docs/group) of the given pins. If any `PartialFlow`
* was among the given pins, its entry pins will be added to the group.
*
*/
from(...pins) {
pins.forEach(pin => this.pins.forEach(p => p.from(pin)));
return traverseFrom(...pins);
}
/**
*
* Connects all pins of this group to all of the given pins, so
* `group(a, b).to(c, d)` means both `a` and `b` will be connected to
* both `c` and `d`.
*
* If any `PartialFlow` is among the given pins, all pins of the group will be connected to all of
* its entry pins (read more about partial flows [here](https://connective.dev/docs/agent#implicit-connection)).
*
* @param pins the pins to connect pins of this group to
* @returns a [group](https://connective.dev/docs/group) of the given pins. If any `PartialFlow`
* was among the given pins, its exit pins added to the group.
*
*/
to(...pins) {
pins.forEach(pin => this.pins.forEach(p => p.to(pin)));
return traverseTo(...pins);
}
/**
*
* Connects given pins serially to pins of this group, i.e. the first to the first,
* second to the second, etc. If any `PartialFlow` is among the given pins, then
* its exit pins will be connected serially to pins of this group
* (read more about partial flows [here](https://connective.dev/docs/agent#implicit-connection)).
* If a mixture of `PartialFlow`s and normal pins are given, the normal pins will
* be connected to pins of this group serially without counting the partial flows, and the
* partial flows will each be connected to pins of this group as described.
*
* @param pins pins to be connected to pins of this group serially.
* @returns a [group](https://connective.dev/docs/group) of the given pins. If any `PartialFlow`
* was among the given pins, its entry pins will be added to the group.
*
*/
serialFrom(...pins) {
pins.filter(pin => pin instanceof PartialFlow).forEach(flow => {
for (let i = 0; i < Math.min(this.pins.length, flow.exits.pins.length); i++)
this.pins[i].from(flow.exits.pins[i]);
});
let purePins = pins.filter(p => !(p instanceof PartialFlow));
for (let i = 0; i < Math.min(this.pins.length, purePins.length); i++)
this.pins[i].from(purePins[i]);
return traverseFrom(...pins);
}
/**
*
* Connects pins of this group serially to given pins, i.e. first to the first,
* second to the second, etc. If any `PartialFlow` is among the given pins, pins of
* this group will be connected serially to its entries
* (read more about partial flows [here](https://connective.dev/docs/agent#implicit-connection)).
* If a mixture of `PartialFlow`s and normal pins are given, pins of this group will
* be connected to the normal pins serially without counting the partial flows, and they
* will be connected to the partial flows as described.
*
* @param pins pins that pins of this group should connect to serially.
* @returns a [group](https://connective.dev/docs/group) of the given pins. If any `PartialFlow`
* was among the given pins, its exit pins added to the group.
*
*/
serialTo(...pins) {
pins.filter(pin => pin instanceof PartialFlow).forEach(flow => {
for (let i = 0; i < Math.min(this.pins.length, flow.entries.pins.length); i++)
this.pins[i].to(flow.entries.pins[i]);
});
let purePins = pins.filter(p => !(p instanceof PartialFlow));
for (let i = 0; i < Math.min(this.pins.length, purePins.length); i++)
this.pins[i].to(purePins[i]);
return traverseTo(...pins);
}
/**
*
* Calls `.clear()` on all pins of the group
*
*/
clear() {
this.pins.forEach(pin => pin.clear());
return this;
}
/**
*
* Calls `.bind()` on all pins of the group
*
*/
bind() {
this.pins.forEach(pin => {
if (isBindable(pin))
pin.bind();
});
return this;
}
/**
*
* Subscribes given observer (or callback functions) to all pins of the group.
*
* @returns a composite subscription holding all of the subscriptions made.
*
*/
subscribe(_, __, ___) {
return this.pins.reduce((sub, pin) => {
sub.add(pin.subscribe(_, __, ___));
return sub;
}, new Subscription());
}
}
/**
*
* Creates a [group of pins](https://connective.dev/docs/group) based on given pins.
*
* @param pins
*
*/
export function group(...pins) { return new Group(pins); }
/**
*
* Determines which pins should be considered if in a connection chain
* we are connecting to the given pins. This is typically a `Group` consisting
* of given pins, but if any `PartialFlow`s are among them, their exit pins are
* added to the group instead.
*
* @param pins
*
*/
export function traverseTo(...pins) {
if (pins.length == 1) {
let pin = pins[0];
if (pin instanceof PartialFlow)
return pin.exits;
else
return pin;
}
else
return group(...pins.reduce((all, pin) => {
if (pin instanceof PartialFlow)
return all.concat(pin.exits.pins);
else
return all.concat([pin]);
}, []));
}
/**
*
* Determines which pins should be considered if in a connection chain
* we are connecting from the given pins. This is typically a `Group` consisting
* of given pins, but if any `PartialFlow`s are among them, their entry pins are
* added to the group instead.
*
* @param pins
*
*/
export function traverseFrom(...pins) {
if (pins.length == 1) {
let pin = pins[0];
if (pin instanceof PartialFlow)
return pin.entries;
else
return pin;
}
else
return group(...pins.reduce((all, pin) => {
if (pin instanceof PartialFlow)
return all.concat(pin.entries.pins);
else
return all.concat([pin]);
}, []));
}
export default group;
//# sourceMappingURL=group.js.map