zen-observable
Advanced tools
Comparing version 0.8.0 to 0.8.2
@@ -14,3 +14,3 @@ module.exports = { | ||
"parserOptions": { | ||
"sourceType": "script" | ||
"sourceType": "module" | ||
}, | ||
@@ -17,0 +17,0 @@ |
@@ -1,1 +0,1 @@ | ||
module.exports = require("./zen-observable.js"); | ||
module.exports = require('./lib/Observable.js').Observable; |
{ | ||
"name": "zen-observable", | ||
"version": "0.8.0", | ||
"version": "0.8.2", | ||
"repository": "zenparsing/zen-observable", | ||
@@ -9,14 +9,14 @@ "description": "An Implementation of ES Observables", | ||
"devDependencies": { | ||
"esdown": "^1.2.8", | ||
"babel-cli": "^6.26.0", | ||
"babel-preset-es2015": "^6.24.1", | ||
"eslint": "^4.16.0", | ||
"mocha": "^5.0.0", | ||
"moon-unit": "^0.2.1" | ||
"mocha": "^5.0.0" | ||
}, | ||
"dependencies": {}, | ||
"scripts": { | ||
"test": "mocha", | ||
"test": "mocha --require babel-core/register", | ||
"lint": "eslint src/*", | ||
"build": "esdown - src/Observable.js zen-observable.js -g '*'", | ||
"prepublishOnly": "eslint src/* && mocha && npm run build" | ||
"build": "git clean -dfX ./lib && babel src --out-dir lib", | ||
"prepublishOnly": "eslint src/* && npm test && npm run build" | ||
} | ||
} |
@@ -11,28 +11,5 @@ # zen-observable | ||
## Download | ||
https://unpkg.com/zen-observable/zen-observable.js | ||
## Usage | ||
Node: | ||
```js | ||
var Observable = require('zen-observable'); | ||
Observable.of(1, 2, 3).subscribe(x => console.log(x)); | ||
``` | ||
Browser: | ||
```html | ||
<script src='zen-observable.js'></script> | ||
<script> | ||
Observable.of(1, 2, 3).subscribe(x => console.log(x)); | ||
</script> | ||
``` | ||
Modules: | ||
```js | ||
import Observable from 'zen-observable'; | ||
@@ -39,0 +16,0 @@ |
@@ -1,51 +0,64 @@ | ||
let Observable = require('./Observable'); | ||
import Observable from './Observable.js'; | ||
// Emits all values from all inputs in parallel | ||
const merge = (...sources) => new Observable(observer => { | ||
let count = sources.length; | ||
export function merge(...sources) { | ||
return new Observable(observer => { | ||
if (sources.length === 0) | ||
return Observable.from([]); | ||
let subscriptions = sources.map(source => source.subscribe({ | ||
next(v) { observer.next(v) }, | ||
error(e) { observer.error(e) }, | ||
complete() { if (--count === 0) observer.complete(); }, | ||
})); | ||
let count = sources.length; | ||
return () => subscriptions.forEach(s => s.unsubscribe()); | ||
}); | ||
let subscriptions = sources.map(source => Observable.from(source).subscribe({ | ||
next(v) { observer.next(v) }, | ||
error(e) { observer.error(e) }, | ||
complete() { if (--count === 0) observer.complete(); }, | ||
})); | ||
return () => subscriptions.forEach(s => s.unsubscribe()); | ||
}); | ||
} | ||
// Emits arrays containing the most current values from each input | ||
const combineLatest = (...sources) => new Observable(observer => { | ||
let count = sources.length; | ||
let values = new Map(); | ||
export function combineLatest(...sources) { | ||
return new Observable(observer => { | ||
if (sources.length === 0) | ||
return Observable.from([]); | ||
let subscriptions = sources.map((source, index) => source.subscribe({ | ||
next(v) { | ||
values.set(index, v); | ||
if (values.size === sources.length) | ||
observer.next(Array.from(values.values())); | ||
}, | ||
error(e) { observer.error(e) }, | ||
complete() { if (--count === 0) observer.complete(); }, | ||
})); | ||
let count = sources.length; | ||
let values = new Map(); | ||
return () => subscriptions.forEach(s => s.unsubscribe()); | ||
}); | ||
let subscriptions = sources.map((source, index) => Observable.from(source).subscribe({ | ||
next(v) { | ||
values.set(index, v); | ||
if (values.size === sources.length) | ||
observer.next(Array.from(values.values())); | ||
}, | ||
error(e) { observer.error(e) }, | ||
complete() { if (--count === 0) observer.complete(); }, | ||
})); | ||
return () => subscriptions.forEach(s => s.unsubscribe()); | ||
}); | ||
} | ||
// Emits arrays containing the matching index values from each input | ||
const zip = (...sources) => new Observable(observer => { | ||
let queues = sources.map(() => []); | ||
export function zip(...sources) { | ||
return new Observable(observer => { | ||
if (sources.length === 0) | ||
return Observable.from([]); | ||
let subscriptions = sources.map((source, index) => source.subscribe({ | ||
next(v) { | ||
queues[index].push(v); | ||
if (queues.every(q => q.length > 0)) | ||
observer.next(queues.map(q => q.shift())); | ||
}, | ||
error(e) { observer.error(e) }, | ||
complete() { observer.complete() }, | ||
})); | ||
let queues = sources.map(() => []); | ||
return () => subscriptions.forEach(s => s.unsubscribe()); | ||
}); | ||
let subscriptions = sources.map((source, index) => Observable.from(source).subscribe({ | ||
next(v) { | ||
queues[index].push(v); | ||
if (queues.every(q => q.length > 0)) | ||
observer.next(queues.map(q => q.shift())); | ||
}, | ||
error(e) { observer.error(e) }, | ||
complete() { observer.complete() }, | ||
})); | ||
module.exports = { merge, combineLatest, zip }; | ||
return () => subscriptions.forEach(s => s.unsubscribe()); | ||
}); | ||
} |
@@ -40,10 +40,2 @@ // === Symbol Support === | ||
function addMethods(target, methods) { | ||
Object.keys(methods).forEach(k => { | ||
let desc = Object.getOwnPropertyDescriptor(methods, k); | ||
desc.enumerable = false; | ||
Object.defineProperty(target, k, desc); | ||
}); | ||
} | ||
function hostReportError(e) { | ||
@@ -105,25 +97,26 @@ if (hostReportError.log) { | ||
function Subscription(observer, subscriber) { | ||
// ASSERT: observer is an object | ||
// ASSERT: subscriber is callable | ||
class Subscription { | ||
this._cleanup = undefined; | ||
this._observer = observer; | ||
this._state = 'initializing'; | ||
constructor(observer, subscriber) { | ||
// ASSERT: observer is an object | ||
// ASSERT: subscriber is callable | ||
let subscriptionObserver = new SubscriptionObserver(this); | ||
this._cleanup = undefined; | ||
this._observer = observer; | ||
this._state = 'initializing'; | ||
try { | ||
this._cleanup = subscriber.call(undefined, subscriptionObserver); | ||
} catch (e) { | ||
enqueue(() => subscriptionObserver.error(e)); | ||
let subscriptionObserver = new SubscriptionObserver(this); | ||
try { | ||
this._cleanup = subscriber.call(undefined, subscriptionObserver); | ||
} catch (e) { | ||
enqueue(() => subscriptionObserver.error(e)); | ||
} | ||
this._state = 'ready'; | ||
} | ||
this._state = 'ready'; | ||
} | ||
addMethods(Subscription.prototype = {}, { | ||
get closed() { | ||
return subscriptionClosed(this); | ||
}, | ||
} | ||
@@ -136,14 +129,14 @@ unsubscribe() { | ||
} | ||
}, | ||
}); | ||
function SubscriptionObserver(subscription) { | ||
this._subscription = subscription; | ||
} | ||
} | ||
addMethods(SubscriptionObserver.prototype = {}, { | ||
class SubscriptionObserver { | ||
constructor(subscription) { | ||
this._subscription = subscription; | ||
} | ||
get closed() { | ||
return subscriptionClosed(this._subscription); | ||
}, | ||
} | ||
@@ -169,3 +162,3 @@ next(value) { | ||
subscription._state = 'ready'; | ||
}, | ||
} | ||
@@ -192,3 +185,3 @@ error(value) { | ||
cleanupSubscription(subscription); | ||
}, | ||
} | ||
@@ -213,17 +206,17 @@ complete() { | ||
cleanupSubscription(subscription); | ||
}, | ||
} | ||
}); | ||
} | ||
function Observable(subscriber) { | ||
if (!(this instanceof Observable)) | ||
throw new TypeError('Observable cannot be called as a function'); | ||
export class Observable { | ||
if (typeof subscriber !== 'function') | ||
throw new TypeError('Observable initializer must be a function'); | ||
constructor(subscriber) { | ||
if (!(this instanceof Observable)) | ||
throw new TypeError('Observable cannot be called as a function'); | ||
this._subscriber = subscriber; | ||
} | ||
if (typeof subscriber !== 'function') | ||
throw new TypeError('Observable initializer must be a function'); | ||
addMethods(Observable.prototype, { | ||
this._subscriber = subscriber; | ||
} | ||
@@ -239,3 +232,3 @@ subscribe(observer) { | ||
return new Subscription(observer, this._subscriber); | ||
}, | ||
} | ||
@@ -262,3 +255,3 @@ forEach(fn) { | ||
}); | ||
}, | ||
} | ||
@@ -280,3 +273,3 @@ map(fn) { | ||
})); | ||
}, | ||
} | ||
@@ -298,3 +291,3 @@ filter(fn) { | ||
})); | ||
}, | ||
} | ||
@@ -336,3 +329,3 @@ reduce(fn) { | ||
})); | ||
}, | ||
} | ||
@@ -369,15 +362,7 @@ concat(...sources) { | ||
}); | ||
}, | ||
} | ||
}); | ||
[getSymbol('observable')]() { return this } | ||
Object.defineProperty(Observable.prototype, getSymbol('observable'), { | ||
value: function() { return this }, | ||
writable: true, | ||
configurable: true, | ||
}); | ||
addMethods(Observable, { | ||
from(x) { | ||
static from(x) { | ||
let C = typeof this === 'function' ? this : Observable; | ||
@@ -431,5 +416,5 @@ | ||
throw new TypeError(x + ' is not observable'); | ||
}, | ||
} | ||
of(...items) { | ||
static of(...items) { | ||
let C = typeof this === 'function' ? this : Observable; | ||
@@ -447,18 +432,16 @@ | ||
}); | ||
}, | ||
} | ||
}); | ||
static get [getSymbol('species')]() { return this } | ||
Object.defineProperty(Observable, getSymbol('species'), { | ||
get() { return this }, | ||
configurable: true, | ||
}); | ||
} | ||
if (hasSymbols()) { | ||
Object.defineProperty(Observable, Symbol('extensions'), { | ||
value: { symbol: getSymbol('observable'), hostReportError }, | ||
configurable: true, | ||
value: { | ||
symbol: getSymbol('observable'), | ||
hostReportError, | ||
}, | ||
configurabe: true, | ||
}); | ||
} | ||
module.exports = Observable; |
@@ -1,3 +0,3 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
@@ -4,0 +4,0 @@ describe('concat', () => { |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -5,0 +5,0 @@ describe('constructor', () => { |
@@ -1,3 +0,3 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
@@ -4,0 +4,0 @@ describe('filter', () => { |
@@ -1,3 +0,3 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
@@ -4,0 +4,0 @@ describe('forEach', () => { |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -5,0 +5,0 @@ describe('from', () => { |
@@ -1,3 +0,3 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
@@ -4,0 +4,0 @@ describe('map', () => { |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -5,0 +5,0 @@ describe('observer.closed', () => { |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -110,2 +110,3 @@ describe('observer.complete', () => { | ||
let calls = []; | ||
let observer; | ||
new Observable(x => { | ||
@@ -123,2 +124,3 @@ observer = x; | ||
let calls = []; | ||
let observer; | ||
new Observable(x => { | ||
@@ -125,0 +127,0 @@ observer = x; |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -112,2 +112,3 @@ describe('observer.error', () => { | ||
let calls = []; | ||
let observer; | ||
new Observable(x => { | ||
@@ -125,2 +126,3 @@ observer = x; | ||
let calls = []; | ||
let observer; | ||
new Observable(x => { | ||
@@ -127,0 +129,0 @@ observer = x; |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -5,0 +5,0 @@ describe('observer.next', () => { |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -5,0 +5,0 @@ describe('of', () => { |
@@ -1,6 +0,4 @@ | ||
const assert = require('assert'); | ||
import assert from 'assert'; | ||
module.exports = { testMethodProperty }; | ||
function testMethodProperty(object, key, options) { | ||
export function testMethodProperty(object, key, options) { | ||
let desc = Object.getOwnPropertyDescriptor(object, key); | ||
@@ -7,0 +5,0 @@ let { enumerable = false, configurable = false, writable = false, length } = options; |
@@ -1,3 +0,3 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
@@ -4,0 +4,0 @@ describe('reduce', () => { |
@@ -1,2 +0,2 @@ | ||
const Observable = require('../src/Observable'); | ||
import { Observable } from '../src/Observable.js'; | ||
@@ -3,0 +3,0 @@ beforeEach(() => { |
@@ -1,3 +0,3 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
@@ -4,0 +4,0 @@ describe('species', () => { |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -5,0 +5,0 @@ describe('subscribe', () => { |
@@ -1,4 +0,4 @@ | ||
const Observable = require('../src/Observable'); | ||
const assert = require('assert'); | ||
const { testMethodProperty } = require('./properties'); | ||
import { Observable } from '../src/Observable.js'; | ||
import assert from 'assert'; | ||
import { testMethodProperty } from './properties.js'; | ||
@@ -5,0 +5,0 @@ describe('subscription', () => { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
64832
29
1887
0
177