UNPKG

@connectv/core

Version:

agent-based reactive programming library for typescript/javascript

226 lines 8.26 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); var operators_1 = require("rxjs/operators"); var emission_1 = require("../shared/emission"); var control_1 = require("../pin/control"); var pin_1 = require("../pin/pin"); var group_1 = __importDefault(require("../pin/group")); var map_1 = __importDefault(require("../pin/map")); var filter_1 = __importStar(require("../pin/filter")); var pipe_1 = __importDefault(require("../pin/pipe")); var agent_1 = require("./agent"); /** * * Creates a sequence token that denotes events happening between `min` and * `max` number of times. * * @param min the minimum number of times the event should happen * @param max the maximum number of times the event should happen * */ function range(min, max) { return { accepts: function (_, list) { return max === undefined || list.length < max; }, complete: function (list) { return list.length >= min; } }; } exports.range = range; /** * * Creates a sequence token that denotes events happening a * specified number of times exactly * * @param c the number of times the event should happen. * */ function count(c) { return range(c, c); } exports.count = count; /** * * Sequence token denoting an event that may or may not happen (multiple times). * */ exports.maybesome = range(0); /** * * Sequence token denoting an event that happens at least once. * */ exports.some = range(1); /** * * Represents [sequence](https://connective.dev/docs/sequence) agents. * */ var Sequence = /** @class */ (function (_super) { __extends(Sequence, _super); /** * * @param tokens the tokens denoting the sequence of desired events. Each token must be * - A `SequenceToken`, * - A number, meaning that an event should happen that number of times exactly, * - `'+'` meaning the event should happen at least once, * - `'*'` meaning the event may or may not happen one or multiple times. * */ function Sequence(tokens) { var _this = _super.call(this, { inputs: tokens.map(function (_, index) { return index.toString(); }), outputs: ['out'] }) || this; _this._head = 0; _this._control = new control_1.Control(); _this._relay = new pin_1.Pin(); _this.tokens = tokens.map(function (t) { if (typeof t == 'number') return count(t); if (t === '+') return exports.some; if (t === '*') return exports.maybesome; return t; }); tokens.forEach(function (_, index) { _this.in(index).to(pipe_1.default(operators_1.map(function (e) { _this._take(e, index, true); return e; }))).to(_this._relay); }); _this.reset(); return _this; } Sequence.prototype._take = function (emission, index, retry) { if (retry === void 0) { retry = false; } if (index == this._head) { if (this.tokens[index].accepts(emission, this._seq[index])) this._seq[index].push(emission); else { this.reset(); if (retry) this._take(emission, index); } } else { if (index < this._head) { this.reset(); this._take(emission, index); } else { if (this._seek(index)) this._take(emission, index, retry); else { this.reset(); if (this._seek(index)) this._take(emission, index, retry); } } } }; Sequence.prototype._seek = function (index) { for (var i = this._head; i < index; i++) if (!this.tokens[i].complete(this._seq[i])) return false; this._head = index; return true; }; Object.defineProperty(Sequence.prototype, "_complete", { get: function () { var _this = this; return this._seq.every(function (e, index) { return _this.tokens[index].complete(e); }); }, enumerable: true, configurable: true }); Sequence.prototype.reset = function () { this._seq = this.tokens.map(function (_) { return []; }); this._head = 0; return this; }; Sequence.prototype.createOutput = function (label) { var _this = this; this.checkOutput(label); return group_1.default(this._control.to(map_1.default(function () { return _this.reset(); })).to(filter_1.block()), this._relay.to(filter_1.default(function () { return _this._complete; }))).to(pipe_1.default(operators_1.map(function () { var _vals = _this._seq.map(function (_comp) { return (_comp.length == 1) ? (_comp[0].value) : (_comp.map(function (_) { return _.value; })); }); var _emission = emission_1.Emission.from(_this._seq.reduce(function (all, list) { return all.concat(list); }, []), (_this.tokens.length == 1) ? _vals[0] : _vals); return _emission; }), operators_1.share())); }; Sequence.prototype.createEntries = function () { var _this = this; return (this.signature.inputs || []).map(function (i) { return _this.in(i); }); }; Sequence.prototype.createExits = function () { return [this.output]; }; Sequence.prototype.clear = function () { this.reset(); this._control.clear(); this._relay.clear(); return _super.prototype.clear.call(this); }; Object.defineProperty(Sequence.prototype, "control", { /** * * Resets the sequence being tracked when receiving emissions * on `.control`. * */ get: function () { return this._control; }, enumerable: true, configurable: true }); Object.defineProperty(Sequence.prototype, "output", { /** * * Shortcut for `.out('out')`, which will emit completed sequences. * [Read this](https://connective.dev/docs/sequence#signature) for more details. * */ get: function () { return this.out('out'); }, enumerable: true, configurable: true }); return Sequence; }(agent_1.Agent)); exports.Sequence = Sequence; /** * * Creates a [sequence](https://connective.dev/docs/sequence) agent. * Sequence agents can determine if a specific sequence of events has occured. * [Checkout the docs](https://connective.dev/docs/sequence) for examples and further information. * * @param tokens the tokens denoting the sequence of desired events. Each token must be * - A `SequenceToken`, * - A number, meaning that an event should happen that number of times exactly, * - `'+'` meaning the event should happen at least once, * - `'*'` meaning the event may or may not happen one or multiple times. * */ function sequence() { var tokens = []; for (var _i = 0; _i < arguments.length; _i++) { tokens[_i] = arguments[_i]; } return new Sequence(tokens); } exports.sequence = sequence; exports.default = sequence; //# sourceMappingURL=sequence.js.map