@ixfx/events 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../__tests__/test.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export * from './race.js';
2
+ export { SimpleEventEmitter } from './simple-event-emitter.js';
3
+ export * from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,cAAc,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './race.js';
2
+ export { SimpleEventEmitter } from './simple-event-emitter.js';
3
+ export * from './types.js';
@@ -0,0 +1,34 @@
1
+ export declare class MapOfSimple<T> {
2
+ #private;
3
+ /**
4
+ * Gets a copy of the underlying array storing values at `key`, or an empty array if
5
+ * key does not exist
6
+ * @param key
7
+ * @returns
8
+ */
9
+ get(key: string): T[];
10
+ /**
11
+ * Returns the number of values stored under `key`
12
+ * @param key
13
+ * @returns
14
+ */
15
+ size(key: string): number;
16
+ /**
17
+ * Iterate over all values contained under `key`
18
+ * @param key
19
+ * @returns
20
+ */
21
+ iterateKey(key: string): Generator<T>;
22
+ /**
23
+ * Iterate all values, regardless of key
24
+ */
25
+ iterateValues(): Generator<T>;
26
+ /**
27
+ * Iterate all keys
28
+ */
29
+ iterateKeys(): Generator<string>;
30
+ addKeyedValues(key: string, ...values: T[]): void;
31
+ deleteKeyValue(key: string, value: T): boolean;
32
+ clear(): void;
33
+ }
34
+ //# sourceMappingURL=map-of.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-of.d.ts","sourceRoot":"","sources":["../../src/map-of.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW,CAAC,CAAC;;IAGxB;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM;IAMf;;;;OAIG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM;IAMhB;;;;OAIG;IACF,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAMtC;;OAEG;IACF,aAAa,IAAI,SAAS,CAAC,CAAC,CAAC;IAM9B;;OAEG;IACF,WAAW,IAAI,SAAS,CAAC,MAAM,CAAC;IAIjC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE;IAS1C,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IASpC,KAAK;CAGN"}
@@ -0,0 +1,72 @@
1
+ export class MapOfSimple {
2
+ #store = new Map();
3
+ /**
4
+ * Gets a copy of the underlying array storing values at `key`, or an empty array if
5
+ * key does not exist
6
+ * @param key
7
+ * @returns
8
+ */
9
+ get(key) {
10
+ const arr = this.#store.get(key);
11
+ if (!arr)
12
+ return [];
13
+ return [...arr];
14
+ }
15
+ /**
16
+ * Returns the number of values stored under `key`
17
+ * @param key
18
+ * @returns
19
+ */
20
+ size(key) {
21
+ const arr = this.#store.get(key);
22
+ if (!arr)
23
+ return 0;
24
+ return arr.length;
25
+ }
26
+ /**
27
+ * Iterate over all values contained under `key`
28
+ * @param key
29
+ * @returns
30
+ */
31
+ *iterateKey(key) {
32
+ const arr = this.#store.get(key);
33
+ if (!arr)
34
+ return;
35
+ yield* arr.values();
36
+ }
37
+ /**
38
+ * Iterate all values, regardless of key
39
+ */
40
+ *iterateValues() {
41
+ for (const key of this.#store.keys()) {
42
+ yield* this.iterateKey(key);
43
+ }
44
+ }
45
+ /**
46
+ * Iterate all keys
47
+ */
48
+ *iterateKeys() {
49
+ yield* this.#store.keys();
50
+ }
51
+ addKeyedValues(key, ...values) {
52
+ let arr = this.#store.get(key);
53
+ if (!arr) {
54
+ arr = [];
55
+ this.#store.set(key, arr);
56
+ }
57
+ arr.push(...values);
58
+ }
59
+ deleteKeyValue(key, value) {
60
+ const arr = this.#store.get(key);
61
+ if (!arr)
62
+ return false;
63
+ const arrCopy = arr.filter(v => v !== value);
64
+ if (arrCopy.length === arr.length)
65
+ return false;
66
+ this.#store.set(key, arrCopy);
67
+ return true;
68
+ }
69
+ clear() {
70
+ this.#store.clear();
71
+ }
72
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Subscribes to events on `target`, returning the event data
3
+ * from the first event that fires.
4
+ *
5
+ * By default waits a maximum of 1 minute.
6
+ *
7
+ * Automatically unsubscribes on success or failure (ie. timeout)
8
+ *
9
+ * ```js
10
+ * // Event will be data from either event, whichever fires first
11
+ * // Exception is thrown if neither fires within 1 second
12
+ * const event = await eventRace(document.body, [`pointermove`, `pointerdown`], { timeout: 1000 });
13
+ * ```
14
+ * @param target Event source
15
+ * @param eventNames Event name(s)
16
+ * @param options Options
17
+ * @returns
18
+ */
19
+ export declare const eventRace: (target: EventTarget, eventNames: Array<string>, options?: Partial<{
20
+ timeoutMs: number;
21
+ signal: AbortSignal;
22
+ }>) => Promise<Event>;
23
+ //# sourceMappingURL=race.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"race.d.ts","sourceRoot":"","sources":["../../src/race.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,SAAS,GAAI,QAAQ,WAAW,EAAE,YAAY,KAAK,CAAC,MAAM,CAAC,EAAE,UAAS,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAAM,mBAmD1I,CAAA"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Subscribes to events on `target`, returning the event data
3
+ * from the first event that fires.
4
+ *
5
+ * By default waits a maximum of 1 minute.
6
+ *
7
+ * Automatically unsubscribes on success or failure (ie. timeout)
8
+ *
9
+ * ```js
10
+ * // Event will be data from either event, whichever fires first
11
+ * // Exception is thrown if neither fires within 1 second
12
+ * const event = await eventRace(document.body, [`pointermove`, `pointerdown`], { timeout: 1000 });
13
+ * ```
14
+ * @param target Event source
15
+ * @param eventNames Event name(s)
16
+ * @param options Options
17
+ * @returns
18
+ */
19
+ export const eventRace = (target, eventNames, options = {}) => {
20
+ const intervalMs = options.timeoutMs ?? 60_1000; //intervalToMs(options.timeout, 60 * 1000);
21
+ const signal = options.signal;
22
+ let triggered = false;
23
+ let disposed = false;
24
+ let timeout;
25
+ const promise = new Promise((resolve, reject) => {
26
+ const onEvent = (event) => {
27
+ if (`type` in event) {
28
+ if (eventNames.includes(event.type)) {
29
+ triggered = true;
30
+ resolve(event);
31
+ dispose();
32
+ }
33
+ else {
34
+ console.warn(`eventRace: Got event '${event.type}' that is not in race list`);
35
+ }
36
+ }
37
+ else {
38
+ console.warn(`eventRace: Event data does not have expected 'type' field`);
39
+ console.log(event);
40
+ }
41
+ };
42
+ for (const name of eventNames) {
43
+ target.addEventListener(name, onEvent);
44
+ }
45
+ const dispose = () => {
46
+ if (disposed)
47
+ return;
48
+ if (timeout !== undefined)
49
+ clearTimeout(timeout);
50
+ timeout = undefined;
51
+ disposed = true;
52
+ for (const name of eventNames) {
53
+ target.removeEventListener(name, onEvent);
54
+ }
55
+ };
56
+ timeout = setTimeout(() => {
57
+ if (triggered || disposed)
58
+ return;
59
+ dispose();
60
+ reject(new Error(`eventRace: Events not fired within interval. Events: ${JSON.stringify(eventNames)} Interval: ${intervalMs}`));
61
+ }, intervalMs);
62
+ signal?.addEventListener(`abort`, () => {
63
+ if (triggered || disposed)
64
+ return;
65
+ dispose();
66
+ reject(new Error(`Abort signal received ${signal.reason}`));
67
+ });
68
+ });
69
+ return promise;
70
+ };
@@ -0,0 +1,34 @@
1
+ import type { ISimpleEventEmitter } from "./types.js";
2
+ export declare class SimpleEventEmitter<Events> implements ISimpleEventEmitter<Events> {
3
+ #private;
4
+ dispose(): void;
5
+ get isDisposed(): boolean;
6
+ /**
7
+ * Fire event
8
+ * @param type Type of event
9
+ * @param args Arguments for event
10
+ * @returns
11
+ */
12
+ protected fireEvent<K extends keyof Events>(type: K, args: Events[K]): void;
13
+ /**
14
+ * Adds event listener.
15
+ *
16
+ * @throws Error if emitter is disposed
17
+ * @typeParam K - Events
18
+ * @param name Event name
19
+ * @param listener Event handler
20
+ */
21
+ addEventListener<K extends keyof Events>(name: K, listener: (event: Events[K], sender: SimpleEventEmitter<Events>) => void): void;
22
+ /**
23
+ * Remove event listener
24
+ *
25
+ * @param listener
26
+ */
27
+ removeEventListener<K extends keyof Events>(type: K, listener: (event: Events[K], sender: SimpleEventEmitter<Events>) => void): void;
28
+ /**
29
+ * Clear all event listeners
30
+ * @private
31
+ */
32
+ clearEventListeners(): void;
33
+ }
34
+ //# sourceMappingURL=simple-event-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple-event-emitter.d.ts","sourceRoot":"","sources":["../../src/simple-event-emitter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAY,MAAM,YAAY,CAAC;AAEhE,qBAAa,kBAAkB,CAAC,MAAM,CAAE,YAAW,mBAAmB,CAAC,MAAM,CAAC;;IAI5E,OAAO;IAKP,IAAI,UAAU,YAEb;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAS,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAE,CAAC,CAAE;IAQtE;;;;;;;OAOG;IACH,gBAAgB,CAAC,CAAC,SAAS,MAAM,MAAM,EACrC,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAE,CAAC,CAAE,EAAE,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,KAAK,IAAI,GACzE,IAAI;IAQP;;;;OAIG;IACH,mBAAmB,CAAC,CAAC,SAAS,MAAM,MAAM,EACxC,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAE,CAAC,CAAE,EAAE,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,KAAK,IAAI;IAW5E;;;OAGG;IACH,mBAAmB;CAIpB"}
@@ -0,0 +1,60 @@
1
+ import { MapOfSimple } from "./map-of.js";
2
+ export class SimpleEventEmitter {
3
+ #listeners = new MapOfSimple();
4
+ #disposed = false;
5
+ dispose() {
6
+ if (this.#disposed)
7
+ return;
8
+ this.clearEventListeners();
9
+ }
10
+ get isDisposed() {
11
+ return this.#disposed;
12
+ }
13
+ /**
14
+ * Fire event
15
+ * @param type Type of event
16
+ * @param args Arguments for event
17
+ * @returns
18
+ */
19
+ fireEvent(type, args) {
20
+ if (this.#disposed)
21
+ throw new Error(`Disposed`);
22
+ //console.log(`Firing ${ type as string }. Listeners: ${ this.#listeners.size(type as string) }`);
23
+ for (const l of this.#listeners.iterateKey(type)) {
24
+ l(args, this);
25
+ }
26
+ }
27
+ /**
28
+ * Adds event listener.
29
+ *
30
+ * @throws Error if emitter is disposed
31
+ * @typeParam K - Events
32
+ * @param name Event name
33
+ * @param listener Event handler
34
+ */
35
+ addEventListener(name, listener) {
36
+ if (this.#disposed)
37
+ throw new Error(`Disposed`);
38
+ this.#listeners.addKeyedValues(name, listener);
39
+ }
40
+ /**
41
+ * Remove event listener
42
+ *
43
+ * @param listener
44
+ */
45
+ removeEventListener(type, listener) {
46
+ if (this.#disposed)
47
+ return;
48
+ // listener: Listener<Events>): void {
49
+ this.#listeners.deleteKeyValue(type, listener);
50
+ }
51
+ /**
52
+ * Clear all event listeners
53
+ * @private
54
+ */
55
+ clearEventListeners() {
56
+ if (this.#disposed)
57
+ return;
58
+ this.#listeners.clear();
59
+ }
60
+ }
@@ -0,0 +1,6 @@
1
+ export type Listener<Events> = (event: unknown, sender: ISimpleEventEmitter<Events>) => void;
2
+ export type ISimpleEventEmitter<Events> = {
3
+ addEventListener<K extends keyof Events>(type: K, listener: (event: Events[K], sender: ISimpleEventEmitter<Events>) => void): void;
4
+ removeEventListener<K extends keyof Events>(type: K, listener: (event: Events[K], sender: ISimpleEventEmitter<Events>) => void): void;
5
+ };
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;AAE7F,MAAM,MAAM,mBAAmB,CAAC,MAAM,IAAI;IACxC,gBAAgB,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAE,CAAC,CAAE,EAAE,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACrI,mBAAmB,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAE,CAAC,CAAE,EAAE,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;CACzI,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ {"root":["../src/index.ts","../src/map-of.ts","../src/race.ts","../src/simple-event-emitter.ts","../src/types.ts","../__tests__/test.ts"],"version":"5.8.3"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@ixfx/events",
3
+ "version": "0.36.0",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "files": [
8
+ "dist/"
9
+ ],
10
+ "scripts": {
11
+ "build-test": "npx rimraf dist && tsc --build"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "types": "./src/index.ts",
16
+ "import": "./src/index.ts"
17
+ }
18
+ },
19
+ "dependencies": {},
20
+ "publishConfig": {
21
+ "main": "dist/src/index.js",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/src/index.d.ts",
25
+ "import": "./dist/src/index.js"
26
+ }
27
+ }
28
+ }
29
+ }