Comparing version 2.0.1 to 2.0.2
# Changelog | ||
## 2.0.2 | ||
- **feat:** improve event performance | ||
- **fix:** export `IDisposable` | ||
## 2.0.1 | ||
@@ -4,0 +9,0 @@ |
@@ -115,4 +115,2 @@ "use strict"; | ||
it('handles isolation correctly', async () => { | ||
p.onBreak(onBreak); | ||
p.onReset(onReset); | ||
const handle1 = p.isolate(); | ||
@@ -119,0 +117,0 @@ chai_1.expect(onBreak).calledOnceWith({ isolated: true }); |
@@ -30,3 +30,3 @@ import { CancellationToken } from '../CancellationToken'; | ||
export declare class EventEmitter<T> { | ||
protected readonly listeners: Set<(data: T) => void>; | ||
private listeners?; | ||
/** | ||
@@ -45,2 +45,3 @@ * Event<T> function. | ||
protected addListenerInner(listener: (data: T) => void): IDisposable; | ||
private removeListener; | ||
} | ||
@@ -47,0 +48,0 @@ /** |
@@ -57,3 +57,2 @@ "use strict"; | ||
constructor() { | ||
this.listeners = new Set(); | ||
/** | ||
@@ -68,3 +67,11 @@ * Event<T> function. | ||
get size() { | ||
return this.listeners.size; | ||
if (!this.listeners) { | ||
return 0; | ||
} | ||
else if (typeof this.listeners === 'function') { | ||
return 1; | ||
} | ||
else { | ||
return this.listeners.length; | ||
} | ||
} | ||
@@ -75,10 +82,47 @@ /** | ||
emit(value) { | ||
for (const listener of this.listeners) { | ||
listener(value); | ||
if (!this.listeners) { | ||
// no-op | ||
} | ||
else if (typeof this.listeners === 'function') { | ||
this.listeners(value); | ||
} | ||
else { | ||
for (const listener of this.listeners) { | ||
listener(value); | ||
} | ||
} | ||
} | ||
addListenerInner(listener) { | ||
this.listeners.add(listener); | ||
return { dispose: () => this.listeners.delete(listener) }; | ||
if (!this.listeners) { | ||
this.listeners = listener; | ||
} | ||
else if (typeof this.listeners === 'function') { | ||
this.listeners = [this.listeners, listener]; | ||
} | ||
else { | ||
this.listeners.push(listener); | ||
} | ||
return { dispose: () => this.removeListener(listener) }; | ||
} | ||
removeListener(listener) { | ||
if (!this.listeners) { | ||
return; | ||
} | ||
if (typeof this.listeners === 'function') { | ||
if (this.listeners === listener) { | ||
this.listeners = undefined; | ||
} | ||
return; | ||
} | ||
const index = this.listeners.indexOf(listener); | ||
if (index === -1) { | ||
return; | ||
} | ||
if (this.listeners.length === 2) { | ||
this.listeners = index === 0 ? this.listeners[1] : this.listeners[0]; | ||
} | ||
else { | ||
this.listeners = this.listeners.slice(0, index).concat(this.listeners.slice(index + 1)); | ||
} | ||
} | ||
} | ||
@@ -115,5 +159,3 @@ exports.EventEmitter = EventEmitter; | ||
this.lastValue = { value }; | ||
for (const listener of this.listeners) { | ||
listener(value); | ||
} | ||
super.emit(value); | ||
} | ||
@@ -120,0 +162,0 @@ } |
@@ -10,9 +10,21 @@ "use strict"; | ||
it('emits events', () => { | ||
const s = sinon_1.stub(); | ||
const s1 = sinon_1.stub(); | ||
const s2 = sinon_1.stub(); | ||
const s3 = sinon_1.stub(); | ||
const emitter = new Event_1.EventEmitter(); | ||
const l = emitter.addListener(s); | ||
emitter.emit(42); | ||
l.dispose(); | ||
emitter.emit(43); | ||
chai_1.expect(s).to.have.been.calledOnceWith(42); | ||
const l1 = emitter.addListener(s1); | ||
emitter.emit(1); | ||
const l2 = emitter.addListener(s2); | ||
emitter.emit(2); | ||
const l3 = emitter.addListener(s3); | ||
emitter.emit(3); | ||
l1.dispose(); | ||
emitter.emit(4); | ||
l2.dispose(); | ||
emitter.emit(5); | ||
l3.dispose(); | ||
emitter.emit(6); | ||
chai_1.expect(s1.args).to.deep.equal([[1], [2], [3]]); | ||
chai_1.expect(s2.args).to.deep.equal([[2], [3], [4]]); | ||
chai_1.expect(s3.args).to.deep.equal([[3], [4], [5]]); | ||
}); | ||
@@ -52,3 +64,3 @@ it('memorizes event emissions', () => { | ||
chai_1.expect(await v).to.equal(42); | ||
chai_1.expect(emitter.listeners.size).to.equal(0); | ||
chai_1.expect(emitter.size).to.equal(0); | ||
}); | ||
@@ -61,3 +73,3 @@ it('cancels conversion to promise', async () => { | ||
await chai_1.expect(v).to.eventually.be.rejectedWith(TaskCancelledError_1.TaskCancelledError); | ||
chai_1.expect(emitter.listeners.size).to.equal(0); | ||
chai_1.expect(emitter.size).to.equal(0); | ||
}); | ||
@@ -68,5 +80,5 @@ it('cancels conversion to promise sync', async () => { | ||
await chai_1.expect(v).to.eventually.be.rejectedWith(TaskCancelledError_1.TaskCancelledError); | ||
chai_1.expect(emitter.listeners.size).to.equal(0); | ||
chai_1.expect(emitter.size).to.equal(0); | ||
}); | ||
}); | ||
//# sourceMappingURL=Event.test.js.map |
@@ -113,4 +113,2 @@ import { expect } from 'chai'; | ||
it('handles isolation correctly', async () => { | ||
p.onBreak(onBreak); | ||
p.onReset(onReset); | ||
const handle1 = p.isolate(); | ||
@@ -117,0 +115,0 @@ expect(onBreak).calledOnceWith({ isolated: true }); |
@@ -30,3 +30,3 @@ import { CancellationToken } from '../CancellationToken'; | ||
export declare class EventEmitter<T> { | ||
protected readonly listeners: Set<(data: T) => void>; | ||
private listeners?; | ||
/** | ||
@@ -45,2 +45,3 @@ * Event<T> function. | ||
protected addListenerInner(listener: (data: T) => void): IDisposable; | ||
private removeListener; | ||
} | ||
@@ -47,0 +48,0 @@ /** |
@@ -55,3 +55,2 @@ import { TaskCancelledError } from '../errors/TaskCancelledError'; | ||
constructor() { | ||
this.listeners = new Set(); | ||
/** | ||
@@ -66,3 +65,11 @@ * Event<T> function. | ||
get size() { | ||
return this.listeners.size; | ||
if (!this.listeners) { | ||
return 0; | ||
} | ||
else if (typeof this.listeners === 'function') { | ||
return 1; | ||
} | ||
else { | ||
return this.listeners.length; | ||
} | ||
} | ||
@@ -73,10 +80,47 @@ /** | ||
emit(value) { | ||
for (const listener of this.listeners) { | ||
listener(value); | ||
if (!this.listeners) { | ||
// no-op | ||
} | ||
else if (typeof this.listeners === 'function') { | ||
this.listeners(value); | ||
} | ||
else { | ||
for (const listener of this.listeners) { | ||
listener(value); | ||
} | ||
} | ||
} | ||
addListenerInner(listener) { | ||
this.listeners.add(listener); | ||
return { dispose: () => this.listeners.delete(listener) }; | ||
if (!this.listeners) { | ||
this.listeners = listener; | ||
} | ||
else if (typeof this.listeners === 'function') { | ||
this.listeners = [this.listeners, listener]; | ||
} | ||
else { | ||
this.listeners.push(listener); | ||
} | ||
return { dispose: () => this.removeListener(listener) }; | ||
} | ||
removeListener(listener) { | ||
if (!this.listeners) { | ||
return; | ||
} | ||
if (typeof this.listeners === 'function') { | ||
if (this.listeners === listener) { | ||
this.listeners = undefined; | ||
} | ||
return; | ||
} | ||
const index = this.listeners.indexOf(listener); | ||
if (index === -1) { | ||
return; | ||
} | ||
if (this.listeners.length === 2) { | ||
this.listeners = index === 0 ? this.listeners[1] : this.listeners[0]; | ||
} | ||
else { | ||
this.listeners = this.listeners.slice(0, index).concat(this.listeners.slice(index + 1)); | ||
} | ||
} | ||
} | ||
@@ -112,7 +156,5 @@ /** | ||
this.lastValue = { value }; | ||
for (const listener of this.listeners) { | ||
listener(value); | ||
} | ||
super.emit(value); | ||
} | ||
} | ||
//# sourceMappingURL=Event.js.map |
@@ -8,9 +8,21 @@ import { expect } from 'chai'; | ||
it('emits events', () => { | ||
const s = stub(); | ||
const s1 = stub(); | ||
const s2 = stub(); | ||
const s3 = stub(); | ||
const emitter = new EventEmitter(); | ||
const l = emitter.addListener(s); | ||
emitter.emit(42); | ||
l.dispose(); | ||
emitter.emit(43); | ||
expect(s).to.have.been.calledOnceWith(42); | ||
const l1 = emitter.addListener(s1); | ||
emitter.emit(1); | ||
const l2 = emitter.addListener(s2); | ||
emitter.emit(2); | ||
const l3 = emitter.addListener(s3); | ||
emitter.emit(3); | ||
l1.dispose(); | ||
emitter.emit(4); | ||
l2.dispose(); | ||
emitter.emit(5); | ||
l3.dispose(); | ||
emitter.emit(6); | ||
expect(s1.args).to.deep.equal([[1], [2], [3]]); | ||
expect(s2.args).to.deep.equal([[2], [3], [4]]); | ||
expect(s3.args).to.deep.equal([[3], [4], [5]]); | ||
}); | ||
@@ -50,3 +62,3 @@ it('memorizes event emissions', () => { | ||
expect(await v).to.equal(42); | ||
expect(emitter.listeners.size).to.equal(0); | ||
expect(emitter.size).to.equal(0); | ||
}); | ||
@@ -59,3 +71,3 @@ it('cancels conversion to promise', async () => { | ||
await expect(v).to.eventually.be.rejectedWith(TaskCancelledError); | ||
expect(emitter.listeners.size).to.equal(0); | ||
expect(emitter.size).to.equal(0); | ||
}); | ||
@@ -66,5 +78,5 @@ it('cancels conversion to promise sync', async () => { | ||
await expect(v).to.eventually.be.rejectedWith(TaskCancelledError); | ||
expect(emitter.listeners.size).to.equal(0); | ||
expect(emitter.size).to.equal(0); | ||
}); | ||
}); | ||
//# sourceMappingURL=Event.test.js.map |
@@ -1,2 +0,1 @@ | ||
export { Event, EventEmitter } from './common/Event'; | ||
export * from './backoff/Backoff'; | ||
@@ -7,7 +6,8 @@ export * from './breaker/Breaker'; | ||
export * from './CircuitBreakerPolicy'; | ||
export { Event, EventEmitter, IDisposable } from './common/Event'; | ||
export * from './errors/Errors'; | ||
export * from './FallbackPolicy'; | ||
export * from './NoopPolicy'; | ||
export * from './Policy'; | ||
export * from './RetryPolicy'; | ||
export * from './TimeoutPolicy'; | ||
export * from './NoopPolicy'; |
@@ -1,2 +0,1 @@ | ||
export { Event, EventEmitter } from './common/Event'; | ||
export * from './backoff/Backoff'; | ||
@@ -7,8 +6,9 @@ export * from './breaker/Breaker'; | ||
export * from './CircuitBreakerPolicy'; | ||
export { Event, EventEmitter } from './common/Event'; | ||
export * from './errors/Errors'; | ||
export * from './FallbackPolicy'; | ||
export * from './NoopPolicy'; | ||
export * from './Policy'; | ||
export * from './RetryPolicy'; | ||
export * from './TimeoutPolicy'; | ||
export * from './NoopPolicy'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,1 @@ | ||
export { Event, EventEmitter } from './common/Event'; | ||
export * from './backoff/Backoff'; | ||
@@ -7,7 +6,8 @@ export * from './breaker/Breaker'; | ||
export * from './CircuitBreakerPolicy'; | ||
export { Event, EventEmitter, IDisposable } from './common/Event'; | ||
export * from './errors/Errors'; | ||
export * from './FallbackPolicy'; | ||
export * from './NoopPolicy'; | ||
export * from './Policy'; | ||
export * from './RetryPolicy'; | ||
export * from './TimeoutPolicy'; | ||
export * from './NoopPolicy'; |
@@ -6,5 +6,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var Event_1 = require("./common/Event"); | ||
exports.Event = Event_1.Event; | ||
exports.EventEmitter = Event_1.EventEmitter; | ||
__export(require("./backoff/Backoff")); | ||
@@ -15,8 +12,11 @@ __export(require("./breaker/Breaker")); | ||
__export(require("./CircuitBreakerPolicy")); | ||
var Event_1 = require("./common/Event"); | ||
exports.Event = Event_1.Event; | ||
exports.EventEmitter = Event_1.EventEmitter; | ||
__export(require("./errors/Errors")); | ||
__export(require("./FallbackPolicy")); | ||
__export(require("./NoopPolicy")); | ||
__export(require("./Policy")); | ||
__export(require("./RetryPolicy")); | ||
__export(require("./TimeoutPolicy")); | ||
__export(require("./NoopPolicy")); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "cockatiel", | ||
"version": "2.0.1", | ||
"version": "2.0.2", | ||
"description": "A resilience and transient-fault-handling library that allows developers to express policies such as Backoff, Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner. Inspired by .NET Polly.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -50,3 +50,3 @@ # Cockatiel | ||
- [`policy.orResultType(ctor[, filter])`](#policyorresulttypector-filter) | ||
- [`Policy.handleResultWhen(filter)`](#policyhandleresultwhenfilter) | ||
- [`Policy.handleWhenResult(filter)`](#policyhandlewhenresultfilter) | ||
- [`policy.orWhenResult(filter)`](#policyorwhenresultfilter) | ||
@@ -200,3 +200,3 @@ - [`Policy.wrap(...policies)`](#policywrappolicies) | ||
### `Policy.handleResultWhen(filter)` | ||
### `Policy.handleWhenResult(filter)` | ||
@@ -208,3 +208,3 @@ ### `policy.orWhenResult(filter)` | ||
```ts | ||
Policy.handleResultWhen(res => res.statusCode === 503).orWhenResult(res => res.statusCode === 429); | ||
Policy.handleWhenResult(res => res.statusCode === 503).orWhenResult(res => res.statusCode === 429); | ||
// ... | ||
@@ -421,3 +421,3 @@ ``` | ||
return 100 * Math.pow(2, context.count); | ||
return { delay: 100 * Math.pow(2, context.count), state: context.result.error }; | ||
}); | ||
@@ -424,0 +424,0 @@ ``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
527325
7625