UNPKG

rxjs-task-subject

Version:

A extension of ReplaySubject to add useful features like time tracking, details, ...

183 lines (152 loc) 5.49 kB
'use strict'; var Rx = require('rxjs/Rx'); var undef = require('ifnotundef'); var vsprintf = require('sprintf-js').vsprintf; var slice = require('sliced'); var q = require('q'); class TaskSubjectInfo { constructor(statusOrTaskSubjectInfo, val, detail) { this.startedDate = new Date(); this.set(statusOrTaskSubjectInfo, val, detail); } static create(statusOrTaskSubjectInfo, val, detail) { return new TaskSubjectInfo(statusOrTaskSubjectInfo, val, detail); } set(statusOrTaskSubjectInfo, val, detail) { this.modifiedDate = new Date(); if (statusOrTaskSubjectInfo instanceof TaskSubjectInfo) { this.status = statusOrTaskSubjectInfo.status; this.val = statusOrTaskSubjectInfo.val; this.detail = statusOrTaskSubjectInfo.detail; this.startedDate = statusOrTaskSubjectInfo.startedDate; } else { this.status = statusOrTaskSubjectInfo; this.val = val; this.detail = detail; } } } /** * * [![GitHub version](https://badge.fury.io/gh/pouc%2Frxjs-task-subject.svg)](https://badge.fury.io/gh/pouc%2Frxjs-task-subject) * [![npm version](https://badge.fury.io/js/rxjs-task-subject.svg)](https://badge.fury.io/js/rxjs-task-subject) * [![NPM monthly downloads](https://img.shields.io/npm/dm/rxjs-task-subject.svg?style=flat)](https://npmjs.org/package/rxjs-task-subject) * [![Build Status](https://travis-ci.org/pouc/rxjs-task-subject.svg?branch=master)](https://travis-ci.org/pouc/rxjs-task-subject) * [![Dependency Status](https://gemnasium.com/badges/github.com/pouc/rxjs-task-subject.svg)](https://gemnasium.com/github.com/pouc/rxjs-task-subject) * [![Coverage Status](https://coveralls.io/repos/github/pouc/rxjs-task-subject/badge.svg?branch=master)](https://coveralls.io/github/pouc/rxjs-task-subject?branch=master) * [![Known Vulnerabilities](https://snyk.io/test/github/pouc/rxjs-task-subject/badge.svg)](https://snyk.io/test/github/pouc/rxjs-task-subject) * * A extension of ReplaySubject to add useful features like time tracking, details, ... * * @module rxjs-task-subject * @typicalname template * @author Loïc Formont * * @license MIT Licensed * * @example * ```javascript * var TaskSubject = require("rxjs-task-subject"); * ``` */ module.exports = class TaskSubject extends Rx.ReplaySubject { constructor() { super(); this.bound = []; this.info = TaskSubjectInfo.create('waiting'); } lift(operator) { const observable = new Rx.Observable(); observable.source = this; observable.operator = operator; return observable; } next(options) { if (options instanceof TaskSubjectInfo) { this.set(options); } else { this.set('running', options); } super.next(this.get()); } error(options) { if (options instanceof TaskSubjectInfo) { this.set(options); } else { this.set('failed', options); } super.error(this.get()); } toPromise(PromiseCtor) { return super .toPromise(PromiseCtor) .then( (ret) => ret.val, (err) => { throw err.val; } ); } get() { return TaskSubjectInfo.create(this.info); } set(statusOrTaskSubjectInfo, val, detail) { this.info.set(statusOrTaskSubjectInfo, val, detail); } changeStatus(status, val, detail, err) { if (!undef.if(err, false)) this.next(TaskSubjectInfo.create(status, val, detail)); else this.error(TaskSubjectInfo.create(status, val, detail)); } start() { this.set('running'); } running(val, detail) { this.changeStatus('running', val, parseDetail(detail, arguments)); } done(val) { this.changeStatus('done', val); this.complete(); } failed(val, detail) { this.changeStatus('failed', val, parseDetail(detail, arguments), true); } bind(f, first) { var myFirst = undef.if(first, false); if (this.bound.map((b) => b.f).indexOf(f) >= 0) { this.bound.filter((b) => b.f == f).forEach((b) => { b.active = true; b.first = myFirst; }); } else { var boundData = {f: f, active: true, first: myFirst}; this.bound.push(boundData); this .filter(() => boundData.active) .filter(() => { if (boundData.first) { boundData.active = false; return true; } else { return true; } }) .subscribe(f, f); } } unbind(f) { this.bound.filter((b) => b.f == f).forEach((b) => { b.active = false; }); } once(f) { this.bind(f, true); } }; module.exports.TaskSubjectInfo = TaskSubjectInfo; function parseDetail(detail, args) { if (!undef.check(detail)) { return; } else if (typeof detail !== 'string') { return detail; } else { return vsprintf(detail, slice(args, 2)); } }