@wixc3/patterns
Advanced tools
Comparing version 14.0.0 to 14.1.0
@@ -90,3 +90,3 @@ import { GroupConstraints } from './constraints'; | ||
*/ | ||
dispose: () => Promise<void>; | ||
dispose(): Promise<void>; | ||
/** | ||
@@ -93,0 +93,0 @@ * |
@@ -57,11 +57,2 @@ "use strict"; | ||
this.constrains = []; | ||
/** | ||
* Disposes all disposables in all groups one at the time, | ||
* order based on constraints | ||
*/ | ||
this.dispose = async () => { | ||
for (const { disposables } of this.groups) { | ||
await disposables.dispose(); | ||
} | ||
}; | ||
this.groups.push(...initialGroups.map(createGroup)); | ||
@@ -130,2 +121,11 @@ } | ||
/** | ||
* Disposes all disposables in all groups one at the time, | ||
* order based on constraints | ||
*/ | ||
async dispose() { | ||
for (const { disposables } of this.groups) { | ||
await disposables.dispose(); | ||
} | ||
} | ||
/** | ||
* | ||
@@ -132,0 +132,0 @@ * @returns a serialized list of groups and their disposables and constraints |
@@ -8,2 +8,3 @@ import { Disposables } from '.'; | ||
/** | ||
* @deprecated | ||
* A base class for disposable objects | ||
@@ -10,0 +11,0 @@ * @example |
@@ -14,2 +14,3 @@ "use strict"; | ||
/** | ||
* @deprecated | ||
* A base class for disposable objects | ||
@@ -16,0 +17,0 @@ * @example |
export * from './create-disposables'; | ||
export * from './disposable'; | ||
export * from './safe-disposable'; | ||
export type { DisposableItem } from './disposables-group'; | ||
export { DisposalGroup, GroupConstraints } from './constraints'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -19,2 +19,3 @@ "use strict"; | ||
__exportStar(require("./disposable"), exports); | ||
__exportStar(require("./safe-disposable"), exports); | ||
//# sourceMappingURL=index.js.map |
import { Signal } from './signal'; | ||
/** | ||
* A simple event emitter | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
@@ -5,0 +26,0 @@ export declare class EventEmitter<Events extends object, EventId extends keyof Events = keyof Events> { |
@@ -6,3 +6,24 @@ "use strict"; | ||
/** | ||
* A simple event emitter | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
@@ -9,0 +30,0 @@ class EventEmitter { |
@@ -34,2 +34,3 @@ export type Listener<T> = (data: T) => void; | ||
export declare class Signal<T> extends Set<Listener<T>> { | ||
private onceHandlers; | ||
/** | ||
@@ -39,3 +40,4 @@ * Subscribe a notification callback | ||
*/ | ||
subscribe: (handler: Listener<T>) => void; | ||
subscribe: (handler: Listener<T>) => () => void; | ||
once: (handler: Listener<T>) => () => void; | ||
/** | ||
@@ -49,27 +51,4 @@ * Unsubscribe an existing callback | ||
notify: (data: T) => void; | ||
clear(): void; | ||
} | ||
/** | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
//# sourceMappingURL=signal.d.ts.map |
@@ -38,2 +38,3 @@ "use strict"; | ||
super(...arguments); | ||
this.onceHandlers = new Set(); | ||
/** | ||
@@ -45,3 +46,8 @@ * Subscribe a notification callback | ||
this.add(handler); | ||
return () => this.unsubscribe(handler); | ||
}; | ||
this.once = (handler) => { | ||
this.onceHandlers.add(handler); | ||
return () => this.unsubscribe(handler); | ||
}; | ||
/** | ||
@@ -51,2 +57,3 @@ * Unsubscribe an existing callback | ||
this.unsubscribe = (handler) => { | ||
this.onceHandlers.delete(handler); | ||
this.delete(handler); | ||
@@ -61,30 +68,14 @@ }; | ||
} | ||
for (const handler of this.onceHandlers) { | ||
handler(data); | ||
this.onceHandlers.delete(handler); | ||
} | ||
}; | ||
} | ||
clear() { | ||
super.clear(); | ||
this.onceHandlers.clear(); | ||
} | ||
} | ||
exports.Signal = Signal; | ||
/** | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
//# sourceMappingURL=signal.js.map |
@@ -90,3 +90,3 @@ import { GroupConstraints } from './constraints'; | ||
*/ | ||
dispose: () => Promise<void>; | ||
dispose(): Promise<void>; | ||
/** | ||
@@ -93,0 +93,0 @@ * |
@@ -53,11 +53,2 @@ import { getGroupConstrainedIndex, normalizeConstraints } from './constraints'; | ||
this.constrains = []; | ||
/** | ||
* Disposes all disposables in all groups one at the time, | ||
* order based on constraints | ||
*/ | ||
this.dispose = async () => { | ||
for (const { disposables } of this.groups) { | ||
await disposables.dispose(); | ||
} | ||
}; | ||
this.groups.push(...initialGroups.map(createGroup)); | ||
@@ -126,2 +117,11 @@ } | ||
/** | ||
* Disposes all disposables in all groups one at the time, | ||
* order based on constraints | ||
*/ | ||
async dispose() { | ||
for (const { disposables } of this.groups) { | ||
await disposables.dispose(); | ||
} | ||
} | ||
/** | ||
* | ||
@@ -128,0 +128,0 @@ * @returns a serialized list of groups and their disposables and constraints |
@@ -8,2 +8,3 @@ import { Disposables } from '.'; | ||
/** | ||
* @deprecated | ||
* A base class for disposable objects | ||
@@ -10,0 +11,0 @@ * @example |
@@ -11,2 +11,3 @@ import { defaults, noop } from '@wixc3/common'; | ||
/** | ||
* @deprecated | ||
* A base class for disposable objects | ||
@@ -13,0 +14,0 @@ * @example |
export * from './create-disposables'; | ||
export * from './disposable'; | ||
export * from './safe-disposable'; | ||
export type { DisposableItem } from './disposables-group'; | ||
export { DisposalGroup, GroupConstraints } from './constraints'; | ||
//# sourceMappingURL=index.d.ts.map |
export * from './create-disposables'; | ||
export * from './disposable'; | ||
export * from './safe-disposable'; | ||
//# sourceMappingURL=index.js.map |
import { Signal } from './signal'; | ||
/** | ||
* A simple event emitter | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
@@ -5,0 +26,0 @@ export declare class EventEmitter<Events extends object, EventId extends keyof Events = keyof Events> { |
import { Signal } from './signal'; | ||
/** | ||
* A simple event emitter | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
@@ -5,0 +26,0 @@ export class EventEmitter { |
@@ -34,2 +34,3 @@ export type Listener<T> = (data: T) => void; | ||
export declare class Signal<T> extends Set<Listener<T>> { | ||
private onceHandlers; | ||
/** | ||
@@ -39,3 +40,4 @@ * Subscribe a notification callback | ||
*/ | ||
subscribe: (handler: Listener<T>) => void; | ||
subscribe: (handler: Listener<T>) => () => void; | ||
once: (handler: Listener<T>) => () => void; | ||
/** | ||
@@ -49,27 +51,4 @@ * Unsubscribe an existing callback | ||
notify: (data: T) => void; | ||
clear(): void; | ||
} | ||
/** | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
//# sourceMappingURL=signal.d.ts.map |
@@ -35,2 +35,3 @@ /** | ||
super(...arguments); | ||
this.onceHandlers = new Set(); | ||
/** | ||
@@ -42,3 +43,8 @@ * Subscribe a notification callback | ||
this.add(handler); | ||
return () => this.unsubscribe(handler); | ||
}; | ||
this.once = (handler) => { | ||
this.onceHandlers.add(handler); | ||
return () => this.unsubscribe(handler); | ||
}; | ||
/** | ||
@@ -48,2 +54,3 @@ * Unsubscribe an existing callback | ||
this.unsubscribe = (handler) => { | ||
this.onceHandlers.delete(handler); | ||
this.delete(handler); | ||
@@ -58,29 +65,13 @@ }; | ||
} | ||
for (const handler of this.onceHandlers) { | ||
handler(data); | ||
this.onceHandlers.delete(handler); | ||
} | ||
}; | ||
} | ||
clear() { | ||
super.clear(); | ||
this.onceHandlers.clear(); | ||
} | ||
} | ||
/** | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
//# sourceMappingURL=signal.js.map |
{ | ||
"name": "@wixc3/patterns", | ||
"version": "14.0.0", | ||
"version": "14.1.0", | ||
"description": "A utility for saving objects to be disposed", | ||
@@ -21,5 +21,5 @@ "main": "dist/cjs/index.js", | ||
"dependencies": { | ||
"@wixc3/common": "^14.0.0", | ||
"@wixc3/common": "^14.1.0", | ||
"promise-assist": "^2.0.1" | ||
} | ||
} |
@@ -37,3 +37,7 @@ import { deferred } from 'promise-assist'; | ||
*/ | ||
constructor(private cb: T, private waitTime: number, private maxWaitTime: number) {} | ||
constructor( | ||
private cb: T, | ||
private waitTime: number, | ||
private maxWaitTime: number, | ||
) {} | ||
@@ -40,0 +44,0 @@ private execute() { |
@@ -37,3 +37,3 @@ import type { DisposablesGroup } from './disposables-group'; | ||
throw new Error( | ||
`Invalid constraints: ${existingGroups[lastAfter]?.name} runs after ${existingGroups[firstBefore]?.name}, which contradicts prior constraints` | ||
`Invalid constraints: ${existingGroups[lastAfter]?.name} runs after ${existingGroups[firstBefore]?.name}, which contradicts prior constraints`, | ||
); | ||
@@ -48,3 +48,3 @@ } | ||
name: string, | ||
groups: DisposalGroup[] | ||
groups: DisposalGroup[], | ||
) => { | ||
@@ -51,0 +51,0 @@ const _constraints: GroupConstraints[] = Array.isArray(constraints) ? constraints : [constraints]; |
@@ -75,3 +75,6 @@ import { DisposalGroup, getGroupConstrainedIndex, GroupConstraints, normalizeConstraints } from './constraints'; | ||
private readonly constrains: GroupConstraints[] = []; | ||
constructor(private name: string, initialGroups: string[] = []) { | ||
constructor( | ||
private name: string, | ||
initialGroups: string[] = [], | ||
) { | ||
this.groups.push(...initialGroups.map(createGroup)); | ||
@@ -115,3 +118,3 @@ } | ||
throw new Error( | ||
`Invalid disposable: must be a function or object with a dispose method got ${disposable}` | ||
`Invalid disposable: must be a function or object with a dispose method got ${disposable}`, | ||
); | ||
@@ -150,7 +153,7 @@ } | ||
*/ | ||
dispose = async () => { | ||
async dispose() { | ||
for (const { disposables } of this.groups) { | ||
await disposables.dispose(); | ||
} | ||
}; | ||
} | ||
@@ -157,0 +160,0 @@ /** |
@@ -12,2 +12,3 @@ import { defaults, noop } from '@wixc3/common'; | ||
/** | ||
* @deprecated | ||
* A base class for disposable objects | ||
@@ -102,3 +103,3 @@ * @example | ||
async: never; | ||
} & Partial<typeof DISPOSAL_GUARD_DEFAULTS> | ||
} & Partial<typeof DISPOSAL_GUARD_DEFAULTS>, | ||
): () => void; | ||
@@ -105,0 +106,0 @@ disposalGuard(): () => void; |
@@ -17,3 +17,3 @@ import { timeout } from 'promise-assist'; | ||
details.timeout, | ||
`Disposal timed out: "${details.name}" after ${details.timeout}ms` | ||
`Disposal timed out: "${details.name}" after ${details.timeout}ms`, | ||
); | ||
@@ -20,0 +20,0 @@ } catch (e) { |
export * from './create-disposables'; | ||
export * from './disposable'; | ||
export * from './safe-disposable'; | ||
export type { DisposableItem } from './disposables-group'; | ||
export { DisposalGroup, GroupConstraints } from './constraints'; |
import { Signal } from './signal'; | ||
/** | ||
* A simple event emitter | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ | ||
@@ -6,0 +27,0 @@ export class EventEmitter<Events extends object, EventId extends keyof Events = keyof Events> { |
@@ -35,2 +35,3 @@ export type Listener<T> = (data: T) => void; | ||
export class Signal<T> extends Set<Listener<T>> { | ||
private onceHandlers = new Set<Listener<T>>(); | ||
/** | ||
@@ -42,3 +43,9 @@ * Subscribe a notification callback | ||
this.add(handler); | ||
return () => this.unsubscribe(handler); | ||
}; | ||
once = (handler: Listener<T>) => { | ||
this.onceHandlers.add(handler); | ||
return () => this.unsubscribe(handler); | ||
}; | ||
/** | ||
@@ -48,2 +55,3 @@ * Unsubscribe an existing callback | ||
unsubscribe = (handler: Listener<T>) => { | ||
this.onceHandlers.delete(handler); | ||
this.delete(handler); | ||
@@ -58,28 +66,12 @@ }; | ||
} | ||
for (const handler of this.onceHandlers) { | ||
handler(data); | ||
this.onceHandlers.delete(handler); | ||
} | ||
}; | ||
override clear(): void { | ||
super.clear(); | ||
this.onceHandlers.clear(); | ||
} | ||
} | ||
/** | ||
* Basic type safe event emitter | ||
* @example | ||
* ```ts | ||
* const ms = new EventEmitter<{ onChange: { id: 'onChange' }; onDelete: { id: 'onDelete' } }>(); | ||
* ms.subscribe('onChange', (event) => { | ||
* event.id; // 'onChange' | ||
* }); | ||
* ms.subscribe('onDelete', (event) => { | ||
* event.id; // 'onDelete' | ||
* }); | ||
* | ||
* ms.notify('onChange', { id: 'onChange' }); // event is type safe | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onChange', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
* @example <caption>payload type mismatch</caption> | ||
* ```ts | ||
* ms.notify('onSomethingElse', { id: 'onDelete' }); // ERROR!!! | ||
* ``` | ||
*/ |
@@ -37,3 +37,3 @@ import { expect } from 'chai'; | ||
expect(() => disposable.disposalGuard({ async: false, usedWhileDisposing: true })).to.throw( | ||
'Instance was disposed' | ||
'Instance was disposed', | ||
); | ||
@@ -40,0 +40,0 @@ }); |
@@ -53,3 +53,3 @@ import { expect, use } from 'chai'; | ||
await expect(disposables.dispose()).to.be.rejectedWith( | ||
/Disposal failed: "\[test\]: disposing with error"\nError: failed!/ | ||
/Disposal failed: "\[test\]: disposing with error"\nError: failed!/, | ||
); | ||
@@ -83,3 +83,3 @@ }); | ||
expect(() => groups.registerGroup('group1', { before: 'group2' })).to.throw( | ||
`Invalid constraint: "before: group2" - group not found` | ||
`Invalid constraint: "before: group2" - group not found`, | ||
); | ||
@@ -90,3 +90,3 @@ }); | ||
expect(() => groups.registerGroup('group1', [])).to.throw( | ||
`Invalid disposal group: must have at least one constraint` | ||
`Invalid disposal group: must have at least one constraint`, | ||
); | ||
@@ -100,3 +100,3 @@ }); | ||
expect(() => groups.registerGroup('invalid', { before: 'before', after: 'after' })).to.throw( | ||
'Invalid constraints: after runs after before, which contradicts prior constraints' | ||
'Invalid constraints: after runs after before, which contradicts prior constraints', | ||
); | ||
@@ -107,3 +107,3 @@ }); | ||
expect(() => groups.registerGroup('default', { before: 'default' })).to.throw( | ||
`Invalid group: "default" already exists` | ||
`Invalid group: "default" already exists`, | ||
); | ||
@@ -110,0 +110,0 @@ }); |
@@ -8,27 +8,84 @@ import chai, { expect } from 'chai'; | ||
chai.use(sinonChai); | ||
interface ChangeEvent { | ||
a: string; | ||
b: number; | ||
} | ||
describe('Signal', () => { | ||
it('should subscribe to accept events and unsubscribe to stop accepting event', () => { | ||
interface ChangeEvent { | ||
a: string; | ||
b: number; | ||
} | ||
const signal = new Signal<ChangeEvent>(); | ||
const onChange = stub(); | ||
let signal: Signal<ChangeEvent>; | ||
let listener = stub(); | ||
beforeEach(() => { | ||
signal = new Signal<ChangeEvent>(); | ||
listener = stub(); | ||
}); | ||
it(`doesn't call listeners before "notify(...)"`, () => { | ||
signal.subscribe(listener); | ||
expect(listener.callCount, 'not calls before event dispatch').to.eql(0); | ||
}); | ||
it('calls listeners after "notify(...)"', () => { | ||
signal.subscribe(listener); | ||
signal.notify({ a: 'value', b: 5 }); | ||
signal.subscribe(onChange); | ||
expect(listener.callCount, 'calls listeners').to.eql(1); | ||
expect(listener.lastCall.args[0], 'event value').to.eql({ a: 'value', b: 5 }); | ||
}); | ||
it('ignores double subscriptions', () => { | ||
signal.subscribe(listener); | ||
signal.subscribe(listener); | ||
signal.subscribe(listener); | ||
expect(onChange.callCount, 'not calls before event dispatch').to.eql(0); | ||
signal.notify({ a: 'value', b: 5 }); | ||
expect(onChange.callCount, 'not calls before event dispatch').to.eql(1); | ||
expect(onChange.lastCall.args[0], 'event value').to.eql({ a: 'value', b: 5 }); | ||
expect(listener.callCount, 'ignore double subscriptions').to.eql(1); | ||
}); | ||
describe('once', () => { | ||
it('calls "once" listeners only one time', () => { | ||
signal.once(listener); | ||
signal.notify({ a: 'value', b: 5 }); | ||
signal.notify({ a: 'value', b: 6 }); | ||
signal.unsubscribe(onChange); | ||
expect(listener.callCount, 'is called only once').to.eql(1); | ||
expect(listener.lastCall.args[0], 'with the first event').to.eql({ a: 'value', b: 5 }); | ||
}); | ||
it('ignores double "once" subscriptions', () => { | ||
signal.once(listener); | ||
signal.once(listener); | ||
signal.once(listener); | ||
signal.notify({ a: 'other-value', b: 10 }); | ||
signal.notify({ a: 'value', b: 5 }); | ||
expect(onChange.callCount, 'no new calls after unsubscribe').to.eql(1); | ||
expect(listener.callCount, 'ignore double subscriptions').to.eql(1); | ||
}); | ||
it(`doesn't call listeners after "unsubscribe"`, () => { | ||
signal.once(listener); | ||
signal.unsubscribe(listener); | ||
signal.notify({ a: 'value', b: 5 }); | ||
expect(listener.callCount, 'no new calls after unsubscribe').to.eql(0); | ||
}); | ||
}); | ||
it(`doesn't call listeners after "unsubscribe"`, () => { | ||
signal.subscribe(listener); | ||
signal.unsubscribe(listener); | ||
signal.notify({ a: 'value', b: 5 }); | ||
expect(listener.callCount, 'no new calls after unsubscribe').to.eql(0); | ||
}); | ||
it(`doesn't call listeners after unsubscribing using subscribe return value`, () => { | ||
const unsubscribe = signal.subscribe(listener); | ||
unsubscribe(); | ||
signal.notify({ a: 'value', b: 5 }); | ||
expect(listener.callCount, 'no new calls after unsubscribe').to.eql(0); | ||
}); | ||
describe('clear', () => { | ||
it('removes all listeners', () => { | ||
signal.subscribe(listener); | ||
signal.clear(); | ||
signal.notify({ a: 'value', b: 5 }); | ||
expect(listener.callCount, 'no new calls after clear').to.eql(0); | ||
}); | ||
it('removes all "once" listeners', () => { | ||
signal.once(listener); | ||
signal.clear(); | ||
signal.notify({ a: 'value', b: 5 }); | ||
expect(listener.callCount, 'no new calls after clear').to.eql(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
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
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
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
255464
121
4963
Updated@wixc3/common@^14.1.0